Skip to content

Commit d2b3aa7

Browse files
committed
feat(mistral): Enhance Mistral provider with new models and API integration
- Updated model aliases in aliases.json to include specific paths for Mistral models. - Added `mistral_api_base` configuration option in configuration.rb. - Introduced new models in models.json, including Mistral Tiny, Pixtral Large, and others. - Refactored Mistral provider methods to support new API structure and error handling. - Removed deprecated image generation methods from the Mistral provider. - Updated tests to reflect changes in model handling and API responses.
1 parent b617cc2 commit d2b3aa7

File tree

55 files changed

+7087
-642
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+7087
-642
lines changed

lib/ruby_llm/aliases.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@
7878
"openrouter": "openai/o3-mini"
7979
},
8080
"mistral-medium": {
81-
"mistral": "mistral-medium-latest"
81+
"mistral": "mistral/mistral-medium-latest"
8282
},
8383
"mistral-large": {
84-
"mistral": "mistral-large-latest"
84+
"mistral": "mistral/mistral-large"
8585
},
8686
"mistral-small": {
87-
"mistral": "mistral-small-latest"
87+
"mistral": "mistral/mistral-small"
8888
}
8989
}

lib/ruby_llm/configuration.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Configuration
2222
:bedrock_session_token,
2323
:openrouter_api_key,
2424
:ollama_api_base,
25+
:mistral_api_base,
2526
:mistral_api_key,
2627
# Default models
2728
:default_model,

lib/ruby_llm/models.json

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11517,8 +11517,62 @@
1151711517
}
1151811518
},
1151911519
{
11520-
"id": "mistralai/mistral-embed",
11521-
"created_at": "2024-03-15T00:00:00Z",
11520+
"id": "mistral-tiny",
11521+
"created_at": "2024-12-23T00:00:00Z",
11522+
"display_name": "Mistral Tiny",
11523+
"provider": "mistral",
11524+
"context_window": 32768,
11525+
"max_tokens": 32768,
11526+
"type": "chat",
11527+
"family": "mistral_tiny",
11528+
"supports_vision": false,
11529+
"supports_functions": true,
11530+
"supports_json_mode": true,
11531+
"input_price_per_million": 0.14,
11532+
"output_price_per_million": 0.42,
11533+
"metadata": {
11534+
"description": "Most affordable model in the Mistral lineup"
11535+
}
11536+
},
11537+
{
11538+
"id": "pixtral-large",
11539+
"created_at": "2024-11-24T00:00:00Z",
11540+
"display_name": "Pixtral Large",
11541+
"provider": "mistral",
11542+
"context_window": 131072,
11543+
"max_tokens": 131072,
11544+
"type": "chat",
11545+
"family": "pixtral_large",
11546+
"supports_vision": true,
11547+
"supports_functions": true,
11548+
"supports_json_mode": true,
11549+
"input_price_per_million": 3,
11550+
"output_price_per_million": 9,
11551+
"metadata": {
11552+
"description": "Pixtral Large - frontier-class multimodal model"
11553+
}
11554+
},
11555+
{
11556+
"id": "codestral",
11557+
"created_at": "2025-01-25T00:00:00Z",
11558+
"display_name": "Codestral",
11559+
"provider": "mistral",
11560+
"context_window": 262144,
11561+
"max_tokens": 262144,
11562+
"type": "chat",
11563+
"family": "codestral",
11564+
"supports_vision": false,
11565+
"supports_functions": true,
11566+
"supports_json_mode": true,
11567+
"input_price_per_million": 1,
11568+
"output_price_per_million": 3,
11569+
"metadata": {
11570+
"description": "Codestral - specialized model for code generation"
11571+
}
11572+
},
11573+
{
11574+
"id": "mistral-embed",
11575+
"created_at": "2023-12-23T00:00:00Z",
1152211576
"display_name": "Mistral Embed",
1152311577
"provider": "mistral",
1152411578
"context_window": 32768,
@@ -11534,6 +11588,114 @@
1153411588
"description": "Mistral Embed - specialized model for generating text embeddings"
1153511589
}
1153611590
},
11591+
{
11592+
"id": "mistral-large-latest",
11593+
"created_at": "2024-11-24T00:00:00Z",
11594+
"display_name": "Mistral Large (Latest)",
11595+
"provider": "mistral",
11596+
"context_window": 131072,
11597+
"max_tokens": 131072,
11598+
"type": "chat",
11599+
"family": "mistral_large",
11600+
"supports_vision": false,
11601+
"supports_functions": true,
11602+
"supports_json_mode": true,
11603+
"input_price_per_million": 3,
11604+
"output_price_per_million": 9,
11605+
"metadata": {
11606+
"description": "Mistral Large 2 - top-tier reasoning model for high-complexity tasks"
11607+
}
11608+
},
11609+
{
11610+
"id": "mistral-small-latest",
11611+
"created_at": "2025-03-25T00:00:00Z",
11612+
"display_name": "Mistral Small (Latest)",
11613+
"provider": "mistral",
11614+
"context_window": 131072,
11615+
"max_tokens": 131072,
11616+
"type": "chat",
11617+
"family": "mistral_small",
11618+
"supports_vision": true,
11619+
"supports_functions": true,
11620+
"supports_json_mode": true,
11621+
"input_price_per_million": 0.2,
11622+
"output_price_per_million": 0.6,
11623+
"metadata": {
11624+
"description": "Mistral Small (Latest) - balanced model with good performance/cost ratio"
11625+
}
11626+
},
11627+
{
11628+
"id": "pixtral-12b-latest",
11629+
"created_at": "2024-09-25T00:00:00Z",
11630+
"display_name": "Pixtral 12B (Latest)",
11631+
"provider": "mistral",
11632+
"context_window": 131072,
11633+
"max_tokens": 131072,
11634+
"type": "chat",
11635+
"family": "pixtral",
11636+
"supports_vision": true,
11637+
"supports_functions": true,
11638+
"supports_json_mode": true,
11639+
"input_price_per_million": 0.15,
11640+
"output_price_per_million": 0.15,
11641+
"metadata": {
11642+
"description": "Pixtral 12B - Mistral's first multimodal model with vision capabilities"
11643+
}
11644+
},
11645+
{
11646+
"id": "mistral-saba",
11647+
"created_at": "2025-02-25T00:00:00Z",
11648+
"display_name": "Mistral Saba",
11649+
"provider": "mistral",
11650+
"context_window": 32768,
11651+
"max_tokens": 32768,
11652+
"type": "chat",
11653+
"family": "mistral_saba",
11654+
"supports_vision": false,
11655+
"supports_functions": true,
11656+
"supports_json_mode": true,
11657+
"input_price_per_million": 0.3,
11658+
"output_price_per_million": 0.3,
11659+
"metadata": {
11660+
"description": "Mistral Saba - powerful and efficient model for languages from the Middle East and South Asia"
11661+
}
11662+
},
11663+
{
11664+
"id": "mistral-moderation",
11665+
"created_at": "2024-11-24T00:00:00Z",
11666+
"display_name": "Mistral Moderation",
11667+
"provider": "mistral",
11668+
"context_window": 32768,
11669+
"max_tokens": 32768,
11670+
"type": "moderation",
11671+
"family": "mistral_moderation",
11672+
"supports_vision": false,
11673+
"supports_functions": false,
11674+
"supports_json_mode": false,
11675+
"input_price_per_million": 0.0,
11676+
"output_price_per_million": 0.0,
11677+
"metadata": {
11678+
"description": "Mistral Moderation - service that enables users to detect harmful text content"
11679+
}
11680+
},
11681+
{
11682+
"id": "mistral-ocr",
11683+
"created_at": "2025-03-25T00:00:00Z",
11684+
"display_name": "Mistral OCR",
11685+
"provider": "mistral",
11686+
"context_window": 32768,
11687+
"max_tokens": 32768,
11688+
"type": "ocr",
11689+
"family": "mistral_ocr",
11690+
"supports_vision": true,
11691+
"supports_functions": false,
11692+
"supports_json_mode": false,
11693+
"input_price_per_million": 0.0,
11694+
"output_price_per_million": 0.0,
11695+
"metadata": {
11696+
"description": "Mistral OCR - service that enables users to extract interleaved text and images"
11697+
}
11698+
},
1153711699
{
1153811700
"id": "moonshotai/kimi-vl-a3b-thinking:free",
1153911701
"created_at": "2025-04-10T19:07:21+02:00",

lib/ruby_llm/providers/mistral.rb

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Mistral
1111
extend Mistral::Tools
1212
extend Mistral::Capabilities
1313
extend Mistral::Media
14+
# Mistral::Images removed as API doesn't support image generation
1415

1516
def self.extended(base)
1617
base.extend(Provider)
@@ -25,13 +26,42 @@ def self.extended(base)
2526

2627
module_function
2728

28-
def api_base
29-
'https://api.mistral.ai/v1'
29+
def api_base(config)
30+
config.mistral_api_base || 'https://api.mistral.ai/v1'
3031
end
3132

32-
def headers
33+
# Add provider-specific error parsing
34+
def parse_error(response)
35+
return if response.body.empty?
36+
37+
body = try_parse_json(response.body)
38+
error_message = case body
39+
when Hash
40+
# Check for standard { detail: [{ msg: ... }] } structure
41+
if body['detail'].is_a?(Array)
42+
body['detail'].map { |err| err['msg'] }.join("; ")
43+
# Check for simple { message: ... } structure (some Mistral errors use this)
44+
elsif body['message']
45+
body['message']
46+
# Fallback for other hash structures
47+
else
48+
body.to_s
49+
end
50+
else
51+
body.to_s # Return raw body if not a hash
52+
end
53+
54+
# Format the error message
55+
if error_message.include?('Input should be a valid')
56+
"Invalid message format: The message content is not properly formatted"
57+
else
58+
error_message
59+
end
60+
end
61+
62+
def headers(config)
3363
{
34-
'Authorization' => "Bearer #{RubyLLM.config.mistral_api_key}"
64+
'Authorization' => "Bearer #{config.mistral_api_key}"
3565
}
3666
end
3767

lib/ruby_llm/providers/mistral/capabilities.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,8 @@ def output_price_for(model_id)
5151
# @param model_id [String] the model identifier
5252
# @return [Boolean] true if the model supports vision
5353
def supports_vision?(model_id)
54-
# Check for all vision-capable models in Mistral's lineup
55-
#
56-
# NOTE: While this correctly identifies models that support vision capabilities,
57-
# there are currently issues with the image handling in the test suite.
58-
# The 'pixtral-12b-latest can understand images' test fails because image data
59-
# isn't properly passed to the API. This requires fixes in the core Content handling code.
60-
#
61-
# Known vision-capable models in Mistral's lineup:
62-
# - pixtral-12b-latest
63-
# - pixtral-large-latest
64-
model_id.match?(/pixtral|mistral-large-vision|other-vision-models/)
54+
# Determine vision support based on model ID pattern
55+
model_id.match?(/pixtral/)
6556
end
6657

6758
# Determines if the model supports function calling

0 commit comments

Comments
 (0)