mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +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.enabled": "Enabled",
|
||||||
"models.check.failed": "Failed",
|
"models.check.failed": "Failed",
|
||||||
"models.check.keys_status_count": "Passed: {{count_passed}} keys, failed: {{count_failed}} keys",
|
"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.no_api_keys": "No API keys found, please add API keys first.",
|
||||||
"models.check.passed": "Passed",
|
"models.check.passed": "Passed",
|
||||||
"models.check.select_api_key": "Select the API key to use:",
|
"models.check.select_api_key": "Select the API key to use:",
|
||||||
|
|||||||
@ -1395,7 +1395,10 @@
|
|||||||
"models.check.enabled": "開く",
|
"models.check.enabled": "開く",
|
||||||
"models.check.failed": "失敗",
|
"models.check.failed": "失敗",
|
||||||
"models.check.keys_status_count": "合格:{{count_passed}}個のキー、不合格:{{count_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.no_api_keys": "APIキーが見つかりません。まずAPIキーを追加してください。",
|
||||||
"models.check.passed": "成功",
|
"models.check.passed": "成功",
|
||||||
"models.check.select_api_key": "使用するAPIキーを選択:",
|
"models.check.select_api_key": "使用するAPIキーを選択:",
|
||||||
|
|||||||
@ -1395,7 +1395,10 @@
|
|||||||
"models.check.enabled": "Включено",
|
"models.check.enabled": "Включено",
|
||||||
"models.check.failed": "Не прошло",
|
"models.check.failed": "Не прошло",
|
||||||
"models.check.keys_status_count": "Прошло: {{count_passed}} ключей, Не прошло: {{count_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.no_api_keys": "API ключи не найдены, пожалуйста, добавьте API ключи.",
|
||||||
"models.check.passed": "Прошло",
|
"models.check.passed": "Прошло",
|
||||||
"models.check.select_api_key": "Выберите API ключ для использования:",
|
"models.check.select_api_key": "Выберите API ключ для использования:",
|
||||||
@ -1657,4 +1660,4 @@
|
|||||||
"visualization": "Визуализация"
|
"visualization": "Визуализация"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1397,7 +1397,10 @@
|
|||||||
"models.check.enabled": "开启",
|
"models.check.enabled": "开启",
|
||||||
"models.check.failed": "失败",
|
"models.check.failed": "失败",
|
||||||
"models.check.keys_status_count": "通过:{{count_passed}}个密钥,失败:{{count_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.no_api_keys": "未找到API密钥,请先添加API密钥。",
|
||||||
"models.check.passed": "通过",
|
"models.check.passed": "通过",
|
||||||
"models.check.select_api_key": "选择要使用的API密钥:",
|
"models.check.select_api_key": "选择要使用的API密钥:",
|
||||||
@ -1657,4 +1660,4 @@
|
|||||||
"visualization": "可视化"
|
"visualization": "可视化"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1396,7 +1396,10 @@
|
|||||||
"models.check.enabled": "開啟",
|
"models.check.enabled": "開啟",
|
||||||
"models.check.failed": "失敗",
|
"models.check.failed": "失敗",
|
||||||
"models.check.keys_status_count": "通過:{{count_passed}}個密鑰,失敗:{{count_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.no_api_keys": "未找到API密鑰,請先添加API密鑰。",
|
||||||
"models.check.passed": "通過",
|
"models.check.passed": "通過",
|
||||||
"models.check.select_api_key": "選擇要使用的API密鑰:",
|
"models.check.select_api_key": "選擇要使用的API密鑰:",
|
||||||
|
|||||||
@ -408,7 +408,6 @@ const StatusIndicator = styled.div<{ type: string }>`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
|
||||||
color: ${(props) => {
|
color: ${(props) => {
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case 'success':
|
case 'success':
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { useAllProviders, useProvider, useProviders } from '@renderer/hooks/useP
|
|||||||
import i18n from '@renderer/i18n'
|
import i18n from '@renderer/i18n'
|
||||||
import { isOpenAIProvider } from '@renderer/providers/AiProvider/ProviderFactory'
|
import { isOpenAIProvider } from '@renderer/providers/AiProvider/ProviderFactory'
|
||||||
import { checkApi, formatApiKeys } from '@renderer/services/ApiService'
|
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 { isProviderSupportAuth } from '@renderer/services/ProviderService'
|
||||||
import { Provider } from '@renderer/types'
|
import { Provider } from '@renderer/types'
|
||||||
import { formatApiHost } from '@renderer/utils/api'
|
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({
|
window.message.info({
|
||||||
key: 'health-check-summary',
|
key: 'health-check-summary',
|
||||||
style: { marginTop: '3vh' },
|
style: { marginTop: '3vh' },
|
||||||
duration: 10,
|
duration: 5,
|
||||||
content: t('settings.models.check.model_status_summary', {
|
content: getModelCheckSummary(checkResults, provider.name)
|
||||||
provider: provider.name,
|
|
||||||
count_passed: successModels.length + partialModels.length,
|
|
||||||
count_partial: partialModels.length,
|
|
||||||
count_failed: failedModels.length
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Reset health check status
|
// Reset health check status
|
||||||
@ -235,8 +224,10 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (result?.validKeys) {
|
if (result?.validKeys) {
|
||||||
setApiKey(result.validKeys.join(','))
|
const newApiKey = result.validKeys.join(',')
|
||||||
updateProvider({ ...provider, apiKey: result.validKeys.join(',') })
|
setInputValue(newApiKey)
|
||||||
|
setApiKey(newApiKey)
|
||||||
|
updateProvider({ ...provider, apiKey: newApiKey })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setApiChecking(true)
|
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)
|
// Try streaming check first
|
||||||
|
const result = await ai.check(model, true)
|
||||||
return {
|
if (result.valid && !result.error) {
|
||||||
valid,
|
return result
|
||||||
error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ai.check(model, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -217,3 +217,33 @@ export async function checkModelsHealth(
|
|||||||
|
|
||||||
return results
|
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,
|
provider,
|
||||||
model,
|
model,
|
||||||
async (ai, 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) {
|
if (result.valid && !result.error) {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
// Try streaming check
|
return ai.check(model, false)
|
||||||
return ai.check(model, true)
|
|
||||||
},
|
},
|
||||||
({ valid, error }) => ({ valid, error: error || null })
|
({ valid, error }) => ({ valid, error: error || null })
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user