fix(qwen3): fix qwen3 thinking control by soft command (#9568)

fix(qwen3): 修复Qwen3模型思考模式处理逻辑

重构processPostsuffixQwen3Model函数,简化后缀处理逻辑
添加nvidia到不支持思考模式的提供商列表
移除postsuffix参数
This commit is contained in:
Phantom 2025-08-26 22:41:10 +08:00 committed by GitHub
parent 267b41242d
commit 7a0da13676
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 38 deletions

View File

@ -621,11 +621,10 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
const lastUserMsg = userMessages.findLast((m) => m.role === 'user')
if (lastUserMsg) {
if (isSupportedThinkingTokenQwenModel(model) && !isSupportEnableThinkingProvider(this.provider)) {
const postsuffix = '/no_think'
const qwenThinkModeEnabled = assistant.settings?.qwenThinkMode === true
const currentContent = lastUserMsg.content
lastUserMsg.content = processPostsuffixQwen3Model(currentContent, postsuffix, qwenThinkModeEnabled) as any
lastUserMsg.content = processPostsuffixQwen3Model(currentContent, qwenThinkModeEnabled)
}
if (this.provider.id === SystemProviderIds.poe) {
// 如果以后 poe 支持 reasoning_effort 参数了,可以删掉这部分

View File

@ -1276,7 +1276,11 @@ export const isSupportStreamOptionsProvider = (provider: Provider) => {
)
}
const NOT_SUPPORT_QWEN3_ENABLE_THINKING_PROVIDER = ['ollama', 'lmstudio'] as const satisfies SystemProviderId[]
const NOT_SUPPORT_QWEN3_ENABLE_THINKING_PROVIDER = [
'ollama',
'lmstudio',
'nvidia'
] as const satisfies SystemProviderId[]
/**
* 使 enable_thinking Qwen3 Only for OpenAI Chat Completions API.

View File

@ -1,5 +1,6 @@
import { Model } from '@renderer/types'
import { ChatCompletionContentPart, ChatCompletionContentPartText, ChatCompletionMessageParam } from 'openai/resources'
import { findLast } from 'lodash'
import { ChatCompletionContentPart, ChatCompletionMessageParam } from 'openai/resources'
export function processReqMessages(
model: Model,
@ -43,60 +44,45 @@ function interleaveUserAndAssistantMessages(messages: ChatCompletionMessageParam
// Process postsuffix for Qwen3 model
export function processPostsuffixQwen3Model(
// content 類型string | ChatCompletionContentPart[] | null
content: string | ChatCompletionContentPart[] | null,
postsuffix: string,
// content 類型string | ChatCompletionContentPart[]
content: string | ChatCompletionContentPart[],
qwenThinkModeEnabled: boolean
): string | ChatCompletionContentPart[] | null {
): string | ChatCompletionContentPart[] {
const noThinkSuffix = '/no_think'
const thinkSuffix = '/think'
if (typeof content === 'string') {
if (qwenThinkModeEnabled) {
// 思考模式启用,移除 postsuffix
if (content.endsWith(postsuffix)) {
return content.substring(0, content.length - postsuffix.length).trimEnd()
if (!content.endsWith(thinkSuffix)) {
return content + ' ' + thinkSuffix
}
} else {
// 思考模式未启用,添加 postsuffix
if (!content.endsWith(postsuffix)) {
return content + ' ' + postsuffix
if (!content.endsWith(noThinkSuffix)) {
return content + ' ' + noThinkSuffix
}
}
} else if (Array.isArray(content)) {
let lastTextPartIndex = -1
for (let i = content.length - 1; i >= 0; i--) {
if (content[i].type === 'text') {
lastTextPartIndex = i
break
}
}
const lastTextPart = findLast(content, (part) => part.type === 'text')
if (lastTextPartIndex !== -1) {
const textPart = content[lastTextPartIndex] as ChatCompletionContentPartText
if (lastTextPart) {
if (qwenThinkModeEnabled) {
// 思考模式启用,移除 postsuffix
if (textPart.text.endsWith(postsuffix)) {
textPart.text = textPart.text.substring(0, textPart.text.length - postsuffix.length).trimEnd()
// 可選:如果 textPart.text 變為空,可以考慮是否移除該 part
if (!lastTextPart.text.endsWith(thinkSuffix)) {
lastTextPart.text += thinkSuffix
}
} else {
// 思考模式未启用,添加 postsuffix
if (!textPart.text.endsWith(postsuffix)) {
textPart.text += postsuffix
if (!lastTextPart.text.endsWith(noThinkSuffix)) {
lastTextPart.text += noThinkSuffix
}
}
} else {
// 數組中沒有文本部分
if (!qwenThinkModeEnabled) {
if (qwenThinkModeEnabled) {
// 思考模式未啓用,需要添加 postsuffix
// 如果沒有文本部分,則添加一個新的文本部分
content.push({ type: 'text', text: postsuffix })
content.push({ type: 'text', text: thinkSuffix })
} else {
content.push({ type: 'text', text: noThinkSuffix })
}
}
} else {
// currentContent 是 null
if (!qwenThinkModeEnabled) {
// 思考模式未启用,需要添加 postsuffix
return content
}
}
return content
}