Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions crates/reasoning_parser/src/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ impl ParserFactory {
registry.register_pattern("glm-5", "glm45"); // GLM-5.x reuse glm45 reasoning format
registry.register_pattern("kimi-k2-thinking", "kimi_thinking");
registry.register_pattern("kimi-k2.5", "kimi_k25");
registry.register_pattern("kimi-k2.6", "kimi_k25"); // K2.6/K2.7 share the K2.5 <think> template
registry.register_pattern("kimi-k2.7", "kimi_k25");
Comment on lines 196 to +198

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of registering individual patterns for each minor version of the Kimi K2 family (e.g., kimi-k2.5, kimi-k2.6, kimi-k2.7), we can register a single pattern kimi-k2. to match all current and future Kimi K2.x models. Since the matching logic uses substring matching (contains), this single pattern will correctly match Kimi-K2.5, Kimi-K2.6, Kimi-K2.7, and any future versions (like Kimi-K2.8), while avoiding matching kimi-k2-thinking or kimi-k2-instruct which do not contain a dot after k2.

Suggested change
registry.register_pattern("kimi-k2.5", "kimi_k25");
registry.register_pattern("kimi-k2.6", "kimi_k25"); // K2.6/K2.7 share the K2.5 <think> template
registry.register_pattern("kimi-k2.7", "kimi_k25");
registry.register_pattern("kimi-k2.", "kimi_k25"); // Kimi K2.x models (K2.5+) share the <think> template

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map K2.7 to a prefilled-think parser

For auto-detected moonshotai/Kimi-K2.7-Code requests with separate_reasoning, this selects kimi_k25, whose parser does not start in reasoning mode; the gateway only calls mark_reasoning_started() when should_mark_reasoning_started() sees a thinking toggle (ThinkingToggle::None => false), but the K2.7-Code template pre-fills <think> unconditionally and has no toggle (HF template). The generated text therefore starts after the prefilled token, e.g. reasoning</think>answer, and BaseReasoningParser treats it as normal text unless it was already marked or sees <think> in the output, so reasoning still leaks into content despite this new auto-map.

Useful? React with 👍 / 👎.

registry.register_pattern("kimi", "kimi"); // legacy: Kimi-K2-Instruct with unicode tokens
registry.register_pattern("step3", "step3");
registry.register_pattern("minimax", "minimax");
Expand Down Expand Up @@ -275,6 +277,31 @@ mod tests {
assert_eq!(parser.model_type(), "kimi");
}

#[test]
fn test_kimi_k2_family_automap() {
let factory = ParserFactory::new();
assert_eq!(
factory.create("moonshotai/Kimi-K2.5").model_type(),
"kimi_k25"
);
assert_eq!(
factory.create("moonshotai/Kimi-K2.6").model_type(),
"kimi_k25"
);
assert_eq!(
factory.create("moonshotai/Kimi-K2.7-Code").model_type(),
"kimi_k25"
);
assert_eq!(
factory.create("moonshotai/Kimi-K2-Thinking").model_type(),
"kimi_thinking"
);
assert_eq!(
factory.create("moonshotai/Kimi-K2-Instruct").model_type(),
"kimi"
);
}

#[test]
fn test_factory_fallback_to_passthrough() {
let factory = ParserFactory::new();
Expand Down
Loading