diff --git a/src/providers/antigravity-models.ts b/src/providers/antigravity-models.ts index 5ad7403aa15..75e8ad5fead 100644 --- a/src/providers/antigravity-models.ts +++ b/src/providers/antigravity-models.ts @@ -66,20 +66,30 @@ const RETIRED_FLASH_TIERS: Record = { const ANTIGRAVITY_WIRE_MODELS = [ "gemini-3.7-flash-tiered", - "gemini-3.1-pro-low", - "gemini-pro-agent", - "gemini-3.1-flash-image", - "claude-sonnet-4-6", - "claude-opus-4-6-thinking", - "gpt-oss-120b-medium", + "gemini-3.1-pro-low", + "gemini-pro-agent", + "gemini-3.1-flash-image", + "claude-sonnet-5-5-low", + "claude-sonnet-5-5-medium", + "claude-sonnet-5-5-high", + "claude-opus-5-5-low", + "claude-opus-5-5-medium", + "claude-opus-5-5-high", + "gpt-oss-120b-medium", ]; const ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID: Record = { "gemini-3.8-flash-low": "gemini-3.8-flash", "gemini-3.8-flash-medium": "gemini-3.8-flash", - "gemini-3.8-flash-high": "gemini-3.8-flash", - "gemini-3.1-pro-low": "gemini-3.1-pro", - "gemini-pro-agent": "gemini-3.1-pro", + "gemini-3.8-flash-high": "gemini-3.8-flash", + "gemini-3.1-pro-low": "gemini-3.1-pro", + "gemini-pro-agent": "gemini-3.1-pro", + "claude-sonnet-5-5-low": "claude-sonnet-5-5", + "claude-sonnet-5-5-medium": "claude-sonnet-5-5", + "claude-sonnet-5-5-high": "claude-sonnet-5-5", + "claude-opus-5-5-low": "claude-opus-5-5", + "claude-opus-5-5-medium": "claude-opus-5-5", + "claude-opus-5-5-high": "claude-opus-5-5", }; const ANTIGRAVITY_WIRE_IDS_BY_PICKER_MODEL: Record = Object.entries( @@ -165,11 +175,11 @@ function collapsesIntoKnownPickerModel(candidateId: string): boolean { export const ANTIGRAVITY_MODEL_EFFORTS: Record = { // No `minimal`: Google documents it as an error for this generation, and CCA exposes only // the three tiers. - "gemini-3.8-flash": ["low", "medium", "high"], - "gemini-3.7-flash": ["low", "medium", "high"], - "gemini-3.1-pro": ["low", "high"], - "claude-sonnet-4-6": ["low", "medium", "high", "max"], - "claude-opus-4-6-thinking": ["low", "medium", "high", "max"], + "gemini-3.8-flash": ["low", "medium", "high"], + "gemini-3.7-flash": ["low", "medium", "high"], + "gemini-3.1-pro": ["low", "high"], + "claude-sonnet-5-5": ["low", "medium", "high"], + "claude-opus-5-5": ["low", "medium", "high"], }; // ── Effort → wire model map for Gemini base models ── @@ -181,9 +191,19 @@ const ANTIGRAVITY_EFFORT_WIRE_MAP: Record> = { medium: "gemini-3.8-flash-medium", high: "gemini-3.8-flash-high", }, - "gemini-3.1-pro": { - low: "gemini-3.1-pro-low", - high: "gemini-pro-agent", + "gemini-3.1-pro": { + low: "gemini-3.1-pro-low", + high: "gemini-pro-agent", + }, + "claude-sonnet-5-5": { + low: "claude-sonnet-5-5-low", + medium: "claude-sonnet-5-5-medium", + high: "claude-sonnet-5-5-high", + }, + "claude-opus-5-5": { + low: "claude-opus-5-5-low", + medium: "claude-opus-5-5-medium", + high: "claude-opus-5-5-high", }, }; @@ -198,7 +218,7 @@ const ANTIGRAVITY_EFFORT_WIRE_MAP: Record> = { * `gemini-3.1-pro` is deliberately absent: its `high` rung is `gemini-pro-agent`, which carries * no tier suffix, so there the level is the only thing naming the effort. */ -const ANTIGRAVITY_SUFFIX_TIER_MODELS = new Set(["gemini-3.8-flash"]); +const ANTIGRAVITY_SUFFIX_TIER_MODELS = new Set(["gemini-3.8-flash", "claude-sonnet-5-5", "claude-opus-5-5"]); function completeDiscoveredEffortWireModelIds( pickerId: string, @@ -223,8 +243,10 @@ function completeDiscoveredEffortWireModelIds( // ── Default effort per Gemini base model ── const ANTIGRAVITY_DEFAULT_EFFORT: Record = { // Google's documented thinking_level default, and the tier CCA marks `recommended`. - "gemini-3.8-flash": "medium", - "gemini-3.1-pro": "high", + "gemini-3.8-flash": "medium", + "gemini-3.1-pro": "high", + "claude-sonnet-5-5": "medium", + "claude-opus-5-5": "medium", }; /** @@ -266,6 +288,22 @@ const ANTIGRAVITY_VISIBLE_MODEL_ALIASES: Record = { // ── Hidden compatibility aliases for saved selections ── // Wire suffix IDs are identity aliases — they resolve to themselves so saved configs // with explicit suffixes (e.g. gemini-3.6-flash-low) continue to work. +/** + * Retired Claude 4.6 generation → base model for fallback routing. + * + * Google took the 4.6 Claude models offline when 5.5 shipped. Unlike retired Flash + * (where the suffix named a tier on a single -tiered wire id), Claude 5.5 wire ids + * encode the tier directly (claude-sonnet-5-5-low/medium/high). + * Carrying the base model and consulting the caller's requested effort preserves + * the user's saved or specified reasoning level. + */ +const RETIRED_CLAUDE_BASE: Record = { + "claude-sonnet-4-6": "claude-sonnet-5-5", + "claude-sonnet-4-6-thinking": "claude-sonnet-5-5", + "claude-opus-4-6": "claude-opus-5-5", + "claude-opus-4-6-thinking": "claude-opus-5-5", +}; + const ANTIGRAVITY_COMPATIBILITY_MODEL_ALIASES: Record = { "gemini-3.1-pro-low": "gemini-3.1-pro-low", "gemini-pro-agent": "gemini-pro-agent", @@ -278,6 +316,10 @@ const ANTIGRAVITY_COMPATIBILITY_MODEL_ALIASES: Record = { ...Object.fromEntries( Object.keys(RETIRED_FLASH_TIERS).map(retired => [retired, GEMINI_RETIRED_FLASH_TARGET_WIRE_ID]), ), + // ── Retired Claude generations ── + ...Object.fromEntries( + Object.keys(RETIRED_CLAUDE_BASE).map(retired => [retired, "claude-sonnet-5-5-medium"]), + ), }; export const ANTIGRAVITY_MODEL_ALIASES: Record = { @@ -291,8 +333,8 @@ export const ANTIGRAVITY_MODELS = [ GEMINI_FLASH_PREVIOUS, "gemini-3.1-pro", "gemini-3.1-flash-image", - "claude-sonnet-4-6", - "claude-opus-4-6-thinking", + "claude-sonnet-5-5", + "claude-opus-5-5", "gpt-oss-120b-medium", ]; @@ -309,6 +351,12 @@ const ANTIGRAVITY_WIRE_MODEL_CONTEXT_WINDOWS: Record = { "gemini-3.1-pro-low": 1_048_576, "gemini-pro-agent": 1_048_576, "gemini-3.1-flash-image": 1_048_576, + "claude-sonnet-5-5-low": 1_000_000, + "claude-sonnet-5-5-medium": 1_000_000, + "claude-sonnet-5-5-high": 1_000_000, + "claude-opus-5-5-low": 1_000_000, + "claude-opus-5-5-medium": 1_000_000, + "claude-opus-5-5-high": 1_000_000, "claude-sonnet-4-6": 250_000, "claude-opus-4-6-thinking": 250_000, "gpt-oss-120b-medium": 131_072, @@ -319,6 +367,8 @@ export const ANTIGRAVITY_MODEL_CONTEXT_WINDOWS: Record = { "gemini-3.8-flash": 1_048_576, "gemini-3.7-flash": 1_048_576, "gemini-3.1-pro": 1_048_576, + "claude-sonnet-5-5": 1_000_000, + "claude-opus-5-5": 1_000_000, // Wire IDs and aliases via derivation. ...ANTIGRAVITY_WIRE_MODEL_CONTEXT_WINDOWS, ...Object.fromEntries( @@ -338,8 +388,8 @@ export const ANTIGRAVITY_MODEL_INPUT_MODALITIES: Record = { "gemini-3.7-flash": ["text", "image"], "gemini-3.1-pro": ["text", "image"], "gemini-3.1-flash-image": ["text", "image"], - "claude-sonnet-4-6": ["text", "image"], - "claude-opus-4-6-thinking": ["text", "image"], + "claude-sonnet-5-5": ["text", "image"], + "claude-opus-5-5": ["text", "image"], "gpt-oss-120b-medium": ["text"], }; @@ -702,6 +752,21 @@ export function resolveAntigravityEffortWireModel( }; } + // Rule 0b: retired Claude generation — Google took the 4.6 models offline when 5.5 shipped. + // Route to the corresponding 5.5 wire id while preserving the caller's requested effort + // (low/medium/high, with max/xhigh/ultra clamped to high). If no effort is specified, + // default to medium. + const retiredClaudeBase = Object.hasOwn(RETIRED_CLAUDE_BASE, modelId) + ? RETIRED_CLAUDE_BASE[modelId] : undefined; + if (retiredClaudeBase) { + const targetEffort = effort + ? resolveAntigravityThinkingLevel(effort) ?? "medium" + : "medium"; + const wireModelId = ANTIGRAVITY_EFFORT_WIRE_MAP[retiredClaudeBase]?.[targetEffort] + ?? `${retiredClaudeBase}-${targetEffort}`; + return { wireModelId }; + } + // Rule 1: suffix/compat alias — suffix IS the effort. if (isAntigravitySuffixModelId(modelId)) { return { wireModelId: resolveAntigravityWireModelId(modelId, baseUrl) }; @@ -770,6 +835,7 @@ const ANTIGRAVITY_USAGE_BASE_BY_ID: Record = (() => { // onto a model that did not exist then, and away from the 3.6 price row that still // prices it correctly. Retirement changes what we CALL, not what we RECORD. for (const retired of Object.keys(RETIRED_FLASH_TIERS)) rev[retired] = retired; + for (const retired of Object.keys(RETIRED_CLAUDE_BASE)) rev[retired] = retired; // Usage identity is stable even before discovery; routing keeps its own live evidence. for (const base of ["claude-sonnet-5-5", "claude-opus-5-5"]) { rev[base] = base; diff --git a/tests/adapters/google/antigravity-discovered-families.test.ts b/tests/adapters/google/antigravity-discovered-families.test.ts index 0d10efe26ef..c53c1ae36a6 100644 --- a/tests/adapters/google/antigravity-discovered-families.test.ts +++ b/tests/adapters/google/antigravity-discovered-families.test.ts @@ -62,7 +62,7 @@ test("family metadata uses the lower common capability instead of first-tier met }); test("discovery mapping remains URL scoped and retires with cache generation", () => { - const base = "claude-opus-5-5"; + const base = "future-flash"; registerAntigravityDiscoveredWireModels(baseUrl, parseAntigravityAvailableModels(payload(base))!, { provider: "family-test", cacheGeneration: captureModelCacheGeneration("family-test"), }); diff --git a/tests/adapters/google/google-antigravity-wire.test.ts b/tests/adapters/google/google-antigravity-wire.test.ts index fdb34de1182..90f119cd2b6 100644 --- a/tests/adapters/google/google-antigravity-wire.test.ts +++ b/tests/adapters/google/google-antigravity-wire.test.ts @@ -84,11 +84,21 @@ describe("antigravity CCA envelope", () => { "gemini-3.7-flash", "gemini-3.1-pro", "gemini-3.1-flash-image", - "claude-sonnet-4-6", - "claude-opus-4-6-thinking", + "claude-sonnet-5-5", + "claude-opus-5-5", "gpt-oss-120b-medium", ]); for (const hidden of [ + "claude-sonnet-4-6", + "claude-sonnet-4-6-thinking", + "claude-opus-4-6", + "claude-opus-4-6-thinking", + "claude-sonnet-5-5-low", + "claude-sonnet-5-5-medium", + "claude-sonnet-5-5-high", + "claude-opus-5-5-low", + "claude-opus-5-5-medium", + "claude-opus-5-5-high", "gemini-3.6-flash", "gemini-3.6-flash-low", "gemini-3.6-flash-medium", @@ -254,7 +264,9 @@ describe("antigravity CCA envelope", () => { "gemini-3.7-flash-high": { displayName: "Gemini 3.7 Flash (High)", maxTokens: 1_048_576 }, "gemini-pro-agent": { displayName: "Gemini 3.1 Pro (High)", maxTokens: 1_048_576 }, "gemini-3.1-pro-low": { displayName: "Gemini 3.1 Pro (Low)", maxTokens: 1_048_576 }, - "claude-sonnet-4-6": { displayName: "Claude Sonnet 4.6 (Thinking)", maxTokens: 250_000 }, + "claude-sonnet-5-5-low": { displayName: "Claude Sonnet 5.5 (Low)", maxTokens: 1_000_000 }, + "claude-sonnet-5-5-medium": { displayName: "Claude Sonnet 5.5 (Medium)", maxTokens: 1_000_000 }, + "claude-sonnet-5-5-high": { displayName: "Claude Sonnet 5.5 (High)", maxTokens: 1_000_000 }, // Renamed on the wire, stable in public. Only THIS case may use the label. "internal-codename-x7": { displayName: "Gemini Nebula", maxTokens: 1_048_576 }, }, @@ -264,7 +276,9 @@ describe("antigravity CCA envelope", () => { "gemini-3.7-flash-high", "gemini-pro-agent", "gemini-3.1-pro-low", - "claude-sonnet-4-6", + "claude-sonnet-5-5-low", + "claude-sonnet-5-5-medium", + "claude-sonnet-5-5-high", "internal-codename-x7", ] }] }], }; @@ -274,7 +288,7 @@ describe("antigravity CCA envelope", () => { expect(rows.map(model => model.id)).toEqual([ "gemini-3.7-flash", "gemini-3.1-pro", - "claude-sonnet-4-6", + "claude-sonnet-5-5", "gemini-nebula", ]); // The display label still resolves an id Google renamed on the wire. @@ -299,8 +313,12 @@ describe("antigravity CCA envelope", () => { .toEqual({ wireModelId: "gemini-3.7-flash-high" }); expect(resolveAntigravityEffortWireModel("gemini-nebula", undefined, baseUrl)) .toEqual({ wireModelId: "internal-codename-x7" }); + expect(resolveAntigravityEffortWireModel("claude-sonnet-5-5", "high", baseUrl)) + .toEqual({ wireModelId: "claude-sonnet-5-5-high" }); expect(resolveAntigravityEffortWireModel("claude-sonnet-4-6", "high", baseUrl)) - .toEqual({ wireModelId: "claude-sonnet-4-6", thinkingLevel: "high" }); + .toEqual({ wireModelId: "claude-sonnet-5-5-high" }); + expect(resolveAntigravityEffortWireModel("claude-sonnet-4-6", undefined, baseUrl)) + .toEqual({ wireModelId: "claude-sonnet-5-5-medium" }); const req = await createGoogleAdapter({ ...effortProvider, baseUrl }).buildRequest( parsedWithEffort("gemini-nebula"), @@ -698,55 +716,58 @@ describe("antigravity CCA envelope", () => { // ── Claude Opus effort via thinkingConfig (no suffix variants) ── - test("claude-opus-4-6-thinking with effort=high sends thinkingConfig", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking", "high")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-opus-4-6-thinking"); - expect(env.request.generationConfig?.thinkingConfig?.thinkingLevel).toBe("high"); - }); + test("claude-opus-5-5 routes to suffixed wire IDs and sends no thinkingConfig", async () => { + const highReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-5-5", "high")); + expect(JSON.parse(highReq.body).model).toBe("claude-opus-5-5-high"); + expect(JSON.parse(highReq.body).request.generationConfig?.thinkingConfig).toBeUndefined(); - test("claude-opus-4-6-thinking with effort=max clamps CCA thinkingLevel to high", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking", "max")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-opus-4-6-thinking"); - expect(env.request.generationConfig?.thinkingConfig?.thinkingLevel).toBe("high"); - }); + const maxReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-5-5", "max")); + expect(JSON.parse(maxReq.body).model).toBe("claude-opus-5-5-high"); - test("claude-opus-4-6-thinking with effort=ultra clamps CCA thinkingLevel to high", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking", "ultra")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-opus-4-6-thinking"); - expect(env.request.generationConfig?.thinkingConfig?.thinkingLevel).toBe("high"); - }); + const lowReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-5-5", "low")); + expect(JSON.parse(lowReq.body).model).toBe("claude-opus-5-5-low"); - test("claude-opus-4-6-thinking with no effort sends no thinkingConfig", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-opus-4-6-thinking"); - expect(env.request.generationConfig?.thinkingConfig).toBeUndefined(); + const defaultReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-5-5")); + expect(JSON.parse(defaultReq.body).model).toBe("claude-opus-5-5-medium"); }); - // ── Non-effort models: no thinkingConfig regardless of effort ── + test("claude-sonnet-5-5 routes to suffixed wire IDs and sends no thinkingConfig", async () => { + const highReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-5-5", "high")); + expect(JSON.parse(highReq.body).model).toBe("claude-sonnet-5-5-high"); + expect(JSON.parse(highReq.body).request.generationConfig?.thinkingConfig).toBeUndefined(); - test("claude-sonnet-4-6 with effort=high sends thinkingConfig", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6", "high")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-sonnet-4-6"); - expect(env.request.generationConfig?.thinkingConfig?.thinkingLevel).toBe("high"); + const maxReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-5-5", "max")); + expect(JSON.parse(maxReq.body).model).toBe("claude-sonnet-5-5-high"); + + const lowReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-5-5", "low")); + expect(JSON.parse(lowReq.body).model).toBe("claude-sonnet-5-5-low"); + + const defaultReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-5-5")); + expect(JSON.parse(defaultReq.body).model).toBe("claude-sonnet-5-5-medium"); }); - test("claude-sonnet-4-6 with effort=max clamps CCA thinkingLevel to high", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6", "max")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-sonnet-4-6"); - expect(env.request.generationConfig?.thinkingConfig?.thinkingLevel).toBe("high"); + test("retired claude-opus-4-6-thinking redirects to 5.5 wire IDs preserving effort", async () => { + const highReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking", "high")); + expect(JSON.parse(highReq.body).model).toBe("claude-opus-5-5-high"); + expect(JSON.parse(highReq.body).request.generationConfig?.thinkingConfig).toBeUndefined(); + + const lowReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking", "low")); + expect(JSON.parse(lowReq.body).model).toBe("claude-opus-5-5-low"); + + const defaultReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-opus-4-6-thinking")); + expect(JSON.parse(defaultReq.body).model).toBe("claude-opus-5-5-medium"); }); - test("claude-sonnet-4-6 with no effort sends no thinkingConfig", async () => { - const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6")); - const env = JSON.parse(req.body); - expect(env.model).toBe("claude-sonnet-4-6"); - expect(env.request.generationConfig?.thinkingConfig).toBeUndefined(); + test("retired claude-sonnet-4-6 redirects to 5.5 wire IDs preserving effort", async () => { + const highReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6", "high")); + expect(JSON.parse(highReq.body).model).toBe("claude-sonnet-5-5-high"); + expect(JSON.parse(highReq.body).request.generationConfig?.thinkingConfig).toBeUndefined(); + + const lowReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6", "low")); + expect(JSON.parse(lowReq.body).model).toBe("claude-sonnet-5-5-low"); + + const defaultReq = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort("claude-sonnet-4-6")); + expect(JSON.parse(defaultReq.body).model).toBe("claude-sonnet-5-5-medium"); }); test("gpt-oss-120b-medium with any effort sends no thinkingConfig", async () => { diff --git a/tests/oauth/oauth-provider-reconcile.test.ts b/tests/oauth/oauth-provider-reconcile.test.ts index 8e8a1b67afd..629e79dd82e 100644 --- a/tests/oauth/oauth-provider-reconcile.test.ts +++ b/tests/oauth/oauth-provider-reconcile.test.ts @@ -267,8 +267,8 @@ describe("OAuth provider reconciliation", () => { "gemini-3.7-flash", "gemini-3.1-pro", "gemini-3.1-flash-image", - "claude-sonnet-4-6", - "claude-opus-4-6-thinking", + "claude-sonnet-5-5", + "claude-opus-5-5", "gpt-oss-120b-medium", ]); expect(provider.models).not.toContain("gemini-3.5-flash-low"); diff --git a/tests/providers/provider-antigravity-wire-snapshot.test.ts b/tests/providers/provider-antigravity-wire-snapshot.test.ts index 2821ae4ffbf..b77e43441b4 100644 --- a/tests/providers/provider-antigravity-wire-snapshot.test.ts +++ b/tests/providers/provider-antigravity-wire-snapshot.test.ts @@ -8,13 +8,14 @@ import { removeTreeWithRetry } from "../helpers/remove-tree"; let home: string; beforeEach(() => { home = mkdtempSync(join(tmpdir(), "ocx-agy-restart-")); }); afterEach(() => removeTreeWithRetry(home)); +const base = 'future-flash'; const prefix = ` import { parseAntigravityAvailableModels, registerAntigravityDiscoveredWireModels, resolveAntigravityEffortWireModel } from './src/providers/antigravity-models'; import { captureModelCacheGeneration, clearModelCache, getStaleCached } from './src/codex/model-cache'; import { gatherRoutedModels } from './src/codex/catalog'; const provider = 'google-antigravity'; const baseUrl = 'https://snapshot.example.test/TenantA'; -const base = 'claude-opus-5-5'; +const base = '${base}'; const ids = ['low','medium','high'].map(tier => base+'-'+tier); const payload = {models: Object.fromEntries(ids.map(id => [id, {maxTokens:350000}])), agentModelSorts:[{groups:[{modelIds:ids}]}]}; const config = {port:0, defaultProvider:provider, providers:{[provider]:{adapter:'google',authMode:'key',apiKey:'fixture-token',baseUrl,googleMode:'cloud-code-assist',project:'fixture-project',liveModels:true,models:['safe-previous'],fetch:(...args)=>globalThis.fetch(...args)}}}; @@ -28,7 +29,7 @@ function run(code: string) { } function discover() { expect(run(`globalThis.fetch=async()=>Response.json(payload); console.log(JSON.stringify((await gatherRoutedModels(config)).map(m=>m.id)));`)) - .toEqual(["claude-opus-5-5"]); + .toEqual([base]); } function snapshotFile() { return join(home, readdirSync(home).find(file => file.startsWith("antigravity-wire-"))!); } @@ -57,8 +58,8 @@ test("discovery survives restart and failed discovery with actual adapter wire e console.log(JSON.stringify(wires)); `); expect(result).toEqual([ - {model:"claude-opus-5-5-low"},{model:"claude-opus-5-5-medium"},{model:"claude-opus-5-5-high"},{model:"claude-opus-5-5-medium"}, - {wireModelId:"claude-opus-5-5"},{wireModelId:"claude-opus-5-5"}, + {model:`${base}-low`},{model:`${base}-medium`},{model:`${base}-high`},{model:`${base}-medium`}, + {wireModelId:base},{wireModelId:base}, ]); }); @@ -67,26 +68,26 @@ test("accepted partial and empty discoveries replace old durable families", () = discover(); run(`registerAntigravityDiscoveredWireModels(baseUrl,${models},{provider,cacheGeneration:captureModelCacheGeneration(provider)});console.log('true');`); expect(run(`console.log(JSON.stringify(resolveAntigravityEffortWireModel(base,'high',baseUrl)));`)) - .toEqual({wireModelId:"claude-opus-5-5"}); + .toEqual({wireModelId:base}); } }); test("stale discovery never overwrites durable evidence and path case remains isolated", () => { discover(); expect(run(`const generation=captureModelCacheGeneration(provider);clearModelCache(provider);registerAntigravityDiscoveredWireModels(baseUrl,[],{provider,cacheGeneration:generation});console.log(JSON.stringify(resolveAntigravityEffortWireModel(base,'high',baseUrl)));`)) - .toEqual({wireModelId:"claude-opus-5-5-high"}); + .toEqual({wireModelId:`${base}-high`}); expect(run(`console.log(JSON.stringify(resolveAntigravityEffortWireModel(base,'high',baseUrl.toLowerCase())));`)) - .toEqual({wireModelId:"claude-opus-5-5"}); + .toEqual({wireModelId:base}); }); test("malformed and oversized snapshots fail closed", () => { discover(); const path = snapshotFile(); for (const content of ["{", JSON.stringify({version:2,provider:"google-antigravity",families:{}}), - JSON.stringify({version:1,provider:"google-antigravity",families:{"claude-opus-5-5":{low:"different",medium:"claude-opus-5-5-medium",high:"claude-opus-5-5-high"}}}), " ".repeat(4*1024*1024+1)]) { + JSON.stringify({version:1,provider:"google-antigravity",families:{[base]:{low:"different",medium:`${base}-medium`,high:`${base}-high`}}}), " ".repeat(4*1024*1024+1)]) { writeFileSync(path,content); expect(run(`console.log(JSON.stringify(resolveAntigravityEffortWireModel(base,'high',baseUrl)));`)) - .toEqual({wireModelId:"claude-opus-5-5"}); + .toEqual({wireModelId:base}); } }); @@ -107,6 +108,6 @@ test("generationless registrations stay memory-only and homes do not share mappi const other=resolveAntigravityEffortWireModel(base,'high',baseUrl); process.env.OPENCODEX_HOME=originalHome; console.log(JSON.stringify([original,other,resolveAntigravityEffortWireModel(base,'low',baseUrl)])); - `)).toEqual([{wireModelId:"claude-opus-5-5-high"},{wireModelId:"claude-opus-5-5"},{wireModelId:"claude-opus-5-5-low"}]); + `)).toEqual([{wireModelId:`${base}-high`},{wireModelId:base},{wireModelId:`${base}-low`}]); expect(readdirSync(home).filter(file=>file.startsWith("antigravity-wire-"))).toEqual([]); }); diff --git a/tests/providers/provider-registry-parity.test.ts b/tests/providers/provider-registry-parity.test.ts index 0bbf33e834b..22f1ee56953 100644 --- a/tests/providers/provider-registry-parity.test.ts +++ b/tests/providers/provider-registry-parity.test.ts @@ -1339,8 +1339,10 @@ describe("provider registry parity", () => { // Collapsed picker: base models only, no effort-suffix variants. expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("gemini-3.7-flash"); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("gemini-3.1-pro"); - expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("claude-sonnet-4-6"); - expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("claude-opus-4-6-thinking"); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("claude-sonnet-5-5"); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("claude-opus-5-5"); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).not.toContain("claude-sonnet-4-6"); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).not.toContain("claude-opus-4-6-thinking"); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("gpt-oss-120b-medium"); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("gemini-3.1-flash-image"); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.models).toContain("gemini-3.8-flash"); @@ -1349,12 +1351,14 @@ describe("provider registry parity", () => { expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["gemini-3.8-flash"]).toEqual(["low", "medium", "high"]); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["gemini-3.7-flash"]).toEqual(["low", "medium", "high"]); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["gemini-3.1-pro"]).toEqual(["low", "high"]); - expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["claude-opus-4-6-thinking"]).toEqual(["low", "medium", "high", "max"]); - expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["claude-sonnet-4-6"]).toEqual(["low", "medium", "high", "max"]); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["claude-opus-5-5"]).toEqual(["low", "medium", "high"]); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelReasoningEfforts?.["claude-sonnet-5-5"]).toEqual(["low", "medium", "high"]); // Context windows on collapsed base models. expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelContextWindows?.["gemini-3.8-flash"]).toBe(1_048_576); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelContextWindows?.["gemini-3.7-flash"]).toBe(1_048_576); expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelContextWindows?.["gemini-3.1-pro"]).toBe(1_048_576); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelContextWindows?.["claude-sonnet-5-5"]).toBe(1_000_000); + expect(OAUTH_PROVIDERS["google-antigravity"].providerConfig.modelContextWindows?.["claude-opus-5-5"]).toBe(1_000_000); // Suffix and compat IDs are NOT in the picker list. for (const hidden of [ "gemini-3.6-flash",