Skip to content

Commit 1bf885b

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 784cc4a commit 1bf885b

File tree

55 files changed

+7113
-602
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

+7113
-602
lines changed

lib/ruby_llm/aliases.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,12 @@
222222
"openrouter": "openai/o3-mini"
223223
},
224224
"mistral-medium": {
225-
"mistral": "mistral-medium-latest"
225+
"mistral": "mistral/mistral-medium-latest"
226226
},
227227
"mistral-large": {
228-
"mistral": "mistral-large-latest"
228+
"mistral": "mistral/mistral-large"
229229
},
230230
"mistral-small": {
231-
"mistral": "mistral-small-latest"
231+
"mistral": "mistral/mistral-small"
232232
}
233233
}

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
@@ -18804,8 +18804,62 @@
1880418804
}
1880518805
},
1880618806
{
18807-
"id": "mistralai/mistral-embed",
18808-
"created_at": "2024-03-15T00:00:00Z",
18807+
"id": "mistral-tiny",
18808+
"created_at": "2024-12-23T00:00:00Z",
18809+
"display_name": "Mistral Tiny",
18810+
"provider": "mistral",
18811+
"context_window": 32768,
18812+
"max_tokens": 32768,
18813+
"type": "chat",
18814+
"family": "mistral_tiny",
18815+
"supports_vision": false,
18816+
"supports_functions": true,
18817+
"supports_json_mode": true,
18818+
"input_price_per_million": 0.14,
18819+
"output_price_per_million": 0.42,
18820+
"metadata": {
18821+
"description": "Most affordable model in the Mistral lineup"
18822+
}
18823+
},
18824+
{
18825+
"id": "pixtral-large",
18826+
"created_at": "2024-11-24T00:00:00Z",
18827+
"display_name": "Pixtral Large",
18828+
"provider": "mistral",
18829+
"context_window": 131072,
18830+
"max_tokens": 131072,
18831+
"type": "chat",
18832+
"family": "pixtral_large",
18833+
"supports_vision": true,
18834+
"supports_functions": true,
18835+
"supports_json_mode": true,
18836+
"input_price_per_million": 3,
18837+
"output_price_per_million": 9,
18838+
"metadata": {
18839+
"description": "Pixtral Large - frontier-class multimodal model"
18840+
}
18841+
},
18842+
{
18843+
"id": "codestral",
18844+
"created_at": "2025-01-25T00:00:00Z",
18845+
"display_name": "Codestral",
18846+
"provider": "mistral",
18847+
"context_window": 262144,
18848+
"max_tokens": 262144,
18849+
"type": "chat",
18850+
"family": "codestral",
18851+
"supports_vision": false,
18852+
"supports_functions": true,
18853+
"supports_json_mode": true,
18854+
"input_price_per_million": 1,
18855+
"output_price_per_million": 3,
18856+
"metadata": {
18857+
"description": "Codestral - specialized model for code generation"
18858+
}
18859+
},
18860+
{
18861+
"id": "mistral-embed",
18862+
"created_at": "2023-12-23T00:00:00Z",
1880918863
"display_name": "Mistral Embed",
1881018864
"provider": "mistral",
1881118865
"context_window": 32768,
@@ -18821,6 +18875,114 @@
1882118875
"description": "Mistral Embed - specialized model for generating text embeddings"
1882218876
}
1882318877
},
18878+
{
18879+
"id": "mistral-large-latest",
18880+
"created_at": "2024-11-24T00:00:00Z",
18881+
"display_name": "Mistral Large (Latest)",
18882+
"provider": "mistral",
18883+
"context_window": 131072,
18884+
"max_tokens": 131072,
18885+
"type": "chat",
18886+
"family": "mistral_large",
18887+
"supports_vision": false,
18888+
"supports_functions": true,
18889+
"supports_json_mode": true,
18890+
"input_price_per_million": 3,
18891+
"output_price_per_million": 9,
18892+
"metadata": {
18893+
"description": "Mistral Large 2 - top-tier reasoning model for high-complexity tasks"
18894+
}
18895+
},
18896+
{
18897+
"id": "mistral-small-latest",
18898+
"created_at": "2025-03-25T00:00:00Z",
18899+
"display_name": "Mistral Small (Latest)",
18900+
"provider": "mistral",
18901+
"context_window": 131072,
18902+
"max_tokens": 131072,
18903+
"type": "chat",
18904+
"family": "mistral_small",
18905+
"supports_vision": true,
18906+
"supports_functions": true,
18907+
"supports_json_mode": true,
18908+
"input_price_per_million": 0.2,
18909+
"output_price_per_million": 0.6,
18910+
"metadata": {
18911+
"description": "Mistral Small (Latest) - balanced model with good performance/cost ratio"
18912+
}
18913+
},
18914+
{
18915+
"id": "pixtral-12b-latest",
18916+
"created_at": "2024-09-25T00:00:00Z",
18917+
"display_name": "Pixtral 12B (Latest)",
18918+
"provider": "mistral",
18919+
"context_window": 131072,
18920+
"max_tokens": 131072,
18921+
"type": "chat",
18922+
"family": "pixtral",
18923+
"supports_vision": true,
18924+
"supports_functions": true,
18925+
"supports_json_mode": true,
18926+
"input_price_per_million": 0.15,
18927+
"output_price_per_million": 0.15,
18928+
"metadata": {
18929+
"description": "Pixtral 12B - Mistral's first multimodal model with vision capabilities"
18930+
}
18931+
},
18932+
{
18933+
"id": "mistral-saba",
18934+
"created_at": "2025-02-25T00:00:00Z",
18935+
"display_name": "Mistral Saba",
18936+
"provider": "mistral",
18937+
"context_window": 32768,
18938+
"max_tokens": 32768,
18939+
"type": "chat",
18940+
"family": "mistral_saba",
18941+
"supports_vision": false,
18942+
"supports_functions": true,
18943+
"supports_json_mode": true,
18944+
"input_price_per_million": 0.3,
18945+
"output_price_per_million": 0.3,
18946+
"metadata": {
18947+
"description": "Mistral Saba - powerful and efficient model for languages from the Middle East and South Asia"
18948+
}
18949+
},
18950+
{
18951+
"id": "mistral-moderation",
18952+
"created_at": "2024-11-24T00:00:00Z",
18953+
"display_name": "Mistral Moderation",
18954+
"provider": "mistral",
18955+
"context_window": 32768,
18956+
"max_tokens": 32768,
18957+
"type": "moderation",
18958+
"family": "mistral_moderation",
18959+
"supports_vision": false,
18960+
"supports_functions": false,
18961+
"supports_json_mode": false,
18962+
"input_price_per_million": 0.0,
18963+
"output_price_per_million": 0.0,
18964+
"metadata": {
18965+
"description": "Mistral Moderation - service that enables users to detect harmful text content"
18966+
}
18967+
},
18968+
{
18969+
"id": "mistral-ocr",
18970+
"created_at": "2025-03-25T00:00:00Z",
18971+
"display_name": "Mistral OCR",
18972+
"provider": "mistral",
18973+
"context_window": 32768,
18974+
"max_tokens": 32768,
18975+
"type": "ocr",
18976+
"family": "mistral_ocr",
18977+
"supports_vision": true,
18978+
"supports_functions": false,
18979+
"supports_json_mode": false,
18980+
"input_price_per_million": 0.0,
18981+
"output_price_per_million": 0.0,
18982+
"metadata": {
18983+
"description": "Mistral OCR - service that enables users to extract interleaved text and images"
18984+
}
18985+
},
1882418986
{
1882518987
"id": "moonshotai/kimi-vl-a3b-thinking:free",
1882618988
"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)