fix(antigravity): strike-break optimistic quota readings that keep 429ing

Google's quota API can report remaining quota while generation endpoints
keep returning 429 (sprint/weekly dual-pool mismatch). handleAntigravityQuotaError
trusted remainingPercentage > 0 as healthy and returned null, causing 429 retry
loops across multi-account pools.

Add a strike-based circuit breaker to the optimistic and unavailable quota paths:
- After 3 strikes (429/409) within 60s for the same connection+model, cache-block
  that pair for 15 minutes by synthesizing an entry in the shared RAM quota cache.
- Re-assert active strike blocks across refreshes so optimistic readings cannot
  resurrect a broken pair prematurely.
- Reset strikes and clear synthesized cache entry upon successful request.
- Keep exact-resetAt handling for genuine 0% exhausted readings.

Closes #3681
This commit is contained in:
louis-cai committed 2026-09-03 09:34:24 +07:00
1 parent a58902e4a7
commit ac98dd9d32
3 files changed
+233 -4

No files matched your search

+3 -1
View File
@@ -7,7 +7,7 @@ import {
extractApiKey,
isValidApiKey,
} from "../services/auth.js";
import { handleAntigravityQuotaError } from "../services/antigravityQuota.js";
import { handleAntigravityQuotaError, clearAntigravityStrikes } from "../services/antigravityQuota.js";
import { getSettings } from "@/lib/localDb";
import { getModelInfo, getComboModels } from "../services/model.js";
import { handleChatCore } from "open-sse/handlers/chatCore.js";
@@ -302,6 +302,8 @@ async function handleSingleModelChat(body, modelStr, clientRawRequest = null, re
},
onRequestSuccess: async () => {
await clearAccountError(credentials.connectionId, credentials, model);
// "Consecutive" strikes: a success clears the breaker for this pair.
clearAntigravityStrikes(credentials.connectionId, model);
}
});