mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 02:20:10 +08:00
feat: support default Quick Assistant model (#6150)
* feat: support default Quick Assistant model - support the configuration of the quick assistant model. - manage the models independently in Quick Assistant and Default Assistant. * docs(i18n): Add translation for quick assistant model * fix(llm): fix the default value of quickAssistantModel to silicon[1] * refactor(i18n): uniformly the terms, changing "快速助手" to "快捷助手"
This commit is contained in:
parent
db01b4981d
commit
75f25d8a44
@ -15,7 +15,7 @@ import {
|
|||||||
updateTopic,
|
updateTopic,
|
||||||
updateTopics
|
updateTopics
|
||||||
} from '@renderer/store/assistants'
|
} from '@renderer/store/assistants'
|
||||||
import { setDefaultModel, setTopicNamingModel, setTranslateModel } from '@renderer/store/llm'
|
import { setDefaultModel, setQuickAssistantModel, setTopicNamingModel, setTranslateModel } from '@renderer/store/llm'
|
||||||
import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types'
|
import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types'
|
||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
@ -103,15 +103,17 @@ export function useDefaultAssistant() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useDefaultModel() {
|
export function useDefaultModel() {
|
||||||
const { defaultModel, topicNamingModel, translateModel } = useAppSelector((state) => state.llm)
|
const { defaultModel, topicNamingModel, translateModel, quickAssistantModel } = useAppSelector((state) => state.llm)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
defaultModel,
|
defaultModel,
|
||||||
topicNamingModel,
|
topicNamingModel,
|
||||||
translateModel,
|
translateModel,
|
||||||
|
quickAssistantModel,
|
||||||
setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })),
|
setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })),
|
||||||
setTopicNamingModel: (model: Model) => dispatch(setTopicNamingModel({ model })),
|
setTopicNamingModel: (model: Model) => dispatch(setTopicNamingModel({ model })),
|
||||||
setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model }))
|
setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model })),
|
||||||
|
setQuickAssistantModel: (model: Model) => dispatch(setQuickAssistantModel({ model }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1472,6 +1472,8 @@
|
|||||||
"models.translate_model_description": "Model used for translation service",
|
"models.translate_model_description": "Model used for translation service",
|
||||||
"models.translate_model_prompt_message": "Please enter the translate model prompt",
|
"models.translate_model_prompt_message": "Please enter the translate model prompt",
|
||||||
"models.translate_model_prompt_title": "Translate Model Prompt",
|
"models.translate_model_prompt_title": "Translate Model Prompt",
|
||||||
|
"models.quick_assistant_model": "Quick Assistant Model",
|
||||||
|
"models.quick_assistant_model_description": "Default model used by Quick Assistant",
|
||||||
"moresetting": "More Settings",
|
"moresetting": "More Settings",
|
||||||
"moresetting.check.confirm": "Confirm Selection",
|
"moresetting.check.confirm": "Confirm Selection",
|
||||||
"moresetting.check.warn": "Please be cautious when selecting this option. Incorrect selection may cause the model to malfunction!",
|
"moresetting.check.warn": "Please be cautious when selecting this option. Incorrect selection may cause the model to malfunction!",
|
||||||
|
|||||||
@ -1468,6 +1468,8 @@
|
|||||||
"models.translate_model_description": "翻訳サービスに使用されるモデル",
|
"models.translate_model_description": "翻訳サービスに使用されるモデル",
|
||||||
"models.translate_model_prompt_message": "翻訳モデルのプロンプトを入力してください",
|
"models.translate_model_prompt_message": "翻訳モデルのプロンプトを入力してください",
|
||||||
"models.translate_model_prompt_title": "翻訳モデルのプロンプト",
|
"models.translate_model_prompt_title": "翻訳モデルのプロンプト",
|
||||||
|
"models.quick_assistant_model": "クイックアシスタントモデル",
|
||||||
|
"models.quick_assistant_model_description": "クイックアシスタントで使用されるデフォルトモデル",
|
||||||
"moresetting": "詳細設定",
|
"moresetting": "詳細設定",
|
||||||
"moresetting.check.confirm": "選択を確認",
|
"moresetting.check.confirm": "選択を確認",
|
||||||
"moresetting.check.warn": "このオプションを選択する際は慎重に行ってください。誤った選択はモデルの誤動作を引き起こす可能性があります!",
|
"moresetting.check.warn": "このオプションを選択する際は慎重に行ってください。誤った選択はモデルの誤動作を引き起こす可能性があります!",
|
||||||
|
|||||||
@ -1468,6 +1468,8 @@
|
|||||||
"models.translate_model_description": "Модель, используемая для сервиса перевода",
|
"models.translate_model_description": "Модель, используемая для сервиса перевода",
|
||||||
"models.translate_model_prompt_message": "Введите модель перевода",
|
"models.translate_model_prompt_message": "Введите модель перевода",
|
||||||
"models.translate_model_prompt_title": "Модель перевода",
|
"models.translate_model_prompt_title": "Модель перевода",
|
||||||
|
"models.quick_assistant_model": "Модель быстрого помощника",
|
||||||
|
"models.quick_assistant_model_description": "Модель по умолчанию, используемая быстрым помощником",
|
||||||
"moresetting": "Дополнительные настройки",
|
"moresetting": "Дополнительные настройки",
|
||||||
"moresetting.check.confirm": "Подтвердить выбор",
|
"moresetting.check.confirm": "Подтвердить выбор",
|
||||||
"moresetting.check.warn": "Пожалуйста, будьте осторожны при выборе этой опции. Неправильный выбор может привести к сбою в работе модели!",
|
"moresetting.check.warn": "Пожалуйста, будьте осторожны при выборе этой опции. Неправильный выбор может привести к сбою в работе модели!",
|
||||||
|
|||||||
@ -1472,6 +1472,8 @@
|
|||||||
"models.translate_model_description": "翻译服务使用的模型",
|
"models.translate_model_description": "翻译服务使用的模型",
|
||||||
"models.translate_model_prompt_message": "请输入翻译模型提示词",
|
"models.translate_model_prompt_message": "请输入翻译模型提示词",
|
||||||
"models.translate_model_prompt_title": "翻译模型提示词",
|
"models.translate_model_prompt_title": "翻译模型提示词",
|
||||||
|
"models.quick_assistant_model": "快捷助手模型",
|
||||||
|
"models.quick_assistant_model_description": "快捷助手使用的默认模型",
|
||||||
"moresetting": "更多设置",
|
"moresetting": "更多设置",
|
||||||
"moresetting.check.confirm": "确认勾选",
|
"moresetting.check.confirm": "确认勾选",
|
||||||
"moresetting.check.warn": "请慎重勾选此选项,勾选错误会导致模型无法正常使用!!!",
|
"moresetting.check.warn": "请慎重勾选此选项,勾选错误会导致模型无法正常使用!!!",
|
||||||
|
|||||||
@ -1471,6 +1471,8 @@
|
|||||||
"models.translate_model_description": "翻譯服務使用的模型",
|
"models.translate_model_description": "翻譯服務使用的模型",
|
||||||
"models.translate_model_prompt_message": "請輸入翻譯模型提示詞",
|
"models.translate_model_prompt_message": "請輸入翻譯模型提示詞",
|
||||||
"models.translate_model_prompt_title": "翻譯模型提示詞",
|
"models.translate_model_prompt_title": "翻譯模型提示詞",
|
||||||
|
"models.quick_assistant_model": "快捷助手模型",
|
||||||
|
"models.quick_assistant_model_description": "快捷助手使用的預設模型",
|
||||||
"moresetting": "更多設定",
|
"moresetting": "更多設定",
|
||||||
"moresetting.check.confirm": "確認勾選",
|
"moresetting.check.confirm": "確認勾選",
|
||||||
"moresetting.check.warn": "請謹慎勾選此選項,勾選錯誤會導致模型無法正常使用!!!",
|
"moresetting.check.warn": "請謹慎勾選此選項,勾選錯誤會導致模型無法正常使用!!!",
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { setTranslateModelPrompt } from '@renderer/store/settings'
|
|||||||
import { Model } from '@renderer/types'
|
import { Model } from '@renderer/types'
|
||||||
import { Button, Select, Tooltip } from 'antd'
|
import { Button, Select, Tooltip } from 'antd'
|
||||||
import { find, sortBy } from 'lodash'
|
import { find, sortBy } from 'lodash'
|
||||||
import { FolderPen, Languages, MessageSquareMore, Settings2 } from 'lucide-react'
|
import { FolderPen, Languages, MessageSquareMore, Rocket, Settings2 } from 'lucide-react'
|
||||||
import { FC, useMemo } from 'react'
|
import { FC, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
@ -22,8 +22,16 @@ import DefaultAssistantSettings from './DefaultAssistantSettings'
|
|||||||
import TopicNamingModalPopup from './TopicNamingModalPopup'
|
import TopicNamingModalPopup from './TopicNamingModalPopup'
|
||||||
|
|
||||||
const ModelSettings: FC = () => {
|
const ModelSettings: FC = () => {
|
||||||
const { defaultModel, topicNamingModel, translateModel, setDefaultModel, setTopicNamingModel, setTranslateModel } =
|
const {
|
||||||
useDefaultModel()
|
defaultModel,
|
||||||
|
topicNamingModel,
|
||||||
|
translateModel,
|
||||||
|
quickAssistantModel,
|
||||||
|
setDefaultModel,
|
||||||
|
setTopicNamingModel,
|
||||||
|
setTranslateModel,
|
||||||
|
setQuickAssistantModel
|
||||||
|
} = useDefaultModel()
|
||||||
const { providers } = useProviders()
|
const { providers } = useProviders()
|
||||||
const allModels = providers.map((p) => p.models).flat()
|
const allModels = providers.map((p) => p.models).flat()
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
@ -60,6 +68,11 @@ const ModelSettings: FC = () => {
|
|||||||
[translateModel]
|
[translateModel]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultQuickAssistantModel = useMemo(
|
||||||
|
() => (hasModel(quickAssistantModel) ? getModelUniqId(quickAssistantModel) : undefined),
|
||||||
|
[quickAssistantModel]
|
||||||
|
)
|
||||||
|
|
||||||
const onUpdateTranslateModel = async () => {
|
const onUpdateTranslateModel = async () => {
|
||||||
const prompt = await PromptPopup.show({
|
const prompt = await PromptPopup.show({
|
||||||
title: t('settings.models.translate_model_prompt_title'),
|
title: t('settings.models.translate_model_prompt_title'),
|
||||||
@ -149,6 +162,26 @@ const ModelSettings: FC = () => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
<SettingDescription>{t('settings.models.translate_model_description')}</SettingDescription>
|
<SettingDescription>{t('settings.models.translate_model_description')}</SettingDescription>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
|
<SettingGroup theme={theme}>
|
||||||
|
<SettingTitle style={{ marginBottom: 12 }}>
|
||||||
|
<HStack alignItems="center" gap={10}>
|
||||||
|
<Rocket size={18} color="var(--color-text)" />
|
||||||
|
{t('settings.models.quick_assistant_model')}
|
||||||
|
</HStack>
|
||||||
|
</SettingTitle>
|
||||||
|
<HStack alignItems="center">
|
||||||
|
<Select
|
||||||
|
value={defaultQuickAssistantModel}
|
||||||
|
defaultValue={defaultQuickAssistantModel}
|
||||||
|
style={{ width: 360 }}
|
||||||
|
onChange={(value) => setQuickAssistantModel(find(allModels, JSON.parse(value)) as Model)}
|
||||||
|
options={selectOptions}
|
||||||
|
showSearch
|
||||||
|
placeholder={t('settings.models.empty')}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
<SettingDescription>{t('settings.models.quick_assistant_model_description')}</SettingDescription>
|
||||||
|
</SettingGroup>
|
||||||
</SettingContainer>
|
</SettingContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ export interface LlmState {
|
|||||||
defaultModel: Model
|
defaultModel: Model
|
||||||
topicNamingModel: Model
|
topicNamingModel: Model
|
||||||
translateModel: Model
|
translateModel: Model
|
||||||
|
quickAssistantModel: Model
|
||||||
settings: LlmSettings
|
settings: LlmSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +484,7 @@ const initialState: LlmState = {
|
|||||||
defaultModel: SYSTEM_MODELS.silicon[1],
|
defaultModel: SYSTEM_MODELS.silicon[1],
|
||||||
topicNamingModel: SYSTEM_MODELS.silicon[2],
|
topicNamingModel: SYSTEM_MODELS.silicon[2],
|
||||||
translateModel: SYSTEM_MODELS.silicon[3],
|
translateModel: SYSTEM_MODELS.silicon[3],
|
||||||
|
quickAssistantModel: SYSTEM_MODELS.silicon[1],
|
||||||
providers: INITIAL_PROVIDERS,
|
providers: INITIAL_PROVIDERS,
|
||||||
settings: {
|
settings: {
|
||||||
ollama: {
|
ollama: {
|
||||||
@ -589,6 +591,9 @@ const llmSlice = createSlice({
|
|||||||
setTranslateModel: (state, action: PayloadAction<{ model: Model }>) => {
|
setTranslateModel: (state, action: PayloadAction<{ model: Model }>) => {
|
||||||
state.translateModel = action.payload.model
|
state.translateModel = action.payload.model
|
||||||
},
|
},
|
||||||
|
setQuickAssistantModel: (state, action: PayloadAction<{ model: Model }>) => {
|
||||||
|
state.quickAssistantModel = action.payload.model
|
||||||
|
},
|
||||||
setOllamaKeepAliveTime: (state, action: PayloadAction<number>) => {
|
setOllamaKeepAliveTime: (state, action: PayloadAction<number>) => {
|
||||||
state.settings.ollama.keepAliveTime = action.payload
|
state.settings.ollama.keepAliveTime = action.payload
|
||||||
},
|
},
|
||||||
@ -626,6 +631,7 @@ export const {
|
|||||||
setDefaultModel,
|
setDefaultModel,
|
||||||
setTopicNamingModel,
|
setTopicNamingModel,
|
||||||
setTranslateModel,
|
setTranslateModel,
|
||||||
|
setQuickAssistantModel,
|
||||||
setOllamaKeepAliveTime,
|
setOllamaKeepAliveTime,
|
||||||
setLMStudioKeepAliveTime,
|
setLMStudioKeepAliveTime,
|
||||||
setGPUStackKeepAliveTime,
|
setGPUStackKeepAliveTime,
|
||||||
|
|||||||
@ -40,7 +40,9 @@ const HomeWindow: FC = () => {
|
|||||||
const textChange = useState(() => {})[1]
|
const textChange = useState(() => {})[1]
|
||||||
const { defaultAssistant } = useDefaultAssistant()
|
const { defaultAssistant } = useDefaultAssistant()
|
||||||
const topic = defaultAssistant.topics[0]
|
const topic = defaultAssistant.topics[0]
|
||||||
const { defaultModel: model } = useDefaultModel()
|
const { defaultModel, quickAssistantModel } = useDefaultModel()
|
||||||
|
// 如果 quickAssistantModel 未設定,則使用 defaultModel
|
||||||
|
const model = quickAssistantModel || defaultModel
|
||||||
const { language, readClipboardAtStartup, windowStyle, theme } = useSettings()
|
const { language, readClipboardAtStartup, windowStyle, theme } = useSettings()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const inputBarRef = useRef<HTMLDivElement>(null)
|
const inputBarRef = useRef<HTMLDivElement>(null)
|
||||||
@ -182,7 +184,7 @@ const HomeWindow: FC = () => {
|
|||||||
|
|
||||||
fetchChatCompletion({
|
fetchChatCompletion({
|
||||||
messages: [userMessage],
|
messages: [userMessage],
|
||||||
assistant: { ...assistant, model: getDefaultModel() },
|
assistant: { ...assistant, model: quickAssistantModel || getDefaultModel() },
|
||||||
onChunkReceived: (chunk: Chunk) => {
|
onChunkReceived: (chunk: Chunk) => {
|
||||||
if (chunk.type === ChunkType.TEXT_DELTA) {
|
if (chunk.type === ChunkType.TEXT_DELTA) {
|
||||||
blockContent += chunk.text
|
blockContent += chunk.text
|
||||||
@ -219,7 +221,7 @@ const HomeWindow: FC = () => {
|
|||||||
setIsFirstMessage(false)
|
setIsFirstMessage(false)
|
||||||
setText('') // ✅ 清除输入框内容
|
setText('') // ✅ 清除输入框内容
|
||||||
},
|
},
|
||||||
[content, defaultAssistant, topic]
|
[content, defaultAssistant, topic, quickAssistantModel]
|
||||||
)
|
)
|
||||||
|
|
||||||
const clearClipboard = () => {
|
const clearClipboard = () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user