Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **feat(antigravity):** add Gemini 3.8 Flash high/medium/low tiers to the Antigravity and AGY catalogs, alias `gemini-3.8-flash` to High, and bump IDE/CLI client fallbacks to 2.5.5 / 1.1.24 so live Cloud Code endpoints no longer 404 ([#12499](https://github.com/diegosouzapw/OmniRoute/pull/12499)) — thanks @Abhishekchhetri020
6 changes: 2 additions & 4 deletions open-sse/config/antigravityModelAliases.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import {
ANTIGRAVITY_SHARED_MODELS,
buildSurfaceCatalog,
} from "./antigravitySharedModels.ts";
import { ANTIGRAVITY_SHARED_MODELS, buildSurfaceCatalog } from "./antigravitySharedModels.ts";

export const ANTIGRAVITY_PUBLIC_MODELS = buildSurfaceCatalog(ANTIGRAVITY_SHARED_MODELS, {
add: [], // IDE-only models (currently none)
remove: [], // Models hidden from IDE (currently none)
});

export const ANTIGRAVITY_MODEL_ALIASES = Object.freeze({
"gemini-3.8-flash": "gemini-3.8-flash-high",
// Gemini 3.7 Flash tiers map to the upstream tiered endpoint model; the thinking
// budget is steered via generationConfig.thinkingConfig.thinkingBudget.
"gemini-3.7-flash": "gemini-3.7-flash-tiered",
Expand Down
30 changes: 30 additions & 0 deletions open-sse/config/antigravitySharedModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,36 @@
// explicit add/remove delta in its own file (currently both deltas are empty).

export const ANTIGRAVITY_SHARED_MODELS = Object.freeze([
// Gemini 3.8 Flash tiers. Unlike 3.7, Google's live Cloud Code endpoint
// (streamGenerateContent) serves 3.8 directly at the -high/-medium/-low tier
// ids — there is no gemini-3.8-flash-tiered upstream endpoint for 3.8.
{
id: "gemini-3.8-flash-high",
name: "Gemini 3.8 Flash (High)",
contextLength: 1048576,
maxOutputTokens: 65536,
supportsReasoning: true,
supportsVision: true,
toolCalling: true,
},
{
id: "gemini-3.8-flash-medium",
name: "Gemini 3.8 Flash (Medium)",
contextLength: 1048576,
maxOutputTokens: 65536,
supportsReasoning: true,
supportsVision: true,
toolCalling: true,
},
{
id: "gemini-3.8-flash-low",
name: "Gemini 3.8 Flash (Low)",
contextLength: 1048576,
maxOutputTokens: 65536,
supportsReasoning: true,
supportsVision: true,
toolCalling: true,
},
// Gemini 3.7 Flash tiers. The live endpoint selects High by default and advertises
// all three ids to both the IDE 2.5.5 and CLI 1.1.x clients.
{
Expand Down
3 changes: 3 additions & 0 deletions open-sse/config/freeModelCatalog.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [
{ provider: "agentrouter", modelId: "claude-opus-4-8", displayName: "Claude Opus 4.8", monthlyTokens: 0, creditTokens: 200000000, freeType: "one-time-initial", poolKey: "agentrouter", tos: "caution" },
{ provider: "agentrouter", modelId: "claude-opus-5", displayName: "Claude Opus 5", monthlyTokens: 0, creditTokens: 200000000, freeType: "one-time-initial", poolKey: "agentrouter", tos: "caution" },
{ provider: "agentrouter", modelId: "gpt-5.6-sol", displayName: "GPT-5.6 Sol", monthlyTokens: 0, creditTokens: 200000000, freeType: "one-time-initial", poolKey: "agentrouter", tos: "caution" },
{ provider: "agy", modelId: "gemini-3.8-flash-high", displayName: "Gemini 3.8 Flash (High)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
{ provider: "agy", modelId: "gemini-3.8-flash-medium", displayName: "Gemini 3.8 Flash (Medium)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
{ provider: "agy", modelId: "gemini-3.8-flash-low", displayName: "Gemini 3.8 Flash (Low)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
{ provider: "agy", modelId: "gemini-3.7-flash-high", displayName: "Gemini 3.7 Flash (High)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
{ provider: "agy", modelId: "gemini-3.7-flash-medium", displayName: "Gemini 3.7 Flash (Medium)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
{ provider: "agy", modelId: "gemini-3.7-flash-low", displayName: "Gemini 3.7 Flash (Low)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
Expand Down
2 changes: 1 addition & 1 deletion open-sse/services/antigravityClientProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function getProjectHeaderValue(body: unknown): string | null {
const project =
body && typeof body === "object" ? (body as Record<string, unknown>).project : null;
if (typeof project !== "string" || project.trim().length === 0) return null;
if (project === "test-project" || project === "project-id") return null;
if (project === "test-project" || project === "project-id" || project === "aicode-consumers") return null;
return project;
}

Expand Down
4 changes: 2 additions & 2 deletions open-sse/services/antigravityVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const ANTIGRAVITY_CLI_RELEASE_URL =

export const ANTIGRAVITY_VERSION_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
export const ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS = 5_000;
export const ANTIGRAVITY_IDE_FALLBACK_VERSION = "2.1.1";
export const ANTIGRAVITY_CLI_FALLBACK_VERSION = "1.1.5";
export const ANTIGRAVITY_IDE_FALLBACK_VERSION = "2.5.5";
export const ANTIGRAVITY_CLI_FALLBACK_VERSION = "1.1.24";

type VersionCache = {
fetchedAt: number;
Expand Down
6 changes: 6 additions & 0 deletions src/shared/constants/cliTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
acpSpawnable: false,
baseUrlSupport: "none",
modelAliases: [
"gemini-3.8-flash-high",
"gemini-3.8-flash-medium",
"gemini-3.8-flash-low",
"gemini-3.7-flash-high",
"gemini-3.7-flash-medium",
"gemini-3.7-flash-low",
Expand All @@ -252,6 +255,9 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
"gpt-oss-120b-medium",
],
defaultModels: [
createCliModel("gemini-3.8-flash-high", "Gemini 3.8 Flash High"),
createCliModel("gemini-3.8-flash-medium", "Gemini 3.8 Flash Medium"),
createCliModel("gemini-3.8-flash-low", "Gemini 3.8 Flash Low"),
createCliModel("gemini-3.7-flash-high", "Gemini 3.7 Flash High"),
createCliModel("gemini-3.7-flash-medium", "Gemini 3.7 Flash Medium"),
createCliModel("gemini-3.7-flash-low", "Gemini 3.7 Flash Low"),
Expand Down
17 changes: 3 additions & 14 deletions src/shared/constants/modelSpecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ export const MODEL_SPECS: Record<string, ModelSpec> = {
supportsTools: true,
supportsVision: true,
},
// Output limit published at https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash.
// Thinking budgets follow the 3.7 Flash high/medium/low/tiered split.
// ── Gemini 3.8 Flash (current Antigravity/AGY live tiers) ─────────
"gemini-3.8-flash-high": {
maxOutputTokens: 65536,
contextWindow: 1048576,
Expand Down Expand Up @@ -229,23 +228,13 @@ export const MODEL_SPECS: Record<string, ModelSpec> = {
"gemini-3.8-flash": {
maxOutputTokens: 65536,
contextWindow: 1048576,
defaultThinkingBudget: 8192,
thinkingBudgetCap: 24576,
supportsThinking: true,
supportsTools: true,
supportsVision: true,
aliases: ["gemini-3.8-flash-tiered"],
},
"gemini-3.8-flash-tiered": {
maxOutputTokens: 65536,
contextWindow: 1048576,
defaultThinkingBudget: 8192,
defaultThinkingBudget: 24576,
thinkingBudgetCap: 24576,
supportsThinking: true,
supportsTools: true,
supportsVision: true,
aliases: ["gemini-3.8-flash-high"],
},

// Gemini 3.7 Flash tiers: high 24.5k, medium 8k, low 1k thinking tokens.
"gemini-3.7-flash-high": {
maxOutputTokens: 65536,
Expand Down
3 changes: 3 additions & 0 deletions src/shared/constants/pricing/oauth-subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import {
} from "./shared-tiers";

const ANTIGRAVITY_GEMINI_3_7_PRICING = {
"gemini-3.8-flash-low": GEMINI_3_7_FLASH_PROMO_PRICING,
"gemini-3.8-flash-medium": GEMINI_3_7_FLASH_PROMO_PRICING,
"gemini-3.8-flash-high": GEMINI_3_7_FLASH_PROMO_PRICING,
"gemini-3.7-flash-low": GEMINI_3_7_FLASH_PROMO_PRICING,
"gemini-3.7-flash-medium": GEMINI_3_7_FLASH_PROMO_PRICING,
"gemini-3.7-flash-high": GEMINI_3_7_FLASH_PROMO_PRICING,
Expand Down
12 changes: 12 additions & 0 deletions tests/unit/agy-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ test("agy ships its own live callable model catalog", () => {
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.8-flash-low"), "must expose Gemini 3.8 Flash Low");
assert.ok(ids.includes("gemini-3.8-flash-medium"), "must expose Gemini 3.8 Flash Medium");
assert.ok(ids.includes("gemini-3.8-flash-high"), "must expose Gemini 3.8 Flash High");
assert.ok(ids.includes("gemini-3.7-flash-low"), "must expose Gemini 3.7 Flash Low");
assert.ok(ids.includes("gemini-3.7-flash-medium"), "must expose Gemini 3.7 Flash Medium");
assert.ok(ids.includes("gemini-3.7-flash-high"), "must expose Gemini 3.7 Flash High");
Expand Down Expand Up @@ -82,6 +85,9 @@ test("agy model helpers resolve catalog ids and display names", () => {
assert.equal(isUserCallableAgyModelId("gemini-2.5-flash"), false);
assert.equal(isUserCallableAgyModelId("gemini-3.1-pro-high"), false);
assert.equal(isUserCallableAgyModelId("gemini-pro-agent"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.8-flash-low"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.8-flash-medium"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.8-flash-high"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.7-flash-low"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.7-flash-medium"), true);
assert.equal(isUserCallableAgyModelId("gemini-3.7-flash-high"), true);
Expand All @@ -102,6 +108,12 @@ test("agy model helpers resolve catalog ids and display names", () => {
"Claude Opus 4.6 (Thinking)"
);
assert.equal(getClientVisibleAgyModelName("gemini-pro-agent"), "Gemini 3.1 Pro (High)");
assert.equal(getClientVisibleAgyModelName("gemini-3.8-flash-low"), "Gemini 3.8 Flash (Low)");
assert.equal(
getClientVisibleAgyModelName("gemini-3.8-flash-medium"),
"Gemini 3.8 Flash (Medium)"
);
assert.equal(getClientVisibleAgyModelName("gemini-3.8-flash-high"), "Gemini 3.8 Flash (High)");
assert.equal(getClientVisibleAgyModelName("gemini-3.7-flash-low"), "Gemini 3.7 Flash (Low)");
assert.equal(
getClientVisibleAgyModelName("gemini-3.7-flash-medium"),
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/antigravity-client-profile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,22 @@ test("content header application emits IDE and CLI identities and strips fake he
assert.equal(cliHeaders["x-goog-user-project"], "project-1");
});

test("content headers omit x-goog-user-project for the aicode-consumers default project", () => {
seedAntigravityIdeVersionCache("2.1.1");
const headers: Record<string, string> = {
Authorization: "Bearer token",
"x-goog-user-project": "stale-project",
};

applyAntigravityClientProfileHeaders(
headers,
{ connectionId: "connection-ide", providerSpecificData: { clientProfile: "ide" } },
{ project: "aicode-consumers" }
);

assert.equal(headers["x-goog-user-project"], undefined);
});

test("public request envelopes never infer the internal jetski identity from email", () => {
assert.equal(getAntigravityEnvelopeUserAgent({ email: "user@gmail.com" }), "antigravity");
assert.equal(getAntigravityEnvelopeUserAgent({ email: "user@company.example" }), "antigravity");
Expand Down
19 changes: 17 additions & 2 deletions tests/unit/antigravity-model-aliases.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,23 @@ function getPublicModel(id: string) {
// `gemini-3.7-flash-tiered`) in favor of three directly-callable tiered public models —
// the suffixed ids now work upstream without the collapsing alias. Keep this list in sync
// with ANTIGRAVITY_PUBLIC_MODELS/ANTIGRAVITY_MODEL_ALIASES instead of the retired bare id.
const EXPECTED_FLASH_TIERS = [
const EXPECTED_38_FLASH_TIERS = [
["gemini-3.8-flash-high", "Gemini 3.8 Flash (High)"],
["gemini-3.8-flash-medium", "Gemini 3.8 Flash (Medium)"],
["gemini-3.8-flash-low", "Gemini 3.8 Flash (Low)"],
] as const;

const EXPECTED_37_FLASH_TIERS = [
["gemini-3.7-flash-high", "Gemini 3.7 Flash (High)"],
["gemini-3.7-flash-medium", "Gemini 3.7 Flash (Medium)"],
["gemini-3.7-flash-low", "Gemini 3.7 Flash (Low)"],
] as const;

const EXPECTED_FLASH_TIERS = [
...EXPECTED_38_FLASH_TIERS,
...EXPECTED_37_FLASH_TIERS,
] as const;

const RETIRED_FLASH_IDS = [
"gemini-3.6-flash-low",
"gemini-3.6-flash-medium",
Expand Down Expand Up @@ -57,7 +68,11 @@ test("toClientAntigravityQuotaModelId preserves upstream Gemini Flash bucket IDs

test("resolveAntigravityModelId maps the documented Antigravity aliases to upstream IDs", () => {
assert.equal(resolveAntigravityModelId("gemini-3-pro-image-preview"), "gemini-3-pro-image");
for (const [modelId] of EXPECTED_FLASH_TIERS) {
for (const [modelId] of EXPECTED_38_FLASH_TIERS) {
assert.equal(resolveAntigravityModelId(modelId), modelId);
}
assert.equal(resolveAntigravityModelId("gemini-3.8-flash"), "gemini-3.8-flash-high");
for (const [modelId] of EXPECTED_37_FLASH_TIERS) {
assert.equal(resolveAntigravityModelId(modelId), "gemini-3.7-flash-tiered");
}
assert.equal(resolveAntigravityModelId("gemini-3.7-flash"), "gemini-3.7-flash-tiered");
Expand Down
2 changes: 0 additions & 2 deletions tests/unit/antigravity-per-model-output-cap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ test("Gemini 3.8 Flash retains its output allowance above the thinking budget",
"gemini-3.8-flash-high",
"gemini-3.8-flash-medium",
"gemini-3.8-flash-low",
"gemini-3.8-flash-tiered",
]) {
const result = await executor.transformRequest(
`antigravity/${model}`,
Expand Down Expand Up @@ -232,7 +231,6 @@ test("Gemini 3.8 Flash static spec keeps thinking and context, not only the outp
"gemini-3.8-flash-high": 24576,
"gemini-3.8-flash-medium": 8192,
"gemini-3.8-flash-low": 1024,
"gemini-3.8-flash-tiered": 8192,
};
for (const model of Object.keys(expectedBudget)) {
const caps = getResolvedModelCapabilities({
Expand Down
8 changes: 7 additions & 1 deletion tests/unit/antigravity-retired-public-models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const RETIRED_PUBLIC_MODELS = [
] as const;

const EXPECTED_LEADING_MODEL_ORDER = [
"gemini-3.8-flash-high",
"gemini-3.8-flash-medium",
"gemini-3.8-flash-low",
"gemini-3.7-flash-high",
"gemini-3.7-flash-medium",
"gemini-3.7-flash-low",
Expand All @@ -45,6 +48,9 @@ const EXPECTED_LEADING_MODEL_ORDER = [
] as const;

const ACTIVE_FLASH_MODEL_IDS = [
"gemini-3.8-flash-high",
"gemini-3.8-flash-medium",
"gemini-3.8-flash-low",
"gemini-3.7-flash-high",
"gemini-3.7-flash-medium",
"gemini-3.7-flash-low",
Expand Down Expand Up @@ -112,7 +118,7 @@ test("Antigravity and AGY expose gemini-pro-agent and gemini-3.1-pro-high as cal
);
});

test("Antigravity support catalogs expose every live Gemini 3.7 Flash tier", () => {
test("Antigravity support catalogs expose every live Gemini Flash tier", () => {
const antigravityModelIds = new Set(ANTIGRAVITY_PUBLIC_MODELS.map((model) => model.id));
const agyModelIds = new Set(AGY_PUBLIC_MODELS.map((model) => model.id));
const cliAliases = new Set(CLI_TOOLS.antigravity.modelAliases);
Expand Down
Loading