diff --git a/src/agents/model-forward-compat.ts b/src/agents/model-forward-compat.ts index d19ab3d1a3f..e27260db832 100644 --- a/src/agents/model-forward-compat.ts +++ b/src/agents/model-forward-compat.ts @@ -241,15 +241,17 @@ function resolveAnthropicSonnet46ForwardCompatModel( }); } -// gemini-3.1-pro-preview / gemini-3.1-flash-preview are not present in pi-ai's built-in -// google-gemini-cli catalog yet. Clone the nearest gemini-3 template so users don't get -// "Unknown model" errors when Google Gemini CLI gains new minor-version models. -function resolveGoogleGeminiCli31ForwardCompatModel( +// gemini-3.1-pro-preview / gemini-3.1-flash-preview are not present in some pi-ai +// Google catalogs yet. Clone the nearest gemini-3 template so users don't get +// "Unknown model" errors when Google ships new minor-version models before pi-ai +// updates its built-in registry. +function resolveGoogle31ForwardCompatModel( provider: string, modelId: string, modelRegistry: ModelRegistry, ): Model | undefined { - if (normalizeProviderId(provider) !== "google-gemini-cli") { + const normalizedProvider = normalizeProviderId(provider); + if (normalizedProvider !== "google" && normalizedProvider !== "google-gemini-cli") { return undefined; } const trimmed = modelId.trim(); @@ -265,7 +267,7 @@ function resolveGoogleGeminiCli31ForwardCompatModel( } return cloneFirstTemplateModel({ - normalizedProvider: "google-gemini-cli", + normalizedProvider, trimmedModelId: trimmed, templateIds: [...templateIds], modelRegistry, @@ -326,6 +328,6 @@ export function resolveForwardCompatModel( resolveAnthropicOpus46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveAnthropicSonnet46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveZaiGlm5ForwardCompatModel(provider, modelId, modelRegistry) ?? - resolveGoogleGeminiCli31ForwardCompatModel(provider, modelId, modelRegistry) + resolveGoogle31ForwardCompatModel(provider, modelId, modelRegistry) ); } diff --git a/src/agents/pi-embedded-runner/model.forward-compat.test.ts b/src/agents/pi-embedded-runner/model.forward-compat.test.ts index 310f62d0d32..bdee17f1e9a 100644 --- a/src/agents/pi-embedded-runner/model.forward-compat.test.ts +++ b/src/agents/pi-embedded-runner/model.forward-compat.test.ts @@ -11,6 +11,7 @@ import { GOOGLE_GEMINI_CLI_FLASH_TEMPLATE_MODEL, GOOGLE_GEMINI_CLI_PRO_TEMPLATE_MODEL, makeModel, + mockDiscoveredModel, mockGoogleGeminiCliFlashTemplateModel, mockGoogleGeminiCliProTemplateModel, mockOpenAICodexTemplateModel, @@ -102,6 +103,54 @@ describe("pi embedded model e2e smoke", () => { }); }); + it("builds a google forward-compat fallback for gemini-3.1-pro-preview", () => { + mockDiscoveredModel({ + provider: "google", + modelId: "gemini-3-pro-preview", + templateModel: { + ...GOOGLE_GEMINI_CLI_PRO_TEMPLATE_MODEL, + provider: "google", + api: "google-generative-ai", + baseUrl: "https://generativelanguage.googleapis.com", + }, + }); + + const result = resolveModel("google", "gemini-3.1-pro-preview", "/tmp/agent"); + expect(result.error).toBeUndefined(); + expect(result.model).toMatchObject({ + provider: "google", + api: "google-generative-ai", + baseUrl: "https://generativelanguage.googleapis.com", + id: "gemini-3.1-pro-preview", + name: "gemini-3.1-pro-preview", + reasoning: true, + }); + }); + + it("builds a google forward-compat fallback for gemini-3.1-flash-lite-preview", () => { + mockDiscoveredModel({ + provider: "google", + modelId: "gemini-3-flash-preview", + templateModel: { + ...GOOGLE_GEMINI_CLI_FLASH_TEMPLATE_MODEL, + provider: "google", + api: "google-generative-ai", + baseUrl: "https://generativelanguage.googleapis.com", + }, + }); + + const result = resolveModel("google", "gemini-3.1-flash-lite-preview", "/tmp/agent"); + expect(result.error).toBeUndefined(); + expect(result.model).toMatchObject({ + provider: "google", + api: "google-generative-ai", + baseUrl: "https://generativelanguage.googleapis.com", + id: "gemini-3.1-flash-lite-preview", + name: "gemini-3.1-flash-lite-preview", + reasoning: true, + }); + }); + it("keeps unknown-model errors for unrecognized google-gemini-cli model IDs", () => { const result = resolveModel("google-gemini-cli", "gemini-4-unknown", "/tmp/agent"); expect(result.model).toBeUndefined();