diff --git a/src/agents/model-id-normalization.ts b/src/agents/model-id-normalization.ts new file mode 100644 index 00000000000..9b0b27a7f01 --- /dev/null +++ b/src/agents/model-id-normalization.ts @@ -0,0 +1,23 @@ +// Keep model ID normalization dependency-free so config parsing and other +// startup-only paths do not pull in provider discovery or plugin loading. +export function normalizeGoogleModelId(id: string): string { + if (id === "gemini-3-pro") { + return "gemini-3-pro-preview"; + } + if (id === "gemini-3-flash") { + return "gemini-3-flash-preview"; + } + if (id === "gemini-3.1-pro") { + return "gemini-3.1-pro-preview"; + } + if (id === "gemini-3.1-flash-lite") { + return "gemini-3.1-flash-lite-preview"; + } + // Preserve compatibility with earlier OpenClaw docs/config that pointed at a + // non-existent Gemini Flash preview ID. Google's current Flash text model is + // `gemini-3-flash-preview`. + if (id === "gemini-3.1-flash" || id === "gemini-3.1-flash-preview") { + return "gemini-3-flash-preview"; + } + return id; +} diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index 72cd5951292..1f73ca6a1b4 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -13,9 +13,9 @@ import { resolveAgentModelFallbacksOverride, } from "./agent-scope.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js"; +import { normalizeGoogleModelId } from "./model-id-normalization.js"; import type { ModelCatalogEntry } from "./model-catalog.js"; import { splitTrailingAuthProfile } from "./model-ref-profile.js"; -import { normalizeGoogleModelId } from "./models-config.providers.js"; const log = createSubsystemLogger("model-selection"); diff --git a/src/agents/models-config.providers.google-antigravity.test.ts b/src/agents/models-config.providers.google-antigravity.test.ts index ea20608b866..f14cab01493 100644 --- a/src/agents/models-config.providers.google-antigravity.test.ts +++ b/src/agents/models-config.providers.google-antigravity.test.ts @@ -2,9 +2,9 @@ import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; +import { normalizeGoogleModelId } from "./model-id-normalization.js"; import { normalizeAntigravityModelId, - normalizeGoogleModelId, normalizeProviders, type ProviderConfig, } from "./models-config.providers.js"; diff --git a/src/agents/models-config.providers.ts b/src/agents/models-config.providers.ts index b4ef8f4b0b1..229a861c0e5 100644 --- a/src/agents/models-config.providers.ts +++ b/src/agents/models-config.providers.ts @@ -8,6 +8,7 @@ import { isRecord } from "../utils.js"; import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js"; import { ensureAuthProfileStore, listProfilesForProvider } from "./auth-profiles.js"; import { discoverBedrockModels } from "./bedrock-discovery.js"; +import { normalizeGoogleModelId } from "./model-id-normalization.js"; import { buildCloudflareAiGatewayModelDefinition, resolveCloudflareAiGatewayBaseUrl, @@ -70,6 +71,7 @@ import { } from "./model-auth-markers.js"; import { resolveAwsSdkEnvVarName, resolveEnvApiKey } from "./model-auth.js"; export { resolveOllamaApiBase } from "./models-config.providers.discovery.js"; +export { normalizeGoogleModelId }; type ModelsConfig = NonNullable; export type ProviderConfig = NonNullable[string]; @@ -223,28 +225,6 @@ function resolveApiKeyFromProfiles(params: { return undefined; } -export function normalizeGoogleModelId(id: string): string { - if (id === "gemini-3-pro") { - return "gemini-3-pro-preview"; - } - if (id === "gemini-3-flash") { - return "gemini-3-flash-preview"; - } - if (id === "gemini-3.1-pro") { - return "gemini-3.1-pro-preview"; - } - if (id === "gemini-3.1-flash-lite") { - return "gemini-3.1-flash-lite-preview"; - } - // Preserve compatibility with earlier OpenClaw docs/config that pointed at a - // non-existent Gemini Flash preview ID. Google's current Flash text model is - // `gemini-3-flash-preview`. - if (id === "gemini-3.1-flash" || id === "gemini-3.1-flash-preview") { - return "gemini-3-flash-preview"; - } - return id; -} - const ANTIGRAVITY_BARE_PRO_IDS = new Set(["gemini-3-pro", "gemini-3.1-pro", "gemini-3-1-pro"]); export function normalizeAntigravityModelId(id: string): string { diff --git a/src/media-understanding/providers/google/inline-data.ts b/src/media-understanding/providers/google/inline-data.ts index 69fd41871e8..18116a54bc2 100644 --- a/src/media-understanding/providers/google/inline-data.ts +++ b/src/media-understanding/providers/google/inline-data.ts @@ -1,4 +1,4 @@ -import { normalizeGoogleModelId } from "../../../agents/models-config.providers.js"; +import { normalizeGoogleModelId } from "../../../agents/model-id-normalization.js"; import { parseGeminiAuth } from "../../../infra/gemini-auth.js"; import { assertOkOrThrowHttpError, normalizeBaseUrl, postJsonRequest } from "../shared.js";