diff --git a/src/dashboard/public/app.js b/src/dashboard/public/app.js index 6ff30c5..ceb4d17 100644 --- a/src/dashboard/public/app.js +++ b/src/dashboard/public/app.js @@ -1421,7 +1421,8 @@ async function renderFailoverTuning() { 5xx feeds breaker burst-429 feeds breaker quota-429 → cooldown + failover - other 4xx count-only + throttle-403 → short cooldown + failover + other 4xx count-only transport errors never trip local outage never burns diff --git a/src/proxy/server.ts b/src/proxy/server.ts index bf4a93d..d21908b 100644 --- a/src/proxy/server.ts +++ b/src/proxy/server.ts @@ -558,13 +558,17 @@ export class ProxyServer { if (!repeatedServerError) { this.keyManager.markError(key.id) } - this.keyManager.recordRequest(key.id, { - statusCode: upstreamRes.status, - durationMs: duration, - model: prepared.model, - sessionId: upstreamSessionId ?? sessionKey ?? null, - successful: false, - }) + if (attempt < maxAttempts - 1) { + // Counted here; on the last attempt the tail recordRequest + // below counts the verbatim 5xx once (no double-count). + this.keyManager.recordRequest(key.id, { + statusCode: upstreamRes.status, + durationMs: duration, + model: prepared.model, + sessionId: upstreamSessionId ?? sessionKey ?? null, + successful: false, + }) + } attemptedKeyIds.add(key.id) if (circuitState === CircuitState.OPEN) {