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:
one 2025-05-11 13:32:47 +08:00 committed by GitHub
parent 1fd1173fd1
commit 299df2aa6e
10 changed files with 69 additions and 33 deletions

View File

@ -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:",

View File

@ -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キーを選択",

View File

@ -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": "Визуализация"
}
}
}
}

View File

@ -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": "可视化"
}
}
}
}

View File

@ -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密鑰",

View File

@ -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':

View File

@ -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)

View File

@ -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)
}

View File

@ -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
})
}

View File

@ -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 })
)