feat: quick model (#9290)

* refactor(i18n): 将话题命名模型相关文案更新为摘要模型

更新所有语言文件中关于话题命名模型的文案,统一改为摘要模型,以反映功能的扩展和更通用的用途

* refactor(设置页面): 优化主题命名弹窗组件性能

使用useCallback和useMemo优化回调函数和渲染性能
将重复的JSX代码提取为独立组件

* feat(设置): 在模型设置中添加话题命名折叠面板

将话题命名设置从直接显示改为折叠面板形式,提升界面整洁度

* refactor(i18n): 重构话题命名相关翻译字段结构

* docs(i18n): 添加生成图像的高度、宽度和安全容忍度翻译占位符

* fix(settings): 修正主题命名弹窗中的翻译键名

* style(ui): 调整主题命名弹窗的间距和文本区域高度

移除多余的上下边距,并使用自适应高度的文本区域

* refactor(llm): 将 topicNamingModel 重命名为 summaryModel

更新相关函数、状态和测试用例以反映命名变更
增加迁移逻辑处理旧状态数据
更新持久化版本号至133

* fix(ApiService): 优先使用摘要模型替代默认模型

当获取摘要时,优先使用getSummaryModel()返回的模型,其次才是助手指定的模型或默认模型,以确保摘要生成的一致性

* docs(i18n): 更新摘要模型描述中的搜索关键词提炼

将"搜索结果摘要"修改为"搜索关键字提炼"以更准确描述功能

* fix(i18n): 更新多语言翻译文件中的摘要模型相关文本

* feat(i18n): 为摘要模型设置添加工具提示说明

添加摘要模型设置的工具提示,建议用户选择轻量模型而非思考模型

* refactor(i18n): 将摘要模型相关文案更新为快速模型

更新国际化文案和组件引用,将"摘要模型"统一改为"快速模型"以更准确描述功能用途

* feat(i18n): 将摘要模型重命名为快速模型并更新相关描述

* refactor(llm): 将summaryModel重命名为quickModel以提升语义清晰度

* test(api): 在ApiService测试中添加LlmState类型和awsBedrock配置

添加LlmState类型以满足类型检查要求,并补充awsBedrock的mock配置以完善测试覆盖

* Revert "feat(设置): 在模型设置中添加话题命名折叠面板"

This reverts commit 4d58c053da.

* refactor(settings): 重命名并移动 TopicNamingModalPopup 组件文件

将 TopicNamingModalPopup.tsx 重命名为 QuickModelPopup.tsx 并移动到相应目录

* refactor(QuickModelPopup): 优化主题命名设置布局和样式

移除 TopicNamingSettings 组件内联实现,直接整合到 Modal 中
调整间距和样式,提升视觉一致性
修复文本区域 onChange 去除换行的逻辑

* feat(模型设置): 在快速模型弹窗中添加重置按钮图标并调整布局

将重置按钮改为图标形式并内联显示,同时调整输入区域的高度样式

* docs(i18n): 更新快速模型相关翻译文本

* fix: 将迁移错误日志从133更新为134

* style(settings): 替换模型设置中的图标为Rocket图标以提升视觉一致性
This commit is contained in:
Phantom 2025-08-19 20:39:52 +08:00 committed by GitHub
parent 0368583cfc
commit 80dfcf05a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 289 additions and 200 deletions

View File

@ -38,7 +38,7 @@ export function useAppInit() {
enableDataCollection enableDataCollection
} = useSettings() } = useSettings()
const { minappShow } = useRuntime() const { minappShow } = useRuntime()
const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel() const { setDefaultModel, setQuickModel, setTranslateModel } = useDefaultModel()
const avatar = useLiveQuery(() => db.settings.get('image://avatar')) const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
const { theme } = useTheme() const { theme } = useTheme()
const memoryConfig = useAppSelector(selectMemoryConfig) const memoryConfig = useAppSelector(selectMemoryConfig)
@ -115,7 +115,7 @@ export function useAppInit() {
if (isLocalAi) { if (isLocalAi) {
const model = JSON.parse(import.meta.env.VITE_RENDERER_INTEGRATED_MODEL) const model = JSON.parse(import.meta.env.VITE_RENDERER_INTEGRATED_MODEL)
setDefaultModel(model) setDefaultModel(model)
setTopicNamingModel(model) setQuickModel(model)
setTranslateModel(model) setTranslateModel(model)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -23,7 +23,7 @@ import {
updateTopic, updateTopic,
updateTopics updateTopics
} from '@renderer/store/assistants' } from '@renderer/store/assistants'
import { setDefaultModel, setTopicNamingModel, setTranslateModel } from '@renderer/store/llm' import { setDefaultModel, setQuickModel, setTranslateModel } from '@renderer/store/llm'
import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types' import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types'
import { uuid } from '@renderer/utils' import { uuid } from '@renderer/utils'
import { useCallback, useEffect, useMemo } from 'react' import { useCallback, useEffect, useMemo } from 'react'
@ -167,15 +167,15 @@ export function useDefaultAssistant() {
} }
export function useDefaultModel() { export function useDefaultModel() {
const { defaultModel, topicNamingModel, translateModel } = useAppSelector((state) => state.llm) const { defaultModel, quickModel, translateModel } = useAppSelector((state) => state.llm)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
return { return {
defaultModel, defaultModel,
topicNamingModel, quickModel,
translateModel, translateModel,
setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })), setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })),
setTopicNamingModel: (model: Model) => dispatch(setTopicNamingModel({ model })), setQuickModel: (model: Model) => dispatch(setQuickModel({ model })),
setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model })) setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model }))
} }
} }

View File

@ -2276,8 +2276,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "When enabled, use topic naming model to create titles for exported messages. This will also affect all Markdown export methods.", "help": "When enabled, use the quick model to name the title for exported messages. This setting also affects all export methods through Markdown.",
"title": "Use topic naming model to create titles for exported messages" "title": "Use the quick model to name the title for the exported message"
} }
}, },
"minute_interval_one": "{{count}} minute", "minute_interval_one": "{{count}} minute",
@ -3115,7 +3115,6 @@
"default_assistant_model": "Default Assistant Model", "default_assistant_model": "Default Assistant Model",
"default_assistant_model_description": "Model used when creating a new assistant, if the assistant is not set, this model will be used", "default_assistant_model_description": "Model used when creating a new assistant, if the assistant is not set, this model will be used",
"empty": "No models found", "empty": "No models found",
"enable_topic_naming": "Topic Auto Naming",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "Are you sure you want to add all models to the list?", "confirm": "Are you sure you want to add all models to the list?",
@ -3141,10 +3140,17 @@
"quick_assistant_default_tag": "Default", "quick_assistant_default_tag": "Default",
"quick_assistant_model": "Quick Assistant Model", "quick_assistant_model": "Quick Assistant Model",
"quick_assistant_selection": "Select Assistant", "quick_assistant_selection": "Select Assistant",
"topic_naming_model": "Topic Naming Model", "quick_model": {
"topic_naming_model_description": "Model used when automatically naming a new topic", "description": "Model used for simple tasks such as topic naming and keyword extraction",
"topic_naming_model_setting_title": "Topic Naming Model Settings", "label": "Quick Model",
"topic_naming_prompt": "Topic Naming Prompt", "setting_title": "Quick model setup",
"tooltip": "It is recommended to choose a lightweight model and not recommended to choose a thinking model."
},
"topic_naming": {
"auto": "Topic Auto Naming",
"label": "Topic naming",
"prompt": "Topic Naming Prompt"
},
"translate_model": "Translate Model", "translate_model": "Translate Model",
"translate_model_description": "Model used for translation service", "translate_model_description": "Model used for translation service",
"translate_model_prompt_message": "Please enter the translate model prompt", "translate_model_prompt_message": "Please enter the translate model prompt",

View File

@ -2276,8 +2276,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "この設定は、すべてのMarkdownエクスポート方法に影響します。", "help": "有効にすると、エクスポートされたメッセージのタイトル名に高速モデルを使用します。この設定はMarkdownによるエクスポート方法全般影響します。",
"title": "トピック命名モデルを使用してメッセージのタイトルを作成" "title": "高速モデルを使用してエクスポートされたメッセージのタイトルを命名"
} }
}, },
"minute_interval_one": "{{count}} 分", "minute_interval_one": "{{count}} 分",
@ -3115,7 +3115,6 @@
"default_assistant_model": "デフォルトアシスタントモデル", "default_assistant_model": "デフォルトアシスタントモデル",
"default_assistant_model_description": "新しいアシスタントを作成する際に使用されるモデル。アシスタントがモデルを設定していない場合、このモデルが使用されます", "default_assistant_model_description": "新しいアシスタントを作成する際に使用されるモデル。アシスタントがモデルを設定していない場合、このモデルが使用されます",
"empty": "モデルが見つかりません", "empty": "モデルが見つかりません",
"enable_topic_naming": "トピックの自動命名",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "すべてのモデルをリストに追加しますか?", "confirm": "すべてのモデルをリストに追加しますか?",
@ -3141,10 +3140,17 @@
"quick_assistant_default_tag": "デフォルト", "quick_assistant_default_tag": "デフォルト",
"quick_assistant_model": "クイックアシスタントモデル", "quick_assistant_model": "クイックアシスタントモデル",
"quick_assistant_selection": "アシスタントを選択します", "quick_assistant_selection": "アシスタントを選択します",
"topic_naming_model": "トピック命名モデル", "quick_model": {
"topic_naming_model_description": "新しいトピックを自動的に命名する際に使用されるモデル", "description": "トピックの命名や検索キーワードの抽出などの簡単なタスクを実行する際に使用されるモデル",
"topic_naming_model_setting_title": "トピック命名モデルの設定", "label": "高速モデル",
"topic_naming_prompt": "トピック命名プロンプト", "setting_title": "高速モデル設定",
"tooltip": "軽量モデルの選択を推奨し、思考モデルの選択は推奨しません"
},
"topic_naming": {
"auto": "トピックの自動命名",
"label": "トピック名",
"prompt": "トピック命名プロンプト"
},
"translate_model": "翻訳モデル", "translate_model": "翻訳モデル",
"translate_model_description": "翻訳サービスに使用されるモデル", "translate_model_description": "翻訳サービスに使用されるモデル",
"translate_model_prompt_message": "翻訳モデルのプロンプトを入力してください", "translate_model_prompt_message": "翻訳モデルのプロンプトを入力してください",

View File

@ -2276,8 +2276,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "Этот параметр влияет на все методы экспорта в Markdown, такие как Notion, Yuque и т.д.", "help": "После включения заголовки экспортируемых сообщений будут назначаться с использованием быстрой модели. Эта настройка также влияет на все способы экспорта через Markdown",
"title": "Использовать модель именования тем для создания заголовков сообщений" "title": "Использование быстрой модели для наименования заголовков экспортированных сообщений"
} }
}, },
"minute_interval_one": "{{count}} минута", "minute_interval_one": "{{count}} минута",
@ -3115,7 +3115,6 @@
"default_assistant_model": "Модель ассистента по умолчанию", "default_assistant_model": "Модель ассистента по умолчанию",
"default_assistant_model_description": "Модель, используемая при создании нового ассистента, если ассистент не имеет настроенной модели, будет использоваться эта модель", "default_assistant_model_description": "Модель, используемая при создании нового ассистента, если ассистент не имеет настроенной модели, будет использоваться эта модель",
"empty": "Модели не найдены", "empty": "Модели не найдены",
"enable_topic_naming": "Автоматическое переименование топика",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "Вы уверены, что хотите добавить все модели в список?", "confirm": "Вы уверены, что хотите добавить все модели в список?",
@ -3141,10 +3140,17 @@
"quick_assistant_default_tag": "умолчанию", "quick_assistant_default_tag": "умолчанию",
"quick_assistant_model": "Модель быстрого помощника", "quick_assistant_model": "Модель быстрого помощника",
"quick_assistant_selection": "Выберите помощника", "quick_assistant_selection": "Выберите помощника",
"topic_naming_model": "Модель именования топика", "quick_model": {
"topic_naming_model_description": "Модель, используемая при автоматическом именовании нового топика", "description": "модель, используемая для выполнения простых задач, таких как именование тем, извлечение ключевых слов для поиска и т.д.",
"topic_naming_model_setting_title": "Настройки модели именования топика", "label": "Быстрая модель",
"topic_naming_prompt": "Подсказка для именования топика", "setting_title": "Быстрая настройка модели",
"tooltip": "Рекомендуется выбирать легковесную модель, не рекомендуется выбирать модель с функцией размышления"
},
"topic_naming": {
"auto": "Автоматическое переименование топика",
"label": "Название темы",
"prompt": "Подсказка для именования топика"
},
"translate_model": "Модель перевода", "translate_model": "Модель перевода",
"translate_model_description": "Модель, используемая для сервиса перевода", "translate_model_description": "Модель, используемая для сервиса перевода",
"translate_model_prompt_message": "Введите модель перевода", "translate_model_prompt_message": "Введите модель перевода",

View File

@ -2276,8 +2276,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "开启后,使用话题命名模型为导出的消息创建标题。该项也会影响所有通过 Markdown 导出的方式", "help": "开启后,使用快速模型为导出的消息命名标题。该项也会影响所有通过 Markdown 导出的方式",
"title": "使用话题命名模型为导出的消息创建标题" "title": "使用快速模型为导出的消息命名标题"
} }
}, },
"minute_interval_one": "{{count}} 分钟", "minute_interval_one": "{{count}} 分钟",
@ -3115,7 +3115,6 @@
"default_assistant_model": "默认助手模型", "default_assistant_model": "默认助手模型",
"default_assistant_model_description": "创建新助手时使用的模型,如果助手未设置模型,则使用此模型", "default_assistant_model_description": "创建新助手时使用的模型,如果助手未设置模型,则使用此模型",
"empty": "没有模型", "empty": "没有模型",
"enable_topic_naming": "话题自动重命名",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "确定要添加所有模型到列表吗?", "confirm": "确定要添加所有模型到列表吗?",
@ -3141,10 +3140,17 @@
"quick_assistant_default_tag": "默认", "quick_assistant_default_tag": "默认",
"quick_assistant_model": "快捷助手模型", "quick_assistant_model": "快捷助手模型",
"quick_assistant_selection": "选择助手", "quick_assistant_selection": "选择助手",
"topic_naming_model": "话题命名模型", "quick_model": {
"topic_naming_model_description": "自动命名新话题时使用的模型", "description": "执行话题命名、搜索关键字提炼等简单任务时使用的模型",
"topic_naming_model_setting_title": "话题命名模型设置", "label": "快速模型",
"topic_naming_prompt": "话题命名提示词", "setting_title": "快速模型设置",
"tooltip": "建议选择轻量模型,不建议选择思考模型"
},
"topic_naming": {
"auto": "话题自动重命名",
"label": "话题命名",
"prompt": "话题命名提示词"
},
"translate_model": "翻译模型", "translate_model": "翻译模型",
"translate_model_description": "翻译服务使用的模型", "translate_model_description": "翻译服务使用的模型",
"translate_model_prompt_message": "请输入翻译模型提示词", "translate_model_prompt_message": "请输入翻译模型提示词",

View File

@ -2276,8 +2276,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "此設定會影響所有通過 Markdown 導出的方式,如 Notion、語雀等", "help": "開啟後,使用快速模型為導出的消息命名標題。該項也會影響所有透過 Markdown 導出的方式",
"title": "使用話題命名模型為導出的消息創建標題" "title": "使用快速模型為導出的消息命名標題"
} }
}, },
"minute_interval_one": "{{count}} 分鐘", "minute_interval_one": "{{count}} 分鐘",
@ -3115,7 +3115,6 @@
"default_assistant_model": "預設助手模型", "default_assistant_model": "預設助手模型",
"default_assistant_model_description": "建立新助手時使用的模型,如果助手未設定模型,則使用此模型", "default_assistant_model_description": "建立新助手時使用的模型,如果助手未設定模型,則使用此模型",
"empty": "找不到模型", "empty": "找不到模型",
"enable_topic_naming": "話題自動重新命名",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "確定要新增所有模型到列表嗎?", "confirm": "確定要新增所有模型到列表嗎?",
@ -3141,10 +3140,17 @@
"quick_assistant_default_tag": "預設", "quick_assistant_default_tag": "預設",
"quick_assistant_model": "快捷助手模型", "quick_assistant_model": "快捷助手模型",
"quick_assistant_selection": "選擇助手", "quick_assistant_selection": "選擇助手",
"topic_naming_model": "話題命名模型", "quick_model": {
"topic_naming_model_description": "自動命名新話題時使用的模型", "description": "用於執行話題命名、搜尋關鍵字提煉等簡單任務的模型",
"topic_naming_model_setting_title": "話題命名模型設定", "label": "快速模型",
"topic_naming_prompt": "話題命名提示詞", "setting_title": "快速模型設定",
"tooltip": "建議選擇輕量模型,不建議選擇思考模型"
},
"topic_naming": {
"auto": "話題自動重新命名",
"label": "話題命名",
"prompt": "話題命名提示詞"
},
"translate_model": "翻譯模型", "translate_model": "翻譯模型",
"translate_model_description": "翻譯服務使用的模型", "translate_model_description": "翻譯服務使用的模型",
"translate_model_prompt_message": "請輸入翻譯模型提示詞", "translate_model_prompt_message": "請輸入翻譯模型提示詞",

View File

@ -2274,8 +2274,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "Όταν είναι ενεργό, δημιουργεί τίτλους για τα μηνύματα που εξάγονται χρησιμοποιώντας μοντέλο ονομασίας θεμάτων. Αυτό επηρεάζει επίσης όλες τις μεθόδους εξαγωγής μέσω Markdown.", "help": "Όταν ενεργοποιηθεί, χρησιμοποιεί το γρήγορο μοντέλο για να ονομάσει τον τίτλο των εξαγόμενων μηνυμάτων. Αυτό επηρεάζει επίσης όλους τους τρόπους εξαγωγής μέσω Markdown.",
"title": "Δημιουργία τίτλων μηνυμάτων χρησιμοποιώντας μοντέλο ονομασίας θεμάτων" "title": "Χρησιμοποιήστε το γρήγορο μοντέλο για να ονομάσετε τον τίτλο των εξαγόμενων μηνυμάτων"
} }
}, },
"minute_interval_one": "{{count}} λεπτά", "minute_interval_one": "{{count}} λεπτά",
@ -3113,7 +3113,6 @@
"default_assistant_model": "Πρόεδρος Υπηρεσίας προεπιλεγμένου μοντέλου", "default_assistant_model": "Πρόεδρος Υπηρεσίας προεπιλεγμένου μοντέλου",
"default_assistant_model_description": "Το μοντέλο που χρησιμοποιείται όταν δημιουργείτε νέο υπάλληλο. Αν το υπάλληλο δεν έχει επιλεγμένο ένα μοντέλο, τότε θα χρησιμοποιεί αυτό το μοντέλο.", "default_assistant_model_description": "Το μοντέλο που χρησιμοποιείται όταν δημιουργείτε νέο υπάλληλο. Αν το υπάλληλο δεν έχει επιλεγμένο ένα μοντέλο, τότε θα χρησιμοποιεί αυτό το μοντέλο.",
"empty": "Δεν υπάρχουν μοντέλα", "empty": "Δεν υπάρχουν μοντέλα",
"enable_topic_naming": "Αυτόματη αναδόμηση θεμάτων",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "Είστε βέβαιοι ότι θέλετε να προσθέσετε όλα τα μοντέλα στη λίστα;", "confirm": "Είστε βέβαιοι ότι θέλετε να προσθέσετε όλα τα μοντέλα στη λίστα;",
@ -3139,10 +3138,17 @@
"quick_assistant_default_tag": "Προεπιλογή", "quick_assistant_default_tag": "Προεπιλογή",
"quick_assistant_model": "Μοντέλο Γρήγορου Βοηθού", "quick_assistant_model": "Μοντέλο Γρήγορου Βοηθού",
"quick_assistant_selection": "Επιλογή Βοηθού", "quick_assistant_selection": "Επιλογή Βοηθού",
"topic_naming_model": "Μοντέλο αναδόμησης θεμάτων", "quick_model": {
"topic_naming_model_description": "Το μοντέλο που χρησιμοποιείται όταν αυτόματα ονομάζεται ένα νέο θέμα", "description": "Το μοντέλο που χρησιμοποιείται για απλές εργασίες, όπως η ονομασία θεμάτων και η εξαγωγή λέξεων-κλειδιών αναζήτησης",
"topic_naming_model_setting_title": "Ρυθμίσεις Μοντέλου Αναδόμησης Θεμάτων", "label": "Γρήγορο μοντέλο",
"topic_naming_prompt": "Προσδιορισμός προκαθορισμένου θέματος", "setting_title": "Γρήγορη ρύθμιση μοντέλου",
"tooltip": "Προτείνεται να επιλέξετε ένα ελαφρύ μοντέλο και δεν συνιστάται να επιλέξετε ένα μοντέλο σκέψης"
},
"topic_naming": {
"auto": "Αυτόματη αναδόμηση θεμάτων",
"label": "Ονομασία θέματος",
"prompt": "Προσδιορισμός προκαθορισμένου θέματος"
},
"translate_model": "Μοντέλο μετάφρασης", "translate_model": "Μοντέλο μετάφρασης",
"translate_model_description": "Το μοντέλο που χρησιμοποιείται για τη μετάφραση", "translate_model_description": "Το μοντέλο που χρησιμοποιείται για τη μετάφραση",
"translate_model_prompt_message": "Εισάγετε την προσδιορισμένη προειδοποίηση μετάφρασης", "translate_model_prompt_message": "Εισάγετε την προσδιορισμένη προειδοποίηση μετάφρασης",

View File

@ -2274,8 +2274,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "Al activarlo, se utilizará el modelo de nombramiento temático para generar títulos de mensajes exportados. Esta opción también afectará a todos los métodos de exportación mediante Markdown.", "help": "Activado, utiliza el modelo rápido para nombrar el título de los mensajes exportados. Esta opción también afecta a todas las formas de exportación mediante Markdown.",
"title": "Usar el modelo de nombramiento temático para crear títulos de mensajes exportados" "title": "Usar el modelo rápido para nombrar el título de los mensajes exportados"
} }
}, },
"minute_interval_one": "{{count}} minuto", "minute_interval_one": "{{count}} minuto",
@ -3113,7 +3113,6 @@
"default_assistant_model": "Modelo predeterminado del asistente", "default_assistant_model": "Modelo predeterminado del asistente",
"default_assistant_model_description": "Modelo utilizado al crear nuevos asistentes, si el asistente no tiene un modelo asignado, se utiliza este modelo", "default_assistant_model_description": "Modelo utilizado al crear nuevos asistentes, si el asistente no tiene un modelo asignado, se utiliza este modelo",
"empty": "Sin modelos", "empty": "Sin modelos",
"enable_topic_naming": "Renombrar temas automáticamente",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "¿Está seguro de que desea agregar todos los modelos a la lista?", "confirm": "¿Está seguro de que desea agregar todos los modelos a la lista?",
@ -3139,10 +3138,17 @@
"quick_assistant_default_tag": "Predeterminado", "quick_assistant_default_tag": "Predeterminado",
"quick_assistant_model": "Modelo del asistente rápido", "quick_assistant_model": "Modelo del asistente rápido",
"quick_assistant_selection": "Seleccionar asistente", "quick_assistant_selection": "Seleccionar asistente",
"topic_naming_model": "Modelo de nombramiento de temas", "quick_model": {
"topic_naming_model_description": "Modelo utilizado para nombrar temas automáticamente", "description": "El modelo rápido es utilizado para realizar tareas sencillas como nombrar temas, extraer palabras clave de búsqueda, etc.",
"topic_naming_model_setting_title": "Configuración del modelo de nombramiento de temas", "label": "Modelo rápido",
"topic_naming_prompt": "Sugerencias para nombramiento de temas", "setting_title": "Configuración del modelo rápido",
"tooltip": "Se recomienda elegir un modelo ligero y no se recomienda elegir un modelo de razonamiento"
},
"topic_naming": {
"auto": "Renombrar temas automáticamente",
"label": "Nombramiento del tema",
"prompt": "Sugerencias para nombramiento de temas"
},
"translate_model": "Modelo de traducción", "translate_model": "Modelo de traducción",
"translate_model_description": "Modelo utilizado para el servicio de traducción", "translate_model_description": "Modelo utilizado para el servicio de traducción",
"translate_model_prompt_message": "Ingrese las sugerencias del modelo de traducción", "translate_model_prompt_message": "Ingrese las sugerencias del modelo de traducción",

View File

@ -2274,8 +2274,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "Lorsque cette option est activée, le modèle de dénomination thématique sera utilisé pour créer les titres des messages exportés. Cette option affectera également toutes les méthodes d'exportation au format Markdown.", "help": "Activé, utilise un modèle rapide pour nommer les titres des messages exportés. Cette option affecte également toutes les méthodes d'exportation via Markdown.",
"title": "Utiliser le modèle de dénomination thématique pour créer les titres des messages exportés" "title": "Utiliser le modèle rapide pour nommer le titre des messages exportés"
} }
}, },
"minute_interval_one": "{{count}} minute", "minute_interval_one": "{{count}} minute",
@ -3113,7 +3113,6 @@
"default_assistant_model": "Modèle d'assistant par défaut", "default_assistant_model": "Modèle d'assistant par défaut",
"default_assistant_model_description": "Modèle utilisé pour créer de nouveaux assistants, si aucun modèle n'est défini pour l'assistant, ce modèle sera utilisé", "default_assistant_model_description": "Modèle utilisé pour créer de nouveaux assistants, si aucun modèle n'est défini pour l'assistant, ce modèle sera utilisé",
"empty": "Aucun modèle", "empty": "Aucun modèle",
"enable_topic_naming": "Renommage automatique des sujets",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "Êtes-vous sûr de vouloir ajouter tous les modèles à la liste ?", "confirm": "Êtes-vous sûr de vouloir ajouter tous les modèles à la liste ?",
@ -3139,10 +3138,17 @@
"quick_assistant_default_tag": "Par défaut", "quick_assistant_default_tag": "Par défaut",
"quick_assistant_model": "Modèle de l'assistant rapide", "quick_assistant_model": "Modèle de l'assistant rapide",
"quick_assistant_selection": "Sélectionner l'assistant", "quick_assistant_selection": "Sélectionner l'assistant",
"topic_naming_model": "Modèle de renommage des sujets", "quick_model": {
"topic_naming_model_description": "Modèle utilisé pour le renommage automatique des nouveaux sujets", "description": "modèle utilisé pour effectuer des tâches simples telles que la nomination de sujets, l'extraction de mots-clés de recherche, etc.",
"topic_naming_model_setting_title": "Paramètres du modèle de renommage des sujets", "label": "Modèle rapide",
"topic_naming_prompt": "Mot-clé de renommage des sujets", "setting_title": "Configuration rapide du modèle",
"tooltip": "Il est recommandé de choisir un modèle léger et déconseillé de choisir un modèle de réflexion."
},
"topic_naming": {
"auto": "Renommage automatique des sujets",
"label": "Nom de sujet",
"prompt": "Mot-clé de renommage des sujets"
},
"translate_model": "Modèle de traduction", "translate_model": "Modèle de traduction",
"translate_model_description": "Modèle utilisé pour le service de traduction", "translate_model_description": "Modèle utilisé pour le service de traduction",
"translate_model_prompt_message": "Entrez le mot-clé du modèle de traduction", "translate_model_prompt_message": "Entrez le mot-clé du modèle de traduction",

View File

@ -2274,8 +2274,8 @@
}, },
"message_title": { "message_title": {
"use_topic_naming": { "use_topic_naming": {
"help": "Ativando esta opção, será usado um modelo de nomeação por tópico para criar os títulos das mensagens exportadas. Esta configuração também afetará todas as formas de exportação feitas por meio de Markdown.", "help": "Ativado, usa um modelo rápido para nomear o título das mensagens exportadas. Esta opção também afeta todas as formas de exportação por Markdown.",
"title": "Usar modelo de nomeação por tópico para criar títulos das mensagens exportadas" "title": "Usar modelo rápido para nomear o título das mensagens exportadas"
} }
}, },
"minute_interval_one": "{{count}} minuto", "minute_interval_one": "{{count}} minuto",
@ -3113,7 +3113,6 @@
"default_assistant_model": "Modelo de assistente padrão", "default_assistant_model": "Modelo de assistente padrão",
"default_assistant_model_description": "Modelo usado ao criar um novo assistente, se o assistente não tiver um modelo definido, este será usado", "default_assistant_model_description": "Modelo usado ao criar um novo assistente, se o assistente não tiver um modelo definido, este será usado",
"empty": "Sem modelos", "empty": "Sem modelos",
"enable_topic_naming": "Renomeação automática de tópicos",
"manage": { "manage": {
"add_listed": { "add_listed": {
"confirm": "Tem a certeza de que deseja adicionar todos os modelos à lista?", "confirm": "Tem a certeza de que deseja adicionar todos os modelos à lista?",
@ -3139,10 +3138,17 @@
"quick_assistant_default_tag": "Padrão", "quick_assistant_default_tag": "Padrão",
"quick_assistant_model": "Modelo do Assistente Rápido", "quick_assistant_model": "Modelo do Assistente Rápido",
"quick_assistant_selection": "Selecionar Assistente", "quick_assistant_selection": "Selecionar Assistente",
"topic_naming_model": "Modelo de nomenclatura de tópicos", "quick_model": {
"topic_naming_model_description": "Modelo usado para nomear tópicos automaticamente", "description": "Modelo utilizado para executar tarefas simples, como nomeação de tópicos, extração de palavras-chave de busca, entre outras.",
"topic_naming_model_setting_title": "Configurações do modelo de nomenclatura de tópicos", "label": "Modelo rápido",
"topic_naming_prompt": "Prompt de nomenclatura de tópicos", "setting_title": "Configuração rápida do modelo",
"tooltip": "Sugere-se escolher um modelo leve e não se recomenda escolher um modelo de raciocínio"
},
"topic_naming": {
"auto": "Renomeação automática de tópicos",
"label": "Nomeação do tópico",
"prompt": "Prompt de nomenclatura de tópicos"
},
"translate_model": "Modelo de tradução", "translate_model": "Modelo de tradução",
"translate_model_description": "Modelo usado para serviços de tradução", "translate_model_description": "Modelo usado para serviços de tradução",
"translate_model_prompt_message": "Digite o prompt do modelo de tradução", "translate_model_prompt_message": "Digite o prompt do modelo de tradução",

View File

@ -1,4 +1,5 @@
import { RedoOutlined } from '@ant-design/icons' import { RedoOutlined } from '@ant-design/icons'
import InfoTooltip from '@renderer/components/InfoTooltip'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
import ModelSelector from '@renderer/components/ModelSelector' import ModelSelector from '@renderer/components/ModelSelector'
import { isEmbeddingModel, isRerankModel, isTextToImageModel } from '@renderer/config/models' import { isEmbeddingModel, isRerankModel, isTextToImageModel } from '@renderer/config/models'
@ -13,17 +14,17 @@ import { setTranslateModelPrompt } from '@renderer/store/settings'
import { Model } from '@renderer/types' import { Model } from '@renderer/types'
import { Button, Tooltip } from 'antd' import { Button, Tooltip } from 'antd'
import { find } from 'lodash' import { find } from 'lodash'
import { FolderPen, Languages, MessageSquareMore, Settings2 } from 'lucide-react' import { Languages, MessageSquareMore, Rocket, Settings2 } from 'lucide-react'
import { FC, useCallback, useMemo } from 'react' import { FC, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { SettingContainer, SettingDescription, SettingGroup, SettingTitle } from '..' import { SettingContainer, SettingDescription, SettingGroup, SettingTitle } from '..'
import TranslateSettingsPopup from '../TranslateSettingsPopup/TranslateSettingsPopup' import TranslateSettingsPopup from '../TranslateSettingsPopup/TranslateSettingsPopup'
import DefaultAssistantSettings from './DefaultAssistantSettings' import DefaultAssistantSettings from './DefaultAssistantSettings'
import TopicNamingModalPopup from './TopicNamingModalPopup' import TopicNamingModalPopup from './QuickModelPopup'
const ModelSettings: FC = () => { const ModelSettings: FC = () => {
const { defaultModel, topicNamingModel, translateModel, setDefaultModel, setTopicNamingModel, setTranslateModel } = const { defaultModel, quickModel, translateModel, setDefaultModel, setQuickModel, setTranslateModel } =
useDefaultModel() useDefaultModel()
const { providers } = useProviders() const { providers } = useProviders()
const allModels = providers.map((p) => p.models).flat() const allModels = providers.map((p) => p.models).flat()
@ -43,10 +44,7 @@ const ModelSettings: FC = () => {
[defaultModel] [defaultModel]
) )
const defaultTopicNamingModel = useMemo( const defaultQuickModel = useMemo(() => (hasModel(quickModel) ? getModelUniqId(quickModel) : undefined), [quickModel])
() => (hasModel(topicNamingModel) ? getModelUniqId(topicNamingModel) : undefined),
[topicNamingModel]
)
const defaultTranslateModel = useMemo( const defaultTranslateModel = useMemo(
() => (hasModel(translateModel) ? getModelUniqId(translateModel) : undefined), () => (hasModel(translateModel) ? getModelUniqId(translateModel) : undefined),
@ -83,23 +81,24 @@ const ModelSettings: FC = () => {
<SettingGroup theme={theme}> <SettingGroup theme={theme}>
<SettingTitle style={{ marginBottom: 12 }}> <SettingTitle style={{ marginBottom: 12 }}>
<HStack alignItems="center" gap={10}> <HStack alignItems="center" gap={10}>
<FolderPen size={18} color="var(--color-text)" /> <Rocket size={18} color="var(--color-text)" />
{t('settings.models.topic_naming_model')} {t('settings.models.quick_model.label')}
<InfoTooltip title={t('settings.models.quick_model.tooltip')} />
</HStack> </HStack>
</SettingTitle> </SettingTitle>
<HStack alignItems="center"> <HStack alignItems="center">
<ModelSelector <ModelSelector
providers={providers} providers={providers}
predicate={modelPredicate} predicate={modelPredicate}
value={defaultTopicNamingModel} value={defaultQuickModel}
defaultValue={defaultTopicNamingModel} defaultValue={defaultQuickModel}
style={{ width: 360 }} style={{ width: 360 }}
onChange={(value) => setTopicNamingModel(find(allModels, JSON.parse(value)) as Model)} onChange={(value) => setQuickModel(find(allModels, JSON.parse(value)) as Model)}
placeholder={t('settings.models.empty')} placeholder={t('settings.models.empty')}
/> />
<Button icon={<Settings2 size={16} />} style={{ marginLeft: 8 }} onClick={TopicNamingModalPopup.show} /> <Button icon={<Settings2 size={16} />} style={{ marginLeft: 8 }} onClick={TopicNamingModalPopup.show} />
</HStack> </HStack>
<SettingDescription>{t('settings.models.topic_naming_model_description')}</SettingDescription> <SettingDescription>{t('settings.models.quick_model.description')}</SettingDescription>
</SettingGroup> </SettingGroup>
<SettingGroup theme={theme}> <SettingGroup theme={theme}>
<SettingTitle style={{ marginBottom: 12 }}> <SettingTitle style={{ marginBottom: 12 }}>

View File

@ -0,0 +1,105 @@
import { QuestionCircleOutlined } from '@ant-design/icons'
import { ResetIcon } from '@renderer/components/Icons'
import { HStack } from '@renderer/components/Layout'
import { useSettings } from '@renderer/hooks/useSettings'
import { useAppDispatch } from '@renderer/store'
import { setEnableTopicNaming, setTopicNamingPrompt } from '@renderer/store/settings'
import { Button, Divider, Flex, Input, Modal, Popover, Switch } from 'antd'
import { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { TopView } from '../../../components/TopView'
import { SettingSubtitle } from '..'
interface Props {
resolve: (data: any) => void
}
const PopupContainer: React.FC<Props> = ({ resolve }) => {
const [open, setOpen] = useState(true)
const { t } = useTranslation()
const { enableTopicNaming, topicNamingPrompt } = useSettings()
const dispatch = useAppDispatch()
const onOk = () => {
setOpen(false)
}
const onCancel = () => {
setOpen(false)
}
const onClose = () => {
resolve({})
}
const handleReset = useCallback(() => {
dispatch(setTopicNamingPrompt(''))
}, [dispatch])
TopicNamingModalPopup.hide = onCancel
const promptVarsContent = useMemo(() => <pre>{t('agents.add.prompt.variables.tip.content')}</pre>, [t])
return (
<Modal
title={t('settings.models.quick_model.setting_title')}
open={open}
onOk={onOk}
onCancel={onCancel}
afterClose={onClose}
maskClosable={false}
transitionName="animation-move-down"
centered
style={{ padding: '24px' }}>
<SettingSubtitle style={{ marginTop: 0, marginBottom: 8 }}>
{t('settings.models.topic_naming.label')}
</SettingSubtitle>
<Flex vertical align="stretch" gap={8}>
<HStack style={{ gap: 16 }} alignItems="center">
<div>{t('settings.models.topic_naming.auto')}</div>
<Switch checked={enableTopicNaming} onChange={(v) => dispatch(setEnableTopicNaming(v))} />
</HStack>
<Divider style={{ margin: 0 }} />
<div>
<Flex align="center" gap={4} style={{ marginBottom: 4, height: 30 }}>
<div>{t('settings.models.topic_naming.prompt')}</div>
<Popover title={t('agents.add.prompt.variables.tip.title')} content={promptVarsContent}>
<QuestionCircleOutlined size={14} style={{ color: 'var(--color-text-2)' }} />
</Popover>
{topicNamingPrompt && <Button icon={<ResetIcon size={14} />} onClick={handleReset} type="text" />}
</Flex>
<Input.TextArea
autoSize={{ minRows: 3, maxRows: 10 }}
value={topicNamingPrompt || t('prompts.title')}
onChange={(e) => dispatch(setTopicNamingPrompt(e.target.value))}
placeholder={t('prompts.title')}
style={{ width: '100%' }}
/>
</div>
</Flex>
</Modal>
)
}
const TopViewKey = 'TopicNamingModalPopup'
export default class TopicNamingModalPopup {
static topviewId = 0
static hide() {
TopView.hide(TopViewKey)
}
static show() {
return new Promise<any>((resolve) => {
TopView.show(
<PopupContainer
resolve={(v) => {
resolve(v)
TopView.hide(TopViewKey)
}}
/>,
TopViewKey
)
})
}
}

View File

@ -1,102 +0,0 @@
import { QuestionCircleOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import { useSettings } from '@renderer/hooks/useSettings'
import { useAppDispatch } from '@renderer/store'
import { setEnableTopicNaming, setTopicNamingPrompt } from '@renderer/store/settings'
import { Button, Divider, Flex, Input, Modal, Popover, Switch } from 'antd'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { TopView } from '../../../components/TopView'
interface Props {
resolve: (data: any) => void
}
const PopupContainer: React.FC<Props> = ({ resolve }) => {
const [open, setOpen] = useState(true)
const { t } = useTranslation()
const { enableTopicNaming, topicNamingPrompt } = useSettings()
const dispatch = useAppDispatch()
const onOk = () => {
setOpen(false)
}
const onCancel = () => {
setOpen(false)
}
const onClose = () => {
resolve({})
}
const handleReset = () => {
dispatch(setTopicNamingPrompt(''))
}
TopicNamingModalPopup.hide = onCancel
const promptVarsContent = <pre>{t('agents.add.prompt.variables.tip.content')}</pre>
return (
<Modal
title={t('settings.models.topic_naming_model_setting_title')}
open={open}
onOk={onOk}
onCancel={onCancel}
afterClose={onClose}
maskClosable={false}
transitionName="animation-move-down"
footer={null}
centered>
<Divider style={{ margin: '10px 0' }} />
<HStack style={{ gap: 10, marginBottom: 20, marginTop: 20 }} alignItems="center">
<div>{t('settings.models.enable_topic_naming')}</div>
<Switch checked={enableTopicNaming} onChange={(v) => dispatch(setEnableTopicNaming(v))} />
</HStack>
<Divider style={{ margin: '10px 0' }} />
<div style={{ marginBottom: 20 }}>
<Flex align="center" style={{ marginBottom: 10, gap: 5 }}>
<div>{t('settings.models.topic_naming_prompt')}</div>
<Popover title={t('agents.add.prompt.variables.tip.title')} content={promptVarsContent}>
<QuestionCircleOutlined size={14} style={{ color: 'var(--color-text-2)' }} />
</Popover>
</Flex>
<Input.TextArea
rows={4}
value={topicNamingPrompt || t('prompts.title')}
onChange={(e) => dispatch(setTopicNamingPrompt(e.target.value.trim()))}
placeholder={t('prompts.title')}
/>
{topicNamingPrompt && (
<Button style={{ marginTop: 10 }} onClick={handleReset}>
{t('common.reset')}
</Button>
)}
</div>
</Modal>
)
}
const TopViewKey = 'TopicNamingModalPopup'
export default class TopicNamingModalPopup {
static topviewId = 0
static hide() {
TopView.hide(TopViewKey)
}
static show() {
return new Promise<any>((resolve) => {
TopView.show(
<PopupContainer
resolve={(v) => {
resolve(v)
TopView.hide(TopViewKey)
}}
/>,
TopViewKey
)
})
}
}

View File

@ -65,7 +65,7 @@ import {
getDefaultAssistant, getDefaultAssistant,
getDefaultModel, getDefaultModel,
getProviderByModel, getProviderByModel,
getTopNamingModel, getQuickModel,
getTranslateModel getTranslateModel
} from './AssistantService' } from './AssistantService'
import { processKnowledgeSearch } from './KnowledgeService' import { processKnowledgeSearch } from './KnowledgeService'
@ -135,7 +135,7 @@ async function fetchExternalTool(
} }
const summaryAssistant = getDefaultAssistant() const summaryAssistant = getDefaultAssistant()
summaryAssistant.model = assistant.model || getDefaultModel() summaryAssistant.model = getQuickModel() || assistant.model || getDefaultModel()
summaryAssistant.prompt = prompt summaryAssistant.prompt = prompt
const callSearchSummary = async (params: { messages: Message[]; assistant: Assistant }) => { const callSearchSummary = async (params: { messages: Message[]; assistant: Assistant }) => {
@ -677,7 +677,7 @@ export async function fetchLanguageDetection({ text, onResponse }: FetchLanguage
export async function fetchMessagesSummary({ messages, assistant }: { messages: Message[]; assistant: Assistant }) { export async function fetchMessagesSummary({ messages, assistant }: { messages: Message[]; assistant: Assistant }) {
let prompt = (getStoreSetting('topicNamingPrompt') as string) || i18n.t('prompts.title') let prompt = (getStoreSetting('topicNamingPrompt') as string) || i18n.t('prompts.title')
const model = getTopNamingModel() || assistant.model || getDefaultModel() const model = getQuickModel() || assistant.model || getDefaultModel()
if (prompt && containsSupportedVariables(prompt)) { if (prompt && containsSupportedVariables(prompt)) {
prompt = await replacePromptVariables(prompt, model.name) prompt = await replacePromptVariables(prompt, model.name)
@ -747,7 +747,7 @@ export async function fetchMessagesSummary({ messages, assistant }: { messages:
} }
export async function fetchSearchSummary({ messages, assistant }: { messages: Message[]; assistant: Assistant }) { export async function fetchSearchSummary({ messages, assistant }: { messages: Message[]; assistant: Assistant }) {
const model = assistant.model || getDefaultModel() const model = getQuickModel() || assistant.model || getDefaultModel()
const provider = getProviderByModel(model) const provider = getProviderByModel(model)
if (!hasApiKey(provider)) { if (!hasApiKey(provider)) {

View File

@ -99,8 +99,8 @@ export function getDefaultModel() {
return store.getState().llm.defaultModel return store.getState().llm.defaultModel
} }
export function getTopNamingModel() { export function getQuickModel() {
return store.getState().llm.topicNamingModel return store.getState().llm.quickModel
} }
export function getTranslateModel() { export function getTranslateModel() {

View File

@ -16,6 +16,7 @@ import { GeminiAPIClient } from '@renderer/aiCore/clients/gemini/GeminiAPIClient
import { OpenAIResponseAPIClient } from '@renderer/aiCore/clients/openai/OpenAIResponseAPIClient' import { OpenAIResponseAPIClient } from '@renderer/aiCore/clients/openai/OpenAIResponseAPIClient'
import { GenericChunk } from '@renderer/aiCore/middleware/schemas' import { GenericChunk } from '@renderer/aiCore/middleware/schemas'
import { isVisionModel } from '@renderer/config/models' import { isVisionModel } from '@renderer/config/models'
import { LlmState } from '@renderer/store/llm'
import { Assistant, MCPCallToolResponse, MCPToolResponse, Model, Provider, WebSearchSource } from '@renderer/types' import { Assistant, MCPCallToolResponse, MCPToolResponse, Model, Provider, WebSearchSource } from '@renderer/types'
import { import {
Chunk, Chunk,
@ -178,7 +179,8 @@ vi.mock('@renderer/store/llm.ts', () => {
id: 'gemini-2.5-pro', id: 'gemini-2.5-pro',
name: 'Gemini 2.5 Pro', name: 'Gemini 2.5 Pro',
provider: 'gemini', provider: 'gemini',
supported_text_delta: true supported_text_delta: true,
group: ''
} }
], ],
isSystem: true, isSystem: true,
@ -189,19 +191,29 @@ vi.mock('@renderer/store/llm.ts', () => {
id: 'gemini-2.5-pro', id: 'gemini-2.5-pro',
name: 'Gemini 2.5 Pro', name: 'Gemini 2.5 Pro',
provider: 'gemini', provider: 'gemini',
supported_text_delta: true supported_text_delta: true,
group: ''
}, },
topicNamingModel: { topicNamingModel: {
id: 'gemini-2.5-pro', id: 'gemini-2.5-pro',
name: 'Gemini 2.5 Pro', name: 'Gemini 2.5 Pro',
provider: 'gemini', provider: 'gemini',
supported_text_delta: true supported_text_delta: true,
group: ''
},
quickModel: {
id: 'gemini-2.5-pro',
name: 'Gemini 2.5 Pro',
provider: 'gemini',
supported_text_delta: true,
group: ''
}, },
translateModel: { translateModel: {
id: 'gemini-2.5-pro', id: 'gemini-2.5-pro',
name: 'Gemini 2.5 Pro', name: 'Gemini 2.5 Pro',
provider: 'gemini', provider: 'gemini',
supported_text_delta: true supported_text_delta: true,
group: ''
}, },
quickAssistantId: '', quickAssistantId: '',
settings: { settings: {
@ -215,9 +227,14 @@ vi.mock('@renderer/store/llm.ts', () => {
}, },
projectId: '', projectId: '',
location: '' location: ''
},
awsBedrock: {
accessKeyId: '',
secretAccessKey: '',
region: ''
} }
} }
} } satisfies LlmState
const mockReducer = (state = mockInitialState) => { const mockReducer = (state = mockInitialState) => {
return state return state

View File

@ -62,7 +62,7 @@ const persistedReducer = persistReducer(
{ {
key: 'cherry-studio', key: 'cherry-studio',
storage, storage,
version: 133, version: 134,
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'], blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'],
migrate migrate
}, },

View File

@ -33,7 +33,9 @@ type LlmSettings = {
export interface LlmState { export interface LlmState {
providers: Provider[] providers: Provider[]
defaultModel: Model defaultModel: Model
/** @deprecated */
topicNamingModel: Model topicNamingModel: Model
quickModel: Model
translateModel: Model translateModel: Model
quickAssistantId: string quickAssistantId: string
settings: LlmSettings settings: LlmSettings
@ -42,6 +44,7 @@ export interface LlmState {
export const initialState: LlmState = { export const initialState: LlmState = {
defaultModel: SYSTEM_MODELS.defaultModel[0], defaultModel: SYSTEM_MODELS.defaultModel[0],
topicNamingModel: SYSTEM_MODELS.defaultModel[1], topicNamingModel: SYSTEM_MODELS.defaultModel[1],
quickModel: SYSTEM_MODELS.defaultModel[1],
translateModel: SYSTEM_MODELS.defaultModel[2], translateModel: SYSTEM_MODELS.defaultModel[2],
quickAssistantId: '', quickAssistantId: '',
providers: SYSTEM_PROVIDERS, providers: SYSTEM_PROVIDERS,
@ -71,12 +74,14 @@ export const initialState: LlmState = {
} }
} }
// 由于 isLocalAi 目前总是为false该函数暂未被使用
// 需要投入使用时,应当保证返回值类型满足 LlmState 要求,而不是使用类型断言
const getIntegratedInitialState = () => { const getIntegratedInitialState = () => {
const model = JSON.parse(import.meta.env.VITE_RENDERER_INTEGRATED_MODEL) const model = JSON.parse(import.meta.env.VITE_RENDERER_INTEGRATED_MODEL)
return { return {
defaultModel: model, defaultModel: model,
topicNamingModel: model, quickModel: model,
translateModel: model, translateModel: model,
providers: [ providers: [
{ {
@ -160,8 +165,8 @@ const llmSlice = createSlice({
setDefaultModel: (state, action: PayloadAction<{ model: Model }>) => { setDefaultModel: (state, action: PayloadAction<{ model: Model }>) => {
state.defaultModel = action.payload.model state.defaultModel = action.payload.model
}, },
setTopicNamingModel: (state, action: PayloadAction<{ model: Model }>) => { setQuickModel: (state, action: PayloadAction<{ model: Model }>) => {
state.topicNamingModel = action.payload.model state.quickModel = action.payload.model
}, },
setTranslateModel: (state, action: PayloadAction<{ model: Model }>) => { setTranslateModel: (state, action: PayloadAction<{ model: Model }>) => {
state.translateModel = action.payload.model state.translateModel = action.payload.model
@ -226,7 +231,7 @@ export const {
addModel, addModel,
removeModel, removeModel,
setDefaultModel, setDefaultModel,
setTopicNamingModel, setQuickModel,
setTranslateModel, setTranslateModel,
setQuickAssistantId, setQuickAssistantId,
setOllamaKeepAliveTime, setOllamaKeepAliveTime,

View File

@ -2135,10 +2135,21 @@ const migrateConfig = {
logger.error('migrate 133 error', error as Error) logger.error('migrate 133 error', error as Error)
return state return state
} }
},
'134': (state: RootState) => {
try {
state.llm.quickModel = state.llm.topicNamingModel
return state
} catch (error) {
logger.error('migrate 134 error', error as Error)
return state
}
} }
} }
// 注意:添加新迁移时,记得同时更新 persistReducer // 注意:添加新迁移时,记得同时更新 persistReducer
// file://./index.ts
const migrate = createMigrate(migrateConfig as any) const migrate = createMigrate(migrateConfig as any)