feat: treat timeout as rate limit for profile rotation

Antigravity rate limits cause requests to hang indefinitely rather than
returning 429 errors. This change detects timeouts and treats them as
potential rate limits:

- Added timedOut flag to track timeout-triggered aborts
- Timeout now triggers profile cooldown + rotation
- Logs: "Profile X timed out (possible rate limit). Trying next account..."

This ensures automatic failover when Antigravity hangs due to rate limiting.
This commit is contained in:
Muhammed Mukhthar CM
2026-01-06 04:48:34 +00:00
parent ce6c7737c1
commit 18c7795ee0
2 changed files with 15 additions and 5 deletions

View File

@@ -808,8 +808,10 @@ export async function runEmbeddedPiAgent(params: {
session.agent.replaceMessages(prior);
}
let aborted = Boolean(params.abortSignal?.aborted);
const abortRun = () => {
let timedOut = false;
const abortRun = (isTimeout = false) => {
aborted = true;
if (isTimeout) timedOut = true;
void session.abort();
};
const subscription = subscribeEmbeddedPiSession({
@@ -848,7 +850,7 @@ export async function runEmbeddedPiAgent(params: {
log.warn(
`embedded run timeout: runId=${params.runId} sessionId=${params.sessionId} timeoutMs=${params.timeoutMs}`,
);
abortRun();
abortRun(true);
if (!abortWarnTimer) {
abortWarnTimer = setTimeout(() => {
if (!session.isStreaming) return;
@@ -953,16 +955,25 @@ export async function runEmbeddedPiAgent(params: {
(params.config?.agent?.model?.fallbacks?.length ?? 0) > 0;
const authFailure = isAuthAssistantError(lastAssistant);
const rateLimitFailure = isRateLimitAssistantError(lastAssistant);
if (!aborted && (authFailure || rateLimitFailure)) {
// Treat timeout as potential rate limit (Antigravity hangs on rate limit)
const shouldRotate = (!aborted && (authFailure || rateLimitFailure)) || timedOut;
if (shouldRotate) {
// Mark current profile for cooldown before rotating
if (lastProfileId) {
markAuthProfileCooldown({ store: authStore, profileId: lastProfileId });
if (timedOut) {
log.warn(
`Profile ${lastProfileId} timed out (possible rate limit). Trying next account...`,
);
}
}
const rotated = await advanceAuthProfile();
if (rotated) {
continue;
}
if (fallbackConfigured) {
if (fallbackConfigured && !timedOut) {
const message =
lastAssistant?.errorMessage?.trim() ||
(lastAssistant

View File

@@ -395,5 +395,4 @@ export type {
CronRunParams,
CronRunsParams,
CronRunLogEntry,
PollParams,
};