Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 71 additions & 3 deletions apps/server/src/provider/antigravityUsageLimits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ const fixture = Effect.fn("AntigravityUsageTest.fixture")(function* (
summary?: unknown;
/** Per-host quota summaries; hosts not listed fall back to `summary`. */
summaryByHost?: Record<string, unknown>;
/** Mirrors the daily endpoint, which leaves out the Gemini group for the legacy hub/1.0.0 client. */
legacyClientOmitsGemini?: boolean;
models?: unknown;
summaryStatus?: number;
/** Per-host summary statuses; hosts not listed fall back to `summaryStatus`. */
Expand Down Expand Up @@ -107,12 +109,21 @@ const fixture = Effect.fn("AntigravityUsageTest.fixture")(function* (
);
}
expect(JSON.parse(body)).toEqual({ project: "project-id" });
const omitGemini =
options.legacyClientOmitsGemini &&
url.host === "daily-cloudcode-pa.googleapis.com" &&
request.headers["user-agent"]?.startsWith("antigravity/hub/1.0.0 ");
return HttpClientResponse.fromWeb(
request,
request.url.endsWith(":retrieveUserQuotaSummary")
? Response.json(options.summaryByHost?.[url.host] ?? options.summary ?? summary, {
status: options.summaryStatusByHost?.[url.host] ?? options.summaryStatus ?? 200,
})
? Response.json(
omitGemini
? {
groups: summary.groups.filter((group) => group.displayName !== "Gemini Models"),
}
: (options.summaryByHost?.[url.host] ?? options.summary ?? summary),
{ status: options.summaryStatusByHost?.[url.host] ?? options.summaryStatus ?? 200 },
)
: Response.json(options.models ?? { models: {} }),
);
}),
Expand Down Expand Up @@ -188,6 +199,63 @@ describe("Antigravity subscription limits", () => {
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("reads consumed Gemini quota that the daily endpoint gates on client version", () =>
Effect.gen(function* () {
const { probe } = yield* fixture({
legacyClientOmitsGemini: true,
summaryByHost: {
// Production reports every bucket as unused for consumer accounts,
// so only the daily endpoint carries the real Gemini readings.
"cloudcode-pa.googleapis.com": {
groups: summary.groups.map((group) => ({
...group,
buckets: group.buckets.map((bucket) => ({ ...bucket, remainingFraction: 1 })),
})),
},
},
});
const limits = yield* probe;
const byId = new Map(limits.windows.map((window) => [window.id, window]));
expect(byId.get("gemini-5h")?.usedPercent).toBeCloseTo(9);
expect(byId.get("gemini-weekly")?.usedPercent).toBeCloseTo(4);
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("labels Argon's weekly quota apart from the default Gemini weekly quota", () =>
Effect.gen(function* () {
const { probe } = yield* fixture({
summary: {
groups: [
...summary.groups,
{
displayName: "Gemini 4 Argon",
buckets: [
{
bucketId: "gemini-argon-wtu-weekly",
window: "weekly",
remainingFraction: 0.6,
resetTime: "2026-10-25T00:25:01Z",
},
],
},
],
},
});
const limits = yield* probe;
const labels = limits.windows.map((window) => window.label);
expect(new Set(labels).size).toBe(labels.length);
const byId = new Map(limits.windows.map((window) => [window.id, window]));
expect(byId.get("gemini-weekly")?.label).toBe("Gemini · Weekly");
expect(byId.get("gemini-argon-wtu-weekly")).toMatchObject({
label: "Gemini 4 Argon · Weekly",
kind: "weekly",
windowDurationMins: 10080,
resetsAt: "2026-10-25T00:25:01.000Z",
});
expect(byId.get("gemini-argon-wtu-weekly")?.usedPercent).toBeCloseTo(40);
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
);

it.effect("keeps one endpoint's quotas when the other fails", () =>
Effect.gen(function* () {
const { probe } = yield* fixture({
Expand Down
20 changes: 14 additions & 6 deletions apps/server/src/provider/antigravityUsageLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,15 @@ function summaryWindows(summary: typeof Summary.Type) {
for (const group of groups ?? []) {
for (const bucket of group.buckets ?? []) {
if (bucket.disabled) continue;
const family = bucket.bucketId.startsWith("gemini-")
? "Gemini"
: bucket.bucketId.startsWith("3p-")
? "Claude & GPT (shared)"
: group.displayName?.trim() || bucket.bucketId;
// Argon's weekly allowance is metered apart from the default Gemini
// buckets, so it keeps its own name instead of a second "Gemini · Weekly".
const family = bucket.bucketId.startsWith("gemini-argon-")
? group.displayName?.trim() || "Gemini 4 Argon"
: bucket.bucketId.startsWith("gemini-")
? "Gemini"
: bucket.bucketId.startsWith("3p-")
? "Claude & GPT (shared)"
: group.displayName?.trim() || bucket.bucketId;
const weekly = bucket.window === "weekly";
const session = bucket.window === "5h";
const window = quotaWindow(
Expand Down Expand Up @@ -260,7 +264,11 @@ export const makeAntigravityUsageProbe = Effect.fn("makeAntigravityUsageProbe")(
HttpClientRequest.post(`${endpoint}/v1internal:${operation}`).pipe(
HttpClientRequest.setHeaders({
Authorization: `Bearer ${accessToken}`,
"User-Agent": `antigravity/hub/1.0.0 (aidev_client; os_type=${platform}; arch=${architecture}; cl=963137146)`,
// Neither endpoint reports consumed Gemini quota to the legacy
// hub/1.0.0 client: daily leaves the Gemini group out, and
// production omits it or reports it unused. 2.24.0 is the
// Antigravity app's version.
"User-Agent": `antigravity/hub/2.24.0 (aidev_client; os_type=${platform}; arch=${architecture}; cl=963137146)`,
}),
HttpClientRequest.bodyJsonUnsafe(
token.project_id ? { project: token.project_id } : {},
Expand Down
Loading