diff --git a/src/sse/handlers/chat.ts b/src/sse/handlers/chat.ts index 161321117e..20e96b2684 100644 --- a/src/sse/handlers/chat.ts +++ b/src/sse/handlers/chat.ts @@ -75,6 +75,7 @@ import { } from "./chatHelpers"; import { isAntigravityMissingProjectError, + PROVIDER_BREAKER_FAILURE_STATUSES, shouldTripProviderBreakerForResult, } from "./chatPredicates"; import { connectionHasExtraKeys } from "@omniroute/open-sse/services/apiKeyRotator.ts"; diff --git a/src/sse/handlers/chatPredicates.ts b/src/sse/handlers/chatPredicates.ts index a45dbc4d5a..fd14015c8d 100644 --- a/src/sse/handlers/chatPredicates.ts +++ b/src/sse/handlers/chatPredicates.ts @@ -1,7 +1,7 @@ import { isLocalStreamLifecycleError } from "../../shared/utils/circuitBreaker"; import { isRequestScopedUpstreamFailure } from "./comboFailureLogging"; -const PROVIDER_BREAKER_FAILURE_STATUSES = new Set([408, 500, 502, 503, 504]); +export const PROVIDER_BREAKER_FAILURE_STATUSES = new Set([408, 500, 502, 503, 504]); // #7907/#7908: single-model breaker trip bypasses the `isFailure` option (only applies // inside `breaker.execute()`), so it needs its own `isLocalStreamLifecycleError` guard — diff --git a/tests/unit/nvidia-quota-phase1.test.ts b/tests/unit/nvidia-quota-phase1.test.ts index ef09091d01..346868be07 100644 --- a/tests/unit/nvidia-quota-phase1.test.ts +++ b/tests/unit/nvidia-quota-phase1.test.ts @@ -214,16 +214,19 @@ test("semaphore.getStats reflects nvidia's per-connection gate key", async () => // ── Failure-mode separation regression guard ──────────────────────────────── test("nvidia 429 does not trip the provider circuit breaker (unchanged 408/500/502/503/504-only classification)", () => { - // This PR does not touch src/sse/handlers/chat.ts or the circuit breaker — this - // is a documentation-alignment guard proving Phase 1 didn't accidentally widen + // This PR does not touch the circuit breaker classification — this is a + // documentation-alignment guard proving Phase 1 didn't accidentally widen // PROVIDER_BREAKER_FAILURE_STATUSES to include 429 (which would collapse the // per-model lockout this PR adds into a whole-connection/provider outage). + // #8013 extracted the const from src/sse/handlers/chat.ts into chatPredicates.ts + // (still consumed by chat.ts's breaker paths) — read the declaration from its + // current home. const chatHandlerPath = path.join( process.cwd(), "src", "sse", "handlers", - "chat.ts" + "chatPredicates.ts" ); const source = fs.readFileSync(chatHandlerPath, "utf8"); const match = source.match(/PROVIDER_BREAKER_FAILURE_STATUSES\s*=\s*new Set\(\[([^\]]+)\]\)/);