fix: handle reasoning_content for thinking mode in OpenAI compatibility layer

- Add reasoning_content field when thinking mode is enabled
- Set reasoning_content to empty string when no thinking content available
- Enable model auto-detection for kimi provider
- Add thinking mode support to costrict provider
This commit is contained in:
Askhz 2026-04-21 15:48:22 +08:00
parent 19112528d5
commit c28cd05d89
3 changed files with 34 additions and 17 deletions

View File

@ -211,21 +211,29 @@ function convertInternalAssistantMessage(
const content = msg.message.content
if (typeof content === 'string') {
return [
{
role: 'assistant',
content,
} satisfies ChatCompletionAssistantMessageParam,
]
const result: ChatCompletionAssistantMessageParam & { reasoning_content?: string } = {
role: 'assistant',
content,
}
// 如果开启了thinking模式必须提供reasoning_content字段
if (preserveReasoning) {
// content是字符串没有reasoning内容设置为空字符串
result.reasoning_content = ' '
}
return [result]
}
if (!Array.isArray(content)) {
return [
{
role: 'assistant',
content: '',
} satisfies ChatCompletionAssistantMessageParam,
]
const result: ChatCompletionAssistantMessageParam & { reasoning_content?: string } = {
role: 'assistant',
content: '',
}
// 如果开启了thinking模式必须提供reasoning_content字段
if (preserveReasoning) {
// content不是数组没有reasoning内容设置为空字符串
result.reasoning_content = ' '
}
return [result]
}
const textParts: string[] = []
@ -258,11 +266,16 @@ function convertInternalAssistantMessage(
// Skip redacted_thinking, server_tool_use, etc.
}
const result: ChatCompletionAssistantMessageParam = {
const result: ChatCompletionAssistantMessageParam & { reasoning_content?: string } = {
role: 'assistant',
content: textParts.length > 0 ? textParts.join('\n') : null,
...(toolCalls.length > 0 && { tool_calls: toolCalls }),
...(reasoningParts.length > 0 && { reasoning_content: reasoningParts.join('\n') }),
}
// 如果开启了thinking模式必须提供reasoning_content字段
if (preserveReasoning) {
// 如果有reasoning内容就用这些内容没有才设置成空字符串
result.reasoning_content = reasoningParts.length > 0 ? reasoningParts.join('\n') : ' '
}
return [result]

View File

@ -31,6 +31,7 @@ import { createCoStrictFetch } from './fetch.js'
import { resolveCoStrictModel } from './modelMapping.js'
import { getCoStrictBaseURL } from './auth.js'
import { loadCoStrictCredentials } from './credentials.js'
import { isOpenAIThinkingEnabled } from '../../services/api/openai/requestBody.js'
/**
* CoStrict
@ -80,9 +81,12 @@ export async function* queryModelCoStrict(
)
// 5. 转换为 OpenAI 格式
// 根据模型名称自动检测是否启用thinking模式
const enableThinking = isOpenAIThinkingEnabled(costrictModel)
const openaiMessages = anthropicMessagesToOpenAI(
messagesForAPI,
systemPrompt
systemPrompt,
{ enableThinking }
)
const openaiTools = anthropicToolsToOpenAI(standardTools)
const openaiToolChoice = anthropicToolChoiceToOpenAI(options.toolChoice)

View File

@ -25,9 +25,9 @@ export function isOpenAIThinkingEnabled(model: string): boolean {
if (isEnvDefinedFalsy(process.env.OPENAI_ENABLE_THINKING)) return false
// Explicit enable
if (isEnvTruthy(process.env.OPENAI_ENABLE_THINKING)) return true
// Auto-detect from model name (deepseek-reasoner and DeepSeek-V3.2 support thinking mode)
// Auto-detect from model name (deepseek-reasoner, DeepSeek-V3.2, kimi support thinking mode)
const modelLower = model.toLowerCase()
return modelLower.includes('deepseek-reasoner') || modelLower.includes('deepseek-v3.2')
return modelLower.includes('deepseek-reasoner') || modelLower.includes('deepseek-v3.2') || modelLower.includes('kimi')
}
/**