Files
2026-07-13 13:39:12 +08:00

81 lines
3.7 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { AI_PROVIDERS, USAGE_SUPPORTED_PROVIDERS } from "../../src/shared/constants/providers.ts";
import { REGISTRY } from "../../open-sse/config/providerRegistry.ts";
import { PROVIDERS as LEGACY_PROVIDERS } from "../../open-sse/config/constants.ts";
import {
PROVIDERS as OAUTH_PROVIDER_IDS,
AGY_CONFIG,
} from "../../src/lib/oauth/constants/oauth.ts";
import { supportsTokenRefresh, REFRESH_LEAD_MS } from "../../open-sse/services/tokenRefresh.ts";
import {
AGY_PUBLIC_MODELS,
isUserCallableAgyModelId,
getClientVisibleAgyModelName,
} from "../../open-sse/config/agyModels.ts";
test("agy is registered as an OAuth provider in the UI catalog", () => {
const agy = AI_PROVIDERS.agy;
assert.ok(agy, "AI_PROVIDERS.agy must exist");
assert.equal(agy.id, "agy");
assert.equal(agy.name, "Antigravity CLI");
assert.equal(agy.riskNoticeVariant, "oauth");
assert.equal(agy.subscriptionRisk, true);
});
test("agy supports the usage/quota API", () => {
assert.ok(USAGE_SUPPORTED_PROVIDERS.includes("agy"));
});
test("agy registry entry reuses the antigravity backend (no duplicate executor/format)", () => {
const agy = REGISTRY.agy;
assert.ok(agy, "REGISTRY.agy must exist");
assert.equal(agy.format, "antigravity");
assert.equal(agy.executor, "antigravity");
assert.equal(agy.authType, "oauth");
assert.equal(agy.authHeader, "bearer");
assert.equal(agy.passthroughModels, true);
});
test("agy reuses the identical antigravity Google OAuth credentials (no new embedded secret)", () => {
// The agy client_id was verified byte-for-byte identical to antigravity's.
assert.equal(LEGACY_PROVIDERS.agy.clientId, LEGACY_PROVIDERS.antigravity.clientId);
assert.equal(LEGACY_PROVIDERS.agy.clientSecret, LEGACY_PROVIDERS.antigravity.clientSecret);
assert.equal(AGY_CONFIG.clientId, LEGACY_PROVIDERS.antigravity.clientId);
assert.equal(OAUTH_PROVIDER_IDS.AGY, "agy");
});
test("agy ships its own catalog including the Claude models antigravity omits", () => {
const ids = REGISTRY.agy.models.map((m) => m.id);
assert.ok(ids.includes("claude-opus-4-6-thinking"), "must expose Claude Opus 4.6 Thinking");
assert.ok(ids.includes("claude-sonnet-4-6"), "must expose Claude Sonnet 4.6");
assert.ok(ids.includes("gemini-3.5-flash-low"), "must expose clean Flash Low tier");
assert.ok(ids.includes("gemini-3.5-flash-medium"), "must expose clean Flash Medium tier");
assert.ok(ids.includes("gemini-3.5-flash-high"), "must expose clean Flash High tier");
assert.ok(!ids.includes("gemini-3-flash-agent"));
assert.ok(!ids.includes("gemini-3-flash"));
assert.ok(!ids.includes("gemini-3.5-flash-extra-low"));
// Tab-completion models are not chat-callable and must be excluded.
assert.ok(!ids.includes("tab_flash_lite_preview"));
assert.ok(!ids.includes("tab_jump_flash_lite_preview"));
assert.equal(ids.length, AGY_PUBLIC_MODELS.length);
});
test("agy model helpers resolve catalog ids and display names", () => {
assert.equal(isUserCallableAgyModelId("claude-opus-4-6-thinking"), true);
assert.equal(isUserCallableAgyModelId("tab_flash_lite_preview"), false);
assert.equal(isUserCallableAgyModelId(""), false);
assert.equal(
getClientVisibleAgyModelName("claude-opus-4-6-thinking"),
"Claude Opus 4.6 (Thinking)"
);
assert.equal(getClientVisibleAgyModelName("unknown-model", "Fallback"), "Fallback");
});
test("agy token refresh is wired on the Google (non-rotating) refresh path", () => {
assert.equal(supportsTokenRefresh("agy"), true);
// Same 15-minute proactive lead as antigravity (Google refresh tokens are permanent).
assert.equal(REFRESH_LEAD_MS.agy, REFRESH_LEAD_MS.antigravity);
});