From 23f8fa51424b3b51131c8ed039290c4f2be04135 Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Thu, 23 Jul 2026 18:43:55 +0800 Subject: [PATCH 1/2] feat: add MiniMax M2.7 to built-in catalog --- crates/core/models.json | 12 ++++++++++++ crates/core/src/model_catalog.rs | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/crates/core/models.json b/crates/core/models.json index 0e50fd153..e91003b61 100644 --- a/crates/core/models.json +++ b/crates/core/models.json @@ -70,6 +70,18 @@ } } }, + { + "slug": "MiniMax-M2.7", + "display_name": "MiniMax-M2.7", + "channel": "MiniMax", + "provider": "openai_chat_completions", + "description": "MiniMax M2.7 model with 204.8k-token context by MiniMax", + "reasoning_capability": "unsupported", + "context_window": 204800, + "input_modalities": [ + "text" + ] + }, { "slug": "glm-5.2", "display_name": "glm-5.2", diff --git a/crates/core/src/model_catalog.rs b/crates/core/src/model_catalog.rs index f3629272b..e78206c8e 100644 --- a/crates/core/src/model_catalog.rs +++ b/crates/core/src/model_catalog.rs @@ -153,6 +153,26 @@ mod tests { ); } + #[test] + fn builtin_minimax_catalog_contains_both_target_models() { + let models = load_builtin_models().expect("load builtin models"); + let m3 = models + .iter() + .find(|model| model.slug == "MiniMax-M3") + .expect("MiniMax-M3 model"); + let m27 = models + .iter() + .find(|model| model.slug == "MiniMax-M2.7") + .expect("MiniMax-M2.7 model"); + + assert_eq!(m3.context_window, 1_000_000); + assert_eq!(m27.context_window, 204_800); + assert!(matches!( + m27.reasoning_capability, + ReasoningCapability::Unsupported + )); + } + #[test] fn load_from_config_applies_partial_builtin_override_without_replacing_metadata() { let builtin = load_builtin_models() From ad0bd4ea9d458e699c2a3e7e471746fe18be22b3 Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:08:39 +0800 Subject: [PATCH 2/2] fix: preserve exact supported reasoning effort selections --- crates/protocol/src/reasoning_effort.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/protocol/src/reasoning_effort.rs b/crates/protocol/src/reasoning_effort.rs index 7ce071aa1..40a3bf994 100644 --- a/crates/protocol/src/reasoning_effort.rs +++ b/crates/protocol/src/reasoning_effort.rs @@ -386,6 +386,9 @@ pub(crate) fn nearest_effort( target: ReasoningEffort, supported: &[ReasoningEffort], ) -> ReasoningEffort { + if supported.contains(&target) { + return target; + } let target_rank = effort_rank(target); supported .iter() @@ -564,6 +567,18 @@ mod tests { ); } + #[test] + fn nearest_effort_preserves_distinct_max_and_xhigh_selections() { + let supported = [ReasoningEffort::XHigh, ReasoningEffort::Max]; + for effort in supported { + assert_eq!(super::nearest_effort(effort, &supported), effort); + } + assert_eq!( + super::nearest_effort(ReasoningEffort::Max, &[ReasoningEffort::XHigh]), + ReasoningEffort::XHigh + ); + } + #[test] fn reasoning_options_use_reasoning_effort_wire_values() { assert_eq!(