Skip to content

Commit 09b192b

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 d2ee337 commit 09b192b

File tree

55 files changed

+7389
-554
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

+7389
-554
lines changed

lib/ruby_llm/aliases.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,12 @@
202202
"openrouter": "openai/o3-mini"
203203
},
204204
"mistral-medium": {
205-
"mistral": "mistral-medium-latest"
205+
"mistral": "mistral/mistral-medium-latest"
206206
},
207207
"mistral-large": {
208-
"mistral": "mistral-large-latest"
208+
"mistral": "mistral/mistral-large"
209209
},
210210
"mistral-small": {
211-
"mistral": "mistral-small-latest"
211+
"mistral": "mistral/mistral-small"
212212
}
213213
}

lib/ruby_llm/configuration.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Configuration
2424
:bedrock_session_token,
2525
:openrouter_api_key,
2626
:ollama_api_base,
27+
:mistral_api_base,
2728
:mistral_api_key,
2829
# Default models
2930
:default_model,

lib/ruby_llm/models.json

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18980,8 +18980,62 @@
1898018980
}
1898118981
},
1898218982
{
18983-
"id": "mistralai/mistral-embed",
18984-
"created_at": "2024-03-15T00:00:00Z",
18983+
"id": "mistral-tiny",
18984+
"created_at": "2024-12-23T00:00:00Z",
18985+
"display_name": "Mistral Tiny",
18986+
"provider": "mistral",
18987+
"context_window": 32768,
18988+
"max_tokens": 32768,
18989+
"type": "chat",
18990+
"family": "mistral_tiny",
18991+
"supports_vision": false,
18992+
"supports_functions": true,
18993+
"supports_json_mode": true,
18994+
"input_price_per_million": 0.14,
18995+
"output_price_per_million": 0.42,
18996+
"metadata": {
18997+
"description": "Most affordable model in the Mistral lineup"
18998+
}
18999+
},
19000+
{
19001+
"id": "pixtral-large",
19002+
"created_at": "2024-11-24T00:00:00Z",
19003+
"display_name": "Pixtral Large",
19004+
"provider": "mistral",
19005+
"context_window": 131072,
19006+
"max_tokens": 131072,
19007+
"type": "chat",
19008+
"family": "pixtral_large",
19009+
"supports_vision": true,
19010+
"supports_functions": true,
19011+
"supports_json_mode": true,
19012+
"input_price_per_million": 3,
19013+
"output_price_per_million": 9,
19014+
"metadata": {
19015+
"description": "Pixtral Large - frontier-class multimodal model"
19016+
}
19017+
},
19018+
{
19019+
"id": "codestral",
19020+
"created_at": "2025-01-25T00:00:00Z",
19021+
"display_name": "Codestral",
19022+
"provider": "mistral",
19023+
"context_window": 262144,
19024+
"max_tokens": 262144,
19025+
"type": "chat",
19026+
"family": "codestral",
19027+
"supports_vision": false,
19028+
"supports_functions": true,
19029+
"supports_json_mode": true,
19030+
"input_price_per_million": 1,
19031+
"output_price_per_million": 3,
19032+
"metadata": {
19033+
"description": "Codestral - specialized model for code generation"
19034+
}
19035+
},
19036+
{
19037+
"id": "mistral-embed",
19038+
"created_at": "2023-12-23T00:00:00Z",
1898519039
"display_name": "Mistral Embed",
1898619040
"provider": "mistral",
1898719041
"context_window": 32768,
@@ -18997,6 +19051,114 @@
1899719051
"description": "Mistral Embed - specialized model for generating text embeddings"
1899819052
}
1899919053
},
19054+
{
19055+
"id": "mistral-large-latest",
19056+
"created_at": "2024-11-24T00:00:00Z",
19057+
"display_name": "Mistral Large (Latest)",
19058+
"provider": "mistral",
19059+
"context_window": 131072,
19060+
"max_tokens": 131072,
19061+
"type": "chat",
19062+
"family": "mistral_large",
19063+
"supports_vision": false,
19064+
"supports_functions": true,
19065+
"supports_json_mode": true,
19066+
"input_price_per_million": 3,
19067+
"output_price_per_million": 9,
19068+
"metadata": {
19069+
"description": "Mistral Large 2 - top-tier reasoning model for high-complexity tasks"
19070+
}
19071+
},
19072+
{
19073+
"id": "mistral-small-latest",
19074+
"created_at": "2025-03-25T00:00:00Z",
19075+
"display_name": "Mistral Small (Latest)",
19076+
"provider": "mistral",
19077+
"context_window": 131072,
19078+
"max_tokens": 131072,
19079+
"type": "chat",
19080+
"family": "mistral_small",
19081+
"supports_vision": true,
19082+
"supports_functions": true,
19083+
"supports_json_mode": true,
19084+
"input_price_per_million": 0.2,
19085+
"output_price_per_million": 0.6,
19086+
"metadata": {
19087+
"description": "Mistral Small (Latest) - balanced model with good performance/cost ratio"
19088+
}
19089+
},
19090+
{
19091+
"id": "pixtral-12b-latest",
19092+
"created_at": "2024-09-25T00:00:00Z",
19093+
"display_name": "Pixtral 12B (Latest)",
19094+
"provider": "mistral",
19095+
"context_window": 131072,
19096+
"max_tokens": 131072,
19097+
"type": "chat",
19098+
"family": "pixtral",
19099+
"supports_vision": true,
19100+
"supports_functions": true,
19101+
"supports_json_mode": true,
19102+
"input_price_per_million": 0.15,
19103+
"output_price_per_million": 0.15,
19104+
"metadata": {
19105+
"description": "Pixtral 12B - Mistral's first multimodal model with vision capabilities"
19106+
}
19107+
},
19108+
{
19109+
"id": "mistral-saba",
19110+
"created_at": "2025-02-25T00:00:00Z",
19111+
"display_name": "Mistral Saba",
19112+
"provider": "mistral",
19113+
"context_window": 32768,
19114+
"max_tokens": 32768,
19115+
"type": "chat",
19116+
"family": "mistral_saba",
19117+
"supports_vision": false,
19118+
"supports_functions": true,
19119+
"supports_json_mode": true,
19120+
"input_price_per_million": 0.3,
19121+
"output_price_per_million": 0.3,
19122+
"metadata": {
19123+
"description": "Mistral Saba - powerful and efficient model for languages from the Middle East and South Asia"
19124+
}
19125+
},
19126+
{
19127+
"id": "mistral-moderation",
19128+
"created_at": "2024-11-24T00:00:00Z",
19129+
"display_name": "Mistral Moderation",
19130+
"provider": "mistral",
19131+
"context_window": 32768,
19132+
"max_tokens": 32768,
19133+
"type": "moderation",
19134+
"family": "mistral_moderation",
19135+
"supports_vision": false,
19136+
"supports_functions": false,
19137+
"supports_json_mode": false,
19138+
"input_price_per_million": 0.0,
19139+
"output_price_per_million": 0.0,
19140+
"metadata": {
19141+
"description": "Mistral Moderation - service that enables users to detect harmful text content"
19142+
}
19143+
},
19144+
{
19145+
"id": "mistral-ocr",
19146+
"created_at": "2025-03-25T00:00:00Z",
19147+
"display_name": "Mistral OCR",
19148+
"provider": "mistral",
19149+
"context_window": 32768,
19150+
"max_tokens": 32768,
19151+
"type": "ocr",
19152+
"family": "mistral_ocr",
19153+
"supports_vision": true,
19154+
"supports_functions": false,
19155+
"supports_json_mode": false,
19156+
"input_price_per_million": 0.0,
19157+
"output_price_per_million": 0.0,
19158+
"metadata": {
19159+
"description": "Mistral OCR - service that enables users to extract interleaved text and images"
19160+
}
19161+
},
1900019162
{
1900119163
"id": "moonshotai/kimi-vl-a3b-thinking:free",
1900219164
"name": "Moonshot AI: Kimi VL A3B Thinking (free)",

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)