feat: a button to add a whole group of models (#2736)

* feat: a button a add a whole group of models

* feat: search as typing in EditModelsPopup

* feat: add a button to remove a whole group of models

* feat: add remove button for model group in the model list
This commit is contained in:
one 2025-03-06 23:04:10 +08:00 committed by GitHub
parent 94e0559dd3
commit 3ba16118b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 55 additions and 5 deletions

View File

@ -752,6 +752,8 @@
"models.add.model_id.tooltip": "Example: gpt-3.5-turbo", "models.add.model_id.tooltip": "Example: gpt-3.5-turbo",
"models.add.model_name": "Model Name", "models.add.model_name": "Model Name",
"models.add.model_name.placeholder": "Optional e.g. GPT-4", "models.add.model_name.placeholder": "Optional e.g. GPT-4",
"models.manage.add_whole_group": "Add the whole group",
"models.manage.remove_whole_group": "Remove the whole group",
"models.default_assistant_model": "Default Assistant Model", "models.default_assistant_model": "Default Assistant Model",
"models.default_assistant_model_description": "Model used when creating a new assistant, if the assistant is not set, this model will be used", "models.default_assistant_model_description": "Model used when creating a new assistant, if the assistant is not set, this model will be used",
"models.empty": "No models found", "models.empty": "No models found",

View File

@ -752,6 +752,8 @@
"models.add.model_id.tooltip": "例gpt-3.5-turbo", "models.add.model_id.tooltip": "例gpt-3.5-turbo",
"models.add.model_name": "モデル名", "models.add.model_name": "モデル名",
"models.add.model_name.placeholder": "例GPT-3.5", "models.add.model_name.placeholder": "例GPT-3.5",
"models.manage.add_whole_group": "グループ全体を追加",
"models.manage.remove_whole_group": "グループ全体を削除",
"models.default_assistant_model": "デフォルトアシスタントモデル", "models.default_assistant_model": "デフォルトアシスタントモデル",
"models.default_assistant_model_description": "新しいアシスタントを作成する際に使用されるモデル。アシスタントがモデルを設定していない場合、このモデルが使用されます", "models.default_assistant_model_description": "新しいアシスタントを作成する際に使用されるモデル。アシスタントがモデルを設定していない場合、このモデルが使用されます",
"models.empty": "モデルが見つかりません", "models.empty": "モデルが見つかりません",

View File

@ -752,6 +752,8 @@
"models.add.model_id.tooltip": "Пример: gpt-3.5-turbo", "models.add.model_id.tooltip": "Пример: gpt-3.5-turbo",
"models.add.model_name": "Имя модели", "models.add.model_name": "Имя модели",
"models.add.model_name.placeholder": "Необязательно, например, GPT-4", "models.add.model_name.placeholder": "Необязательно, например, GPT-4",
"models.manage.add_whole_group": "Добавить всю группу",
"models.manage.remove_whole_group": "Удалить всю группу",
"models.default_assistant_model": "Модель ассистента по умолчанию", "models.default_assistant_model": "Модель ассистента по умолчанию",
"models.default_assistant_model_description": "Модель, используемая при создании нового ассистента, если ассистент не имеет настроенной модели, будет использоваться эта модель", "models.default_assistant_model_description": "Модель, используемая при создании нового ассистента, если ассистент не имеет настроенной модели, будет использоваться эта модель",
"models.empty": "Модели не найдены", "models.empty": "Модели не найдены",

View File

@ -752,6 +752,8 @@
"models.add.model_id.tooltip": "例如 gpt-3.5-turbo", "models.add.model_id.tooltip": "例如 gpt-3.5-turbo",
"models.add.model_name": "模型名称", "models.add.model_name": "模型名称",
"models.add.model_name.placeholder": "例如 GPT-3.5", "models.add.model_name.placeholder": "例如 GPT-3.5",
"models.manage.add_whole_group": "添加整个分组",
"models.manage.remove_whole_group": "移除整个分组",
"models.default_assistant_model": "默认助手模型", "models.default_assistant_model": "默认助手模型",
"models.default_assistant_model_description": "创建新助手时使用的模型,如果助手未设置模型,则使用此模型", "models.default_assistant_model_description": "创建新助手时使用的模型,如果助手未设置模型,则使用此模型",
"models.empty": "没有模型", "models.empty": "没有模型",

View File

@ -751,6 +751,8 @@
"models.add.model_id.tooltip": "例如 gpt-3.5-turbo", "models.add.model_id.tooltip": "例如 gpt-3.5-turbo",
"models.add.model_name": "模型名稱", "models.add.model_name": "模型名稱",
"models.add.model_name.placeholder": "可選,例如 GPT-4", "models.add.model_name.placeholder": "可選,例如 GPT-4",
"models.manage.add_whole_group": "添加整個分組",
"models.manage.remove_whole_group": "移除整個分組",
"models.default_assistant_model": "預設助手模型", "models.default_assistant_model": "預設助手模型",
"models.default_assistant_model_description": "建立新助手時使用的模型,如果助手未設定模型,則使用此模型", "models.default_assistant_model_description": "建立新助手時使用的模型,如果助手未設定模型,則使用此模型",
"models.empty": "找不到模型", "models.empty": "找不到模型",

View File

@ -30,6 +30,11 @@ interface Props extends ShowParams {
resolve: (data: any) => void resolve: (data: any) => void
} }
// Check if the model exists in the provider's model list
const isModelInProvider = (provider: Provider, modelId: string): boolean => {
return provider.models.some((m) => m.id === modelId)
}
const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => { const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
const [open, setOpen] = useState(true) const [open, setOpen] = useState(true)
const { provider, models, addModel, removeModel } = useProvider(_provider.id) const { provider, models, addModel, removeModel } = useProvider(_provider.id)
@ -156,14 +161,38 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
<Radio.Button value="embedding">{t('models.embedding')}</Radio.Button> <Radio.Button value="embedding">{t('models.embedding')}</Radio.Button>
</Radio.Group> </Radio.Group>
</Center> </Center>
<Search placeholder={t('settings.provider.search_placeholder')} allowClear onSearch={setSearchText} /> <Search
placeholder={t('settings.provider.search_placeholder')}
allowClear
onChange={(e) => setSearchText(e.target.value)}
onSearch={setSearchText}
/>
</SearchContainer> </SearchContainer>
<ListContainer> <ListContainer>
{Object.keys(modelGroups).map((group) => ( {Object.keys(modelGroups).map((group) => (
<div key={group}> <div key={group}>
<ListHeader key={group}>{group}</ListHeader> <ListHeader key={group}>
{group}
<div>
<Button
type="text"
icon={<PlusOutlined />}
title={t(`settings.models.manage.add_whole_group`)}
onClick={() => {
modelGroups[group].filter((model) => !isModelInProvider(provider, model.id)).forEach(onAddModel)
}}
/>
<Button
type="text"
icon={<MinusOutlined />}
title={t(`settings.models.manage.remove_whole_group`)}
onClick={() => {
modelGroups[group].filter((model) => isModelInProvider(provider, model.id)).forEach(onRemoveModel)
}}
/>
</div>
</ListHeader>
{modelGroups[group].map((model) => { {modelGroups[group].map((model) => {
const hasModel = provider.models.find((m) => m.id === model.id)
return ( return (
<ListItem key={model.id}> <ListItem key={model.id}>
<ListItemHeader> <ListItemHeader>
@ -186,7 +215,7 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
)} )}
</ListItemName> </ListItemName>
</ListItemHeader> </ListItemHeader>
{hasModel ? ( {isModelInProvider(provider, model.id) ? (
<Button type="default" onClick={() => onRemoveModel(model)} icon={<MinusOutlined />} /> <Button type="default" onClick={() => onRemoveModel(model)} icon={<MinusOutlined />} />
) : ( ) : (
<Button type="primary" onClick={() => onAddModel(model)} icon={<PlusOutlined />} /> <Button type="primary" onClick={() => onAddModel(model)} icon={<PlusOutlined />} />

View File

@ -24,7 +24,7 @@ import { setModel } from '@renderer/store/assistants'
import { Model, Provider } from '@renderer/types' import { Model, Provider } from '@renderer/types'
import { formatApiHost } from '@renderer/utils/api' import { formatApiHost } from '@renderer/utils/api'
import { providerCharge } from '@renderer/utils/oauth' import { providerCharge } from '@renderer/utils/oauth'
import { Avatar, Button, Card, Divider, Flex, Input, Space, Switch } from 'antd' import { Avatar, Button, Card, Divider, Flex, Input, Space, Switch, Tooltip } from 'antd'
import Link from 'antd/es/typography/Link' import Link from 'antd/es/typography/Link'
import { groupBy, isEmpty, sortBy, toPairs } from 'lodash' import { groupBy, isEmpty, sortBy, toPairs } from 'lodash'
import { FC, useEffect, useState } from 'react' import { FC, useEffect, useState } from 'react'
@ -315,6 +315,17 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
key={group} key={group}
type="inner" type="inner"
title={group} title={group}
extra={
<Tooltip title={t('settings.models.manage.remove_whole_group')}>
<RemoveIcon
onClick={() =>
modelGroups[group]
.filter((model) => provider.models.some((m) => m.id === model.id))
.forEach((model) => removeModel(model))
}
/>
</Tooltip>
}
style={{ marginBottom: '10px', border: '0.5px solid var(--color-border)' }} style={{ marginBottom: '10px', border: '0.5px solid var(--color-border)' }}
size="small"> size="small">
{sortedModelGroups[group].map((model) => ( {sortedModelGroups[group].map((model) => (