From b857a8d8bc4aa818ee6a2a1d4aee49e1a497d6ac Mon Sep 17 00:00:00 2001 From: scoootscooob <167050519+scoootscooob@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:45:34 -0700 Subject: [PATCH] fix(models): apply Gemini model-id normalization to google-vertex provider (#42435) * fix(models): apply Gemini model-id normalization to google-vertex provider The existing normalizeGoogleModelId() (which maps e.g. gemini-3.1-flash-lite to gemini-3.1-flash-lite-preview) was only applied when the provider was "google". Users configuring google-vertex/gemini-3.1-flash-lite would get a "missing" model because the -preview suffix was never appended. Extend the normalization to google-vertex in both model-selection (parseModelRef path) and normalizeProviders (config normalization path). Ref: https://github.com/openclaw/openclaw/issues/36838 Ref: https://github.com/openclaw/openclaw/pull/36918#issuecomment-4032732959 * fix(models): normalize google-vertex flash-lite * fix(models): place unreleased changelog entry last * fix(models): place unreleased changelog entry before releases --- CHANGELOG.md | 2 ++ src/agents/model-selection.test.ts | 7 ++++- src/agents/model-selection.ts | 2 +- ...onfig.providers.google-antigravity.test.ts | 30 +++++++++++++++++++ src/agents/models-config.providers.ts | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71dbee62a2f..c4ac79f3df4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ Docs: https://docs.openclaw.ai - Discord/allowlists: honor raw `guild_id` when hydrated guild objects are missing so allowlisted channels and threads like `#maintainers` no longer get false-dropped before channel allowlist checks. - macOS/runtime locator: require Node >=22.16.0 during macOS runtime discovery so the app no longer accepts Node versions that the main runtime guard rejects later. Thanks @sumleo. - Agents/custom providers: preserve blank API keys for loopback OpenAI-compatible custom providers by clearing the synthetic Authorization header at runtime, while keeping explicit apiKey and oauth/token config from silently downgrading into fake bearer auth. (#45631) Thanks @xinhuagu. +- Models/google-vertex Gemini flash-lite normalization: apply existing bare-ID preview normalization to `google-vertex` model refs and provider configs so `google-vertex/gemini-3.1-flash-lite` resolves as `gemini-3.1-flash-lite-preview`. (#42435) thanks @scoootscooob. ## 2026.3.12 @@ -373,6 +374,7 @@ Docs: https://docs.openclaw.ai - Agents/compaction transcript updates: emit a transcript-update event immediately after successful embedded compaction so downstream listeners observe the post-compact transcript without waiting for a later write. (#25558) thanks @rodrigouroz. - Agents/sessions_spawn: use the target agent workspace for cross-agent spawned runs instead of inheriting the caller workspace, so child sessions load the correct workspace-scoped instructions and persona files. (#40176) Thanks @moshehbenavraham. + ## 2026.3.7 ### Changes diff --git a/src/agents/model-selection.test.ts b/src/agents/model-selection.test.ts index bf4c3aee03e..7fa8832e0e7 100644 --- a/src/agents/model-selection.test.ts +++ b/src/agents/model-selection.test.ts @@ -241,6 +241,12 @@ describe("model-selection", () => { defaultProvider: "anthropic", expected: { provider: "openai", model: "gpt-5.3-codex-codex" }, }, + { + name: "normalizes gemini 3.1 flash-lite ids for google-vertex", + variants: ["google-vertex/gemini-3.1-flash-lite", "gemini-3.1-flash-lite"], + defaultProvider: "google-vertex", + expected: { provider: "google-vertex", model: "gemini-3.1-flash-lite-preview" }, + }, ])("$name", ({ variants, defaultProvider, expected }) => { expectParsedModelVariants(variants, defaultProvider, expected); }); @@ -252,7 +258,6 @@ describe("model-selection", () => { "anthropic/claude-opus-4-6", ); }); - it.each(["", " ", "/", "anthropic/", "/model"])("returns null for invalid ref %j", (raw) => { expect(parseModelRef(raw, "anthropic")).toBeNull(); }); diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index 6606b0bc4b4..72cd5951292 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -171,7 +171,7 @@ function normalizeProviderModelId(provider: string, model: string): string { return `anthropic/${normalizedAnthropicModel}`; } } - if (provider === "google") { + if (provider === "google" || provider === "google-vertex") { return normalizeGoogleModelId(model); } // OpenRouter-native models (e.g. "openrouter/aurora-alpha") need the full diff --git a/src/agents/models-config.providers.google-antigravity.test.ts b/src/agents/models-config.providers.google-antigravity.test.ts index 3886b237e27..ea20608b866 100644 --- a/src/agents/models-config.providers.google-antigravity.test.ts +++ b/src/agents/models-config.providers.google-antigravity.test.ts @@ -97,3 +97,33 @@ describe("google-antigravity provider normalization", () => { expect(normalized).toBe(providers); }); }); + +describe("google-vertex provider normalization", () => { + it("normalizes gemini flash-lite IDs for google-vertex providers", () => { + const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); + const providers = { + "google-vertex": buildProvider(["gemini-3.1-flash-lite", "gemini-3-flash-preview"]), + openai: buildProvider(["gpt-5"]), + }; + + const normalized = normalizeProviders({ providers, agentDir }); + + expect(normalized).not.toBe(providers); + expect(normalized?.["google-vertex"]?.models.map((model) => model.id)).toEqual([ + "gemini-3.1-flash-lite-preview", + "gemini-3-flash-preview", + ]); + expect(normalized?.openai).toBe(providers.openai); + }); + + it("returns original providers object when no google-vertex IDs need normalization", () => { + const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); + const providers = { + "google-vertex": buildProvider(["gemini-3.1-flash-lite-preview", "gemini-3-flash-preview"]), + }; + + const normalized = normalizeProviders({ providers, agentDir }); + + expect(normalized).toBe(providers); + }); +}); diff --git a/src/agents/models-config.providers.ts b/src/agents/models-config.providers.ts index 4c9febf2ef1..b4ef8f4b0b1 100644 --- a/src/agents/models-config.providers.ts +++ b/src/agents/models-config.providers.ts @@ -545,7 +545,7 @@ export function normalizeProviders(params: { } } - if (normalizedKey === "google") { + if (normalizedKey === "google" || normalizedKey === "google-vertex") { const googleNormalized = normalizeGoogleProvider(normalizedProvider); if (googleNormalized !== normalizedProvider) { mutated = true;