fix(health): surface ollama endpoint diagnosis
This commit is contained in:
@@ -16,11 +16,18 @@ interface ModelInfo {
|
||||
role: 'primary' | 'backup' | 'local' | 'agent' | 'provider'
|
||||
status: 'up' | 'down' | 'degraded' | 'unknown'
|
||||
latencyMs?: number | null
|
||||
diagnosisCode?: string | null
|
||||
retryAfterSeconds?: number | null
|
||||
isCooldown?: boolean
|
||||
}
|
||||
|
||||
interface HealthComponent {
|
||||
status?: 'up' | 'down' | 'degraded'
|
||||
latency_ms?: number | null
|
||||
diagnosis_code?: string | null
|
||||
retry_after_seconds?: number | null
|
||||
is_cooldown?: boolean
|
||||
error?: string | null
|
||||
}
|
||||
|
||||
interface HealthResponse {
|
||||
@@ -49,6 +56,31 @@ function statusColor(status: ModelInfo['status']) {
|
||||
return '#87867f'
|
||||
}
|
||||
|
||||
function modelDetail(model: ModelInfo, t: ReturnType<typeof useTranslations>) {
|
||||
if (typeof model.latencyMs === 'number' && model.status === 'up') {
|
||||
return `${Math.round(model.latencyMs)}ms`
|
||||
}
|
||||
if (model.isCooldown) {
|
||||
const seconds = Math.max(0, Math.round(model.retryAfterSeconds ?? 0))
|
||||
return seconds > 0
|
||||
? t('aiModelHealth.cooldownSeconds', { seconds })
|
||||
: t('aiModelHealth.cooldown')
|
||||
}
|
||||
if (model.diagnosisCode === 'local_proxy_upstream_unreachable') {
|
||||
return t('aiModelHealth.localProxy')
|
||||
}
|
||||
if (model.diagnosisCode === 'endpoint_timeout') {
|
||||
return t('aiModelHealth.timeout')
|
||||
}
|
||||
if (model.diagnosisCode === 'endpoint_network_unreachable') {
|
||||
return t('aiModelHealth.network')
|
||||
}
|
||||
if (model.diagnosisCode === 'endpoint_connection_refused') {
|
||||
return t('aiModelHealth.refused')
|
||||
}
|
||||
return t(`aiModelRoles.${model.role}` as never)
|
||||
}
|
||||
|
||||
export function AIModelStatus() {
|
||||
const t = useTranslations('dashboard')
|
||||
const [models, setModels] = useState<ModelInfo[]>([
|
||||
@@ -72,6 +104,9 @@ export function AIModelStatus() {
|
||||
role: PROVIDER_ROLES[key] ?? 'provider',
|
||||
status: d.components?.[key]?.status ?? 'unknown',
|
||||
latencyMs: d.components?.[key]?.latency_ms,
|
||||
diagnosisCode: d.components?.[key]?.diagnosis_code,
|
||||
retryAfterSeconds: d.components?.[key]?.retry_after_seconds,
|
||||
isCooldown: d.components?.[key]?.is_cooldown,
|
||||
})))
|
||||
})
|
||||
.catch(() => {})
|
||||
@@ -98,9 +133,7 @@ export function AIModelStatus() {
|
||||
<span style={{ width: 5, height: 5, borderRadius: '50%', background: statusColor(m.status), flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 12, fontWeight: 500, color: '#141413' }}>{m.name}</span>
|
||||
<span style={{ fontSize: 10, color: '#87867f', marginLeft: 'auto' }}>
|
||||
{typeof m.latencyMs === 'number'
|
||||
? `${Math.round(m.latencyMs)}ms`
|
||||
: t(`aiModelRoles.${m.role}` as never)}
|
||||
{modelDetail(m, t)}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user