mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 11:44:28 +08:00
* feat: add LongCat provider support - Add LongCat to SystemProviderIds enum - Add LongCat provider logo and configuration - Configure API endpoints and URLs based on official docs - Add two models: LongCat-Flash-Chat and LongCat-Flash-Thinking - Update provider mappings for proper integration The LongCat provider uses OpenAI-compatible API format and supports up to 8K tokens output with daily free quota of 500K tokens. Signed-off-by: LeaderOnePro <leaderonepro@outlook.com> * feat: add migration for LongCat provider - Add migration version 158 for LongCat provider - Ensure existing users get LongCat provider on app update - Follow standard migration pattern for simple provider additions Signed-off-by: LeaderOnePro <leaderonepro@outlook.com> --------- Signed-off-by: LeaderOnePro <leaderonepro@outlook.com>
2561 lines
70 KiB
TypeScript
2561 lines
70 KiB
TypeScript
import { loggerService } from '@logger'
|
||
import { nanoid } from '@reduxjs/toolkit'
|
||
import { DEFAULT_CONTEXTCOUNT, DEFAULT_TEMPERATURE, isMac } from '@renderer/config/constant'
|
||
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
||
import {
|
||
glm45FlashModel,
|
||
isFunctionCallingModel,
|
||
isNotSupportedTextDelta,
|
||
SYSTEM_MODELS
|
||
} from '@renderer/config/models'
|
||
import { BUILTIN_OCR_PROVIDERS, BUILTIN_OCR_PROVIDERS_MAP, DEFAULT_OCR_PROVIDER } from '@renderer/config/ocr'
|
||
import { TRANSLATE_PROMPT } from '@renderer/config/prompts'
|
||
import {
|
||
isSupportArrayContentProvider,
|
||
isSupportDeveloperRoleProvider,
|
||
isSupportStreamOptionsProvider,
|
||
SYSTEM_PROVIDERS
|
||
} from '@renderer/config/providers'
|
||
import { DEFAULT_SIDEBAR_ICONS } from '@renderer/config/sidebar'
|
||
import db from '@renderer/databases'
|
||
import i18n from '@renderer/i18n'
|
||
import { DEFAULT_ASSISTANT_SETTINGS } from '@renderer/services/AssistantService'
|
||
import {
|
||
Assistant,
|
||
BuiltinOcrProvider,
|
||
isSystemProvider,
|
||
Model,
|
||
Provider,
|
||
ProviderApiOptions,
|
||
SystemProviderIds,
|
||
TranslateLanguageCode,
|
||
WebSearchProvider
|
||
} from '@renderer/types'
|
||
import { getDefaultGroupName, getLeadingEmoji, runAsyncFunction, uuid } from '@renderer/utils'
|
||
import { defaultByPassRules, UpgradeChannel } from '@shared/config/constant'
|
||
import { isEmpty } from 'lodash'
|
||
import { createMigrate } from 'redux-persist'
|
||
|
||
import { RootState } from '.'
|
||
import { DEFAULT_TOOL_ORDER } from './inputTools'
|
||
import { initialState as llmInitialState, moveProvider } from './llm'
|
||
import { mcpSlice } from './mcp'
|
||
import { initialState as notesInitialState } from './note'
|
||
import { defaultActionItems } from './selectionStore'
|
||
import { initialState as settingsInitialState } from './settings'
|
||
import { initialState as shortcutsInitialState } from './shortcuts'
|
||
import { defaultWebSearchProviders } from './websearch'
|
||
|
||
const logger = loggerService.withContext('Migrate')
|
||
|
||
// remove logo base64 data to reduce the size of the state
|
||
function removeMiniAppIconsFromState(state: RootState) {
|
||
if (state.minapps) {
|
||
state.minapps.enabled = state.minapps.enabled.map((app) => ({ ...app, logo: undefined }))
|
||
state.minapps.disabled = state.minapps.disabled.map((app) => ({ ...app, logo: undefined }))
|
||
state.minapps.pinned = state.minapps.pinned.map((app) => ({ ...app, logo: undefined }))
|
||
}
|
||
}
|
||
|
||
function removeMiniAppFromState(state: RootState, id: string) {
|
||
if (state.minapps) {
|
||
state.minapps.enabled = state.minapps.enabled.filter((app) => app.id !== id)
|
||
state.minapps.disabled = state.minapps.disabled.filter((app) => app.id !== id)
|
||
}
|
||
}
|
||
|
||
function addMiniApp(state: RootState, id: string) {
|
||
if (state.minapps) {
|
||
const app = DEFAULT_MIN_APPS.find((app) => app.id === id)
|
||
if (app) {
|
||
if (!state.minapps.enabled.find((app) => app.id === id)) {
|
||
state.minapps.enabled.push(app)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// add provider to state
|
||
function addProvider(state: RootState, id: string) {
|
||
if (!state.llm.providers.find((p) => p.id === id)) {
|
||
const _provider = SYSTEM_PROVIDERS.find((p) => p.id === id)
|
||
if (_provider) {
|
||
state.llm.providers.push(_provider)
|
||
}
|
||
}
|
||
}
|
||
|
||
// add ocr provider
|
||
function addOcrProvider(state: RootState, provider: BuiltinOcrProvider) {
|
||
if (!state.ocr.providers.find((p) => p.id === provider.id)) {
|
||
state.ocr.providers.push(provider)
|
||
}
|
||
}
|
||
|
||
function updateProvider(state: RootState, id: string, provider: Partial<Provider>) {
|
||
if (state.llm.providers) {
|
||
const index = state.llm.providers.findIndex((p) => p.id === id)
|
||
if (index !== -1) {
|
||
state.llm.providers[index] = { ...state.llm.providers[index], ...provider }
|
||
}
|
||
}
|
||
}
|
||
|
||
function addWebSearchProvider(state: RootState, id: string) {
|
||
if (state.websearch && state.websearch.providers) {
|
||
if (!state.websearch.providers.find((p) => p.id === id)) {
|
||
const provider = defaultWebSearchProviders.find((p) => p.id === id)
|
||
if (provider) {
|
||
// Prevent mutating read only property of object
|
||
// Otherwise, it will cause the error: Cannot assign to read only property 'apiKey' of object '#<Object>'
|
||
state.websearch.providers.push({ ...provider })
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function updateWebSearchProvider(state: RootState, provider: Partial<WebSearchProvider>) {
|
||
if (state.websearch && state.websearch.providers) {
|
||
const index = state.websearch.providers.findIndex((p) => p.id === provider.id)
|
||
if (index !== -1) {
|
||
state.websearch.providers[index] = {
|
||
...state.websearch.providers[index],
|
||
...provider
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function addSelectionAction(state: RootState, id: string) {
|
||
if (state.selectionStore && state.selectionStore.actionItems) {
|
||
if (!state.selectionStore.actionItems.some((item) => item.id === id)) {
|
||
const action = defaultActionItems.find((item) => item.id === id)
|
||
if (action) {
|
||
state.selectionStore.actionItems.push(action)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add shortcuts(ids from shortcutsInitialState) after the shortcut(afterId)
|
||
* if afterId is 'first', add to the first
|
||
* if afterId is 'last', add to the last
|
||
*/
|
||
function addShortcuts(state: RootState, ids: string[], afterId: string) {
|
||
const defaultShortcuts = shortcutsInitialState.shortcuts
|
||
|
||
// 确保 state.shortcuts 存在
|
||
if (!state.shortcuts) {
|
||
return
|
||
}
|
||
|
||
// 从 defaultShortcuts 中找到要添加的快捷键
|
||
const shortcutsToAdd = defaultShortcuts.filter((shortcut) => ids.includes(shortcut.key))
|
||
|
||
// 过滤掉已经存在的快捷键
|
||
const existingKeys = state.shortcuts.shortcuts.map((s) => s.key)
|
||
const newShortcuts = shortcutsToAdd.filter((shortcut) => !existingKeys.includes(shortcut.key))
|
||
|
||
if (newShortcuts.length === 0) {
|
||
return
|
||
}
|
||
|
||
if (afterId === 'first') {
|
||
// 添加到最前面
|
||
state.shortcuts.shortcuts.unshift(...newShortcuts)
|
||
} else if (afterId === 'last') {
|
||
// 添加到最后面
|
||
state.shortcuts.shortcuts.push(...newShortcuts)
|
||
} else {
|
||
// 添加到指定快捷键后面
|
||
const afterIndex = state.shortcuts.shortcuts.findIndex((shortcut) => shortcut.key === afterId)
|
||
if (afterIndex !== -1) {
|
||
state.shortcuts.shortcuts.splice(afterIndex + 1, 0, ...newShortcuts)
|
||
} else {
|
||
// 如果找不到指定的快捷键,则添加到最后
|
||
state.shortcuts.shortcuts.push(...newShortcuts)
|
||
}
|
||
}
|
||
}
|
||
|
||
const migrateConfig = {
|
||
'2': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'yi')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'3': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'zhipu')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'4': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'ollama')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'5': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'moonshot')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'6': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'openrouter')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'7': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
language: navigator.language
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'8': (state: RootState) => {
|
||
try {
|
||
const fixAssistantName = (assistant: Assistant) => {
|
||
// 2025/07/25 这俩键早没了,从远古版本迁移包出错的
|
||
if (isEmpty(assistant.name)) {
|
||
assistant.name = i18n.t('chat.default.name')
|
||
}
|
||
|
||
assistant.topics = assistant.topics.map((topic) => {
|
||
if (isEmpty(topic.name)) {
|
||
topic.name = i18n.t('chat.default.topic.name')
|
||
}
|
||
return topic
|
||
})
|
||
|
||
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) => {
|
||
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) => {
|
||
try {
|
||
addProvider(state, 'baichuan')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'11': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'dashscope')
|
||
addProvider(state, 'anthropic')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'12': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'aihubmix')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'13': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
assistants: {
|
||
...state.assistants,
|
||
defaultAssistant: {
|
||
...state.assistants.defaultAssistant,
|
||
name: ['Default Assistant', '默认助手'].includes(state.assistants.defaultAssistant.name)
|
||
? i18n.t('settings.assistant.label')
|
||
: state.assistants.defaultAssistant.name
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'14': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
showAssistants: true,
|
||
proxyUrl: undefined
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'15': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
userName: '',
|
||
showMessageDivider: true
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'16': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
messageFont: 'system',
|
||
showInputEstimatedTokens: false
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'17': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
theme: 'auto'
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'19': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
agents: {
|
||
agents: []
|
||
},
|
||
llm: {
|
||
...state.llm,
|
||
settings: {
|
||
ollama: {
|
||
keepAliveTime: 5
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'20': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
fontSize: 14
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'21': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'gemini')
|
||
addProvider(state, 'stepfun')
|
||
addProvider(state, 'doubao')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'22': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'minimax')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'23': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
showTopics: true,
|
||
windowStyle: 'transparent'
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'24': (state: RootState) => {
|
||
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'
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'25': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'github')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'26': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'ocoolai')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'27': (state: RootState) => {
|
||
try {
|
||
return {
|
||
...state,
|
||
settings: {
|
||
...state.settings,
|
||
renderInputMessageAsMarkdown: true
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'28': (state: RootState) => {
|
||
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) => {
|
||
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) => {
|
||
try {
|
||
addProvider(state, 'azure-openai')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'31': (state: RootState) => {
|
||
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) => {
|
||
try {
|
||
addProvider(state, 'hunyuan')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'33': (state: RootState) => {
|
||
try {
|
||
state.assistants.defaultAssistant.type = 'assistant'
|
||
|
||
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'
|
||
}
|
||
})
|
||
}
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'34': (state: RootState) => {
|
||
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
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'35': (state: RootState) => {
|
||
try {
|
||
state.settings.mathEngine = 'KaTeX'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'36': (state: RootState) => {
|
||
try {
|
||
state.settings.topicPosition = 'left'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'37': (state: RootState) => {
|
||
try {
|
||
state.settings.messageStyle = 'plain'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'38': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'grok')
|
||
addProvider(state, 'hyperbolic')
|
||
addProvider(state, 'mistral')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'39': (state: RootState) => {
|
||
try {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeStyle = 'auto'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'40': (state: RootState) => {
|
||
try {
|
||
state.settings.tray = true
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'41': (state: RootState) => {
|
||
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) => {
|
||
try {
|
||
state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'43': (state: RootState) => {
|
||
try {
|
||
if (state.settings.proxyMode === 'none') {
|
||
state.settings.proxyMode = 'system'
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'44': (state: RootState) => {
|
||
try {
|
||
state.settings.translateModelPrompt = TRANSLATE_PROMPT
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'45': (state: RootState) => {
|
||
state.settings.enableTopicNaming = true
|
||
return state
|
||
},
|
||
'46': (state: RootState) => {
|
||
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
|
||
}
|
||
},
|
||
'47': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
provider.models.forEach((model) => {
|
||
model.group = getDefaultGroupName(model.id)
|
||
})
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'48': (state: RootState) => {
|
||
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
|
||
}
|
||
},
|
||
'49': (state: RootState) => {
|
||
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
|
||
}
|
||
},
|
||
'50': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'jina')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'51': (state: RootState) => {
|
||
state.settings.topicNamingPrompt = ''
|
||
return state
|
||
},
|
||
'54': (state: RootState) => {
|
||
try {
|
||
if (state.shortcuts) {
|
||
state.shortcuts.shortcuts.push({
|
||
key: 'search_message',
|
||
shortcut: [isMac ? 'Command' : 'Ctrl', 'F'],
|
||
editable: true,
|
||
enabled: true,
|
||
system: false
|
||
})
|
||
}
|
||
state.settings.sidebarIcons = {
|
||
visible: DEFAULT_SIDEBAR_ICONS,
|
||
disabled: []
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'55': (state: RootState) => {
|
||
try {
|
||
if (!state.settings.sidebarIcons) {
|
||
state.settings.sidebarIcons = {
|
||
visible: DEFAULT_SIDEBAR_ICONS,
|
||
disabled: []
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'57': (state: RootState) => {
|
||
try {
|
||
if (state.shortcuts) {
|
||
state.shortcuts.shortcuts.push({
|
||
key: 'mini_window',
|
||
shortcut: [isMac ? 'Command' : 'Ctrl', 'E'],
|
||
editable: true,
|
||
enabled: false,
|
||
system: true
|
||
})
|
||
}
|
||
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'qwenlm') {
|
||
// @ts-ignore eslint-disable-next-line
|
||
provider.type = 'qwenlm'
|
||
}
|
||
})
|
||
|
||
state.settings.enableQuickAssistant = false
|
||
state.settings.clickTrayToShowQuickAssistant = true
|
||
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'58': (state: RootState) => {
|
||
try {
|
||
if (state.shortcuts) {
|
||
state.shortcuts.shortcuts.push(
|
||
{
|
||
key: 'clear_topic',
|
||
shortcut: [isMac ? 'Command' : 'Ctrl', 'L'],
|
||
editable: true,
|
||
enabled: true,
|
||
system: false
|
||
},
|
||
{
|
||
key: 'toggle_new_context',
|
||
shortcut: [isMac ? 'Command' : 'Ctrl', 'R'],
|
||
editable: true,
|
||
enabled: true,
|
||
system: false
|
||
}
|
||
)
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'59': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'flowith')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'60': (state: RootState) => {
|
||
try {
|
||
state.settings.multiModelMessageStyle = 'fold'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'61': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'qwenlm') {
|
||
// @ts-ignore eslint-disable-next-line
|
||
provider.type = 'qwenlm'
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'62': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'azure-openai') {
|
||
provider.type = 'azure-openai'
|
||
}
|
||
})
|
||
state.settings.translateModelPrompt = TRANSLATE_PROMPT
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'63': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, '3mintop')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'64': (state: RootState) => {
|
||
try {
|
||
state.llm.providers = state.llm.providers.filter((provider) => provider.id !== 'qwenlm')
|
||
addProvider(state, 'baidu-cloud')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'65': (state: RootState) => {
|
||
try {
|
||
// @ts-ignore expect error
|
||
state.settings.targetLanguage = 'english'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'66': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'gitee-ai')
|
||
addProvider(state, 'ppio')
|
||
addMiniApp(state, 'aistudio')
|
||
state.llm.providers = state.llm.providers.filter((provider) => provider.id !== 'graphrag-kylin-mountain')
|
||
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'67': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, '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
|
||
}
|
||
},
|
||
'68': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'notebooklm')
|
||
addProvider(state, 'modelscope')
|
||
addProvider(state, 'lmstudio')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'69': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'coze')
|
||
state.settings.gridColumns = 2
|
||
state.settings.gridPopoverTrigger = 'hover'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'70': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'dmxapi') {
|
||
provider.apiHost = 'https://www.dmxapi.cn'
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'71': (state: RootState) => {
|
||
try {
|
||
const appIds = ['dify', 'wpslingxi', 'lechat', 'abacus', 'lambdachat', 'baidu-ai-search']
|
||
|
||
if (state.minapps) {
|
||
appIds.forEach((id) => {
|
||
const app = DEFAULT_MIN_APPS.find((app) => app.id === id)
|
||
if (app) {
|
||
state.minapps.enabled.push(app)
|
||
}
|
||
})
|
||
// remove zhihu-zhiada
|
||
state.minapps.enabled = state.minapps.enabled.filter((app) => app.id !== 'zhihu-zhiada')
|
||
state.minapps.disabled = state.minapps.disabled.filter((app) => app.id !== 'zhihu-zhiada')
|
||
}
|
||
|
||
state.settings.thoughtAutoCollapse = true
|
||
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'72': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'monica')
|
||
|
||
// remove duplicate lmstudio providers
|
||
const emptyLmStudioProviderIndex = state.llm.providers.findLastIndex(
|
||
(provider) => provider.id === 'lmstudio' && provider.models.length === 0
|
||
)
|
||
|
||
if (emptyLmStudioProviderIndex !== -1) {
|
||
state.llm.providers.splice(emptyLmStudioProviderIndex, 1)
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'73': (state: RootState) => {
|
||
try {
|
||
if (state.websearch) {
|
||
state.websearch.searchWithTime = true
|
||
state.websearch.maxResults = 5
|
||
state.websearch.excludeDomains = []
|
||
}
|
||
|
||
addProvider(state, 'lmstudio')
|
||
addProvider(state, 'o3')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'o3', 2)
|
||
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
const leadingEmoji = getLeadingEmoji(assistant.name)
|
||
if (leadingEmoji) {
|
||
assistant.emoji = leadingEmoji
|
||
assistant.name = assistant.name.replace(leadingEmoji, '').trim()
|
||
}
|
||
})
|
||
|
||
state.agents.agents.forEach((agent) => {
|
||
const leadingEmoji = getLeadingEmoji(agent.name)
|
||
if (leadingEmoji) {
|
||
agent.emoji = leadingEmoji
|
||
agent.name = agent.name.replace(leadingEmoji, '').trim()
|
||
}
|
||
})
|
||
|
||
const defaultAssistantEmoji = getLeadingEmoji(state.assistants.defaultAssistant.name)
|
||
|
||
if (defaultAssistantEmoji) {
|
||
state.assistants.defaultAssistant.emoji = defaultAssistantEmoji
|
||
state.assistants.defaultAssistant.name = state.assistants.defaultAssistant.name
|
||
.replace(defaultAssistantEmoji, '')
|
||
.trim()
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'74': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'xirang')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'75': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'you')
|
||
addMiniApp(state, 'cici')
|
||
addMiniApp(state, 'zhihu')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'76': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'tencent-cloud-ti')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'77': (state: RootState) => {
|
||
try {
|
||
addWebSearchProvider(state, 'searxng')
|
||
addWebSearchProvider(state, 'exa')
|
||
if (state.websearch) {
|
||
state.websearch.providers.forEach((p) => {
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete p.enabled
|
||
})
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'78': (state: RootState) => {
|
||
try {
|
||
state.llm.providers = moveProvider(state.llm.providers, 'ppio', 9)
|
||
state.llm.providers = moveProvider(state.llm.providers, 'infini', 10)
|
||
removeMiniAppIconsFromState(state)
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'79': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'gpustack')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'80': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'alayanew')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'alayanew', 10)
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'81': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'copilot')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'82': (state: RootState) => {
|
||
try {
|
||
const runtimeState = state.runtime as any
|
||
if (runtimeState?.webdavSync) {
|
||
state.backup = state.backup || {}
|
||
state.backup = {
|
||
...state.backup,
|
||
webdavSync: {
|
||
lastSyncTime: runtimeState.webdavSync.lastSyncTime || null,
|
||
syncing: runtimeState.webdavSync.syncing || false,
|
||
lastSyncError: runtimeState.webdavSync.lastSyncError || null
|
||
}
|
||
}
|
||
delete runtimeState.webdavSync
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'83': (state: RootState) => {
|
||
try {
|
||
state.settings.messageNavigation = 'buttons'
|
||
state.settings.launchOnBoot = false
|
||
state.settings.launchToTray = false
|
||
state.settings.trayOnClose = true
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 83 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'84': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'voyageai')
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 84 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'85': (state: RootState) => {
|
||
try {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.autoCheckUpdate = !state.settings.manualUpdateCheck
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.manualUpdateCheck
|
||
state.settings.gridPopoverTrigger = 'click'
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'86': (state: RootState) => {
|
||
try {
|
||
if (state?.mcp?.servers) {
|
||
state.mcp.servers = state.mcp.servers.map((server) => ({
|
||
...server,
|
||
id: nanoid()
|
||
}))
|
||
}
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
return state
|
||
},
|
||
'87': (state: RootState) => {
|
||
try {
|
||
state.settings.maxKeepAliveMinapps = 3
|
||
state.settings.showOpenedMinappsInSidebar = true
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'88': (state: RootState) => {
|
||
try {
|
||
if (state?.mcp?.servers) {
|
||
const hasAutoInstall = state.mcp.servers.some((server) => server.name === '@cherry/mcp-auto-install')
|
||
if (!hasAutoInstall) {
|
||
const defaultServer = mcpSlice.getInitialState().servers[0]
|
||
state.mcp.servers = [{ ...defaultServer, id: nanoid() }, ...state.mcp.servers]
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'89': (state: RootState) => {
|
||
try {
|
||
removeMiniAppFromState(state, 'aistudio')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'90': (state: RootState) => {
|
||
try {
|
||
state.settings.enableDataCollection = true
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'91': (state: RootState) => {
|
||
try {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeCacheable = false
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeCacheMaxSize = 1000
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeCacheTTL = 15
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeCacheThreshold = 2
|
||
addProvider(state, 'qiniu')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'92': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'dangbei')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'qiniu', 12)
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'93': (state: RootState) => {
|
||
try {
|
||
if (!state?.settings?.exportMenuOptions) {
|
||
state.settings.exportMenuOptions = settingsInitialState.exportMenuOptions
|
||
return state
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'94': (state: RootState) => {
|
||
try {
|
||
state.settings.enableQuickPanelTriggers = false
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'95': (state: RootState) => {
|
||
try {
|
||
addWebSearchProvider(state, 'local-google')
|
||
addWebSearchProvider(state, 'local-bing')
|
||
addWebSearchProvider(state, 'local-baidu')
|
||
|
||
if (state.websearch) {
|
||
if (isEmpty(state.websearch.subscribeSources)) {
|
||
state.websearch.subscribeSources = []
|
||
}
|
||
}
|
||
|
||
const qiniuProvider = state.llm.providers.find((provider) => provider.id === 'qiniu')
|
||
if (qiniuProvider && isEmpty(qiniuProvider.models)) {
|
||
qiniuProvider.models = SYSTEM_MODELS.qiniu
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'96': (state: RootState) => {
|
||
try {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.assistantIconType = state.settings?.showAssistantIcon ? 'model' : 'emoji'
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.showAssistantIcon
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'97': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'zai')
|
||
state.settings.webdavMaxBackups = 0
|
||
if (state.websearch && state.websearch.providers) {
|
||
state.websearch.providers.forEach((provider) => {
|
||
provider.basicAuthUsername = ''
|
||
provider.basicAuthPassword = ''
|
||
})
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'98': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.type === 'openai' && provider.id !== 'openai') {
|
||
// @ts-ignore eslint-disable-next-line
|
||
provider.type = 'openai-compatible'
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'99': (state: RootState) => {
|
||
try {
|
||
state.settings.showPrompt = true
|
||
|
||
addWebSearchProvider(state, 'bocha')
|
||
|
||
updateWebSearchProvider(state, {
|
||
id: 'exa',
|
||
apiHost: 'https://api.exa.ai'
|
||
})
|
||
|
||
updateWebSearchProvider(state, {
|
||
id: 'tavily',
|
||
apiHost: 'https://api.tavily.com'
|
||
})
|
||
|
||
// Remove basic auth fields from exa and tavily
|
||
if (state.websearch?.providers) {
|
||
state.websearch.providers = state.websearch.providers.map((provider) => {
|
||
if (provider.id === 'exa' || provider.id === 'tavily') {
|
||
// oxlint-disable-next-line @typescript-eslint/no-unused-vars
|
||
const { basicAuthUsername, basicAuthPassword, ...rest } = provider
|
||
return rest
|
||
}
|
||
return provider
|
||
})
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'100': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (['openai-compatible', 'openai'].includes(provider.type)) {
|
||
provider.type = 'openai'
|
||
}
|
||
if (provider.id === 'openai') {
|
||
provider.type = 'openai-response'
|
||
}
|
||
})
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
assistant.knowledgeRecognition = 'off'
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 100 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'101': (state: RootState) => {
|
||
try {
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
if (assistant.settings) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (assistant.settings.enableToolUse) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
assistant.settings.toolUseMode = assistant.settings.enableToolUse ? 'function' : 'prompt'
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete assistant.settings.enableToolUse
|
||
}
|
||
}
|
||
})
|
||
if (state.shortcuts) {
|
||
state.shortcuts.shortcuts.push({
|
||
key: 'exit_fullscreen',
|
||
shortcut: ['Escape'],
|
||
editable: false,
|
||
enabled: true,
|
||
system: true
|
||
})
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 101 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'102': (state: RootState) => {
|
||
try {
|
||
state.settings.openAI = {
|
||
summaryText: 'off',
|
||
serviceTier: 'auto',
|
||
verbosity: 'medium'
|
||
}
|
||
|
||
state.settings.codeExecution = {
|
||
enabled: false,
|
||
timeoutMinutes: 1
|
||
}
|
||
state.settings.codeEditor = {
|
||
enabled: false,
|
||
themeLight: 'auto',
|
||
themeDark: 'auto',
|
||
highlightActiveLine: false,
|
||
foldGutter: false,
|
||
autocompletion: true,
|
||
keymap: false
|
||
}
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codePreview = {
|
||
themeLight: 'auto',
|
||
themeDark: 'auto'
|
||
}
|
||
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (state.settings.codeStyle) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codePreview.themeLight = state.settings.codeStyle
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codePreview.themeDark = state.settings.codeStyle
|
||
}
|
||
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.codeStyle
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.codeCacheable
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.codeCacheMaxSize
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.codeCacheTTL
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.settings.codeCacheThreshold
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 102 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'103': (state: RootState) => {
|
||
try {
|
||
if (state.shortcuts) {
|
||
if (!state.shortcuts.shortcuts.find((shortcut) => shortcut.key === 'search_message_in_chat')) {
|
||
state.shortcuts.shortcuts.push({
|
||
key: 'search_message_in_chat',
|
||
shortcut: [isMac ? 'Command' : 'Ctrl', 'F'],
|
||
editable: true,
|
||
enabled: true,
|
||
system: false
|
||
})
|
||
}
|
||
const searchMessageShortcut = state.shortcuts.shortcuts.find((shortcut) => shortcut.key === 'search_message')
|
||
const targetShortcut = [isMac ? 'Command' : 'Ctrl', 'F']
|
||
if (
|
||
searchMessageShortcut &&
|
||
Array.isArray(searchMessageShortcut.shortcut) &&
|
||
searchMessageShortcut.shortcut.length === targetShortcut.length &&
|
||
searchMessageShortcut.shortcut.every((v, i) => v === targetShortcut[i])
|
||
) {
|
||
searchMessageShortcut.shortcut = [isMac ? 'Command' : 'Ctrl', 'Shift', 'F']
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 103 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'104': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'burncloud')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'burncloud', 10)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 104 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'105': (state: RootState) => {
|
||
try {
|
||
state.settings.notification = settingsInitialState.notification
|
||
addMiniApp(state, 'google')
|
||
if (!state.settings.openAI) {
|
||
state.settings.openAI = {
|
||
summaryText: 'off',
|
||
serviceTier: 'auto',
|
||
verbosity: 'medium'
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 105 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'106': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'tokenflux')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'tokenflux', 15)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 106 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'107': (state: RootState) => {
|
||
try {
|
||
if (state.paintings && !state.paintings.dmxapi_paintings) {
|
||
state.paintings.dmxapi_paintings = []
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 107 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'108': (state: RootState) => {
|
||
try {
|
||
state.inputTools.toolOrder = DEFAULT_TOOL_ORDER
|
||
state.inputTools.isCollapsed = false
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 108 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'109': (state: RootState) => {
|
||
try {
|
||
state.settings.userTheme = settingsInitialState.userTheme
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 109 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'110': (state: RootState) => {
|
||
try {
|
||
if (state.paintings && !state.paintings.tokenflux_paintings) {
|
||
state.paintings.tokenflux_paintings = []
|
||
}
|
||
state.settings.testPlan = false
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 110 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'111': (state: RootState) => {
|
||
try {
|
||
addSelectionAction(state, 'quote')
|
||
if (
|
||
state.llm.translateModel.provider === 'silicon' &&
|
||
state.llm.translateModel.id === 'meta-llama/Llama-3.3-70B-Instruct'
|
||
) {
|
||
state.llm.translateModel = SYSTEM_MODELS.defaultModel[2]
|
||
}
|
||
|
||
// add selection_assistant_toggle and selection_assistant_select_text shortcuts after mini_window
|
||
addShortcuts(state, ['selection_assistant_toggle', 'selection_assistant_select_text'], 'mini_window')
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 111 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'112': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'cephalon')
|
||
addProvider(state, '302ai')
|
||
addProvider(state, 'lanyun')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'cephalon', 13)
|
||
state.llm.providers = moveProvider(state.llm.providers, '302ai', 14)
|
||
state.llm.providers = moveProvider(state.llm.providers, 'lanyun', 15)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 112 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'113': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'vertexai')
|
||
if (!state.llm.settings.vertexai) {
|
||
state.llm.settings.vertexai = llmInitialState.settings.vertexai
|
||
}
|
||
updateProvider(state, 'gemini', {
|
||
isVertex: false
|
||
})
|
||
updateProvider(state, 'vertexai', {
|
||
isVertex: true
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 113 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'114': (state: RootState) => {
|
||
try {
|
||
if (state.settings && state.settings.exportMenuOptions) {
|
||
if (typeof state.settings.exportMenuOptions.plain_text === 'undefined') {
|
||
state.settings.exportMenuOptions.plain_text = true
|
||
}
|
||
}
|
||
if (state.settings) {
|
||
state.settings.enableSpellCheck = false
|
||
state.settings.spellCheckLanguages = []
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 114 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'115': (state: RootState) => {
|
||
try {
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
if (!assistant.settings) {
|
||
assistant.settings = {
|
||
temperature: DEFAULT_TEMPERATURE,
|
||
contextCount: DEFAULT_CONTEXTCOUNT,
|
||
topP: 1,
|
||
toolUseMode: 'prompt',
|
||
customParameters: [],
|
||
streamOutput: true,
|
||
enableMaxTokens: false
|
||
}
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 115 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'116': (state: RootState) => {
|
||
try {
|
||
if (state.websearch) {
|
||
// migrate contentLimit to cutoffLimit
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (state.websearch.contentLimit) {
|
||
state.websearch.compressionConfig = {
|
||
method: 'cutoff',
|
||
cutoffUnit: 'char',
|
||
// @ts-ignore eslint-disable-next-line
|
||
cutoffLimit: state.websearch.contentLimit
|
||
}
|
||
} else {
|
||
state.websearch.compressionConfig = { method: 'none', cutoffUnit: 'char' }
|
||
}
|
||
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete state.websearch.contentLimit
|
||
}
|
||
if (state.settings) {
|
||
state.settings.testChannel = UpgradeChannel.LATEST
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 116 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'117': (state: RootState) => {
|
||
try {
|
||
const ppioProvider = state.llm.providers.find((provider) => provider.id === 'ppio')
|
||
const modelsToRemove = [
|
||
'qwen/qwen-2.5-72b-instruct',
|
||
'qwen/qwen2.5-32b-instruct',
|
||
'meta-llama/llama-3.1-70b-instruct',
|
||
'meta-llama/llama-3.1-8b-instruct',
|
||
'01-ai/yi-1.5-34b-chat',
|
||
'01-ai/yi-1.5-9b-chat',
|
||
'thudm/glm-z1-32b-0414',
|
||
'thudm/glm-z1-9b-0414'
|
||
]
|
||
if (ppioProvider) {
|
||
updateProvider(state, 'ppio', {
|
||
models: [
|
||
...ppioProvider.models.filter((model) => !modelsToRemove.includes(model.id)),
|
||
...SYSTEM_MODELS.ppio.filter(
|
||
(systemModel) => !ppioProvider.models.some((existingModel) => existingModel.id === systemModel.id)
|
||
)
|
||
],
|
||
apiHost: 'https://api.ppinfra.com/v3/openai/'
|
||
})
|
||
}
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
if (assistant.settings && assistant.settings.streamOutput === undefined) {
|
||
assistant.settings = {
|
||
...assistant.settings,
|
||
streamOutput: true
|
||
}
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 117 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'118': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'ph8')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'ph8', 14)
|
||
|
||
if (!state.settings.userId) {
|
||
state.settings.userId = uuid()
|
||
}
|
||
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'mistral') {
|
||
provider.type = 'mistral'
|
||
}
|
||
})
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 118 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'119': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'new-api')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'new-api', 16)
|
||
state.settings.disableHardwareAcceleration = false
|
||
// migrate to enable memory feature on sidebar
|
||
if (state.settings && state.settings.sidebarIcons) {
|
||
// Check if 'memory' is not already in visible icons
|
||
if (!state.settings.sidebarIcons.visible.includes('memory' as any)) {
|
||
state.settings.sidebarIcons.visible = [...state.settings.sidebarIcons.visible, 'memory' as any]
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 119 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'120': (state: RootState) => {
|
||
try {
|
||
// migrate to remove memory feature from sidebar (moved to settings)
|
||
if (state.settings && state.settings.sidebarIcons) {
|
||
// Remove 'memory' from visible icons if present
|
||
state.settings.sidebarIcons.visible = state.settings.sidebarIcons.visible.filter(
|
||
(icon) => icon !== ('memory' as any)
|
||
)
|
||
// Remove 'memory' from disabled icons if present
|
||
state.settings.sidebarIcons.disabled = state.settings.sidebarIcons.disabled.filter(
|
||
(icon) => icon !== ('memory' as any)
|
||
)
|
||
}
|
||
|
||
if (!state.settings.s3) {
|
||
state.settings.s3 = settingsInitialState.s3
|
||
}
|
||
|
||
const langMap: Record<string, TranslateLanguageCode> = {
|
||
english: 'en-us',
|
||
chinese: 'zh-cn',
|
||
'chinese-traditional': 'zh-tw',
|
||
japanese: 'ja-jp',
|
||
russian: 'ru-ru'
|
||
}
|
||
|
||
const origin = state.settings.targetLanguage
|
||
const newLang = langMap[origin]
|
||
if (newLang) state.settings.targetLanguage = newLang
|
||
else state.settings.targetLanguage = 'en-us'
|
||
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === 'azure-openai') {
|
||
provider.type = 'azure-openai'
|
||
}
|
||
})
|
||
|
||
state.settings.localBackupMaxBackups = 0
|
||
state.settings.localBackupSkipBackupFile = false
|
||
state.settings.localBackupDir = ''
|
||
state.settings.localBackupAutoSync = false
|
||
state.settings.localBackupSyncInterval = 0
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 120 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'121': (state: RootState) => {
|
||
try {
|
||
const { toolOrder } = state.inputTools
|
||
const urlContextKey = 'url_context'
|
||
if (!toolOrder.visible.includes(urlContextKey)) {
|
||
const webSearchIndex = toolOrder.visible.indexOf('web_search')
|
||
const knowledgeBaseIndex = toolOrder.visible.indexOf('knowledge_base')
|
||
if (webSearchIndex !== -1) {
|
||
toolOrder.visible.splice(webSearchIndex, 0, urlContextKey)
|
||
} else if (knowledgeBaseIndex !== -1) {
|
||
toolOrder.visible.splice(knowledgeBaseIndex, 0, urlContextKey)
|
||
} else {
|
||
toolOrder.visible.push(urlContextKey)
|
||
}
|
||
}
|
||
|
||
for (const assistant of state.assistants.assistants) {
|
||
if (assistant.settings?.toolUseMode === 'prompt' && isFunctionCallingModel(assistant.model)) {
|
||
assistant.settings.toolUseMode = 'function'
|
||
}
|
||
}
|
||
|
||
if (state.settings && typeof state.settings.webdavDisableStream === 'undefined') {
|
||
state.settings.webdavDisableStream = false
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 121 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'122': (state: RootState) => {
|
||
try {
|
||
state.settings.navbarPosition = 'left'
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 122 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
|
||
'123': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
provider.models.forEach((model) => {
|
||
if (model.type && Array.isArray(model.type)) {
|
||
model.capabilities = model.type.map((t) => ({
|
||
type: t,
|
||
isUserSelected: true
|
||
}))
|
||
delete model.type
|
||
}
|
||
})
|
||
})
|
||
|
||
const lanyunProvider = state.llm.providers.find((provider) => provider.id === 'lanyun')
|
||
if (lanyunProvider && lanyunProvider.models.length === 0) {
|
||
updateProvider(state, 'lanyun', { models: SYSTEM_MODELS.lanyun })
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 123 error', error as Error)
|
||
return state
|
||
}
|
||
}, // 1.5.4
|
||
'124': (state: RootState) => {
|
||
try {
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
if (assistant.settings && !assistant.settings.toolUseMode) {
|
||
assistant.settings.toolUseMode = 'prompt'
|
||
}
|
||
})
|
||
|
||
const updateModelTextDelta = (model?: Model) => {
|
||
if (model) {
|
||
model.supported_text_delta = true
|
||
if (isNotSupportedTextDelta(model)) {
|
||
model.supported_text_delta = false
|
||
}
|
||
}
|
||
}
|
||
|
||
state.llm.providers.forEach((provider) => {
|
||
provider.models.forEach((model) => {
|
||
updateModelTextDelta(model)
|
||
})
|
||
})
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
updateModelTextDelta(assistant.defaultModel)
|
||
updateModelTextDelta(assistant.model)
|
||
})
|
||
|
||
updateModelTextDelta(state.llm.defaultModel)
|
||
updateModelTextDelta(state.llm.topicNamingModel)
|
||
updateModelTextDelta(state.llm.translateModel)
|
||
|
||
if (state.assistants.defaultAssistant.model) {
|
||
updateModelTextDelta(state.assistants.defaultAssistant.model)
|
||
updateModelTextDelta(state.assistants.defaultAssistant.defaultModel)
|
||
}
|
||
|
||
addProvider(state, 'aws-bedrock')
|
||
|
||
// 初始化 awsBedrock 设置
|
||
if (!state.llm.settings.awsBedrock) {
|
||
state.llm.settings.awsBedrock = llmInitialState.settings.awsBedrock
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 124 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'125': (state: RootState) => {
|
||
try {
|
||
// Initialize API server configuration if not present
|
||
if (!state.settings.apiServer) {
|
||
state.settings.apiServer = {
|
||
enabled: false,
|
||
host: 'localhost',
|
||
port: 23333,
|
||
apiKey: `cs-sk-${uuid()}`
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 125 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'126': (state: RootState) => {
|
||
try {
|
||
state.knowledge.bases.forEach((base) => {
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (base.preprocessOrOcrProvider) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
base.preprocessProvider = base.preprocessOrOcrProvider
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete base.preprocessOrOcrProvider
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (base.preprocessProvider.type === 'ocr') {
|
||
// @ts-ignore eslint-disable-next-line
|
||
delete base.preprocessProvider
|
||
}
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 126 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'127': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'poe')
|
||
|
||
// 迁移api选项设置
|
||
state.llm.providers.forEach((provider) => {
|
||
// 新字段默认支持
|
||
const changes = {
|
||
isNotSupportArrayContent: false,
|
||
isNotSupportDeveloperRole: false,
|
||
isNotSupportStreamOptions: false
|
||
}
|
||
if (!isSupportArrayContentProvider(provider) || provider.isNotSupportArrayContent) {
|
||
// 原本开启了兼容模式的provider不受影响
|
||
changes.isNotSupportArrayContent = true
|
||
}
|
||
if (!isSupportDeveloperRoleProvider(provider)) {
|
||
changes.isNotSupportDeveloperRole = true
|
||
}
|
||
if (!isSupportStreamOptionsProvider(provider)) {
|
||
changes.isNotSupportStreamOptions = true
|
||
}
|
||
updateProvider(state, provider.id, changes)
|
||
})
|
||
|
||
// 迁移以前删除掉的内置提供商
|
||
for (const provider of state.llm.providers) {
|
||
if (provider.isSystem && !isSystemProvider(provider)) {
|
||
updateProvider(state, provider.id, { isSystem: false })
|
||
}
|
||
}
|
||
|
||
if (!state.settings.proxyBypassRules) {
|
||
state.settings.proxyBypassRules = defaultByPassRules
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 127 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'128': (state: RootState) => {
|
||
try {
|
||
// 迁移 service tier 设置
|
||
const openai = state.llm.providers.find((provider) => provider.id === SystemProviderIds.openai)
|
||
const serviceTier = state.settings.openAI.serviceTier
|
||
if (openai) {
|
||
openai.serviceTier = serviceTier
|
||
}
|
||
|
||
// @ts-ignore eslint-disable-next-line
|
||
if (state.settings.codePreview) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.settings.codeViewer = state.settings.codePreview
|
||
} else {
|
||
state.settings.codeViewer = {
|
||
themeLight: 'auto',
|
||
themeDark: 'auto'
|
||
}
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 128 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'129': (state: RootState) => {
|
||
try {
|
||
// 聚合 api options
|
||
state.llm.providers.forEach((p) => {
|
||
if (isSystemProvider(p)) {
|
||
updateProvider(state, p.id, { apiOptions: undefined })
|
||
} else {
|
||
const changes: ProviderApiOptions = {
|
||
isNotSupportArrayContent: p.isNotSupportArrayContent,
|
||
isNotSupportServiceTier: p.isNotSupportServiceTier,
|
||
isNotSupportDeveloperRole: p.isNotSupportDeveloperRole,
|
||
isNotSupportStreamOptions: p.isNotSupportStreamOptions
|
||
}
|
||
updateProvider(state, p.id, { apiOptions: changes })
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 129 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'130': (state: RootState) => {
|
||
try {
|
||
if (state.settings && state.settings.openAI && !state.settings.openAI.verbosity) {
|
||
state.settings.openAI.verbosity = 'medium'
|
||
}
|
||
// 为 nutstore 添加备份数量限制的默认值
|
||
if (state.nutstore && state.nutstore.nutstoreMaxBackups === undefined) {
|
||
state.nutstore.nutstoreMaxBackups = 0
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 130 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'131': (state: RootState) => {
|
||
try {
|
||
state.settings.mathEnableSingleDollar = true
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 131 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'132': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((p) => {
|
||
// 如果原本是undefined则不做改动,静默从默认支持改为默认不支持
|
||
if (p.apiOptions?.isNotSupportDeveloperRole) {
|
||
p.apiOptions.isSupportDeveloperRole = !p.apiOptions.isNotSupportDeveloperRole
|
||
}
|
||
if (p.apiOptions?.isNotSupportServiceTier) {
|
||
p.apiOptions.isSupportServiceTier = !p.apiOptions.isNotSupportServiceTier
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 132 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'133': (state: RootState) => {
|
||
try {
|
||
state.settings.sidebarIcons.visible.push('code_tools')
|
||
if (state.codeTools) {
|
||
state.codeTools.environmentVariables = {
|
||
'qwen-code': '',
|
||
'claude-code': '',
|
||
'gemini-cli': ''
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 133 error', error as Error)
|
||
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
|
||
}
|
||
},
|
||
'135': (state: RootState) => {
|
||
try {
|
||
if (!state.assistants.defaultAssistant.settings) {
|
||
state.assistants.defaultAssistant.settings = DEFAULT_ASSISTANT_SETTINGS
|
||
} else if (!state.assistants.defaultAssistant.settings.toolUseMode) {
|
||
state.assistants.defaultAssistant.settings.toolUseMode = 'prompt'
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 135 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'136': (state: RootState) => {
|
||
try {
|
||
state.settings.sidebarIcons.visible = [...new Set(state.settings.sidebarIcons.visible)].filter((icon) =>
|
||
DEFAULT_SIDEBAR_ICONS.includes(icon)
|
||
)
|
||
state.settings.sidebarIcons.disabled = [...new Set(state.settings.sidebarIcons.disabled)].filter((icon) =>
|
||
DEFAULT_SIDEBAR_ICONS.includes(icon)
|
||
)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 136 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'137': (state: RootState) => {
|
||
try {
|
||
state.ocr = {
|
||
providers: BUILTIN_OCR_PROVIDERS,
|
||
imageProviderId: DEFAULT_OCR_PROVIDER.image.id
|
||
}
|
||
state.translate.translateInput = ''
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 137 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'138': (state: RootState) => {
|
||
try {
|
||
addOcrProvider(state, BUILTIN_OCR_PROVIDERS_MAP.system)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 138 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'139': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'cherryin')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'cherryin', 1)
|
||
|
||
const zhipuProvider = state.llm.providers.find((p) => p.id === 'zhipu')
|
||
|
||
if (zhipuProvider) {
|
||
// Update zhipu model list
|
||
if (!zhipuProvider.enabled) {
|
||
zhipuProvider.models = SYSTEM_MODELS.zhipu
|
||
}
|
||
|
||
// Update zhipu model list
|
||
if (zhipuProvider.models.length === 0) {
|
||
zhipuProvider.models = SYSTEM_MODELS.zhipu
|
||
}
|
||
|
||
// Add GLM-4.5-Flash model if not exists
|
||
const hasGlm45FlashModel = zhipuProvider?.models.find((m) => m.id === 'glm-4.5-flash')
|
||
|
||
if (!hasGlm45FlashModel) {
|
||
zhipuProvider?.models.push(glm45FlashModel)
|
||
}
|
||
|
||
// Update default painting provider to zhipu
|
||
state.settings.defaultPaintingProvider = 'zhipu'
|
||
|
||
// Add zhipu web search provider
|
||
addWebSearchProvider(state, 'zhipu')
|
||
|
||
// Update zhipu web search provider api key
|
||
if (zhipuProvider.apiKey) {
|
||
state?.websearch?.providers.forEach((provider) => {
|
||
if (provider.id === 'zhipu') {
|
||
provider.apiKey = zhipuProvider.apiKey
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 139 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'140': (state: RootState) => {
|
||
try {
|
||
state.paintings = {
|
||
// @ts-ignore paintings
|
||
siliconflow_paintings: state?.paintings?.paintings || [],
|
||
// @ts-ignore DMXAPIPaintings
|
||
dmxapi_paintings: state?.paintings?.DMXAPIPaintings || [],
|
||
// @ts-ignore tokenFluxPaintings
|
||
tokenflux_paintings: state?.paintings?.tokenFluxPaintings || [],
|
||
zhipu_paintings: [],
|
||
// @ts-ignore generate
|
||
aihubmix_image_generate: state?.paintings?.generate || [],
|
||
// @ts-ignore remix
|
||
aihubmix_image_remix: state?.paintings?.remix || [],
|
||
// @ts-ignore edit
|
||
aihubmix_image_edit: state?.paintings?.edit || [],
|
||
// @ts-ignore upscale
|
||
aihubmix_image_upscale: state?.paintings?.upscale || [],
|
||
openai_image_generate: state?.paintings?.openai_image_generate || [],
|
||
openai_image_edit: state?.paintings?.openai_image_edit || []
|
||
}
|
||
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 140 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'141': (state: RootState) => {
|
||
try {
|
||
if (state.settings && state.settings.sidebarIcons) {
|
||
// Check if 'notes' is not already in visible icons
|
||
if (!state.settings.sidebarIcons.visible.includes('notes')) {
|
||
state.settings.sidebarIcons.visible = [...state.settings.sidebarIcons.visible, 'notes']
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 141 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'142': (state: RootState) => {
|
||
try {
|
||
// Initialize notes settings if not present
|
||
if (!state.note) {
|
||
state.note = notesInitialState
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 142 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'143': (state: RootState) => {
|
||
try {
|
||
addMiniApp(state, 'longcat')
|
||
return state
|
||
} catch (error) {
|
||
return state
|
||
}
|
||
},
|
||
'144': (state: RootState) => {
|
||
try {
|
||
if (state.settings) {
|
||
state.settings.confirmDeleteMessage = settingsInitialState.confirmDeleteMessage
|
||
state.settings.confirmRegenerateMessage = settingsInitialState.confirmRegenerateMessage
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 144 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'145': (state: RootState) => {
|
||
try {
|
||
if (state.settings) {
|
||
if (state.settings.showMessageOutline === undefined || state.settings.showMessageOutline === null) {
|
||
state.settings.showMessageOutline = false
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 145 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'146': (state: RootState) => {
|
||
try {
|
||
// Migrate showWorkspace from settings to note store
|
||
if (state.settings && state.note) {
|
||
const showWorkspaceValue = (state.settings as any)?.showWorkspace
|
||
if (showWorkspaceValue !== undefined) {
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.note.settings.showWorkspace = showWorkspaceValue
|
||
// Remove from settings
|
||
delete (state.settings as any).showWorkspace
|
||
// @ts-ignore eslint-disable-next-line
|
||
} else if (state.note.settings.showWorkspace === undefined) {
|
||
// Set default value if not exists
|
||
// @ts-ignore eslint-disable-next-line
|
||
state.note.settings.showWorkspace = true
|
||
}
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 146 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'147': (state: RootState) => {
|
||
try {
|
||
state.knowledge.bases.forEach((base) => {
|
||
if ((base as any).framework) {
|
||
delete (base as any).framework
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 147 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'148': (state: RootState) => {
|
||
try {
|
||
addOcrProvider(state, BUILTIN_OCR_PROVIDERS_MAP.paddleocr)
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 148 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'149': (state: RootState) => {
|
||
try {
|
||
state.knowledge.bases.forEach((base) => {
|
||
if ((base as any).framework) {
|
||
delete (base as any).framework
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 149 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'150': (state: RootState) => {
|
||
try {
|
||
addShortcuts(state, ['rename_topic'], 'new_topic')
|
||
addShortcuts(state, ['edit_last_user_message'], 'copy_last_message')
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 150 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'151': (state: RootState) => {
|
||
try {
|
||
if (state.settings) {
|
||
state.settings.codeFancyBlock = true
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 151 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'152': (state: RootState) => {
|
||
try {
|
||
state.translate.settings = {
|
||
autoCopy: false
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 152 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'153': (state: RootState) => {
|
||
try {
|
||
if (state.note.settings) {
|
||
state.note.settings.fontSize = notesInitialState.settings.fontSize
|
||
state.note.settings.showTableOfContents = notesInitialState.settings.showTableOfContents
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 153 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'154': (state: RootState) => {
|
||
try {
|
||
if (state.settings.userTheme) {
|
||
state.settings.userTheme.userFontFamily = settingsInitialState.userTheme.userFontFamily
|
||
state.settings.userTheme.userCodeFontFamily = settingsInitialState.userTheme.userCodeFontFamily
|
||
}
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 154 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'155': (state: RootState) => {
|
||
try {
|
||
state.knowledge.bases.forEach((base) => {
|
||
if ((base as any).framework) {
|
||
delete (base as any).framework
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 155 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'156': (state: RootState) => {
|
||
try {
|
||
state.llm.providers.forEach((provider) => {
|
||
if (provider.id === SystemProviderIds.anthropic) {
|
||
if (provider.apiHost.endsWith('/')) {
|
||
provider.apiHost = provider.apiHost.slice(0, -1)
|
||
}
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 156 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'157': (state: RootState) => {
|
||
try {
|
||
addProvider(state, 'aionly')
|
||
state.llm.providers = moveProvider(state.llm.providers, 'aionly', 10)
|
||
|
||
const cherryinProvider = state.llm.providers.find((provider) => provider.id === 'cherryin')
|
||
|
||
if (cherryinProvider) {
|
||
updateProvider(state, 'cherryin', { apiHost: 'https://open.cherryin.ai', models: [] })
|
||
}
|
||
|
||
if (state.llm.defaultModel?.provider === 'cherryin') {
|
||
state.llm.defaultModel.provider = 'cherryai'
|
||
}
|
||
|
||
if (state.llm.quickModel?.provider === 'cherryin') {
|
||
state.llm.quickModel.provider = 'cherryai'
|
||
}
|
||
|
||
if (state.llm.translateModel?.provider === 'cherryin') {
|
||
state.llm.translateModel.provider = 'cherryai'
|
||
}
|
||
|
||
state.assistants.assistants.forEach((assistant) => {
|
||
if (assistant.model?.provider === 'cherryin') {
|
||
assistant.model.provider = 'cherryai'
|
||
}
|
||
if (assistant.defaultModel?.provider === 'cherryin') {
|
||
assistant.defaultModel.provider = 'cherryai'
|
||
}
|
||
})
|
||
|
||
state.agents.agents.forEach((agent) => {
|
||
// @ts-ignore model is not defined in Agent
|
||
if (agent.model?.provider === 'cherryin') {
|
||
// @ts-ignore model is not defined in Agent
|
||
agent.model.provider = 'cherryai'
|
||
}
|
||
if (agent.defaultModel?.provider === 'cherryin') {
|
||
agent.defaultModel.provider = 'cherryai'
|
||
}
|
||
})
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 157 error', error as Error)
|
||
return state
|
||
}
|
||
},
|
||
'158': (state: RootState) => {
|
||
try {
|
||
state.llm.providers = state.llm.providers.filter((provider) => provider.id !== 'cherryin')
|
||
addProvider(state, 'longcat')
|
||
return state
|
||
} catch (error) {
|
||
logger.error('migrate 158 error', error as Error)
|
||
return state
|
||
}
|
||
}
|
||
}
|
||
|
||
// 注意:添加新迁移时,记得同时更新 persistReducer
|
||
// file://./index.ts
|
||
|
||
const migrate = createMigrate(migrateConfig as any)
|
||
|
||
export default migrate
|