mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-20 05:42:19 +03:00
feat(antigravity): expose physical send telemetry (#13659)
Co-authored-by: ginettododo <117327638+ginettododo@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d715190bb0
commit
c8434436af
@@ -508,6 +508,7 @@ function isAntigravityGeminiChatModel(upstreamModel: string): boolean {
|
||||
export const __test_stripTrailingAntigravityAssistantTurn = stripTrailingAntigravityAssistantTurn;
|
||||
|
||||
type AntigravityCreditsRetryState = { attempted: boolean };
|
||||
type AntigravityPhysicalSendCounter = { value: number };
|
||||
|
||||
/** Base per-url-index attempt context, before the request has been sent. */
|
||||
type AntigravityAttemptContext = {
|
||||
@@ -527,6 +528,8 @@ type AntigravityAttemptContext = {
|
||||
urlIndex: number;
|
||||
retryAttemptsByUrl: Record<number, number>;
|
||||
fallbackCount: number;
|
||||
physicalSendCounter: AntigravityPhysicalSendCounter;
|
||||
correlationId: string | null;
|
||||
};
|
||||
|
||||
/** Context threaded through the 429/503 handling helpers — adds the sent response. */
|
||||
@@ -1169,6 +1172,7 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
* exactly the same single call as before (zero extra upstream requests).
|
||||
*/
|
||||
async execute(input: ExecuteInput) {
|
||||
const physicalSendCounter: AntigravityPhysicalSendCounter = { value: 0 };
|
||||
await resolveAntigravityClientVersion(getAntigravityClientProfile(input.credentials));
|
||||
|
||||
// Look up the chain by the NORMALLY-resolved upstream id (honours MITM/static aliases).
|
||||
@@ -1178,7 +1182,7 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
|
||||
if (chain.length <= 1) {
|
||||
// No fallback chain (flash, claude, plain pro, unknown) → single attempt, unchanged.
|
||||
return this.executeOnce(input);
|
||||
return this.executeOnce(input, undefined, physicalSendCounter);
|
||||
}
|
||||
|
||||
let firstResult: Awaited<ReturnType<AntigravityExecutor["executeOnce"]>> | null = null;
|
||||
@@ -1186,7 +1190,7 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
const candidate = chain[i];
|
||||
let result: Awaited<ReturnType<AntigravityExecutor["executeOnce"]>>;
|
||||
try {
|
||||
result = await this.executeOnce(input, candidate);
|
||||
result = await this.executeOnce(input, candidate, physicalSendCounter);
|
||||
} catch (error) {
|
||||
const outcome = handleAntigravityFallbackChainError(
|
||||
input,
|
||||
@@ -1228,7 +1232,7 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
}
|
||||
|
||||
// Unreachable (loop always returns), but keeps the type checker happy.
|
||||
return firstResult ?? this.executeOnce(input);
|
||||
return firstResult ?? this.executeOnce(input, undefined, physicalSendCounter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1239,8 +1243,18 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
* status of the first response so `execute()` can decide whether to fall through. @internal
|
||||
*/
|
||||
private async executeOnce(
|
||||
{ model, body, stream, credentials, signal, log, upstreamExtraHeaders }: ExecuteInput,
|
||||
modelIdOverride?: string
|
||||
{
|
||||
model,
|
||||
body,
|
||||
stream,
|
||||
credentials,
|
||||
signal,
|
||||
log,
|
||||
upstreamExtraHeaders,
|
||||
correlationId = null,
|
||||
}: ExecuteInput,
|
||||
modelIdOverride?: string,
|
||||
physicalSendCounter: AntigravityPhysicalSendCounter = { value: 0 }
|
||||
) {
|
||||
await resolveAntigravityClientVersion(getAntigravityClientProfile(credentials));
|
||||
const fallbackCount = this.getFallbackCount();
|
||||
@@ -1307,6 +1321,8 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
urlIndex,
|
||||
retryAttemptsByUrl,
|
||||
fallbackCount,
|
||||
physicalSendCounter,
|
||||
correlationId,
|
||||
});
|
||||
|
||||
if (outcome.action === "return") return outcome.result;
|
||||
@@ -1356,6 +1372,8 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
urlIndex,
|
||||
retryAttemptsByUrl,
|
||||
fallbackCount,
|
||||
physicalSendCounter,
|
||||
correlationId,
|
||||
} = ctx;
|
||||
|
||||
const { response, finalHeaders } = await sendAntigravityRequest(
|
||||
@@ -1368,7 +1386,9 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
stream,
|
||||
signal,
|
||||
log,
|
||||
retryAttemptsByUrl[urlIndex]
|
||||
retryAttemptsByUrl[urlIndex],
|
||||
physicalSendCounter,
|
||||
correlationId
|
||||
);
|
||||
|
||||
let retryMs: number | null = null;
|
||||
@@ -1619,7 +1639,9 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
signal,
|
||||
log,
|
||||
accountId,
|
||||
updateAntigravityRemainingCredits
|
||||
updateAntigravityRemainingCredits,
|
||||
ctx.physicalSendCounter,
|
||||
ctx.correlationId
|
||||
);
|
||||
if (creditsResult) return { kind: "return", result: creditsResult };
|
||||
if (retryMs) markConnectionQuotaExhausted(accountId, retryMs, ctx.model);
|
||||
|
||||
@@ -333,7 +333,9 @@ export async function sendAntigravityRequest(
|
||||
stream: boolean,
|
||||
signal: AbortSignal | null | undefined,
|
||||
log: SafeAntigravityLog,
|
||||
retryAttempt: number
|
||||
retryAttempt: number,
|
||||
physicalSendCounter: { value: number },
|
||||
correlationId: string | null
|
||||
): Promise<{ response: Response; finalHeaders: Record<string, string> }> {
|
||||
const serializedRequest = serializeAntigravityRequest(provider, headers, transformedBody);
|
||||
let finalHeaders = serializedRequest.headers;
|
||||
@@ -356,6 +358,11 @@ export async function sendAntigravityRequest(
|
||||
}
|
||||
|
||||
await prl.captureCurrentProviderBody(url, finalHeaders, serializedRequest.bodyString, log);
|
||||
const physicalSendOrdinal = ++physicalSendCounter.value;
|
||||
log.debug(
|
||||
"TELEMETRY",
|
||||
`[Antigravity] PhysicalSend - RequestId: ${correlationId ?? "none"}, URL: ${url}, Model: ${model}, PhysicalSend: ${physicalSendOrdinal}, RetryAttempt: ${retryAttempt}`
|
||||
);
|
||||
let response = await fetchAntigravityWithReadinessTimeout(url, {
|
||||
method: "POST",
|
||||
headers: finalHeaders,
|
||||
@@ -369,6 +376,11 @@ export async function sendAntigravityRequest(
|
||||
removeHeaderCaseInsensitive(retryHeaders, "x-goog-user-project");
|
||||
log.debug("RETRY", "403 with x-goog-user-project, retrying once without it");
|
||||
await prl.captureCurrentProviderBody(url, retryHeaders, serializedRequest.bodyString, log);
|
||||
const retryPhysicalSendOrdinal = ++physicalSendCounter.value;
|
||||
log.debug(
|
||||
"TELEMETRY",
|
||||
`[Antigravity] PhysicalSend - RequestId: ${correlationId ?? "none"}, URL: ${url}, Model: ${model}, PhysicalSend: ${retryPhysicalSendOrdinal}, RetryAttempt: ${retryAttempt}, Cause: x-goog-user-project-403`
|
||||
);
|
||||
response = await fetchAntigravityWithReadinessTimeout(url, {
|
||||
method: "POST",
|
||||
headers: retryHeaders,
|
||||
@@ -416,7 +428,9 @@ export async function tryCreditsRetry(
|
||||
signal: AbortSignal | null | undefined,
|
||||
log: SafeAntigravityLog,
|
||||
accountId: string,
|
||||
onCreditsUpdate: OnAntigravityCreditsUpdate
|
||||
onCreditsUpdate: OnAntigravityCreditsUpdate,
|
||||
physicalSendCounter: { value: number },
|
||||
correlationId: string | null
|
||||
): Promise<SsePassthroughResult | null> {
|
||||
log.info("AG_CREDITS", "Retrying with Google One AI credits");
|
||||
const creditsBody = attachToolNameMap(
|
||||
@@ -433,6 +447,11 @@ export async function tryCreditsRetry(
|
||||
serializedCreditsRequest.bodyString,
|
||||
log
|
||||
);
|
||||
const creditsPhysicalSendOrdinal = ++physicalSendCounter.value;
|
||||
log.debug(
|
||||
"TELEMETRY",
|
||||
`[Antigravity] PhysicalSend - RequestId: ${correlationId ?? "none"}, URL: ${url}, PhysicalSend: ${creditsPhysicalSendOrdinal}, Cause: google-one-ai-credits-retry`
|
||||
);
|
||||
const creditsResp = await fetchAntigravityWithReadinessTimeout(url, {
|
||||
method: "POST",
|
||||
headers: finalCreditsHeaders,
|
||||
|
||||
@@ -36,6 +36,7 @@ test("AntigravityExecutor.execute auto-retries short 429 responses and collects
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalSetTimeout = globalThis.setTimeout;
|
||||
const calls = [];
|
||||
const telemetry: string[] = [];
|
||||
seedAntigravityIdeVersionCache("2026.04.17-test");
|
||||
seedAntigravityCliVersionCache("2026.04.17-test");
|
||||
|
||||
@@ -71,7 +72,13 @@ test("AntigravityExecutor.execute auto-retries short 429 responses and collects
|
||||
body: { request: { contents: [] } },
|
||||
stream: false,
|
||||
credentials: { accessToken: "token", projectId: "project-1" },
|
||||
log: { debug() {}, warn() {} },
|
||||
log: {
|
||||
debug(_scope, message) {
|
||||
telemetry.push(String(message));
|
||||
},
|
||||
warn() {},
|
||||
},
|
||||
correlationId: "prompt194-native-retry-test",
|
||||
});
|
||||
// Non-streaming collects the upstream SSE and returns the already-converted
|
||||
// OpenAI chat.completion payload — no further SSE parsing on the caller side.
|
||||
@@ -79,6 +86,10 @@ test("AntigravityExecutor.execute auto-retries short 429 responses and collects
|
||||
assert.equal(payload.object, "chat.completion");
|
||||
|
||||
assert.equal(calls.length, 2);
|
||||
const physicalSends = telemetry.filter((line) => line.includes("[Antigravity] PhysicalSend"));
|
||||
assert.equal(physicalSends.length, calls.length);
|
||||
assert.match(physicalSends[0] ?? "", /RequestId: prompt194-native-retry-test/);
|
||||
assert.match(physicalSends[1] ?? "", /PhysicalSend: 2/);
|
||||
assert.equal(result.response.status, 200);
|
||||
assert.equal(payload.choices[0].message.content, "Hello again");
|
||||
assert.deepEqual(payload.usage, {
|
||||
|
||||
@@ -871,6 +871,7 @@ test("AntigravityExecutor.execute bounds a persistent short-retry 429 instead of
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalSetTimeout = globalThis.setTimeout;
|
||||
const calls: string[] = [];
|
||||
const telemetry: string[] = [];
|
||||
seedAntigravityIdeVersionCache("2.1.1");
|
||||
|
||||
// "rate limited" with no parseable retry hint classifies as rate_limited →
|
||||
@@ -897,7 +898,13 @@ test("AntigravityExecutor.execute bounds a persistent short-retry 429 instead of
|
||||
body: { request: { contents: [] } },
|
||||
stream: true,
|
||||
credentials: { accessToken: "token", projectId: "project-1" },
|
||||
log: { debug() {}, warn() {} },
|
||||
log: {
|
||||
debug(_scope, message) {
|
||||
telemetry.push(String(message));
|
||||
},
|
||||
warn() {},
|
||||
},
|
||||
correlationId: "prompt194-physical-send-test",
|
||||
});
|
||||
|
||||
// Returns the 429 rather than hanging.
|
||||
@@ -906,6 +913,11 @@ test("AntigravityExecutor.execute bounds a persistent short-retry 429 instead of
|
||||
// Bounded: switchAuth declines same-URL retries → 2 live runtime endpoints
|
||||
// × 1 attempt each = 2 attempts total (#9351).
|
||||
assert.equal(calls.length, 2);
|
||||
const physicalSends = telemetry.filter((line) => line.includes("[Antigravity] PhysicalSend"));
|
||||
assert.equal(physicalSends.length, calls.length);
|
||||
assert.match(physicalSends[0] ?? "", /RequestId: prompt194-physical-send-test/);
|
||||
assert.match(physicalSends[0] ?? "", /PhysicalSend: 1/);
|
||||
assert.match(physicalSends[1] ?? "", /PhysicalSend: 2/);
|
||||
|
||||
// Tried every distinct live runtime base URL before giving up.
|
||||
const distinctHosts = new Set(calls.map((u) => new URL(u).host));
|
||||
|
||||
Reference in New Issue
Block a user