Skip to content

Commit c2437e9

Browse files
ImBIOSforge-code-agentautofix-ci[bot]
authored
fix(minimax): MiniMax M3 model support (#3434)
Co-authored-by: ForgeCode <noreply@forgecode.dev> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 22edd31 commit c2437e9

2 files changed

Lines changed: 67 additions & 6 deletions

File tree

crates/forge_app/src/dto/openai/transformers/minimax.rs

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,45 @@ use crate::dto::openai::Request;
44

55
/// Transformer that applies minimax-specific parameter adjustments
66
///
7-
/// Minimax M2 models require specific temperature, top_p, and top_k values
7+
/// Minimax models require specific temperature, top_p, and top_k values
88
/// for optimal performance:
99
/// - Temperature: 1.0
1010
/// - Top P: 0.95
11-
/// - Top K: 40 (for m2.1), 20 (for other m2 models)
11+
/// - Top K: 40 (for m2.1), 20 (for all other models including M2, M2.5, M2.7,
12+
/// M3)
13+
///
14+
/// These parameters are based on official MiniMax evaluation methodology
15+
/// (see VideoMMMU, Video-MME benchmarks in M3 blog post).
1216
pub struct SetMinimaxParams;
1317

1418
impl Transformer for SetMinimaxParams {
1519
type Value = Request;
1620

1721
fn transform(&mut self, mut request: Self::Value) -> Self::Value {
18-
// Check if model is a minimax-m2 model
1922
let model_id = request
2023
.model
2124
.as_ref()
2225
.map(|m| m.as_str().to_lowercase())
2326
.unwrap_or_default();
2427

25-
if !model_id.contains("minimax-m2") {
28+
// Match MiniMax model patterns (minimax-m2, minimax-m3, etc.)
29+
let is_minimax = model_id.contains("minimax-m2") || model_id.contains("minimax-m3");
30+
31+
if !is_minimax {
2632
return request;
2733
}
2834

29-
// Set temperature to 1.0 for minimax-m2 models
35+
// Set temperature to 1.0 for minimax models
3036
request.temperature = Some(1.0);
3137

32-
// Set top_p to 0.95 for minimax-m2 models
38+
// Set top_p to 0.95 for minimax models
3339
request.top_p = Some(0.95);
3440

3541
// Set top_k based on model variant
3642
if model_id.contains("minimax-m2.1") {
3743
request.top_k = Some(40);
3844
} else {
45+
// M2, M2.5, M2.7, M3 all use top_k = 20
3946
request.top_k = Some(20);
4047
}
4148

@@ -145,4 +152,37 @@ mod tests {
145152
assert_eq!(actual.top_p, fixture.top_p);
146153
assert_eq!(actual.top_k, fixture.top_k);
147154
}
155+
156+
#[test]
157+
fn test_minimax_m3_sets_parameters() {
158+
let fixture = create_request_fixture("minimax-m3");
159+
let mut transformer = SetMinimaxParams;
160+
let actual = transformer.transform(fixture);
161+
162+
assert_eq!(actual.temperature, Some(1.0));
163+
assert_eq!(actual.top_p, Some(0.95));
164+
assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7
165+
}
166+
167+
#[test]
168+
fn test_minimax_m3_case_insensitive() {
169+
let fixture = create_request_fixture("MiniMax-M3");
170+
let mut transformer = SetMinimaxParams;
171+
let actual = transformer.transform(fixture);
172+
173+
assert_eq!(actual.temperature, Some(1.0));
174+
assert_eq!(actual.top_p, Some(0.95));
175+
assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7
176+
}
177+
178+
#[test]
179+
fn test_minimax_m3_bedrock_provider_id() {
180+
let fixture = create_request_fixture("minimax.minimax-m3");
181+
let mut transformer = SetMinimaxParams;
182+
let actual = transformer.transform(fixture);
183+
184+
assert_eq!(actual.temperature, Some(1.0));
185+
assert_eq!(actual.top_p, Some(0.95));
186+
assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7
187+
}
148188
}

crates/forge_repo/src/provider/provider.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,16 @@
14431443
"supports_reasoning": true,
14441444
"input_modalities": ["text"]
14451445
},
1446+
{
1447+
"id": "minimax.minimax-m3",
1448+
"name": "MiniMax M3",
1449+
"description": "Frontier coding model with 1M context, MSA sparse attention, native multimodality, and agentic capabilities",
1450+
"context_length": 1000000,
1451+
"tools_supported": true,
1452+
"supports_parallel_tool_calls": true,
1453+
"supports_reasoning": true,
1454+
"input_modalities": ["text", "image"]
1455+
},
14461456
{
14471457
"id": "minimax.minimax-m2.1",
14481458
"name": "MiniMax M2.1",
@@ -1453,6 +1463,7 @@
14531463
"supports_reasoning": true,
14541464
"input_modalities": ["text"]
14551465
},
1466+
14561467
{
14571468
"id": "us.anthropic.claude-sonnet-4-20250514-v1:0",
14581469
"name": "Claude Sonnet 4 (US)",
@@ -2506,6 +2517,16 @@
25062517
"response_type": "Anthropic",
25072518
"url": "https://{{#if HOSTNAME}}{{HOSTNAME}}{{else}}api.minimax.io{{/if}}/anthropic/v1/messages",
25082519
"models": [
2520+
{
2521+
"id": "MiniMax-M3",
2522+
"name": "MiniMax M3",
2523+
"description": "Frontier coding model with 1M context, MSA sparse attention, native multimodality (image/video), and agentic capabilities",
2524+
"context_length": 1000000,
2525+
"tools_supported": true,
2526+
"supports_parallel_tool_calls": true,
2527+
"supports_reasoning": true,
2528+
"input_modalities": ["text", "image"]
2529+
},
25092530
{
25102531
"id": "MiniMax-M2.7",
25112532
"name": "MiniMax M2.7",

0 commit comments

Comments
 (0)