Compare commits

...

11 Commits

Author SHA1 Message Date
icarus
8e0c96d118 test(InputEmbeddingDimension): update snapshot after adding button testid
Update test snapshot to reflect changes in the InputEmbeddingDimension component where a testid was added to the button and the data-title attribute was removed
2025-11-01 18:31:14 +08:00
icarus
60b7795d16 Merge branch 'feat/reset-default-model' of github.com:CherryHQ/cherry-studio into feat/reset-default-model 2025-11-01 14:11:05 +08:00
icarus
9df850b226 refactor(ModelSettings): move ResetIcon inside Button component for consistency 2025-11-01 14:11:01 +08:00
icarus
44378cc879 feat(theme): add primary-foreground color variable to body styles 2025-11-01 14:10:56 +08:00
GitHub Action
50edf016f6 fix(i18n): Auto update translations for PR #11054 2025-11-01 06:04:32 +00:00
icarus
c49c592175 test: update mock models configuration in compatibility tests
Replace SYSTEM_MODELS.defaultModel array with DEFAULT_MODEL_MAP object to better reflect actual model structure
2025-11-01 14:03:05 +08:00
icarus
4437871644 fix(useAssistant): correct function name in resetQuickModel callback
Use setQuickModel instead of setTranslateModel to properly reset the quick model
2025-11-01 14:03:05 +08:00
icarus
e59dfdd27d refactor(TranslatePromptSettings): replace RedoOutlined with ResetIcon and update button styles
migrate icon usage to custom ResetIcon component and improve button styling
add TODO comment for future button component migration
2025-11-01 14:03:05 +08:00
icarus
ac917e12f2 refactor(ModelSettings): remove unused translate prompt related code 2025-11-01 14:02:38 +08:00
icarus
7ecfbce5a5 feat(settings): add reset buttons for model settings
Add reset functionality for default assistant, quick and translate models.
Replace RedoOutlined icon with custom ResetIcon for consistency.
2025-11-01 14:02:16 +08:00
icarus
e6e20d2d72 refactor(models): restructure default model configuration and usage
- Replace SYSTEM_MODELS.defaultModel array with DEFAULT_MODEL_MAP object for clearer model assignments
- Update related store and hook implementations to use new model map
- Add reset functions for default models in useAssistant hook
2025-11-01 13:59:30 +08:00
15 changed files with 142 additions and 75 deletions

View File

@@ -10,12 +10,12 @@ import type { EndpointType, Model, Provider } from '@renderer/types'
import { beforeEach, describe, expect, it, vi } from 'vitest'
vi.mock('@renderer/config/models', () => ({
DEFAULT_MODEL_MAP: {
assistant: { id: 'gpt-4', name: 'GPT-4' },
quick: { id: 'gpt-4', name: 'GPT-4' },
translate: { id: 'gpt-4', name: 'GPT-4' }
},
SYSTEM_MODELS: {
defaultModel: [
{ id: 'gpt-4', name: 'GPT-4' },
{ id: 'gpt-4', name: 'GPT-4' },
{ id: 'gpt-4', name: 'GPT-4' }
],
zhipu: [],
silicon: [],
openai: [],

View File

@@ -14,17 +14,13 @@ export const qwen38bModel: Model = {
group: 'Qwen'
}
export const SYSTEM_MODELS: Record<SystemProviderId | 'defaultModel', Model[]> = {
defaultModel: [
// Default assistant model
glm45FlashModel,
// Default topic naming model
qwen38bModel,
// Default translation model
glm45FlashModel,
// Default quick assistant model
glm45FlashModel
],
export const DEFAULT_MODEL_MAP = {
assistant: glm45FlashModel,
quick: qwen38bModel,
translate: glm45FlashModel
} as const
export const SYSTEM_MODELS: Record<SystemProviderId, Model[]> = {
cherryin: [],
vertexai: [],
'302ai': [

View File

@@ -1,5 +1,6 @@
import { loggerService } from '@logger'
import {
DEFAULT_MODEL_MAP,
getThinkModelType,
isSupportedReasoningEffortModel,
isSupportedThinkingTokenModel,
@@ -24,7 +25,11 @@ import {
updateTopic,
updateTopics
} from '@renderer/store/assistants'
import { setDefaultModel, setQuickModel, setTranslateModel } from '@renderer/store/llm'
import {
setDefaultModel as setDefaultModelAction,
setQuickModel as setQuickModelAction,
setTranslateModel as setTranslateModelAction
} from '@renderer/store/llm'
import type { Assistant, AssistantSettings, Model, ThinkingOption, Topic } from '@renderer/types'
import { uuid } from '@renderer/utils'
import { useCallback, useEffect, useMemo, useRef } from 'react'
@@ -198,12 +203,31 @@ export function useDefaultModel() {
const { defaultModel, quickModel, translateModel } = useAppSelector((state) => state.llm)
const dispatch = useAppDispatch()
const setDefaultModel = useCallback((model: Model) => dispatch(setDefaultModelAction({ model })), [dispatch])
const setQuickModel = useCallback((model: Model) => dispatch(setQuickModelAction({ model })), [dispatch])
const setTranslateModel = useCallback((model: Model) => dispatch(setTranslateModelAction({ model })), [dispatch])
const resetDefaultAssistantModel = useCallback(() => {
setDefaultModel(DEFAULT_MODEL_MAP.assistant)
}, [setDefaultModel])
const resetTranslateModel = useCallback(() => {
setTranslateModel(DEFAULT_MODEL_MAP.translate)
}, [setTranslateModel])
const resetQuickModel = useCallback(() => {
setQuickModel(DEFAULT_MODEL_MAP.quick)
}, [setQuickModel])
return {
defaultModel,
setDefaultModel,
resetDefaultAssistantModel,
quickModel,
resetQuickModel,
setQuickModel,
translateModel,
setDefaultModel: (model: Model) => dispatch(setDefaultModel({ model })),
setQuickModel: (model: Model) => dispatch(setQuickModel({ model })),
setTranslateModel: (model: Model) => dispatch(setTranslateModel({ model }))
setTranslateModel,
resetTranslateModel
}
}

View File

@@ -14,6 +14,7 @@ export default function useUserTheme() {
const colorPrimary = Color(theme.colorPrimary)
document.body.style.setProperty('--color-primary', colorPrimary.toString())
document.body.style.setProperty('--color-primary-foreground', getForegroundColor(colorPrimary.hex()))
// overwrite hero UI primary color.
document.body.style.setProperty('--primary', colorPrimary.toString())
document.body.style.setProperty('--primary-foreground', getForegroundColor(colorPrimary.hex()))

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Bearbeiten Sie komplexe Aufgaben mit verschiedenen Werkzeugen",
"error": {
"failed": "Agent hinzufügen fehlgeschlagen",
"invalid_agent": "Ungültiger Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Tägliche Gespräche und kurze Fragen & Antworten",
"title": "Assistent hinzufügen"
},
"option": {
"title": "Typ auswählen"
},
"topic": {
"title": "Neues Thema erstellen"
}
@@ -2923,15 +2928,14 @@
},
"description": "Ein KI-Assistent für Kreative",
"downloading": "Update wird heruntergeladen...",
"enterprise": {
"title": "Unternehmen"
},
"feedback": {
"button": "Feedback",
"title": "Feedback"
},
"label": "Über uns",
"license": {
"button": "Anzeigen",
"title": "Lizenz"
},
"releases": {
"button": "Anzeigen",
"title": "Changelog"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Χειριστείτε πολύπλοκες εργασίες με διάφορα εργαλεία",
"error": {
"failed": "Αποτυχία προσθήκης πράκτορα",
"invalid_agent": "Μη έγκυρος Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Καθημερινές συνομιλίες και γρήγορες ερωταπαντήσεις",
"title": "Προσθήκη βοηθού"
},
"option": {
"title": "Επιλέξτε Τύπο"
},
"topic": {
"title": "Δημιουργία νέου θέματος"
}
@@ -2923,15 +2928,14 @@
},
"description": "Ένα AI ασιστάντα που έχει σχεδιαστεί για δημιουργούς",
"downloading": "Λήψη ενημερώσεων...",
"enterprise": {
"title": "Επιχείρηση"
},
"feedback": {
"button": "Σχόλια και Παρατηρήσεις",
"title": "Αποστολή σχολίων"
},
"label": "Περί μας",
"license": {
"button": "Προβολή",
"title": "Licenses"
},
"releases": {
"button": "Προβολή",
"title": "Ημερολόγιο Ενημερώσεων"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Maneja tareas complejas con varias herramientas",
"error": {
"failed": "Error al añadir agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversaciones diarias y preguntas y respuestas rápidas",
"title": "Agregar asistente"
},
"option": {
"title": "Seleccionar Tipo"
},
"topic": {
"title": "Crear nuevo tema"
}
@@ -2923,15 +2928,14 @@
},
"description": "Una asistente de IA creada para los creadores",
"downloading": "Descargando actualización...",
"enterprise": {
"title": "Empresa"
},
"feedback": {
"button": "Enviar feedback",
"title": "Enviar comentarios"
},
"label": "Acerca de nosotros",
"license": {
"button": "Ver",
"title": "Licencia"
},
"releases": {
"button": "Ver",
"title": "Registro de cambios"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Gérez des tâches complexes avec divers outils",
"error": {
"failed": "Échec de l'ajout de l'agent",
"invalid_agent": "Agent invalide"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversations quotidiennes et Q&R rapides",
"title": "Ajouter un assistant"
},
"option": {
"title": "Sélectionner le type"
},
"topic": {
"title": "Nouveau sujet"
}
@@ -2923,15 +2928,14 @@
},
"description": "Un assistant IA conçu pour les créateurs",
"downloading": "Téléchargement de la mise à jour en cours...",
"enterprise": {
"title": "Entreprise"
},
"feedback": {
"button": "Faire un retour",
"title": "Retour d'information"
},
"label": "À propos de nous",
"license": {
"button": "Afficher",
"title": "Licence"
},
"releases": {
"button": "Afficher",
"title": "Journal des mises à jour"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "さまざまなツールを使って複雑なタスクを処理する",
"error": {
"failed": "エージェントの追加に失敗しました",
"invalid_agent": "無効なエージェント"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "日常会話と簡単なQ&A",
"title": "アシスタントを追加"
},
"option": {
"title": "タイプを選択"
},
"topic": {
"title": "新しいトピック"
}
@@ -2923,15 +2928,14 @@
},
"description": "クリエイターのための強力なAIアシスタント",
"downloading": "ダウンロード中...",
"enterprise": {
"title": "エンタープライズ"
},
"feedback": {
"button": "フィードバック",
"title": "フィードバック"
},
"label": "について",
"license": {
"button": "ライセンス",
"title": "ライセンス"
},
"releases": {
"button": "リリース",
"title": "リリースノート"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Lide com tarefas complexas usando várias ferramentas",
"error": {
"failed": "Falha ao adicionar agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversas diárias e perguntas e respostas rápidas",
"title": "Adicionar assistente"
},
"option": {
"title": "Selecionar Tipo"
},
"topic": {
"title": "Novo Tópico"
}
@@ -2923,15 +2928,14 @@
},
"description": "Um assistente de IA criado para criadores",
"downloading": "Baixando atualizações...",
"enterprise": {
"title": "Empresa"
},
"feedback": {
"button": "Feedback",
"title": "Enviar feedback"
},
"label": "Sobre Nós",
"license": {
"button": "Ver",
"title": "Licença"
},
"releases": {
"button": "Ver",
"title": "Registro de alterações"

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Справляйтесь со сложными задачами с помощью различных инструментов",
"error": {
"failed": "Не удалось добавить агента",
"invalid_agent": "Недействительный агент"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Ежедневные разговоры и быстрые вопросы и ответы",
"title": "Добавить ассистента"
},
"option": {
"title": "Выберите тип"
},
"topic": {
"title": "Новый топик"
}
@@ -2923,15 +2928,14 @@
},
"description": "Мощный AI-ассистент для созидания",
"downloading": "Загрузка...",
"enterprise": {
"title": "Предприятие"
},
"feedback": {
"button": "Обратная связь",
"title": "Обратная связь"
},
"label": "О программе и обратная связь",
"license": {
"button": "Лицензия",
"title": "Лицензия"
},
"releases": {
"button": "Релизы",
"title": "Заметки о релизах"

View File

@@ -1,14 +1,11 @@
import { RedoOutlined } from '@ant-design/icons'
import { Button, InfoTooltip, RowFlex, Tooltip } from '@cherrystudio/ui'
import { usePreference } from '@data/hooks/usePreference'
import { Button, InfoTooltip, ResetIcon, RowFlex, Tooltip } from '@cherrystudio/ui'
import ModelSelector from '@renderer/components/ModelSelector'
import { isEmbeddingModel, isRerankModel, isTextToImageModel } from '@renderer/config/models'
import { DEFAULT_MODEL_MAP, isEmbeddingModel, isRerankModel, isTextToImageModel } from '@renderer/config/models'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useDefaultModel } from '@renderer/hooks/useAssistant'
import { useProviders } from '@renderer/hooks/useProvider'
import { getModelUniqId, hasModel } from '@renderer/services/ModelService'
import type { Model } from '@renderer/types'
import { TRANSLATE_PROMPT } from '@shared/config/prompts'
import { find } from 'lodash'
import { Languages, MessageSquareMore, Rocket, Settings2 } from 'lucide-react'
import type { FC } from 'react'
@@ -21,15 +18,22 @@ import DefaultAssistantSettings from './DefaultAssistantSettings'
import TopicNamingModalPopup from './QuickModelPopup'
const ModelSettings: FC = () => {
const { defaultModel, quickModel, translateModel, setDefaultModel, setQuickModel, setTranslateModel } =
useDefaultModel()
const {
defaultModel,
quickModel,
translateModel,
setDefaultModel,
setQuickModel,
setTranslateModel,
resetDefaultAssistantModel,
resetQuickModel,
resetTranslateModel
} = useDefaultModel()
const { providers } = useProviders()
const allModels = providers.map((p) => p.models).flat()
const { theme } = useTheme()
const { t } = useTranslation()
const [translateModelPrompt, setTranslateModelPrompt] = usePreference('feature.translate.model_prompt')
const modelPredicate = useCallback(
(m: Model) => !isEmbeddingModel(m) && !isRerankModel(m) && !isTextToImageModel(m),
[]
@@ -47,10 +51,6 @@ const ModelSettings: FC = () => {
[translateModel]
)
const onResetTranslatePrompt = () => {
setTranslateModelPrompt(TRANSLATE_PROMPT)
}
return (
<SettingContainer theme={theme}>
<SettingGroup theme={theme}>
@@ -73,6 +73,13 @@ const ModelSettings: FC = () => {
<Button className="ml-2" onClick={DefaultAssistantSettings.show} size="icon">
<Settings2 size={16} />
</Button>
{defaultModelValue !== getModelUniqId(DEFAULT_MODEL_MAP.assistant) && (
<Tooltip title={t('common.reset')}>
<Button style={{ marginLeft: 8 }} onClick={resetDefaultAssistantModel}>
<ResetIcon size={16} />
</Button>
</Tooltip>
)}
</RowFlex>
<SettingDescription>{t('settings.models.default_assistant_model_description')}</SettingDescription>
</SettingGroup>
@@ -97,6 +104,13 @@ const ModelSettings: FC = () => {
<Button className="ml-2" onClick={TopicNamingModalPopup.show} size="icon">
<Settings2 size={16} />
</Button>
{defaultQuickModel !== getModelUniqId(DEFAULT_MODEL_MAP.quick) && (
<Tooltip title={t('common.reset')}>
<Button style={{ marginLeft: 8 }} onClick={resetQuickModel}>
<ResetIcon size={16} />
</Button>
</Tooltip>
)}
</RowFlex>
<SettingDescription>{t('settings.models.quick_model.description')}</SettingDescription>
</SettingGroup>
@@ -120,10 +134,10 @@ const ModelSettings: FC = () => {
<Button className="ml-2" onClick={() => TranslateSettingsPopup.show()} size="icon">
<Settings2 size={16} />
</Button>
{translateModelPrompt !== TRANSLATE_PROMPT && (
<Tooltip content={t('common.reset')}>
<Button className="ml-2" onClick={onResetTranslatePrompt} size="icon">
<RedoOutlined />
{defaultTranslateModel !== getModelUniqId(DEFAULT_MODEL_MAP.translate) && (
<Tooltip title={t('common.reset')}>
<Button style={{ marginLeft: 8 }} onClick={resetTranslateModel}>
<ResetIcon size={16} />
</Button>
</Tooltip>
)}

View File

@@ -1,5 +1,4 @@
import { RedoOutlined } from '@ant-design/icons'
import { RowFlex } from '@cherrystudio/ui'
import { ResetIcon, RowFlex } from '@cherrystudio/ui'
import { Tooltip } from '@cherrystudio/ui'
import { usePreference } from '@data/hooks/usePreference'
import { useTheme } from '@renderer/context/ThemeProvider'
@@ -31,7 +30,7 @@ const TranslatePromptSettings = () => {
{localPrompt !== TRANSLATE_PROMPT && (
<Tooltip content={t('common.reset')}>
<ResetButton type="reset" onClick={onResetTranslatePrompt}>
<RedoOutlined size={16} />
<ResetIcon size={16} />
</ResetButton>
</Tooltip>
)}
@@ -48,6 +47,7 @@ const TranslatePromptSettings = () => {
)
}
// TODO: Should be migrated to consistent button component
const ResetButton = styled.button`
background-color: transparent;
border: none;
@@ -56,9 +56,12 @@ const ResetButton = styled.button`
padding: 0;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
&:hover {
background: var(--color-list-item);
background: color-mix(in srgb, var(--color-list-item) 95%, #000);
border-radius: 8px;
}
`

View File

@@ -1,7 +1,7 @@
import type { PayloadAction } from '@reduxjs/toolkit'
import { createSlice } from '@reduxjs/toolkit'
import { isLocalAi } from '@renderer/config/env'
import { SYSTEM_MODELS } from '@renderer/config/models'
import { DEFAULT_MODEL_MAP } from '@renderer/config/models'
import { SYSTEM_PROVIDERS } from '@renderer/config/providers'
import type { Model, Provider } from '@renderer/types'
import { uniqBy } from 'lodash'
@@ -43,10 +43,10 @@ export interface LlmState {
}
export const initialState: LlmState = {
defaultModel: SYSTEM_MODELS.defaultModel[0],
topicNamingModel: SYSTEM_MODELS.defaultModel[1],
quickModel: SYSTEM_MODELS.defaultModel[1],
translateModel: SYSTEM_MODELS.defaultModel[2],
defaultModel: DEFAULT_MODEL_MAP.assistant,
topicNamingModel: DEFAULT_MODEL_MAP.quick,
quickModel: DEFAULT_MODEL_MAP.quick,
translateModel: DEFAULT_MODEL_MAP.translate,
quickAssistantId: '',
providers: SYSTEM_PROVIDERS,
settings: {

View File

@@ -6,6 +6,7 @@ import { nanoid } from '@reduxjs/toolkit'
import { DEFAULT_CONTEXTCOUNT, DEFAULT_TEMPERATURE, isMac } from '@renderer/config/constant'
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import {
DEFAULT_MODEL_MAP,
glm45FlashModel,
isFunctionCallingModel,
isNotSupportedTextDelta,
@@ -1667,7 +1668,7 @@ const migrateConfig = {
state.llm.translateModel.provider === 'silicon' &&
state.llm.translateModel.id === 'meta-llama/Llama-3.3-70B-Instruct'
) {
state.llm.translateModel = SYSTEM_MODELS.defaultModel[2]
state.llm.translateModel = DEFAULT_MODEL_MAP.translate
}
// add selection_assistant_toggle and selection_assistant_select_text shortcuts after mini_window