Fix Antigravity

This commit is contained in:
decolua
2026-01-12 16:53:27 +07:00
parent 87c8f7f229
commit fb5be37e14
5 changed files with 320 additions and 52 deletions
+111 -8
View File
@@ -2,6 +2,8 @@ import crypto from "crypto";
import { BaseExecutor } from "./base.js";
import { PROVIDERS, OAUTH_ENDPOINTS } from "../config/constants.js";
const MAX_RETRY_AFTER_MS = 5000;
export class AntigravityExecutor extends BaseExecutor {
constructor() {
super("antigravity", PROVIDERS.antigravity);
@@ -26,6 +28,15 @@ export class AntigravityExecutor extends BaseExecutor {
transformRequest(model, body, stream, credentials) {
const projectId = credentials?.projectId || this.generateProjectId();
const transformedRequest = {
...body.request,
sessionId: body.request?.sessionId || this.generateSessionId(),
safetySettings: undefined,
toolConfig: body.request?.tools?.length > 0
? { functionCallingConfig: { mode: "VALIDATED" } }
: body.request?.toolConfig
};
return {
...body,
project: projectId,
@@ -33,14 +44,7 @@ export class AntigravityExecutor extends BaseExecutor {
userAgent: "antigravity",
requestType: "agent",
requestId: `agent-${crypto.randomUUID()}`,
request: {
...body.request,
sessionId: body.request?.sessionId || this.generateSessionId(),
safetySettings: undefined,
toolConfig: body.request?.tools?.length > 0
? { functionCallingConfig: { mode: "VALIDATED" } }
: body.request?.toolConfig
}
request: transformedRequest
};
}
@@ -85,6 +89,105 @@ export class AntigravityExecutor extends BaseExecutor {
generateSessionId() {
return `-${Math.floor(Math.random() * 9_000_000_000_000_000_000)}`;
}
parseRetryHeaders(headers) {
console.log("🚀 ~ AntigravityExecutor ~ parseRetryHeaders ~ headers:", headers)
if (!headers?.get) return null;
const retryAfter = headers.get('retry-after');
if (retryAfter) {
const seconds = parseInt(retryAfter, 10);
if (!isNaN(seconds) && seconds > 0) return seconds * 1000;
const date = new Date(retryAfter);
if (!isNaN(date.getTime())) {
const diff = date.getTime() - Date.now();
return diff > 0 ? diff : null;
}
}
const resetAfter = headers.get('x-ratelimit-reset-after');
if (resetAfter) {
const seconds = parseInt(resetAfter, 10);
if (!isNaN(seconds) && seconds > 0) return seconds * 1000;
}
const resetTimestamp = headers.get('x-ratelimit-reset');
if (resetTimestamp) {
const ts = parseInt(resetTimestamp, 10) * 1000;
const diff = ts - Date.now();
return diff > 0 ? diff : null;
}
return null;
}
async execute({ model, body, stream, credentials, signal, log }) {
const fallbackCount = this.getFallbackCount();
let lastError = null;
let lastStatus = 0;
const MAX_AUTO_RETRIES = 2;
for (let urlIndex = 0; urlIndex < fallbackCount; urlIndex++) {
const url = this.buildUrl(model, stream, urlIndex);
const headers = this.buildHeaders(credentials, stream);
const transformedBody = this.transformRequest(model, body, stream, credentials);
let retryAttempts = 0;
try {
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(transformedBody),
signal
});
if (response.status === 429 || response.status === 503) {
const retryMs = this.parseRetryHeaders(response.headers);
if (retryMs && retryMs <= MAX_RETRY_AFTER_MS) {
log?.debug?.("RETRY", `${response.status} with Retry-After: ${Math.ceil(retryMs/1000)}s, waiting...`);
await new Promise(resolve => setTimeout(resolve, retryMs));
urlIndex--;
continue;
}
// Auto retry only for 429 when retryMs is 0 or undefined
if (response.status === 429 && (!retryMs || retryMs === 0) && retryAttempts < MAX_AUTO_RETRIES) {
retryAttempts++;
log?.debug?.("RETRY", `429 auto retry ${retryAttempts}/${MAX_AUTO_RETRIES} after 1s`);
await new Promise(resolve => setTimeout(resolve, 1000));
urlIndex--;
continue;
}
log?.debug?.("RETRY", `${response.status}, Retry-After ${retryMs ? `too long (${Math.ceil(retryMs/1000)}s)` : 'missing'}, trying fallback`);
lastStatus = response.status;
if (urlIndex + 1 < fallbackCount) {
continue;
}
}
if (this.shouldRetry(response.status, urlIndex)) {
log?.debug?.("RETRY", `${response.status} on ${url}, trying fallback ${urlIndex + 1}`);
lastStatus = response.status;
continue;
}
return { response, url, headers, transformedBody };
} catch (error) {
lastError = error;
if (urlIndex + 1 < fallbackCount) {
log?.debug?.("RETRY", `Error on ${url}, trying fallback ${urlIndex + 1}`);
continue;
}
throw error;
}
}
throw lastError || new Error(`All ${fallbackCount} URLs failed with status ${lastStatus}`);
}
}
export default AntigravityExecutor;