mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
feat: reasoning effort cache (#9357)
* feat(useAssistant): 修改模型切换时推理努力值回退逻辑 当模型切换时,确保推理努力值回退到模型支持的第一个有效值,并默认开启思考模式。使用useRef优化设置引用,避免不必要的依赖。 * feat(assistant): 添加 reasoning_effort_cache 以保留思考模型设置 当从非思考模型切换回思考模型时,恢复上次使用的 reasoning_effort 值 * fix(assistant): 修复思考模式切换时缓存未正确更新的问题 * fix(useAssistant): 修复模型选项回退逻辑以支持推理模式 当启用推理模式时,回退到支持推理的选项,否则回退到默认选项 * docs(types): 完善 AssistantSettings 类型注释中的 TODO 说明
This commit is contained in:
parent
062b3b0a33
commit
ea6a1752e7
@ -3,7 +3,8 @@ import {
|
||||
getThinkModelType,
|
||||
isSupportedReasoningEffortModel,
|
||||
isSupportedThinkingTokenModel,
|
||||
MODEL_SUPPORTED_OPTIONS
|
||||
MODEL_SUPPORTED_OPTIONS,
|
||||
MODEL_SUPPORTED_REASONING_EFFORT
|
||||
} from '@renderer/config/models'
|
||||
import { db } from '@renderer/databases'
|
||||
import { getDefaultTopic } from '@renderer/services/AssistantService'
|
||||
@ -24,9 +25,9 @@ import {
|
||||
updateTopics
|
||||
} from '@renderer/store/assistants'
|
||||
import { setDefaultModel, setQuickModel, setTranslateModel } from '@renderer/store/llm'
|
||||
import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types'
|
||||
import { Assistant, AssistantSettings, Model, ThinkingOption, Topic } from '@renderer/types'
|
||||
import { uuid } from '@renderer/utils'
|
||||
import { useCallback, useEffect, useMemo } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { TopicManager } from './useTopic'
|
||||
@ -84,6 +85,12 @@ export function useAssistant(id: string) {
|
||||
|
||||
const assistantWithModel = useMemo(() => ({ ...assistant, model }), [assistant, model])
|
||||
|
||||
const settingsRef = useRef(assistant?.settings)
|
||||
|
||||
useEffect(() => {
|
||||
settingsRef.current = assistant.settings
|
||||
}, [assistant?.settings])
|
||||
|
||||
const updateAssistantSettings = useCallback(
|
||||
(settings: Partial<AssistantSettings>) => {
|
||||
assistant?.id && dispatch(_updateAssistantSettings({ assistantId: assistant.id, settings }))
|
||||
@ -93,28 +100,46 @@ export function useAssistant(id: string) {
|
||||
|
||||
// 当model变化时,同步reasoning effort为模型支持的合法值
|
||||
useEffect(() => {
|
||||
if (assistant?.settings) {
|
||||
const settings = settingsRef.current
|
||||
if (settings) {
|
||||
const currentReasoningEffort = settings.reasoning_effort
|
||||
if (isSupportedThinkingTokenModel(model) || isSupportedReasoningEffortModel(model)) {
|
||||
const currentReasoningEffort = assistant?.settings?.reasoning_effort
|
||||
const supportedOptions = MODEL_SUPPORTED_OPTIONS[getThinkModelType(model)]
|
||||
if (currentReasoningEffort && !supportedOptions.includes(currentReasoningEffort)) {
|
||||
// 选项不支持时,回退到第一个支持的值
|
||||
// 注意:这里假设可用的options不会为空
|
||||
const fallbackOption = supportedOptions[0]
|
||||
const modelType = getThinkModelType(model)
|
||||
const supportedOptions = MODEL_SUPPORTED_OPTIONS[modelType]
|
||||
if (supportedOptions.every((option) => option !== currentReasoningEffort)) {
|
||||
const cache = settings.reasoning_effort_cache
|
||||
let fallbackOption: ThinkingOption
|
||||
|
||||
// 选项不支持时,首先尝试恢复到上次使用的值
|
||||
if (cache && supportedOptions.includes(cache)) {
|
||||
fallbackOption = cache
|
||||
} else {
|
||||
// 灵活回退到支持的值
|
||||
// 注意:这里假设可用的options不会为空
|
||||
const enableThinking = currentReasoningEffort !== undefined
|
||||
fallbackOption = enableThinking
|
||||
? MODEL_SUPPORTED_REASONING_EFFORT[modelType][0]
|
||||
: MODEL_SUPPORTED_OPTIONS[modelType][0]
|
||||
}
|
||||
|
||||
updateAssistantSettings({
|
||||
reasoning_effort: fallbackOption === 'off' ? undefined : fallbackOption,
|
||||
qwenThinkMode: fallbackOption === 'off'
|
||||
reasoning_effort_cache: fallbackOption === 'off' ? undefined : fallbackOption,
|
||||
qwenThinkMode: fallbackOption === 'off' ? undefined : true
|
||||
})
|
||||
} else {
|
||||
// 对于支持的选项, 不再更新 cache.
|
||||
}
|
||||
} else {
|
||||
// 切换到非思考模型时保留cache
|
||||
updateAssistantSettings({
|
||||
reasoning_effort: undefined,
|
||||
reasoning_effort_cache: currentReasoningEffort,
|
||||
qwenThinkMode: undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [assistant?.settings, model, updateAssistantSettings])
|
||||
}, [model, updateAssistantSettings])
|
||||
|
||||
return {
|
||||
assistant: assistantWithModel,
|
||||
|
||||
@ -77,12 +77,14 @@ const ThinkingButton: FC<Props> = ({ ref, model, assistant, ToolbarButton }): Re
|
||||
if (!isEnabled) {
|
||||
updateAssistantSettings({
|
||||
reasoning_effort: undefined,
|
||||
reasoning_effort_cache: undefined,
|
||||
qwenThinkMode: false
|
||||
})
|
||||
return
|
||||
}
|
||||
updateAssistantSettings({
|
||||
reasoning_effort: option,
|
||||
reasoning_effort_cache: option,
|
||||
qwenThinkMode: true
|
||||
})
|
||||
return
|
||||
|
||||
@ -99,6 +99,13 @@ export type AssistantSettings = {
|
||||
defaultModel?: Model
|
||||
customParameters?: AssistantSettingCustomParameters[]
|
||||
reasoning_effort?: ReasoningEffortOption
|
||||
/** 保留上一次使用思考模型时的 reasoning effort, 在从非思考模型切换到思考模型时恢复.
|
||||
*
|
||||
* TODO: 目前 reasoning_effort === undefined 有两个语义,有的场景是显式关闭思考,有的场景是不传参。
|
||||
* 未来应该重构思考控制,将启用/关闭思考和思考选项分离,这样就不用依赖 cache 了。
|
||||
*
|
||||
*/
|
||||
reasoning_effort_cache?: ReasoningEffortOption
|
||||
qwenThinkMode?: boolean
|
||||
toolUseMode: 'function' | 'prompt'
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user