Skip to content

Commit c23d520

Browse files
Evsdrgdeepseek-v4-pro[1m]
andcommitted
feat: 添加 MiMo 模型 thinking mode 自动检测与兼容
isOpenAIThinkingEnabled() 现在自动检测模型名包含 "mimo" 的模型 (与 DeepSeek 并列),因为 MiMo 同样使用 reasoning_content 字段 且支持 thinking mode。 buildOpenAIRequestBody() 在 chat_template_kwargs 中同时发送 thinking: true 和 enable_thinking: true,兼容 DeepSeek 自托管和 MiMo 的 thinking 启用格式。 已有 reasoning_content 回传逻辑(openaiConvertMessages.ts)和流 解析逻辑(openaiStreamAdapter.ts)无需修改,MiMo 与 DeepSeek 共用 相同的 reasoning_content 字段协议。 Co-Authored-By: deepseek-v4-pro[1m] <deepseek-ai@claude-code-best.win>
1 parent b3d28bc commit c23d520

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

src/services/api/openai/__tests__/thinking.test.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ describe('isOpenAIThinkingEnabled', () => {
147147
expect(isOpenAIThinkingEnabled('deepseek-coder')).toBe(true)
148148
})
149149

150+
test('returns true when model name is "mimo-v2-flash"', () => {
151+
expect(isOpenAIThinkingEnabled('mimo-v2-flash')).toBe(true)
152+
})
153+
154+
test('returns true when model name is "mimo-v2-pro"', () => {
155+
expect(isOpenAIThinkingEnabled('mimo-v2-pro')).toBe(true)
156+
})
157+
158+
test('returns true when model name is "mimo-v2.5-pro"', () => {
159+
expect(isOpenAIThinkingEnabled('mimo-v2.5-pro')).toBe(true)
160+
})
161+
162+
test('returns true when model name contains "mimo"', () => {
163+
expect(isOpenAIThinkingEnabled('MiMo-V2-Omni')).toBe(true)
164+
})
165+
150166
test('returns false when model name is "gpt-4o"', () => {
151167
expect(isOpenAIThinkingEnabled('gpt-4o')).toBe(false)
152168
})
@@ -197,7 +213,10 @@ describe('buildOpenAIRequestBody — thinking params', () => {
197213
test('includes vLLM/self-hosted thinking format when enabled', () => {
198214
const body = buildOpenAIRequestBody({ ...baseParams, enableThinking: true })
199215
expect(body.enable_thinking).toBe(true)
200-
expect(body.chat_template_kwargs).toEqual({ thinking: true })
216+
expect(body.chat_template_kwargs).toEqual({
217+
thinking: true,
218+
enable_thinking: true,
219+
})
201220
})
202221

203222
test('includes both formats simultaneously when enabled', () => {

src/services/api/openai/requestBody.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import type { ChatCompletionCreateParamsStreaming } from 'openai/resources/chat/
77
import { 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
*/
6868
export 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

Comments
 (0)