From 2ad6a1f24c4180c571e478f90777749b14fdee83 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Mon, 13 Jan 2025 16:11:09 +0800 Subject: [PATCH] feat: check api use selected model --- src/renderer/src/i18n/locales/en-us.json | 1 + src/renderer/src/i18n/locales/ja-jp.json | 1 + src/renderer/src/i18n/locales/ru-ru.json | 1 + src/renderer/src/i18n/locales/zh-cn.json | 1 + src/renderer/src/i18n/locales/zh-tw.json | 1 + .../ProviderSettings/ApiCheckPopup.tsx | 9 +- .../ProviderSettings/ProviderSetting.tsx | 13 ++- .../SelectProviderModelPopup.tsx | 90 +++++++++++++++++++ src/renderer/src/providers/AiProvider.ts | 4 +- .../src/providers/AnthropicProvider.ts | 9 +- src/renderer/src/providers/BaseProvider.ts | 2 +- src/renderer/src/providers/GeminiProvider.ts | 8 +- src/renderer/src/providers/OpenAIProvider.ts | 8 +- src/renderer/src/services/ApiService.ts | 6 +- 14 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 src/renderer/src/pages/settings/ProviderSettings/SelectProviderModelPopup.tsx diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index aeedcb1a..f8ce637e 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -231,6 +231,7 @@ "message": { "api.connection.failed": "Connection failed", "api.connection.success": "Connection successful", + "api.check.model.title": "Select the model to use for detection", "assistant.added.content": "Assistant added successfully", "backup.failed": "Backup failed", "backup.success": "Backup successful", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index f8ba5a2c..4870b265 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -231,6 +231,7 @@ "message": { "api.connection.failed": "接続に失敗しました", "api.connection.success": "接続に成功しました", + "api.check.model.title": "検出に使用するモデルを選択してください", "assistant.added.content": "アシスタントが追加されました", "backup.failed": "バックアップに失敗しました", "backup.success": "バックアップに成功しました", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index e144ef30..2c39e3f7 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -231,6 +231,7 @@ "message": { "api.connection.failed": "Соединение не удалось", "api.connection.success": "Соединение успешно", + "api.check.model.title": "Выберите модель для проверки", "assistant.added.content": "Ассистент успешно добавлен", "backup.failed": "Создание резервной копии не удалось", "backup.success": "Резервная копия успешно создана", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index c841ab36..af56a32e 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -232,6 +232,7 @@ "message": { "api.connection.failed": "连接失败", "api.connection.success": "连接成功", + "api.check.model.title": "请选择要检测的模型", "assistant.added.content": "智能体添加成功", "backup.failed": "备份失败", "backup.success": "备份成功", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index e72c36e9..f18260f2 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -231,6 +231,7 @@ "message": { "api.connection.failed": "連接失敗", "api.connection.success": "連接成功", + "api.check.model.title": "請選擇要檢測的模型", "assistant.added.content": "智能體添加成功", "backup.failed": "備份失敗", "backup.success": "備份成功", diff --git a/src/renderer/src/pages/settings/ProviderSettings/ApiCheckPopup.tsx b/src/renderer/src/pages/settings/ProviderSettings/ApiCheckPopup.tsx index 67d54c37..910acce2 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ApiCheckPopup.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ApiCheckPopup.tsx @@ -2,13 +2,16 @@ import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from '@ant-desi import Scrollbar from '@renderer/components/Scrollbar' import { TopView } from '@renderer/components/TopView' import { checkApi } from '@renderer/services/ApiService' +import { Model } from '@renderer/types' +import { Provider } from '@renderer/types' import { Button, List, Modal, Space, Spin, Typography } from 'antd' import { useState } from 'react' import { useTranslation } from 'react-i18next' interface ShowParams { title: string - provider: any + provider: Provider + model: Model apiKeys: string[] } @@ -22,7 +25,7 @@ interface KeyStatus { checking?: boolean } -const PopupContainer: React.FC = ({ title, provider, apiKeys, resolve }) => { +const PopupContainer: React.FC = ({ title, provider, model, apiKeys, resolve }) => { const [open, setOpen] = useState(true) const [keyStatuses, setKeyStatuses] = useState(() => { const uniqueKeys = new Set(apiKeys) @@ -39,7 +42,7 @@ const PopupContainer: React.FC = ({ title, provider, apiKeys, resolve }) for (let i = 0; i < newStatuses.length; i++) { setKeyStatuses((prev) => prev.map((status, idx) => (idx === i ? { ...status, checking: true } : status))) - const valid = await checkApi({ ...provider, apiKey: newStatuses[i].key }) + const valid = await checkApi({ ...provider, apiKey: newStatuses[i].key }, model) setKeyStatuses((prev) => prev.map((status, idx) => (idx === i ? { ...status, checking: false, isValid: valid } : status)) diff --git a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx index 68b95770..8aa90437 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx @@ -39,6 +39,7 @@ import ApiCheckPopup from './ApiCheckPopup' import EditModelsPopup from './EditModelsPopup' import GraphRAGSettings from './GraphRAGSettings' import OllamSettings from './OllamaSettings' +import SelectProviderModelPopup from './SelectProviderModelPopup' interface Props { provider: Provider @@ -83,14 +84,23 @@ const ProviderSetting: FC = ({ provider: _provider }) => { return } + const model = await SelectProviderModelPopup.show({ provider }) + + if (!model) { + window.message.error({ content: i18n.t('message.error.enter.model'), key: 'api-check' }) + return + } + if (apiKey.includes(',')) { const keys = apiKey .split(',') .map((k) => k.trim()) .filter((k) => k) + const result = await ApiCheckPopup.show({ title: t('settings.provider.check_multiple_keys'), provider: { ...provider, apiHost }, + model, apiKeys: keys }) @@ -100,7 +110,8 @@ const ProviderSetting: FC = ({ provider: _provider }) => { } } else { setApiChecking(true) - const valid = await checkApi({ ...provider, apiKey, apiHost }) + + const valid = await checkApi({ ...provider, apiKey, apiHost }, model) window.message[valid ? 'success' : 'error']({ key: 'api-check', style: { marginTop: '3vh' }, diff --git a/src/renderer/src/pages/settings/ProviderSettings/SelectProviderModelPopup.tsx b/src/renderer/src/pages/settings/ProviderSettings/SelectProviderModelPopup.tsx new file mode 100644 index 00000000..d46afbe4 --- /dev/null +++ b/src/renderer/src/pages/settings/ProviderSettings/SelectProviderModelPopup.tsx @@ -0,0 +1,90 @@ +import { TopView } from '@renderer/components/TopView' +import { isEmbeddingModel } from '@renderer/config/models' +import i18n from '@renderer/i18n' +import { Provider } from '@renderer/types' +import { Modal, Select } from 'antd' +import { last, orderBy } from 'lodash' +import { useState } from 'react' + +interface ShowParams { + provider: Provider +} + +interface Props extends ShowParams { + reject: (reason?: any) => void + resolve: (data: any) => void +} + +const PopupContainer: React.FC = ({ provider, resolve, reject }) => { + const models = orderBy(provider.models, 'group').filter((i) => !isEmbeddingModel(i)) + const [open, setOpen] = useState(true) + const [model, setModel] = useState(last(models)) + + const onOk = () => { + if (!model) { + window.message.error({ content: i18n.t('message.error.enter.model'), key: 'api-check' }) + return + } + setOpen(false) + resolve(model) + } + + const onCancel = () => { + setOpen(false) + setTimeout(reject, 300) + } + + const onClose = () => { + TopView.hide(TopViewKey) + } + + SelectProviderModelPopup.hide = onCancel + + return ( + +