From c3c9c2a8fdb61ebc69737c6b2ed7668a02661feb Mon Sep 17 00:00:00 2001 From: luvs01 Date: Sat, 15 Aug 2026 11:40:24 +0900 Subject: [PATCH] fix(antigravity): route partial Gemini 3.7 tiers --- src/providers/antigravity-models.ts | 27 ++++++++++++++++++++++----- tests/google-antigravity-wire.test.ts | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/providers/antigravity-models.ts b/src/providers/antigravity-models.ts index c6b0ea283d..ca581b5062 100644 --- a/src/providers/antigravity-models.ts +++ b/src/providers/antigravity-models.ts @@ -48,6 +48,15 @@ const RETIRED_FLASH_TIERS: Record = { "gemini-3-flash-agent": "high", }; +// Some discovery responses still publish the current Flash thinking levels as +// separate rows. These IDs are picker-visible when the response contains only a +// partial tier set, but CCA accepts them only through the tiered wire ID. +const CURRENT_FLASH_DISCOVERY_TIERS: Record = { + "gemini-3.7-flash-low": "low", + "gemini-3.7-flash-medium": "medium", + "gemini-3.7-flash-high": "high", +}; + const ANTIGRAVITY_WIRE_MODELS = [ "gemini-3.7-flash-tiered", "gemini-3.1-pro-low", @@ -361,16 +370,24 @@ export function retiredAntigravityFlashTier(modelId: string): string | undefined * Resolve a picker-visible base model + optional reasoning effort to the CCA wire model ID. * * Precedence (evaluated in order): - * 1. Suffix wire ID or compat alias → resolve via `resolveAntigravityWireModelId`, no thinkingConfig. - * 2. Mapped Gemini base with effort → return mapped wire ID + thinkingLevel. - * 3. Mapped Gemini base without effort → return default-effort wire ID, no thinkingConfig. - * 4. Claude Opus with effort → return identity + thinkingLevel (no suffix variants exist). - * 5. All other IDs → return `resolveAntigravityWireModelId(modelId)`, no thinkingConfig. + * 1. Current Flash discovery tier → tiered wire ID + its thinkingLevel. + * 2. Suffix wire ID or compat alias → resolve via `resolveAntigravityWireModelId`, no thinkingConfig. + * 3. Mapped Gemini base with effort → return mapped wire ID + thinkingLevel. + * 4. Mapped Gemini base without effort → return default-effort wire ID, no thinkingConfig. + * 5. Claude Opus with effort → return identity + thinkingLevel (no suffix variants exist). + * 6. All other IDs → return `resolveAntigravityWireModelId(modelId)`, no thinkingConfig. */ export function resolveAntigravityEffortWireModel( modelId: string, effort?: string, ): { wireModelId: string; thinkingLevel?: string } { + const discoveryTier = Object.hasOwn(CURRENT_FLASH_DISCOVERY_TIERS, modelId) + ? CURRENT_FLASH_DISCOVERY_TIERS[modelId] + : undefined; + if (discoveryTier) { + return { wireModelId: GEMINI_FLASH_WIRE_ID, thinkingLevel: discoveryTier }; + } + // Rule 0: retired Flash id — Google has taken the wire id offline, so route to the // current generation and carry the tier the retired id encoded. This runs BEFORE the // suffix check because those ids are aliases, and rule 1 would drop the tier. diff --git a/tests/google-antigravity-wire.test.ts b/tests/google-antigravity-wire.test.ts index 5ea15eff2a..6241544bce 100644 --- a/tests/google-antigravity-wire.test.ts +++ b/tests/google-antigravity-wire.test.ts @@ -197,6 +197,24 @@ describe("antigravity CCA envelope", () => { } }); + test("routes partial Gemini 3.7 discovery tiers through thinkingLevel", async () => { + for (const [modelId, thinkingLevel] of [ + ["gemini-3.7-flash-low", "low"], + ["gemini-3.7-flash-medium", "medium"], + ["gemini-3.7-flash-high", "high"], + ] as const) { + expect(resolveAntigravityEffortWireModel(modelId)).toEqual({ + wireModelId: "gemini-3.7-flash-tiered", + thinkingLevel, + }); + + const req = await createGoogleAdapter(effortProvider).buildRequest(parsedWithEffort(modelId)); + const env = JSON.parse(req.body); + expect(env.model).toBe("gemini-3.7-flash-tiered"); + expect(env.request.generationConfig.thinkingConfig).toEqual({ thinkingLevel }); + } + }); + test("ignores inherited CCA model and alias properties", () => { const inheritedModels = Object.create(null) as Record; Object.defineProperty(inheritedModels, "__proto__", {