mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 18:50:56 +08:00
refactor(checkAPI): check api or model with stream enabled first (#5857)
* refactor(checkAPI): check api or model with stream enabled first * refactor: improve healthcheck summary * refactor: remove cursor style from status indicator * fix: update apikey input box after deleting invalid keys
This commit is contained in:
parent
1fd1173fd1
commit
299df2aa6e
@ -1397,7 +1397,10 @@
|
||||
"models.check.enabled": "Enabled",
|
||||
"models.check.failed": "Failed",
|
||||
"models.check.keys_status_count": "Passed: {{count_passed}} keys, failed: {{count_failed}} keys",
|
||||
"models.check.model_status_summary": "{{provider}}: {{count_passed}} models passed health checks ({{count_partial}} models had inaccessible keys), {{count_failed}} models completely inaccessible.",
|
||||
"models.check.model_status_failed": "{{count}} models completely inaccessible",
|
||||
"models.check.model_status_partial": "{{count}} models had inaccessible keys",
|
||||
"models.check.model_status_passed": "{{count}} models passed health checks",
|
||||
"models.check.model_status_summary": "{{provider}}: {{summary}}",
|
||||
"models.check.no_api_keys": "No API keys found, please add API keys first.",
|
||||
"models.check.passed": "Passed",
|
||||
"models.check.select_api_key": "Select the API key to use:",
|
||||
|
||||
@ -1395,7 +1395,10 @@
|
||||
"models.check.enabled": "開く",
|
||||
"models.check.failed": "失敗",
|
||||
"models.check.keys_status_count": "合格:{{count_passed}}個のキー、不合格:{{count_failed}}個のキー",
|
||||
"models.check.model_status_summary": "{{provider}}: {{count_passed}} 個のモデルが健康チェックを完了しました({{count_partial}} 個のモデルは一部のキーにアクセスできませんでした)、{{count_failed}} 個のモデルは完全にアクセスできませんでした。",
|
||||
"models.check.model_status_failed": "{{count}} 個のモデルが完全にアクセスできません",
|
||||
"models.check.model_status_partial": "{{count}} 個のモデルが一部のキーでアクセスできません",
|
||||
"models.check.model_status_passed": "{{count}} 個のモデルが健康チェックを通過しました",
|
||||
"models.check.model_status_summary": "{{provider}}: {{summary}}",
|
||||
"models.check.no_api_keys": "APIキーが見つかりません。まずAPIキーを追加してください。",
|
||||
"models.check.passed": "成功",
|
||||
"models.check.select_api_key": "使用するAPIキーを選択:",
|
||||
|
||||
@ -1395,7 +1395,10 @@
|
||||
"models.check.enabled": "Включено",
|
||||
"models.check.failed": "Не прошло",
|
||||
"models.check.keys_status_count": "Прошло: {{count_passed}} ключей, Не прошло: {{count_failed}} ключей",
|
||||
"models.check.model_status_summary": "{{provider}}: {{count_passed}} моделей прошли проверку состояния (из них {{count_partial}} моделей недоступны с некоторыми ключами), {{count_failed}} моделей полностью недоступны.",
|
||||
"models.check.model_status_failed": "{{count}} моделей полностью недоступны",
|
||||
"models.check.model_status_partial": "{{count}} моделей недоступны с некоторыми ключами",
|
||||
"models.check.model_status_passed": "{{count}} моделей прошли проверку состояния",
|
||||
"models.check.model_status_summary": "{{provider}}: {{summary}}",
|
||||
"models.check.no_api_keys": "API ключи не найдены, пожалуйста, добавьте API ключи.",
|
||||
"models.check.passed": "Прошло",
|
||||
"models.check.select_api_key": "Выберите API ключ для использования:",
|
||||
@ -1657,4 +1660,4 @@
|
||||
"visualization": "Визуализация"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1397,7 +1397,10 @@
|
||||
"models.check.enabled": "开启",
|
||||
"models.check.failed": "失败",
|
||||
"models.check.keys_status_count": "通过:{{count_passed}}个密钥,失败:{{count_failed}}个密钥",
|
||||
"models.check.model_status_summary": "{{provider}}: {{count_passed}} 个模型完成健康检测(其中 {{count_partial}} 个模型用某些密钥无法访问),{{count_failed}} 个模型完全无法访问。",
|
||||
"models.check.model_status_failed": "{{count}} 个模型完全无法访问",
|
||||
"models.check.model_status_partial": "其中 {{count}} 个模型用某些密钥无法访问",
|
||||
"models.check.model_status_passed": "{{count}} 个模型通过健康检测",
|
||||
"models.check.model_status_summary": "{{provider}}: {{summary}}",
|
||||
"models.check.no_api_keys": "未找到API密钥,请先添加API密钥。",
|
||||
"models.check.passed": "通过",
|
||||
"models.check.select_api_key": "选择要使用的API密钥:",
|
||||
@ -1657,4 +1660,4 @@
|
||||
"visualization": "可视化"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1396,7 +1396,10 @@
|
||||
"models.check.enabled": "開啟",
|
||||
"models.check.failed": "失敗",
|
||||
"models.check.keys_status_count": "通過:{{count_passed}}個密鑰,失敗:{{count_failed}}個密鑰",
|
||||
"models.check.model_status_summary": "{{provider}}: {{count_passed}} 個模型完成健康檢查(其中 {{count_partial}} 個模型用某些密鑰無法訪問),{{count_failed}} 個模型完全無法訪問。",
|
||||
"models.check.model_status_failed": "{{count}} 個模型完全無法訪問",
|
||||
"models.check.model_status_partial": "其中 {{count}} 個模型用某些密鑰無法訪問",
|
||||
"models.check.model_status_passed": "{{count}} 個模型通過健康檢查",
|
||||
"models.check.model_status_summary": "{{provider}}: {{summary}}",
|
||||
"models.check.no_api_keys": "未找到API密鑰,請先添加API密鑰。",
|
||||
"models.check.passed": "通過",
|
||||
"models.check.select_api_key": "選擇要使用的API密鑰:",
|
||||
|
||||
@ -408,7 +408,6 @@ const StatusIndicator = styled.div<{ type: string }>`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: ${(props) => {
|
||||
switch (props.type) {
|
||||
case 'success':
|
||||
|
||||
@ -8,7 +8,7 @@ import { useAllProviders, useProvider, useProviders } from '@renderer/hooks/useP
|
||||
import i18n from '@renderer/i18n'
|
||||
import { isOpenAIProvider } from '@renderer/providers/AiProvider/ProviderFactory'
|
||||
import { checkApi, formatApiKeys } from '@renderer/services/ApiService'
|
||||
import { checkModelsHealth, ModelCheckStatus } from '@renderer/services/HealthCheckService'
|
||||
import { checkModelsHealth, getModelCheckSummary } from '@renderer/services/HealthCheckService'
|
||||
import { isProviderSupportAuth } from '@renderer/services/ProviderService'
|
||||
import { Provider } from '@renderer/types'
|
||||
import { formatApiHost } from '@renderer/utils/api'
|
||||
@ -177,22 +177,11 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
||||
}
|
||||
)
|
||||
|
||||
// Show summary of results after checking
|
||||
const failedModels = checkResults.filter((result) => result.status === ModelCheckStatus.FAILED)
|
||||
const partialModels = checkResults.filter((result) => result.status === ModelCheckStatus.PARTIAL)
|
||||
const successModels = checkResults.filter((result) => result.status === ModelCheckStatus.SUCCESS)
|
||||
|
||||
// Display statistics of all model check results
|
||||
window.message.info({
|
||||
key: 'health-check-summary',
|
||||
style: { marginTop: '3vh' },
|
||||
duration: 10,
|
||||
content: t('settings.models.check.model_status_summary', {
|
||||
provider: provider.name,
|
||||
count_passed: successModels.length + partialModels.length,
|
||||
count_partial: partialModels.length,
|
||||
count_failed: failedModels.length
|
||||
})
|
||||
duration: 5,
|
||||
content: getModelCheckSummary(checkResults, provider.name)
|
||||
})
|
||||
|
||||
// Reset health check status
|
||||
@ -235,8 +224,10 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
||||
})
|
||||
|
||||
if (result?.validKeys) {
|
||||
setApiKey(result.validKeys.join(','))
|
||||
updateProvider({ ...provider, apiKey: result.validKeys.join(',') })
|
||||
const newApiKey = result.validKeys.join(',')
|
||||
setInputValue(newApiKey)
|
||||
setApiKey(newApiKey)
|
||||
updateProvider({ ...provider, apiKey: newApiKey })
|
||||
}
|
||||
} else {
|
||||
setApiChecking(true)
|
||||
|
||||
@ -477,12 +477,13 @@ export async function checkApi(provider: Provider, model: Model) {
|
||||
}
|
||||
}
|
||||
|
||||
const AI = new AiProvider(provider)
|
||||
const ai = new AiProvider(provider)
|
||||
|
||||
const { valid, error } = await AI.check(model)
|
||||
|
||||
return {
|
||||
valid,
|
||||
error
|
||||
// Try streaming check first
|
||||
const result = await ai.check(model, true)
|
||||
if (result.valid && !result.error) {
|
||||
return result
|
||||
}
|
||||
|
||||
return ai.check(model, false)
|
||||
}
|
||||
|
||||
@ -217,3 +217,33 @@ export async function checkModelsHealth(
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
export function getModelCheckSummary(results: ModelCheckResult[], providerName?: string): string {
|
||||
const t = i18n.t
|
||||
|
||||
// Show summary of results after checking
|
||||
const failedModels = results.filter((result) => result.status === ModelCheckStatus.FAILED)
|
||||
const partialModels = results.filter((result) => result.status === ModelCheckStatus.PARTIAL)
|
||||
const successModels = results.filter((result) => result.status === ModelCheckStatus.SUCCESS)
|
||||
|
||||
// Display statistics of all model check results
|
||||
const summaryParts: string[] = []
|
||||
|
||||
if (failedModels.length > 0) {
|
||||
summaryParts.push(t('settings.models.check.model_status_failed', { count: failedModels.length }))
|
||||
}
|
||||
if (successModels.length + partialModels.length > 0) {
|
||||
summaryParts.push(
|
||||
t('settings.models.check.model_status_passed', { count: successModels.length + partialModels.length })
|
||||
)
|
||||
}
|
||||
if (partialModels.length > 0) {
|
||||
summaryParts.push(t('settings.models.check.model_status_partial', { count: partialModels.length }))
|
||||
}
|
||||
|
||||
const summary = summaryParts.join(', ')
|
||||
return t('settings.models.check.model_status_summary', {
|
||||
provider: providerName ?? 'Unknown Provider',
|
||||
summary
|
||||
})
|
||||
}
|
||||
|
||||
@ -83,12 +83,12 @@ export async function checkModel(provider: Provider, model: Model) {
|
||||
provider,
|
||||
model,
|
||||
async (ai, model) => {
|
||||
const result = await ai.check(model, false)
|
||||
// Try streaming check first
|
||||
const result = await ai.check(model, true)
|
||||
if (result.valid && !result.error) {
|
||||
return result
|
||||
}
|
||||
// Try streaming check
|
||||
return ai.check(model, true)
|
||||
return ai.check(model, false)
|
||||
},
|
||||
({ valid, error }) => ({ valid, error: error || null })
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user