mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
fix(usage): route agy quota through antigravity (#3232)
Route agy quota through the Antigravity usage implementation (closes #3230). Integrated into release/v3.8.11. Thanks @wilsonicdev.
This commit is contained in:
@@ -1424,6 +1424,7 @@ export const USAGE_FETCHER_PROVIDERS = [
|
||||
"github",
|
||||
"gemini-cli",
|
||||
"antigravity",
|
||||
"agy",
|
||||
"claude",
|
||||
"codex",
|
||||
"cursor",
|
||||
@@ -1467,6 +1468,7 @@ export async function getUsageForProvider(
|
||||
case "gemini-cli":
|
||||
return await getGeminiUsage(accessToken, providerSpecificData, projectId);
|
||||
case "antigravity":
|
||||
case "agy":
|
||||
return await getAntigravityUsage(accessToken, providerSpecificData, projectId, id, options);
|
||||
case "claude":
|
||||
return await getClaudeUsage(accessToken);
|
||||
|
||||
@@ -260,6 +260,7 @@ export function parseQuotaData(provider, data) {
|
||||
break;
|
||||
|
||||
case "antigravity":
|
||||
case "agy":
|
||||
if (data.quotas) {
|
||||
Object.entries(data.quotas).forEach(([modelKey, quota]: [string, any]) => {
|
||||
if (modelKey === "credits") {
|
||||
|
||||
@@ -37,6 +37,7 @@ export async function getUsageForProvider(connection) {
|
||||
case "gemini-cli":
|
||||
return await getGeminiUsage(accessToken);
|
||||
case "antigravity":
|
||||
case "agy":
|
||||
return await getAntigravityUsage(
|
||||
accessToken,
|
||||
providerSpecificData,
|
||||
|
||||
@@ -323,7 +323,7 @@ async function syncAntigravitySubscriptionIfNeeded(
|
||||
connection: ProviderConnectionLike,
|
||||
usage: JsonRecord
|
||||
): Promise<ProviderConnectionLike> {
|
||||
if (connection.provider !== "antigravity") return connection;
|
||||
if (connection.provider !== "antigravity" && connection.provider !== "agy") return connection;
|
||||
|
||||
const subscriptionInfo = usage.subscriptionInfo;
|
||||
if (!subscriptionInfo) return connection;
|
||||
|
||||
82
tests/unit/agy-usage-quota.test.ts
Normal file
82
tests/unit/agy-usage-quota.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import test, { mock } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const usageModule = await import("../../open-sse/services/usage.ts");
|
||||
const providerLimitUtils =
|
||||
await import("../../src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.tsx");
|
||||
|
||||
test("agy is registered for the background usage fetcher", () => {
|
||||
assert.ok(
|
||||
usageModule.USAGE_FETCHER_PROVIDERS.includes("agy"),
|
||||
"agy should be fetched by the generic quota refresher"
|
||||
);
|
||||
});
|
||||
|
||||
test("getUsageForProvider routes agy through the Antigravity usage implementation", async () => {
|
||||
const fetchMock = mock.method(globalThis, "fetch", async () => ({
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
models: {
|
||||
"gemini-3.5-flash-preview": {
|
||||
quotaInfo: {
|
||||
remainingFraction: 0.75,
|
||||
resetTime: "2026-06-06T00:00:00Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
try {
|
||||
const result = await usageModule.getUsageForProvider(
|
||||
{
|
||||
id: "agy-test-conn",
|
||||
provider: "agy",
|
||||
accessToken: "fake-token",
|
||||
providerSpecificData: {},
|
||||
},
|
||||
{ forceRefresh: true }
|
||||
);
|
||||
|
||||
assert.ok(result && typeof result === "object");
|
||||
assert.notEqual(
|
||||
(result as { message?: string }).message,
|
||||
"Usage API not implemented for agy",
|
||||
"agy must not fall through to the unsupported-provider branch"
|
||||
);
|
||||
assert.ok("quotas" in result, "agy should return quota data when upstream responds");
|
||||
|
||||
const quota = (result as { quotas: Record<string, any> }).quotas["gemini-3.5-flash-preview"];
|
||||
assert.ok(quota, "should expose the Antigravity per-model quota for agy");
|
||||
assert.equal(quota.remainingPercentage, 75);
|
||||
} finally {
|
||||
fetchMock.mock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test("parseQuotaData treats agy quota payloads like Antigravity", () => {
|
||||
const parsed = providerLimitUtils.parseQuotaData("agy", {
|
||||
quotas: {
|
||||
credits: { remaining: 42 },
|
||||
"gemini-3.5-flash-preview": {
|
||||
used: 250,
|
||||
total: 1000,
|
||||
remainingPercentage: 75,
|
||||
},
|
||||
models: { used: 0, total: 0 },
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
parsed.length,
|
||||
2,
|
||||
"credits and model quota should be rendered, models summary skipped"
|
||||
);
|
||||
const credits = parsed.find((quota: any) => quota.name === "credits");
|
||||
assert.ok(credits, "credits quota should be rendered");
|
||||
assert.equal(credits.isCredits, true);
|
||||
|
||||
const modelQuota = parsed.find((quota: any) => quota.name === "gemini-3.5-flash-preview");
|
||||
assert.ok(modelQuota, "model quota should be rendered");
|
||||
assert.equal(modelQuota.remainingPercentage, 75);
|
||||
});
|
||||
Reference in New Issue
Block a user