diff --git a/lib/ai/runtime/model-health.ts b/lib/ai/runtime/model-health.ts index 6df4a9db4..6205c6a35 100644 --- a/lib/ai/runtime/model-health.ts +++ b/lib/ai/runtime/model-health.ts @@ -537,7 +537,12 @@ export async function recordAiModelHealthSuccess(params: { if (!existing) return; const now = new Date(); - const isObservation = isObservationPoolModel(existing); + // A request that started before the circuit opened can still prove the + // provider is reachable. Treat that success as the circuit's half-open + // probe instead of leaving the model disabled until the full cooldown. + const recoveredFromAutoDisable = existing.healthStatus === "auto_disabled"; + const isObservation = + isObservationPoolModel(existing) || recoveredFromAutoDisable; const nextRecoverySuccessStreak = isObservation ? (existing.healthRecoverySuccessStreak || 0) + 1 : 0; @@ -547,9 +552,7 @@ export async function recordAiModelHealthSuccess(params: { const updateData: Partial = { healthStatus: - existing.healthStatus === "auto_disabled" - ? "auto_disabled" - : recoveredToHealthy + recoveredToHealthy ? "healthy" : isObservation ? "degraded" @@ -566,12 +569,16 @@ export async function recordAiModelHealthSuccess(params: { healthObservationStartedAt: recoveredToHealthy ? null : isObservation - ? existing.healthObservationStartedAt + ? existing.healthObservationStartedAt || now : null, healthUpdatedAt: now, updatedAt: now, }; + if (recoveredFromAutoDisable) { + updateData.isEnabled = true; + } + if (recoveredToHealthy) { updateData.healthAutoDisabledAt = null; updateData.healthAutoDisabledReason = null;