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:
jwcrystal 2025-05-19 20:49:13 +08:00 committed by GitHub
parent db01b4981d
commit 75f25d8a44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 62 additions and 9 deletions

View File

@ -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 }))
} }
} }

View File

@ -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!",

View File

@ -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": "このオプションを選択する際は慎重に行ってください。誤った選択はモデルの誤動作を引き起こす可能性があります!",

View File

@ -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": "Пожалуйста, будьте осторожны при выборе этой опции. Неправильный выбор может привести к сбою в работе модели!",

View File

@ -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": "请慎重勾选此选项,勾选错误会导致模型无法正常使用!!!",

View File

@ -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": "請謹慎勾選此選項,勾選錯誤會導致模型無法正常使用!!!",

View File

@ -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>
) )
} }

View File

@ -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,

View File

@ -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 = () => {