diff --git a/src/renderer/src/components/Popups/SelectModelPopup.tsx b/src/renderer/src/components/Popups/SelectModelPopup.tsx index b932c976c9..714fe27633 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup.tsx @@ -7,7 +7,7 @@ import { useProviders } from '@renderer/hooks/useProvider' import { getModelUniqId } from '@renderer/services/ModelService' import { Model } from '@renderer/types' import { Avatar, Divider, Empty, Input, InputRef, Menu, MenuProps, Modal } from 'antd' -import { first, reverse, sortBy } from 'lodash' +import { first, sortBy } from 'lodash' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -47,7 +47,7 @@ const PopupContainer: React.FC = ({ model, resolve }) => { await db.settings.put({ id: 'pinned:models', value: validPinnedModels }) } - setPinnedModels(validPinnedModels) + setPinnedModels(sortBy(validPinnedModels, ['group', 'name'])) } loadPinnedModels() }, [providers]) @@ -58,13 +58,13 @@ const PopupContainer: React.FC = ({ model, resolve }) => { : [...pinnedModels, modelId] await db.settings.put({ id: 'pinned:models', value: newPinnedModels }) - setPinnedModels(newPinnedModels) + setPinnedModels(sortBy(newPinnedModels, ['group', 'name'])) } const filteredItems: MenuItem[] = providers .filter((p) => p.models && p.models.length > 0) .map((p) => { - const filteredModels = reverse(sortBy(p.models, 'name')) + const filteredModels = sortBy(p.models, ['group', 'name']) .filter((m) => [m.name + m.provider + t('provider.' + p.id)].join('').toLowerCase().includes(searchText.toLowerCase()) ) diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 0ae184dfca..e31450efbb 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -26,7 +26,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 46, + version: 47, blacklist: ['runtime'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 0f0e9bf18a..c4740bcc99 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -3,7 +3,7 @@ import { TRANSLATE_PROMPT } from '@renderer/config/prompts' import db from '@renderer/databases' import i18n from '@renderer/i18n' import { Assistant } from '@renderer/types' -import { runAsyncFunction, uuid } from '@renderer/utils' +import { getDefaultGroupName, runAsyncFunction, uuid } from '@renderer/utils' import { isEmpty } from 'lodash' import { createMigrate } from 'redux-persist' @@ -718,6 +718,14 @@ const migrateConfig = { state.settings.translateModelPrompt = TRANSLATE_PROMPT } return state + }, + '47': (state: RootState) => { + state.llm.providers.forEach((provider) => { + provider.models.forEach((model) => { + model.group = getDefaultGroupName(model.id) + }) + }) + return state } } diff --git a/src/renderer/src/utils/index.ts b/src/renderer/src/utils/index.ts index 91209fb987..54a7d7d960 100644 --- a/src/renderer/src/utils/index.ts +++ b/src/renderer/src/utils/index.ts @@ -75,13 +75,17 @@ export const compressImage = async (file: File) => { // Converts 'gpt-3.5-turbo-16k-0613' to 'GPT-3.5-Turbo' // Converts 'qwen2:1.5b' to 'QWEN2' export const getDefaultGroupName = (id: string) => { + if (id.includes('/')) { + return id.split('/')[0] + } + if (id.includes(':')) { - return id.split(':')[0].toUpperCase() + return id.split(':')[0] } if (id.includes('-')) { const parts = id.split('-') - return parts[0].toUpperCase() + '-' + parts[1].toUpperCase() + return parts[0] + '-' + parts[1] } return id