fix: disable MiniMax-M3 thinking via thinking_mode (fixes classifier 60s timeout)

#4
by pierric HF Staff - opened
Files changed (1) hide show
  1. src/adapter/convert_request.rs +20 -8
src/adapter/convert_request.rs CHANGED
@@ -35,13 +35,18 @@ pub fn convert_anthropic_to_openrouter(
35
  extra: serde_json::Map::new(),
36
  };
37
 
38
- // Reasoning models (e.g. GLM-5.2) "think" before answering by default, which
39
- // adds several seconds of latency. Claude Code's auto-mode safety classifier
40
- // issues short, structured calls (signalled by stop_sequences) with a tight
41
- // timeout — the thinking latency makes it time out ("model temporarily
42
- // unavailable"). For those calls, disable native thinking. We emit every known
43
- // convention because the actual provider behind the HF router (fireworks,
44
- // together, zai-org, ...) honours a different one.
 
 
 
 
 
45
  if !src.stop_sequences.is_empty() {
46
  use serde_json::{json, Value};
47
  dst.extra
@@ -50,7 +55,7 @@ pub fn convert_anthropic_to_openrouter(
50
  .insert("thinking".to_string(), json!({ "type": "disabled" }));
51
  dst.extra.insert(
52
  "chat_template_kwargs".to_string(),
53
- json!({ "enable_thinking": false }),
54
  );
55
  }
56
 
@@ -470,6 +475,13 @@ mod tests {
470
  );
471
  assert!(result.extra.contains_key("thinking"));
472
  assert!(result.extra.contains_key("chat_template_kwargs"));
 
 
 
 
 
 
 
473
  }
474
 
475
  #[test]
 
35
  extra: serde_json::Map::new(),
36
  };
37
 
38
+ // Reasoning models (e.g. GLM-5.2, MiniMax-M3) "think" before answering by
39
+ // default, which adds several seconds of latency. Claude Code's auto-mode
40
+ // safety classifier issues short, structured calls (signalled by
41
+ // stop_sequences) with a tight timeout — the thinking latency makes it time
42
+ // out ("model temporarily unavailable"). For those calls, disable native
43
+ // thinking. We emit every known convention because the actual provider behind
44
+ // the HF router (fireworks, together, deepinfra, zai-org, ...) honours a
45
+ // different one. Note: MiniMax-M3's chat_template reads `thinking_mode`
46
+ // (string: enabled/disabled/adaptive, default adaptive), NOT `enable_thinking`
47
+ // (bool) — so `chat_template_kwargs` must carry `thinking_mode: "disabled"`,
48
+ // verified against DeepInfra (the `enable_thinking`-only form is a no-op there
49
+ // and reasoning_content still streams).
50
  if !src.stop_sequences.is_empty() {
51
  use serde_json::{json, Value};
52
  dst.extra
 
55
  .insert("thinking".to_string(), json!({ "type": "disabled" }));
56
  dst.extra.insert(
57
  "chat_template_kwargs".to_string(),
58
+ json!({ "enable_thinking": false, "thinking_mode": "disabled" }),
59
  );
60
  }
61
 
 
475
  );
476
  assert!(result.extra.contains_key("thinking"));
477
  assert!(result.extra.contains_key("chat_template_kwargs"));
478
+ // MiniMax-M3's chat_template reads `thinking_mode` (string), not
479
+ // `enable_thinking` (bool) — without this, reasoning stays on and the
480
+ // non-stream classifier call times out on DeepInfra.
481
+ assert_eq!(
482
+ result.extra.get("chat_template_kwargs").and_then(|v| v.get("thinking_mode")),
483
+ Some(&serde_json::Value::String("disabled".to_string()))
484
+ );
485
  }
486
 
487
  #[test]