diff --git a/crates/forge_app/src/dto/openai/transformers/minimax.rs b/crates/forge_app/src/dto/openai/transformers/minimax.rs index cdfb6c90ac..ca55d1d57f 100644 --- a/crates/forge_app/src/dto/openai/transformers/minimax.rs +++ b/crates/forge_app/src/dto/openai/transformers/minimax.rs @@ -4,38 +4,45 @@ use crate::dto::openai::Request; /// Transformer that applies minimax-specific parameter adjustments /// -/// Minimax M2 models require specific temperature, top_p, and top_k values +/// Minimax models require specific temperature, top_p, and top_k values /// for optimal performance: /// - Temperature: 1.0 /// - Top P: 0.95 -/// - Top K: 40 (for m2.1), 20 (for other m2 models) +/// - Top K: 40 (for m2.1), 20 (for all other models including M2, M2.5, M2.7, +/// M3) +/// +/// These parameters are based on official MiniMax evaluation methodology +/// (see VideoMMMU, Video-MME benchmarks in M3 blog post). pub struct SetMinimaxParams; impl Transformer for SetMinimaxParams { type Value = Request; fn transform(&mut self, mut request: Self::Value) -> Self::Value { - // Check if model is a minimax-m2 model let model_id = request .model .as_ref() .map(|m| m.as_str().to_lowercase()) .unwrap_or_default(); - if !model_id.contains("minimax-m2") { + // Match MiniMax model patterns (minimax-m2, minimax-m3, etc.) + let is_minimax = model_id.contains("minimax-m2") || model_id.contains("minimax-m3"); + + if !is_minimax { return request; } - // Set temperature to 1.0 for minimax-m2 models + // Set temperature to 1.0 for minimax models request.temperature = Some(1.0); - // Set top_p to 0.95 for minimax-m2 models + // Set top_p to 0.95 for minimax models request.top_p = Some(0.95); // Set top_k based on model variant if model_id.contains("minimax-m2.1") { request.top_k = Some(40); } else { + // M2, M2.5, M2.7, M3 all use top_k = 20 request.top_k = Some(20); } @@ -145,4 +152,37 @@ mod tests { assert_eq!(actual.top_p, fixture.top_p); assert_eq!(actual.top_k, fixture.top_k); } + + #[test] + fn test_minimax_m3_sets_parameters() { + let fixture = create_request_fixture("minimax-m3"); + let mut transformer = SetMinimaxParams; + let actual = transformer.transform(fixture); + + assert_eq!(actual.temperature, Some(1.0)); + assert_eq!(actual.top_p, Some(0.95)); + assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7 + } + + #[test] + fn test_minimax_m3_case_insensitive() { + let fixture = create_request_fixture("MiniMax-M3"); + let mut transformer = SetMinimaxParams; + let actual = transformer.transform(fixture); + + assert_eq!(actual.temperature, Some(1.0)); + assert_eq!(actual.top_p, Some(0.95)); + assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7 + } + + #[test] + fn test_minimax_m3_bedrock_provider_id() { + let fixture = create_request_fixture("minimax.minimax-m3"); + let mut transformer = SetMinimaxParams; + let actual = transformer.transform(fixture); + + assert_eq!(actual.temperature, Some(1.0)); + assert_eq!(actual.top_p, Some(0.95)); + assert_eq!(actual.top_k, Some(20)); // M3 uses same config as M2.7 + } } diff --git a/crates/forge_repo/src/provider/provider.json b/crates/forge_repo/src/provider/provider.json index d492d38696..04c42ecc0a 100644 --- a/crates/forge_repo/src/provider/provider.json +++ b/crates/forge_repo/src/provider/provider.json @@ -1443,6 +1443,16 @@ "supports_reasoning": true, "input_modalities": ["text"] }, + { + "id": "minimax.minimax-m3", + "name": "MiniMax M3", + "description": "Frontier coding model with 1M context, MSA sparse attention, native multimodality, and agentic capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "minimax.minimax-m2.1", "name": "MiniMax M2.1", @@ -1453,6 +1463,7 @@ "supports_reasoning": true, "input_modalities": ["text"] }, + { "id": "us.anthropic.claude-sonnet-4-20250514-v1:0", "name": "Claude Sonnet 4 (US)", @@ -2506,6 +2517,16 @@ "response_type": "Anthropic", "url": "https://{{#if HOSTNAME}}{{HOSTNAME}}{{else}}api.minimax.io{{/if}}/anthropic/v1/messages", "models": [ + { + "id": "MiniMax-M3", + "name": "MiniMax M3", + "description": "Frontier coding model with 1M context, MSA sparse attention, native multimodality (image/video), and agentic capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "MiniMax-M2.7", "name": "MiniMax M2.7",