fix: hide retired google gemini chat models

Summary:
- Hide retired and non-public Google Gemini model IDs from Control UI/chat model catalogs.
- Route the bare gemini-3-pro alias to gemini-3.1-pro-preview.
- Keep models.list fallback rows filtered by manifest suppressions and update stale pricing-cache expectations.

Verification:
- pnpm test src/commands/models/list.list-command.forward-compat.test.ts src/commands/models/list.rows.test.ts extensions/google/manifest.test.ts extensions/google/model-id.test.ts extensions/google/provider-models.test.ts extensions/google/provider-policy-api.test.ts extensions/google/media-understanding-provider.video.test.ts src/plugin-sdk/provider-model-id-normalize.test.ts src/plugins/manifest-model-suppression.test.ts src/gateway/server-methods/models.test.ts ui/src/ui/chat-model-select-state.test.ts ui/src/ui/chat-model-ref.test.ts
- pnpm test src/gateway/model-pricing-cache.test.ts
- pnpm --silent openclaw models list --all --json --provider google / google-vertex hidden-row probe
- Testbox pnpm check:changed: https://github.com/openclaw/openclaw/actions/runs/25534551033
This commit is contained in:
Val Alexander
2026-05-07 22:20:07 -05:00
committed by GitHub
parent fb106fb9ae
commit 4e983aa57b
14 changed files with 669 additions and 11 deletions

View File

@@ -164,6 +164,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Control UI/chat: hide retired and non-public Google Gemini model IDs from chat model catalogs and route the bare `gemini-3-pro` alias to Gemini 3.1 Pro Preview instead of the shut-down Gemini 3 Pro Preview. Thanks @BunsDev.
- Gateway/watch: leave `OPENCLAW_TRACE_SYNC_IO` disabled by default in `pnpm gateway:watch:raw` so watch mode avoids noisy Node sync-I/O stack traces unless explicitly requested.
- Codex app-server: close stdio stdin before force-killing the managed app-server, matching Codex single-client shutdown behavior and avoiding unsettled CLI exits after successful runs.
- CLI/Codex: dispose registered agent harnesses during short-lived CLI shutdown so successful Codex-backed `agent --local` runs do not leave app-server child processes alive.

View File

@@ -0,0 +1,86 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
type GoogleManifest = {
modelCatalog?: {
suppressions?: Array<{
provider?: string;
model?: string;
reason?: string;
}>;
};
};
const RETIRED_GEMINI_CHAT_MODELS = [
"gemini-1.5-flash",
"gemini-1.5-flash-8b",
"gemini-1.5-pro",
"gemini-2.0-flash-exp",
"gemini-2.0-flash-exp-image-generation",
"gemini-2.0-flash-live-001",
"gemini-2.0-flash-lite-preview",
"gemini-2.0-flash-lite-preview-02-05",
"gemini-2.0-flash-preview-image-generation",
"gemini-2.0-flash-thinking-exp",
"gemini-2.0-flash-thinking-exp-01-21",
"gemini-2.0-flash-thinking-exp-1219",
"gemini-2.0-pro-exp",
"gemini-2.0-pro-exp-02-05",
"gemini-2.5-flash-exp-native-audio-thinking-dialog",
"gemini-2.5-flash-image-preview",
"gemini-2.5-flash-lite-preview-06-17",
"gemini-2.5-flash-lite-preview-09-25",
"gemini-2.5-flash-lite-preview-09-2025",
"gemini-2.5-flash-preview-04-17",
"gemini-2.5-flash-preview-05-20",
"gemini-2.5-flash-preview-09-25",
"gemini-2.5-flash-preview-09-2025",
"gemini-2.5-flash-preview-native-audio-dialog",
"gemini-2.5-pro-exp-03-25",
"gemini-2.5-pro-preview-03-25",
"gemini-2.5-pro-preview-05-06",
"gemini-2.5-pro-preview-06-05",
"gemini-3-pro-preview",
"gemini-3.1-pro-preview-customtools",
"gemini-live-2.5-flash",
"gemini-live-2.5-flash-preview",
"gemini-live-2.5-flash-preview-native-audio",
] as const;
const GOOGLE_CHAT_PROVIDERS = ["google", "google-gemini-cli", "google-vertex"] as const;
function loadManifest(): GoogleManifest {
return JSON.parse(readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf8"));
}
describe("google manifest model catalog", () => {
it("suppresses retired Gemini chat model identifiers for all Google chat providers", () => {
const manifest = loadManifest();
const suppressionRefs = new Set(
(manifest.modelCatalog?.suppressions ?? []).map(
(suppression) => `${suppression.provider}/${suppression.model}`,
),
);
for (const provider of GOOGLE_CHAT_PROVIDERS) {
for (const model of RETIRED_GEMINI_CHAT_MODELS) {
expect(suppressionRefs).toContain(`${provider}/${model}`);
}
}
});
it("does not suppress still-callable Google replacement models", () => {
const manifest = loadManifest();
const suppressionRefs = new Set(
(manifest.modelCatalog?.suppressions ?? []).map(
(suppression) => `${suppression.provider}/${suppression.model}`,
),
);
expect(suppressionRefs).not.toContain("google/gemini-2.0-flash");
expect(suppressionRefs).not.toContain("google/gemini-2.5-flash");
expect(suppressionRefs).not.toContain("google/gemini-2.5-flash-lite");
expect(suppressionRefs).not.toContain("google/gemini-2.5-pro");
expect(suppressionRefs).not.toContain("google/gemini-3.1-pro-preview");
});
});

View File

@@ -86,10 +86,10 @@ describe("describeGeminiVideo", () => {
});
const { url: seenUrl, init: seenInit } = getRequest();
expect(result.model).toBe("gemini-3-pro-preview");
expect(result.model).toBe("gemini-3.1-pro-preview");
expect(result.text).toBe("first\nsecond");
expect(seenUrl).toBe(
"https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent",
"https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro-preview:generateContent",
);
expect(seenInit?.method).toBe("POST");
expect(seenInit?.signal).toBeInstanceOf(AbortSignal);

View File

@@ -24,6 +24,7 @@ describe("google model id helpers", () => {
});
it("keeps bare Gemini 3.1 Pro as an alias for Google's preview-suffixed API id", () => {
expect(normalizeGoogleModelId("gemini-3-pro")).toBe("gemini-3.1-pro-preview");
expect(normalizeGoogleModelId("gemini-3.1-pro")).toBe("gemini-3.1-pro-preview");
expect(normalizeGoogleModelId("gemini-3.1-pro-preview")).toBe("gemini-3.1-pro-preview");
});

View File

@@ -2,7 +2,7 @@ const ANTIGRAVITY_BARE_PRO_IDS = new Set(["gemini-3-pro", "gemini-3.1-pro", "gem
export function normalizeGoogleModelId(id: string): string {
if (id === "gemini-3-pro") {
return "gemini-3-pro-preview";
return "gemini-3.1-pro-preview";
}
if (id === "gemini-3-flash") {
return "gemini-3-flash-preview";

View File

@@ -10,7 +10,7 @@
"providers": {
"google": {
"aliases": {
"gemini-3-pro": "gemini-3-pro-preview",
"gemini-3-pro": "gemini-3.1-pro-preview",
"gemini-3-flash": "gemini-3-flash-preview",
"gemini-3.1-pro": "gemini-3.1-pro-preview",
"gemini-3.1-flash-lite": "gemini-3.1-flash-lite-preview",
@@ -20,7 +20,7 @@
},
"google-vertex": {
"aliases": {
"gemini-3-pro": "gemini-3-pro-preview",
"gemini-3-pro": "gemini-3.1-pro-preview",
"gemini-3-flash": "gemini-3-flash-preview",
"gemini-3.1-pro": "gemini-3.1-pro-preview",
"gemini-3.1-flash-lite": "gemini-3.1-flash-lite-preview",
@@ -30,6 +30,505 @@
}
}
},
"modelCatalog": {
"suppressions": [
{
"provider": "google",
"model": "gemini-1.5-flash",
"reason": "Google shut down Gemini 1.5 Flash on 2025-09-29. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-1.5-flash-8b",
"reason": "Google shut down Gemini 1.5 Flash-8B on 2025-09-29. Use google/gemini-2.5-flash-lite."
},
{
"provider": "google",
"model": "gemini-1.5-pro",
"reason": "Google shut down Gemini 1.5 Pro on 2025-09-29. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.0-flash-exp",
"reason": "Google shut down this Gemini 2.0 experimental model. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.0-flash-exp-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google/gemini-2.5-flash-image."
},
{
"provider": "google",
"model": "gemini-2.0-flash-live-001",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google/gemini-3.1-flash-live-preview."
},
{
"provider": "google",
"model": "gemini-2.0-flash-lite-preview",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google/gemini-2.5-flash-lite."
},
{
"provider": "google",
"model": "gemini-2.0-flash-lite-preview-02-05",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google/gemini-2.5-flash-lite."
},
{
"provider": "google",
"model": "gemini-2.0-flash-preview-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google/gemini-2.5-flash-image."
},
{
"provider": "google",
"model": "gemini-2.0-flash-thinking-exp",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.0-flash-thinking-exp-01-21",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.0-flash-thinking-exp-1219",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.0-pro-exp",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.0-pro-exp-02-05",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-exp-native-audio-thinking-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google/gemini-3.1-flash-live-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-image-preview",
"reason": "Google shut down this Gemini image preview on 2026-01-15. Use google/gemini-2.5-flash-image."
},
{
"provider": "google",
"model": "gemini-2.5-flash-lite-preview-06-17",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2025-11-18. Use google/gemini-2.5-flash-lite."
},
{
"provider": "google",
"model": "gemini-2.5-flash-lite-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google/gemini-3.1-flash-lite-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-lite-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google/gemini-3.1-flash-lite-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-preview-04-17",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-07-15. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.5-flash-preview-05-20",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-11-18. Use google/gemini-2.5-flash."
},
{
"provider": "google",
"model": "gemini-2.5-flash-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google/gemini-3-flash-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google/gemini-3-flash-preview."
},
{
"provider": "google",
"model": "gemini-2.5-flash-preview-native-audio-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google/gemini-3.1-flash-live-preview."
},
{
"provider": "google",
"model": "gemini-2.5-pro-exp-03-25",
"reason": "Google shut down this Gemini 2.5 Pro experiment. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.5-pro-preview-03-25",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.5-pro-preview-05-06",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-2.5-pro-preview-06-05",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-3-pro-preview",
"reason": "Google shut down Gemini 3 Pro Preview on 2026-03-09. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-3.1-pro-preview-customtools",
"reason": "This is not a public Google Gemini chat model ID. Use google/gemini-3.1-pro-preview."
},
{
"provider": "google",
"model": "gemini-live-2.5-flash",
"reason": "This is not a current public Gemini chat model ID. Use google/gemini-3.1-flash-live-preview for Live API."
},
{
"provider": "google",
"model": "gemini-live-2.5-flash-preview",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google/gemini-3.1-flash-live-preview."
},
{
"provider": "google",
"model": "gemini-live-2.5-flash-preview-native-audio",
"reason": "Google shut down this Gemini Live preview. Use google/gemini-3.1-flash-live-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-1.5-flash",
"reason": "Google shut down Gemini 1.5 Flash on 2025-09-29. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-1.5-flash-8b",
"reason": "Google shut down Gemini 1.5 Flash-8B on 2025-09-29. Use google-gemini-cli/gemini-2.5-flash-lite."
},
{
"provider": "google-gemini-cli",
"model": "gemini-1.5-pro",
"reason": "Google shut down Gemini 1.5 Pro on 2025-09-29. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-exp",
"reason": "Google shut down this Gemini 2.0 experimental model. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-exp-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google-gemini-cli/gemini-2.5-flash-image."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-live-001",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google-gemini-cli/gemini-3.1-flash-live-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-lite-preview",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google-gemini-cli/gemini-2.5-flash-lite."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-lite-preview-02-05",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google-gemini-cli/gemini-2.5-flash-lite."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-preview-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google-gemini-cli/gemini-2.5-flash-image."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-thinking-exp",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-thinking-exp-01-21",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-flash-thinking-exp-1219",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-pro-exp",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.0-pro-exp-02-05",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-exp-native-audio-thinking-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google-gemini-cli/gemini-3.1-flash-live-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-image-preview",
"reason": "Google shut down this Gemini image preview on 2026-01-15. Use google-gemini-cli/gemini-2.5-flash-image."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-lite-preview-06-17",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2025-11-18. Use google-gemini-cli/gemini-2.5-flash-lite."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-lite-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google-gemini-cli/gemini-3.1-flash-lite-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-lite-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google-gemini-cli/gemini-3.1-flash-lite-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-preview-04-17",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-07-15. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-preview-05-20",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-11-18. Use google-gemini-cli/gemini-2.5-flash."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google-gemini-cli/gemini-3-flash-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google-gemini-cli/gemini-3-flash-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-flash-preview-native-audio-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google-gemini-cli/gemini-3.1-flash-live-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-pro-exp-03-25",
"reason": "Google shut down this Gemini 2.5 Pro experiment. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-pro-preview-03-25",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-pro-preview-05-06",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-2.5-pro-preview-06-05",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-3-pro-preview",
"reason": "Google shut down Gemini 3 Pro Preview on 2026-03-09. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-3.1-pro-preview-customtools",
"reason": "This is not a public Google Gemini chat model ID. Use google-gemini-cli/gemini-3.1-pro-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-live-2.5-flash",
"reason": "This is not a current public Gemini chat model ID. Use google-gemini-cli/gemini-3.1-flash-live-preview for Live API."
},
{
"provider": "google-gemini-cli",
"model": "gemini-live-2.5-flash-preview",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google-gemini-cli/gemini-3.1-flash-live-preview."
},
{
"provider": "google-gemini-cli",
"model": "gemini-live-2.5-flash-preview-native-audio",
"reason": "Google shut down this Gemini Live preview. Use google-gemini-cli/gemini-3.1-flash-live-preview."
},
{
"provider": "google-vertex",
"model": "gemini-1.5-flash",
"reason": "Google retired Gemini 1.5 Flash. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-1.5-flash-8b",
"reason": "Google retired Gemini 1.5 Flash-8B. Use google-vertex/gemini-2.5-flash-lite."
},
{
"provider": "google-vertex",
"model": "gemini-1.5-pro",
"reason": "Google retired Gemini 1.5 Pro. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-exp",
"reason": "Google shut down this Gemini 2.0 experimental model. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-exp-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google-vertex/gemini-2.5-flash-image."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-live-001",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google-vertex/gemini-3.1-flash-live-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-lite-preview",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google-vertex/gemini-2.5-flash-lite."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-lite-preview-02-05",
"reason": "Google shut down this Gemini 2.0 Flash-Lite preview on 2025-12-09. Use google-vertex/gemini-2.5-flash-lite."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-preview-image-generation",
"reason": "Google shut down this Gemini 2.0 image preview. Use google-vertex/gemini-2.5-flash-image."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-thinking-exp",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-thinking-exp-01-21",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-flash-thinking-exp-1219",
"reason": "Google shut down this Gemini 2.0 thinking experiment. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-pro-exp",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.0-pro-exp-02-05",
"reason": "Google shut down this Gemini 2.0 Pro experiment. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-exp-native-audio-thinking-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google-vertex/gemini-3.1-flash-live-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-image-preview",
"reason": "Google shut down this Gemini image preview on 2026-01-15. Use google-vertex/gemini-2.5-flash-image."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-lite-preview-06-17",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2025-11-18. Use google-vertex/gemini-2.5-flash-lite."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-lite-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google-vertex/gemini-3.1-flash-lite-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-lite-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash-Lite preview on 2026-03-31. Use google-vertex/gemini-3.1-flash-lite-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-preview-04-17",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-07-15. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-preview-05-20",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2025-11-18. Use google-vertex/gemini-2.5-flash."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-preview-09-25",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google-vertex/gemini-3-flash-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-preview-09-2025",
"reason": "Google shut down this Gemini 2.5 Flash preview on 2026-02-17. Use google-vertex/gemini-3-flash-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-flash-preview-native-audio-dialog",
"reason": "Google shut down this Gemini native-audio preview. Use google-vertex/gemini-3.1-flash-live-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-pro-exp-03-25",
"reason": "Google shut down this Gemini 2.5 Pro experiment. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-pro-preview-03-25",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-pro-preview-05-06",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-2.5-pro-preview-06-05",
"reason": "Google shut down this Gemini 2.5 Pro preview on 2025-12-02. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-3-pro-preview",
"reason": "Google shut down Gemini 3 Pro Preview on 2026-03-09. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-3.1-pro-preview-customtools",
"reason": "This is not a public Google Gemini chat model ID. Use google-vertex/gemini-3.1-pro-preview."
},
{
"provider": "google-vertex",
"model": "gemini-live-2.5-flash",
"reason": "This is not a current public Gemini chat model ID. Use google-vertex/gemini-3.1-flash-live-preview for Live API."
},
{
"provider": "google-vertex",
"model": "gemini-live-2.5-flash-preview",
"reason": "Google shut down this Gemini Live model on 2025-12-09. Use google-vertex/gemini-3.1-flash-live-preview."
},
{
"provider": "google-vertex",
"model": "gemini-live-2.5-flash-preview-native-audio",
"reason": "Google shut down this Gemini Live preview. Use google-vertex/gemini-3.1-flash-live-preview."
}
]
},
"modelPricing": {
"providers": {
"google-gemini-cli": {

View File

@@ -118,6 +118,30 @@ describe("resolveGoogleGeminiForwardCompatModel", () => {
});
});
it("prefers current Gemini 3.1 Pro templates over retired Gemini 3 Pro templates", () => {
const model = resolveGoogleGeminiForwardCompatModel({
providerId: "google-gemini-cli",
ctx: createContext({
provider: "google-gemini-cli",
modelId: "gemini-3.1-pro-preview",
models: [
createTemplateModel("google-gemini-cli", "gemini-3-pro-preview", {
contextWindow: 100_000,
}),
createTemplateModel("google-gemini-cli", "gemini-3.1-pro-preview", {
contextWindow: 1_048_576,
}),
],
}),
});
expect(model).toMatchObject({
provider: "google-gemini-cli",
id: "gemini-3.1-pro-preview",
contextWindow: 1_048_576,
});
});
it("preserves template reasoning metadata instead of forcing it on forward-compat clones", () => {
const model = resolveGoogleGeminiForwardCompatModel({
providerId: "google",

View File

@@ -20,7 +20,7 @@ const GEMMA_PREFIX = "gemma-";
const GEMINI_2_5_PRO_TEMPLATE_IDS = ["gemini-2.5-pro"] as const;
const GEMINI_2_5_FLASH_LITE_TEMPLATE_IDS = ["gemini-2.5-flash-lite"] as const;
const GEMINI_2_5_FLASH_TEMPLATE_IDS = ["gemini-2.5-flash"] as const;
const GEMINI_3_1_PRO_TEMPLATE_IDS = ["gemini-3-pro-preview"] as const;
const GEMINI_3_1_PRO_TEMPLATE_IDS = ["gemini-3.1-pro-preview", "gemini-3-pro-preview"] as const;
const GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS = ["gemini-3.1-flash-lite-preview"] as const;
const GEMINI_3_1_FLASH_TEMPLATE_IDS = ["gemini-3-flash-preview"] as const;
const GEMINI_3_PRO_ANTIGRAVITY_TEMPLATE_IDS = ["gemini-3-pro-low", "gemini-3-pro-high"] as const;

View File

@@ -25,7 +25,7 @@ describe("google provider policy public artifact", () => {
}),
).toMatchObject({
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
models: [{ id: "gemini-3-pro-preview" }],
models: [{ id: "gemini-3.1-pro-preview" }],
});
});

View File

@@ -396,6 +396,40 @@ describe("modelsListCommand forward-compat", () => {
]);
});
it("keeps scoped provider fallback rows filtered by model suppression", async () => {
mocks.resolveConfiguredEntries.mockReturnValueOnce({ entries: [] });
const currentModel = {
provider: "openai",
id: "gpt-5.5",
name: "GPT-5.5",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
input: ["text", "image"],
contextWindow: 1_048_576,
maxTokens: 65_536,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
};
const suppressedModel = {
...currentModel,
id: "gpt-5.3-codex-spark",
name: "GPT-5.3 Codex Spark",
};
mocks.loadModelRegistry.mockResolvedValueOnce({
models: [currentModel],
availableKeys: undefined,
registry: {
getAll: () => [currentModel, suppressedModel],
},
});
const runtime = createRuntime();
await modelsListCommand({ json: true, provider: "openai" }, runtime as never);
expect(lastPrintedRows<{ key: string }>()).toEqual([
expect.objectContaining({ key: "openai/gpt-5.5" }),
]);
});
it("uses provider static catalog rows for provider filters without --all", async () => {
mocks.resolveConfiguredEntries.mockReturnValueOnce({ entries: [] });
mocks.hasProviderStaticCatalogForFilter.mockResolvedValueOnce(true);

View File

@@ -88,11 +88,10 @@ export async function appendAllModelRowSources(
}
await appendDiscoveredRows({
rows: params.rows,
models: params.modelRegistry.getAll(),
models: params.registryModels ?? params.modelRegistry.getAll(),
modelRegistry: params.modelRegistry,
context: params.context,
resolveWithRegistry: false,
skipSuppression: true,
});
}
return { requiresRegistryFallback: false };

View File

@@ -129,7 +129,7 @@ describe("model-pricing-cache", () => {
expect.arrayContaining([
"openai/gpt-5.4",
"anthropic/claude-sonnet-4-6",
"google/gemini-3-pro-preview",
"google/gemini-3.1-pro-preview",
"anthropic/claude-opus-4-6",
"xai/grok-4",
"openrouter/anthropic/claude-opus-4-6",

View File

@@ -0,0 +1,14 @@
import { describe, expect, it } from "vitest";
import { normalizeGooglePreviewModelId } from "./provider-model-id-normalize.js";
describe("provider model id normalization", () => {
it("routes bare Gemini 3 Pro to the current Gemini 3.1 Pro preview", () => {
expect(normalizeGooglePreviewModelId("gemini-3-pro")).toBe("gemini-3.1-pro-preview");
expect(normalizeGooglePreviewModelId("gemini-3.1-pro")).toBe("gemini-3.1-pro-preview");
});
it("does not rewrite already-current Gemini replacement ids", () => {
expect(normalizeGooglePreviewModelId("gemini-3.1-pro-preview")).toBe("gemini-3.1-pro-preview");
expect(normalizeGooglePreviewModelId("gemini-2.5-flash")).toBe("gemini-2.5-flash");
});
});

View File

@@ -2,7 +2,7 @@ const ANTIGRAVITY_BARE_PRO_IDS = new Set(["gemini-3-pro", "gemini-3.1-pro", "gem
export function normalizeGooglePreviewModelId(id: string): string {
if (id === "gemini-3-pro") {
return "gemini-3-pro-preview";
return "gemini-3.1-pro-preview";
}
if (id === "gemini-3-flash") {
return "gemini-3-flash-preview";