@@ -7,11 +7,11 @@ import type { ChatCompletionCreateParamsStreaming } from 'openai/resources/chat/
77import { isEnvTruthy , isEnvDefinedFalsy } from '../../../utils/envUtils.js'
88
99/**
10- * Detect whether DeepSeek-style thinking mode should be enabled.
10+ * Detect whether thinking mode should be enabled for this model .
1111 *
1212 * Enabled when:
1313 * 1. OPENAI_ENABLE_THINKING=1 is set (explicit enable), OR
14- * 2. Model name contains "deepseek-reasoner" OR "DeepSeek-V3.2 " (auto-detect, case-insensitive)
14+ * 2. Model name contains "deepseek" or "mimo " (auto-detect, case-insensitive)
1515 *
1616 * Disabled when:
1717 * - OPENAI_ENABLE_THINKING=0/false/no/off is explicitly set (overrides model detection)
@@ -23,9 +23,9 @@ export function isOpenAIThinkingEnabled(model: string): boolean {
2323 if ( isEnvDefinedFalsy ( process . env . OPENAI_ENABLE_THINKING ) ) return false
2424 // Explicit enable
2525 if ( isEnvTruthy ( process . env . OPENAI_ENABLE_THINKING ) ) return true
26- // Auto-detect from model name (all DeepSeek models support thinking mode)
26+ // Auto-detect from model name (DeepSeek and MiMo models support thinking mode)
2727 const modelLower = model . toLowerCase ( )
28- return modelLower . includes ( 'deepseek' )
28+ return modelLower . includes ( 'deepseek' ) || modelLower . includes ( 'mimo' )
2929}
3030
3131/**
@@ -58,12 +58,12 @@ export function resolveOpenAIMaxTokens(
5858 * Build the request body for OpenAI chat.completions.create().
5959 * Extracted for testability — the thinking mode params are injected here.
6060 *
61- * DeepSeek thinking mode: inject thinking params via request body.
62- * Two formats are added simultaneously to support different deployments:
63- * - Official DeepSeek API: `thinking: { type: 'enabled' }`
64- * - Self-hosted DeepSeek-V3.2: `enable_thinking: true` + `chat_template_kwargs: { thinking: true }`
61+ * Three thinking-mode formats are sent simultaneously; each endpoint uses the
62+ * format it recognizes and ignores the others:
63+ * - Official DeepSeek API: `thinking: { type: 'enabled' }`
64+ * - Self-hosted DeepSeek: `enable_thinking: true` + `chat_template_kwargs: { thinking: true }`
65+ * - MiMo (Xiaomi): `chat_template_kwargs: { enable_thinking: true }`
6566 * OpenAI SDK passes unknown keys through to the HTTP body.
66- * Each endpoint will use the format it recognizes and ignore the others.
6767 */
6868export function buildOpenAIRequestBody ( params : {
6969 model : string
@@ -76,7 +76,7 @@ export function buildOpenAIRequestBody(params: {
7676} ) : ChatCompletionCreateParamsStreaming & {
7777 thinking ?: { type : string }
7878 enable_thinking ?: boolean
79- chat_template_kwargs ?: { thinking : boolean }
79+ chat_template_kwargs ?: { thinking : boolean ; enable_thinking : boolean }
8080} {
8181 const {
8282 model,
@@ -97,14 +97,15 @@ export function buildOpenAIRequestBody(params: {
9797 } ) ,
9898 stream : true ,
9999 stream_options : { include_usage : true } ,
100- // DeepSeek thinking mode: enable chain-of-thought output.
101- // When active, temperature/top_p/presence_penalty/frequency_penalty are ignored by DeepSeek .
100+ // Enable chain-of-thought output for DeepSeek and MiMo models .
101+ // When active, temperature/top_p/presence_penalty/frequency_penalty are ignored.
102102 ...( enableThinking && {
103103 // Official DeepSeek API format
104104 thinking : { type : 'enabled' } ,
105105 // Self-hosted DeepSeek-V3.2 format
106106 enable_thinking : true ,
107- chat_template_kwargs : { thinking : true } ,
107+ // Both DeepSeek self-hosted and MiMo formats in chat_template_kwargs
108+ chat_template_kwargs : { thinking : true , enable_thinking : true } ,
108109 } ) ,
109110 // Only send temperature when thinking mode is off (DeepSeek ignores it anyway,
110111 // but other providers may respect it)
0 commit comments