diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index b4ad565b..53a3aba3 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -42,7 +42,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 86, + version: 87, blacklist: ['runtime', 'messages'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 6861f1f5..c35693c6 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -35,420 +35,609 @@ function addProvider(state: RootState, id: string) { const migrateConfig = { '2': (state: RootState) => { - addProvider(state, 'yi') - return state + try { + addProvider(state, 'yi') + return state + } catch (error) { + return state + } }, '3': (state: RootState) => { - addProvider(state, 'zhipu') - return state + try { + addProvider(state, 'zhipu') + return state + } catch (error) { + return state + } }, '4': (state: RootState) => { - addProvider(state, 'ollama') - return state + try { + addProvider(state, 'ollama') + return state + } catch (error) { + return state + } }, '5': (state: RootState) => { - addProvider(state, 'moonshot') - return state + try { + addProvider(state, 'moonshot') + return state + } catch (error) { + return state + } }, '6': (state: RootState) => { - addProvider(state, 'openrouter') - return state + try { + addProvider(state, 'openrouter') + return state + } catch (error) { + return state + } }, '7': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - language: navigator.language + try { + return { + ...state, + settings: { + ...state.settings, + language: navigator.language + } } + } catch (error) { + return state } }, '8': (state: RootState) => { - const fixAssistantName = (assistant: Assistant) => { - if (isEmpty(assistant.name)) { - assistant.name = i18n.t(`assistant.${assistant.id}.name`) - } - - assistant.topics = assistant.topics.map((topic) => { - if (isEmpty(topic.name)) { - topic.name = i18n.t(`assistant.${assistant.id}.topic.name`) + try { + const fixAssistantName = (assistant: Assistant) => { + if (isEmpty(assistant.name)) { + assistant.name = i18n.t(`assistant.${assistant.id}.name`) } - return topic - }) - return assistant - } + assistant.topics = assistant.topics.map((topic) => { + if (isEmpty(topic.name)) { + topic.name = i18n.t(`assistant.${assistant.id}.topic.name`) + } + return topic + }) - return { - ...state, - assistants: { - ...state.assistants, - defaultAssistant: fixAssistantName(state.assistants.defaultAssistant), - assistants: state.assistants.assistants.map((assistant) => fixAssistantName(assistant)) + return assistant } + + return { + ...state, + assistants: { + ...state.assistants, + defaultAssistant: fixAssistantName(state.assistants.defaultAssistant), + assistants: state.assistants.assistants.map((assistant) => fixAssistantName(assistant)) + } + } + } catch (error) { + return state } }, '9': (state: RootState) => { - return { - ...state, - llm: { - ...state.llm, - providers: state.llm.providers.map((provider) => { - if (provider.id === 'zhipu' && provider.models[0] && provider.models[0].id === 'llama3-70b-8192') { - provider.models = SYSTEM_MODELS.zhipu - } - return provider - }) + try { + return { + ...state, + llm: { + ...state.llm, + providers: state.llm.providers.map((provider) => { + if (provider.id === 'zhipu' && provider.models[0] && provider.models[0].id === 'llama3-70b-8192') { + provider.models = SYSTEM_MODELS.zhipu + } + return provider + }) + } } + } catch (error) { + return state } }, '10': (state: RootState) => { - addProvider(state, 'baichuan') - return state + try { + addProvider(state, 'baichuan') + return state + } catch (error) { + return state + } }, '11': (state: RootState) => { - addProvider(state, 'dashscope') - addProvider(state, 'anthropic') - return state + try { + addProvider(state, 'dashscope') + addProvider(state, 'anthropic') + return state + } catch (error) { + return state + } }, '12': (state: RootState) => { - addProvider(state, 'aihubmix') - return state + try { + addProvider(state, 'aihubmix') + return state + } catch (error) { + return state + } }, '13': (state: RootState) => { - return { - ...state, - assistants: { - ...state.assistants, - defaultAssistant: { - ...state.assistants.defaultAssistant, - name: ['Default Assistant', '默认助手'].includes(state.assistants.defaultAssistant.name) - ? i18n.t(`assistant.default.name`) - : state.assistants.defaultAssistant.name + try { + return { + ...state, + assistants: { + ...state.assistants, + defaultAssistant: { + ...state.assistants.defaultAssistant, + name: ['Default Assistant', '默认助手'].includes(state.assistants.defaultAssistant.name) + ? i18n.t(`assistant.default.name`) + : state.assistants.defaultAssistant.name + } } } + } catch (error) { + return state } }, '14': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - showAssistants: true, - proxyUrl: undefined + try { + return { + ...state, + settings: { + ...state.settings, + showAssistants: true, + proxyUrl: undefined + } } + } catch (error) { + return state } }, '15': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - userName: '', - showMessageDivider: true + try { + return { + ...state, + settings: { + ...state.settings, + userName: '', + showMessageDivider: true + } } + } catch (error) { + return state } }, '16': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - messageFont: 'system', - showInputEstimatedTokens: false + try { + return { + ...state, + settings: { + ...state.settings, + messageFont: 'system', + showInputEstimatedTokens: false + } } + } catch (error) { + return state } }, '17': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - theme: 'auto' + try { + return { + ...state, + settings: { + ...state.settings, + theme: 'auto' + } } + } catch (error) { + return state } }, '19': (state: RootState) => { - return { - ...state, - agents: { - agents: [] - }, - llm: { - ...state.llm, - settings: { - ollama: { - keepAliveTime: 5 + try { + return { + ...state, + agents: { + agents: [] + }, + llm: { + ...state.llm, + settings: { + ollama: { + keepAliveTime: 5 + } } } } + } catch (error) { + return state } }, '20': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - fontSize: 14 + try { + return { + ...state, + settings: { + ...state.settings, + fontSize: 14 + } } + } catch (error) { + return state } }, '21': (state: RootState) => { - addProvider(state, 'gemini') - addProvider(state, 'stepfun') - addProvider(state, 'doubao') - return state + try { + addProvider(state, 'gemini') + addProvider(state, 'stepfun') + addProvider(state, 'doubao') + return state + } catch (error) { + return state + } }, '22': (state: RootState) => { - addProvider(state, 'minimax') - return state + try { + addProvider(state, 'minimax') + return state + } catch (error) { + return state + } }, '23': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - showTopics: true, - windowStyle: 'transparent' + try { + return { + ...state, + settings: { + ...state.settings, + showTopics: true, + windowStyle: 'transparent' + } } + } catch (error) { + return state } }, '24': (state: RootState) => { - return { - ...state, - assistants: { - ...state.assistants, - assistants: state.assistants.assistants.map((assistant) => ({ - ...assistant, - topics: assistant.topics.map((topic) => ({ - ...topic, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() + try { + return { + ...state, + assistants: { + ...state.assistants, + assistants: state.assistants.assistants.map((assistant) => ({ + ...assistant, + topics: assistant.topics.map((topic) => ({ + ...topic, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() + })) })) - })) - }, - settings: { - ...state.settings, - topicPosition: 'right' + }, + settings: { + ...state.settings, + topicPosition: 'right' + } } + } catch (error) { + return state } }, '25': (state: RootState) => { - addProvider(state, 'github') - return state + try { + addProvider(state, 'github') + return state + } catch (error) { + return state + } }, '26': (state: RootState) => { - addProvider(state, 'ocoolai') - return state + try { + addProvider(state, 'ocoolai') + return state + } catch (error) { + return state + } }, '27': (state: RootState) => { - return { - ...state, - settings: { - ...state.settings, - renderInputMessageAsMarkdown: true + try { + return { + ...state, + settings: { + ...state.settings, + renderInputMessageAsMarkdown: true + } } + } catch (error) { + return state } }, '28': (state: RootState) => { - addProvider(state, 'together') - addProvider(state, 'fireworks') - addProvider(state, 'zhinao') - addProvider(state, 'hunyuan') - addProvider(state, 'nvidia') + try { + addProvider(state, 'together') + addProvider(state, 'fireworks') + addProvider(state, 'zhinao') + addProvider(state, 'hunyuan') + addProvider(state, 'nvidia') + return state + } catch (error) { + return state + } }, '29': (state: RootState) => { - return { - ...state, - assistants: { - ...state.assistants, - assistants: state.assistants.assistants.map((assistant) => { - assistant.topics = assistant.topics.map((topic) => ({ - ...topic, - assistantId: assistant.id - })) - return assistant - }) + try { + return { + ...state, + assistants: { + ...state.assistants, + assistants: state.assistants.assistants.map((assistant) => { + assistant.topics = assistant.topics.map((topic) => ({ + ...topic, + assistantId: assistant.id + })) + return assistant + }) + } } + } catch (error) { + return state } }, '30': (state: RootState) => { - addProvider(state, 'azure-openai') - return state + try { + addProvider(state, 'azure-openai') + return state + } catch (error) { + return state + } }, '31': (state: RootState) => { - return { - ...state, - llm: { - ...state.llm, - providers: state.llm.providers.map((provider) => { - if (provider.id === 'azure-openai') { - provider.models = provider.models.map((model) => ({ ...model, provider: 'azure-openai' })) - } - return provider - }) + try { + return { + ...state, + llm: { + ...state.llm, + providers: state.llm.providers.map((provider) => { + if (provider.id === 'azure-openai') { + provider.models = provider.models.map((model) => ({ ...model, provider: 'azure-openai' })) + } + return provider + }) + } } + } catch (error) { + return state } }, '32': (state: RootState) => { - addProvider(state, 'hunyuan') - return state + try { + addProvider(state, 'hunyuan') + return state + } catch (error) { + return state + } }, '33': (state: RootState) => { - state.assistants.defaultAssistant.type = 'assistant' + try { + state.assistants.defaultAssistant.type = 'assistant' - state.agents.agents.forEach((agent) => { - agent.type = 'agent' - // @ts-ignore eslint-disable-next-line - delete agent.group - }) + state.agents.agents.forEach((agent) => { + agent.type = 'agent' + // @ts-ignore eslint-disable-next-line + delete agent.group + }) - return { - ...state, - assistants: { - ...state.assistants, - assistants: [...state.assistants.assistants].map((assistant) => { - // @ts-ignore eslint-disable-next-line - delete assistant.group - return { - ...assistant, - id: assistant.id.length === 36 ? assistant.id : uuid(), - type: assistant.type === 'system' ? assistant.type : 'assistant' - } - }) + return { + ...state, + assistants: { + ...state.assistants, + assistants: [...state.assistants.assistants].map((assistant) => { + // @ts-ignore eslint-disable-next-line + delete assistant.group + return { + ...assistant, + id: assistant.id.length === 36 ? assistant.id : uuid(), + type: assistant.type === 'system' ? assistant.type : 'assistant' + } + }) + } } + } catch (error) { + return state } }, '34': (state: RootState) => { - state.assistants.assistants.forEach((assistant) => { - assistant.topics.forEach((topic) => { - topic.assistantId = assistant.id - runAsyncFunction(async () => { - const _topic = await db.topics.get(topic.id) - if (_topic) { - const messages = (_topic?.messages || []).map((message) => ({ ...message, assistantId: assistant.id })) - db.topics.put({ ..._topic, messages }, topic.id) - } + try { + state.assistants.assistants.forEach((assistant) => { + assistant.topics.forEach((topic) => { + topic.assistantId = assistant.id + runAsyncFunction(async () => { + const _topic = await db.topics.get(topic.id) + if (_topic) { + const messages = (_topic?.messages || []).map((message) => ({ ...message, assistantId: assistant.id })) + db.topics.put({ ..._topic, messages }, topic.id) + } + }) }) }) - }) - return state + return state + } catch (error) { + return state + } }, '35': (state: RootState) => { - state.settings.mathEngine = 'KaTeX' - return state + try { + state.settings.mathEngine = 'KaTeX' + return state + } catch (error) { + return state + } }, '36': (state: RootState) => { - state.settings.topicPosition = 'left' - return state + try { + state.settings.topicPosition = 'left' + return state + } catch (error) { + return state + } }, '37': (state: RootState) => { - state.settings.messageStyle = 'plain' - return state + try { + state.settings.messageStyle = 'plain' + return state + } catch (error) { + return state + } }, '38': (state: RootState) => { - addProvider(state, 'grok') - addProvider(state, 'hyperbolic') - addProvider(state, 'mistral') - return state + try { + addProvider(state, 'grok') + addProvider(state, 'hyperbolic') + addProvider(state, 'mistral') + return state + } catch (error) { + return state + } }, '39': (state: RootState) => { - state.settings.codeStyle = 'auto' - return state + try { + state.settings.codeStyle = 'auto' + return state + } catch (error) { + return state + } }, '40': (state: RootState) => { - state.settings.tray = true - return state + try { + state.settings.tray = true + return state + } catch (error) { + return state + } }, '41': (state: RootState) => { - state.llm.providers.forEach((provider) => { - if (provider.id === 'gemini') { - provider.type = 'gemini' - } else if (provider.id === 'anthropic') { - provider.type = 'anthropic' - } else { - provider.type = 'openai' - } - }) - return state + try { + state.llm.providers.forEach((provider) => { + if (provider.id === 'gemini') { + provider.type = 'gemini' + } else if (provider.id === 'anthropic') { + provider.type = 'anthropic' + } else { + provider.type = 'openai' + } + }) + return state + } catch (error) { + return state + } }, '42': (state: RootState) => { - state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none' - return state + try { + state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none' + return state + } catch (error) { + return state + } }, '43': (state: RootState) => { - if (state.settings.proxyMode === 'none') { - state.settings.proxyMode = 'system' + try { + if (state.settings.proxyMode === 'none') { + state.settings.proxyMode = 'system' + } + return state + } catch (error) { + return state } - return state }, '44': (state: RootState) => { - state.settings.translateModelPrompt = TRANSLATE_PROMPT - return state + try { + state.settings.translateModelPrompt = TRANSLATE_PROMPT + return state + } catch (error) { + return state + } }, '45': (state: RootState) => { state.settings.enableTopicNaming = true return state }, '46': (state: RootState) => { - if ( - state.settings?.translateModelPrompt?.includes( - 'If the target language is the same as the source language, do not translate' - ) - ) { - state.settings.translateModelPrompt = TRANSLATE_PROMPT + try { + if ( + state.settings?.translateModelPrompt?.includes( + 'If the target language is the same as the source language, do not translate' + ) + ) { + state.settings.translateModelPrompt = TRANSLATE_PROMPT + } + return state + } catch (error) { + return state } - return state }, '47': (state: RootState) => { - state.llm.providers.forEach((provider) => { - provider.models.forEach((model) => { - model.group = getDefaultGroupName(model.id) + try { + state.llm.providers.forEach((provider) => { + provider.models.forEach((model) => { + model.group = getDefaultGroupName(model.id) + }) }) - }) - return state + return state + } catch (error) { + return state + } }, '48': (state: RootState) => { - if (state.shortcuts) { - state.shortcuts.shortcuts.forEach((shortcut) => { - shortcut.system = shortcut.key !== 'new_topic' - }) - state.shortcuts.shortcuts.push({ - key: 'toggle_show_assistants', - shortcut: [isMac ? 'Command' : 'Ctrl', '['], - editable: true, - enabled: true, - system: false - }) - state.shortcuts.shortcuts.push({ - key: 'toggle_show_topics', - shortcut: [isMac ? 'Command' : 'Ctrl', ']'], - editable: true, - enabled: true, - system: false - }) + try { + if (state.shortcuts) { + state.shortcuts.shortcuts.forEach((shortcut) => { + shortcut.system = shortcut.key !== 'new_topic' + }) + state.shortcuts.shortcuts.push({ + key: 'toggle_show_assistants', + shortcut: [isMac ? 'Command' : 'Ctrl', '['], + editable: true, + enabled: true, + system: false + }) + state.shortcuts.shortcuts.push({ + key: 'toggle_show_topics', + shortcut: [isMac ? 'Command' : 'Ctrl', ']'], + editable: true, + enabled: true, + system: false + }) + } + return state + } catch (error) { + return state } - return state }, '49': (state: RootState) => { - state.settings.pasteLongTextThreshold = 1500 - if (state.shortcuts) { - state.shortcuts.shortcuts = [ - ...state.shortcuts.shortcuts, - { - key: 'copy_last_message', - shortcut: [isMac ? 'Command' : 'Ctrl', 'Shift', 'C'], - editable: true, - enabled: false, - system: false - } - ] + try { + state.settings.pasteLongTextThreshold = 1500 + if (state.shortcuts) { + state.shortcuts.shortcuts = [ + ...state.shortcuts.shortcuts, + { + key: 'copy_last_message', + shortcut: [isMac ? 'Command' : 'Ctrl', 'Shift', 'C'], + editable: true, + enabled: false, + system: false + } + ] + } + return state + } catch (error) { + return state } - return state }, '50': (state: RootState) => { - addProvider(state, 'jina') - return state + try { + addProvider(state, 'jina') + return state + } catch (error) { + return state + } }, '51': (state: RootState) => { state.settings.topicNamingPrompt = '' @@ -634,24 +823,28 @@ const migrateConfig = { } }, '67': (state: RootState) => { - if (state.minapps) { - const xiaoyi = DEFAULT_MIN_APPS.find((app) => app.id === 'xiaoyi') - if (xiaoyi) { - state.minapps.enabled.push(xiaoyi) + try { + if (state.minapps) { + const xiaoyi = DEFAULT_MIN_APPS.find((app) => app.id === 'xiaoyi') + if (xiaoyi) { + state.minapps.enabled.push(xiaoyi) + } } + + addProvider(state, 'modelscope') + addProvider(state, 'lmstudio') + addProvider(state, 'perplexity') + addProvider(state, 'infini') + addProvider(state, 'dmxapi') + + state.llm.settings.lmstudio = { + keepAliveTime: 5 + } + + return state + } catch (error) { + return state } - - addProvider(state, 'modelscope') - addProvider(state, 'lmstudio') - addProvider(state, 'perplexity') - addProvider(state, 'infini') - addProvider(state, 'dmxapi') - - state.llm.settings.lmstudio = { - keepAliveTime: 5 - } - - return state }, '68': (state: RootState) => { try { @@ -946,6 +1139,15 @@ const migrateConfig = { } return state + }, + '87': (state: RootState) => { + try { + state.settings.maxKeepAliveMinapps = 3 + state.settings.showOpenedMinappsInSidebar = true + return state + } catch (error) { + return state + } } }