fix: address PR review findings for Antigravity 429 cascade fix

- Standardize cooldown fallback to 2 min (COOLDOWN_MS.rateLimit) in both
  chatCore and auth.ts instead of inconsistent 60s/undefined
- Return 504 Gateway Timeout instead of 200 OK when SSE collection times
  out, with finish_reason "length" to signal incomplete response
This commit is contained in:
Chris Staley
2026-03-31 21:58:21 -06:00
parent c4e2627b43
commit c7da922383
3 changed files with 10 additions and 6 deletions

View File

@@ -224,6 +224,7 @@ export class AntigravityExecutor extends BaseExecutor {
const collect = async () => {
const chunks: string[] = [];
let timedOut = false;
const timeout = AbortSignal.timeout(SSE_COLLECT_TIMEOUT_MS);
try {
// eslint-disable-next-line no-constant-condition
@@ -239,7 +240,9 @@ export class AntigravityExecutor extends BaseExecutor {
chunks.push(decoder.decode(value, { stream: true }));
}
} catch (err) {
log?.warn?.("SSE_COLLECT", `Error collecting SSE stream: ${err?.message || err}`);
const msg = err?.message || String(err);
timedOut = msg.includes("timed out");
log?.warn?.("SSE_COLLECT", `Error collecting SSE stream: ${msg}`);
// Fall through — return whatever was collected so far
}
const rawSSE = chunks.join("");
@@ -289,15 +292,16 @@ export class AntigravityExecutor extends BaseExecutor {
{
index: 0,
message: { role: "assistant", content: textContent },
finish_reason: finishReason,
finish_reason: timedOut ? "length" : finishReason,
},
],
...(usage && { usage }),
};
const syntheticStatus = timedOut ? 504 : response.status;
const syntheticResponse = new Response(JSON.stringify(result), {
status: response.status,
statusText: response.statusText,
status: syntheticStatus,
statusText: timedOut ? "Gateway Timeout" : response.statusText,
headers: [["Content-Type", "application/json"]],
});

View File

@@ -1217,7 +1217,7 @@ export async function handleChatCore({
const isPassthrough = provider && getPassthroughProviders().has(provider);
if (isPassthrough) {
const { lockModel } = await import("../services/accountFallback.ts");
const cooldown = retryAfterMs || 60_000;
const cooldown = retryAfterMs || 120_000; // 2 min default, same as COOLDOWN_MS.rateLimit
lockModel(provider, connectionId, model, "rate_limited", cooldown);
console.warn(
`[provider] Node ${connectionId} model-only rate limited (${statusCode}) for ${model} - ${Math.ceil(cooldown / 1000)}s (connection stays active)`

View File

@@ -809,7 +809,7 @@ export async function markAccountUnavailable(
// may still have quota available. Use lockModel() instead of connection-wide
// rateLimitedUntil, same pattern as the 404 model-only lockout above.
if (isPassthroughProvider && status === 429 && provider && model) {
const modelCooldown = cooldownMs || COOLDOWN_MS.rateLimited;
const modelCooldown = cooldownMs || COOLDOWN_MS.rateLimit;
lockModel(provider, connectionId, model, reason || "rate_limited", modelCooldown);
log.info(
"AUTH",