fix(ai): update Google Vertex Gemini models

closes #5761
This commit is contained in:
Armin Ronacher
2026-06-16 01:03:12 +02:00
parent 7cfd1af395
commit b0c8f65ffa
6 changed files with 162 additions and 298 deletions

View File

@@ -4,6 +4,7 @@
### Fixed
- Fixed Google and `google-vertex` Gemini model metadata to map `latest` aliases to the current models, add Gemini 3.5 Flash for Vertex, correct Gemini 2.5 Flash Vertex cache pricing, and remove shut-down Vertex preview models ([#5761](https://github.com/earendil-works/pi/issues/5761)).
- Fixed Moonshot AI China model metadata to include Kimi K2.7 Code, and omitted unsupported thinking-off payloads for Kimi K2.7 Code models ([#5760](https://github.com/earendil-works/pi/issues/5760)).
## [0.79.4] - 2026-06-15

View File

@@ -123,6 +123,7 @@ const TOGETHER_TOGGLE_REASONING_LEVEL_MAP = {
const AI_GATEWAY_MODELS_URL = "https://ai-gateway.vercel.sh/v1";
const AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
const VERTEX_BASE_URL = "https://{location}-aiplatform.googleapis.com";
const NVIDIA_BASE_URL = "https://integrate.api.nvidia.com/v1";
const NVIDIA_HEADERS = {
"NVCF-POLL-SECONDS": "3600",
@@ -270,7 +271,8 @@ function isGemini3ProModel(modelId: string): boolean {
}
function isGemini3FlashModel(modelId: string): boolean {
return /gemini-3(?:\.\d+)?-flash/.test(modelId.toLowerCase());
const id = modelId.toLowerCase();
return /gemini-3(?:\.\d+)?-flash/.test(id) || id === "gemini-flash-latest" || id === "gemini-flash-lite-latest";
}
function isGemma4Model(modelId: string): boolean {
@@ -624,6 +626,13 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
for (const [modelId, model] of Object.entries(data.google.models)) {
const m = model as ModelsDevModel;
if (m.tool_call !== true) continue;
let source = m;
if (modelId === "gemini-flash-latest") {
source = (data.google.models["gemini-3.5-flash"] as ModelsDevModel | undefined) ?? m;
}
if (modelId === "gemini-flash-lite-latest") {
source = (data.google.models["gemini-3.1-flash-lite"] as ModelsDevModel | undefined) ?? m;
}
models.push({
id: modelId,
@@ -631,16 +640,57 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
api: "google-generative-ai",
provider: "google",
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
reasoning: m.reasoning === true,
input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"],
reasoning: source.reasoning === true,
input: source.modalities?.input?.includes("image") ? ["text", "image"] : ["text"],
cost: {
input: m.cost?.input || 0,
output: m.cost?.output || 0,
cacheRead: m.cost?.cache_read || 0,
cacheWrite: m.cost?.cache_write || 0,
input: source.cost?.input || 0,
output: source.cost?.output || 0,
cacheRead: source.cost?.cache_read || 0,
cacheWrite: source.cost?.cache_write || 0,
},
contextWindow: m.limit?.context || 4096,
maxTokens: m.limit?.output || 4096,
contextWindow: source.limit?.context || 4096,
maxTokens: source.limit?.output || 4096,
});
}
}
// Process Google Vertex Gemini models. The google-vertex models.dev catalog also includes
// Claude, OpenAI, and other MaaS models that do not use the @google/genai Gemini streaming
// path implemented by our google-vertex provider.
if (data["google-vertex"]?.models) {
for (const [modelId, model] of Object.entries(data["google-vertex"].models)) {
const m = model as ModelsDevModel;
if (m.tool_call !== true) continue;
if (!modelId.startsWith("gemini-")) continue;
if (modelId === "gemini-3.1-flash-lite-preview") continue;
let source = m;
if (modelId === "gemini-flash-latest") {
source = (data["google-vertex"].models["gemini-3.5-flash"] as ModelsDevModel | undefined) ?? m;
}
if (modelId === "gemini-flash-lite-latest") {
source = (data["google-vertex"].models["gemini-3.1-flash-lite"] as ModelsDevModel | undefined) ?? m;
}
// models.dev reports Vertex cache_read/cache_write values for Gemini 2.5 Flash that
// do not match the official Gemini API standard pricing table. pi only accounts
// cachedContentTokenCount as cacheRead.
const cacheRead = modelId === "gemini-2.5-flash" ? 0.03 : source.cost?.cache_read || 0;
models.push({
id: modelId,
name: m.name || modelId,
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: source.reasoning === true,
input: source.modalities?.input?.includes("image") ? ["text", "image"] : ["text"],
cost: {
input: source.cost?.input || 0,
output: source.cost?.output || 0,
cacheRead,
cacheWrite: 0,
},
contextWindow: source.limit?.context || 4096,
maxTokens: source.limit?.output || 4096,
});
}
}
@@ -1968,167 +2018,6 @@ async function generateModels() {
});
}
const VERTEX_BASE_URL = "https://{location}-aiplatform.googleapis.com";
const vertexModels: Model<"google-vertex">[] = [
{
id: "gemini-3-pro-preview",
name: "Gemini 3 Pro Preview (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 },
contextWindow: 1000000,
maxTokens: 64000,
},
{
id: "gemini-3.1-pro-preview",
name: "Gemini 3.1 Pro Preview (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-3.1-pro-preview-customtools",
name: "Gemini 3.1 Pro Preview Custom Tools (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-3-flash-preview",
name: "Gemini 3 Flash Preview (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-2.0-flash",
name: "Gemini 2.0 Flash (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: false,
input: ["text", "image"],
cost: { input: 0.15, output: 0.6, cacheRead: 0.0375, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 8192,
},
{
id: "gemini-2.0-flash-lite",
name: "Gemini 2.0 Flash Lite (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 0.075, output: 0.3, cacheRead: 0.01875, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-2.5-pro",
name: "Gemini 2.5 Pro (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-2.5-flash",
name: "Gemini 2.5 Flash (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-2.5-flash-lite-preview-09-2025",
name: "Gemini 2.5 Flash Lite Preview 09-25 (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-2.5-flash-lite",
name: "Gemini 2.5 Flash Lite (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: true,
input: ["text", "image"],
cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 },
contextWindow: 1048576,
maxTokens: 65536,
},
{
id: "gemini-1.5-pro",
name: "Gemini 1.5 Pro (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: false,
input: ["text", "image"],
cost: { input: 1.25, output: 5, cacheRead: 0.3125, cacheWrite: 0 },
contextWindow: 1000000,
maxTokens: 8192,
},
{
id: "gemini-1.5-flash",
name: "Gemini 1.5 Flash (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: false,
input: ["text", "image"],
cost: { input: 0.075, output: 0.3, cacheRead: 0.01875, cacheWrite: 0 },
contextWindow: 1000000,
maxTokens: 8192,
},
{
id: "gemini-1.5-flash-8b",
name: "Gemini 1.5 Flash-8B (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: VERTEX_BASE_URL,
reasoning: false,
input: ["text", "image"],
cost: { input: 0.0375, output: 0.15, cacheRead: 0.01, cacheWrite: 0 },
contextWindow: 1000000,
maxTokens: 8192,
},
];
allModels.push(...vertexModels);
// Azure Foundry deploys these with larger context windows than OpenAI's own API,
// which caps gpt-5.4/gpt-5.5 at 272k. See models-sold-directly-by-azure docs.
const AZURE_CONTEXT_WINDOW_OVERRIDES: Record<string, number> = {

View File

@@ -4769,11 +4769,12 @@ export const MODELS = {
provider: "google",
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
reasoning: true,
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 0.3,
output: 2.5,
cacheRead: 0.075,
input: 1.5,
output: 9,
cacheRead: 0.15,
cacheWrite: 0,
},
contextWindow: 1048576,
@@ -4786,10 +4787,11 @@ export const MODELS = {
provider: "google",
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
reasoning: true,
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 0.1,
output: 0.4,
input: 0.25,
output: 1.5,
cacheRead: 0.025,
cacheWrite: 0,
},
@@ -4870,94 +4872,9 @@ export const MODELS = {
} satisfies Model<"google-generative-ai">,
},
"google-vertex": {
"gemini-1.5-flash": {
id: "gemini-1.5-flash",
name: "Gemini 1.5 Flash (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.075,
output: 0.3,
cacheRead: 0.01875,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 8192,
} satisfies Model<"google-vertex">,
"gemini-1.5-flash-8b": {
id: "gemini-1.5-flash-8b",
name: "Gemini 1.5 Flash-8B (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.0375,
output: 0.15,
cacheRead: 0.01,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 8192,
} satisfies Model<"google-vertex">,
"gemini-1.5-pro": {
id: "gemini-1.5-pro",
name: "Gemini 1.5 Pro (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 1.25,
output: 5,
cacheRead: 0.3125,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 8192,
} satisfies Model<"google-vertex">,
"gemini-2.0-flash": {
id: "gemini-2.0-flash",
name: "Gemini 2.0 Flash (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.15,
output: 0.6,
cacheRead: 0.0375,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 8192,
} satisfies Model<"google-vertex">,
"gemini-2.0-flash-lite": {
id: "gemini-2.0-flash-lite",
name: "Gemini 2.0 Flash Lite (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.075,
output: 0.3,
cacheRead: 0.01875,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-2.5-flash": {
id: "gemini-2.5-flash",
name: "Gemini 2.5 Flash (Vertex)",
name: "Gemini 2.5 Flash",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -4974,24 +4891,7 @@ export const MODELS = {
} satisfies Model<"google-vertex">,
"gemini-2.5-flash-lite": {
id: "gemini-2.5-flash-lite",
name: "Gemini 2.5 Flash Lite (Vertex)",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.1,
output: 0.4,
cacheRead: 0.01,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-2.5-flash-lite-preview-09-2025": {
id: "gemini-2.5-flash-lite-preview-09-2025",
name: "Gemini 2.5 Flash Lite Preview 09-25 (Vertex)",
name: "Gemini 2.5 Flash-Lite",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -5008,7 +4908,7 @@ export const MODELS = {
} satisfies Model<"google-vertex">,
"gemini-2.5-pro": {
id: "gemini-2.5-pro",
name: "Gemini 2.5 Pro (Vertex)",
name: "Gemini 2.5 Pro",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -5025,7 +4925,7 @@ export const MODELS = {
} satisfies Model<"google-vertex">,
"gemini-3-flash-preview": {
id: "gemini-3-flash-preview",
name: "Gemini 3 Flash Preview (Vertex)",
name: "Gemini 3 Flash Preview",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -5041,27 +4941,27 @@ export const MODELS = {
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-3-pro-preview": {
id: "gemini-3-pro-preview",
name: "Gemini 3 Pro Preview (Vertex)",
"gemini-3.1-flash-lite": {
id: "gemini-3.1-flash-lite",
name: "Gemini 3.1 Flash Lite",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
thinkingLevelMap: {"off":null,"minimal":null,"low":"LOW","medium":null,"high":"HIGH"},
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 2,
output: 12,
cacheRead: 0.2,
input: 0.25,
output: 1.5,
cacheRead: 0.025,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 64000,
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-3.1-pro-preview": {
id: "gemini-3.1-pro-preview",
name: "Gemini 3.1 Pro Preview (Vertex)",
name: "Gemini 3.1 Pro Preview",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -5079,7 +4979,7 @@ export const MODELS = {
} satisfies Model<"google-vertex">,
"gemini-3.1-pro-preview-customtools": {
id: "gemini-3.1-pro-preview-customtools",
name: "Gemini 3.1 Pro Preview Custom Tools (Vertex)",
name: "Gemini 3.1 Pro Preview Custom Tools",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
@@ -5095,6 +4995,60 @@ export const MODELS = {
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-3.5-flash": {
id: "gemini-3.5-flash",
name: "Gemini 3.5 Flash",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 1.5,
output: 9,
cacheRead: 0.15,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-flash-latest": {
id: "gemini-flash-latest",
name: "Gemini Flash Latest",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 1.5,
output: 9,
cacheRead: 0.15,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
"gemini-flash-lite-latest": {
id: "gemini-flash-lite-latest",
name: "Gemini Flash-Lite Latest",
api: "google-vertex",
provider: "google-vertex",
baseUrl: "https://{location}-aiplatform.googleapis.com",
reasoning: true,
thinkingLevelMap: {"off":null},
input: ["text", "image"],
cost: {
input: 0.25,
output: 1.5,
cacheRead: 0.025,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
} satisfies Model<"google-vertex">,
},
"groq": {
"llama-3.1-8b-instant": {
@@ -9489,13 +9443,13 @@ export const MODELS = {
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh"},
input: ["text"],
cost: {
input: 0.09,
output: 0.18,
input: 0.098,
output: 0.196,
cacheRead: 0.02,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 65536,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"deepseek/deepseek-v4-pro": {
id: "deepseek/deepseek-v4-pro",
@@ -12333,7 +12287,7 @@ export const MODELS = {
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
maxTokens: 81920,
} satisfies Model<"openai-completions">,
"qwen/qwen3.5-397b-a17b": {
id: "qwen/qwen3.5-397b-a17b",
@@ -15065,6 +15019,23 @@ export const MODELS = {
contextWindow: 256000,
maxTokens: 32768,
} satisfies Model<"anthropic-messages">,
"moonshotai/kimi-k2.7-code-highspeed": {
id: "moonshotai/kimi-k2.7-code-highspeed",
name: "Kimi K2.7 Code High Speed",
api: "anthropic-messages",
provider: "vercel-ai-gateway",
baseUrl: "https://ai-gateway.vercel.sh",
reasoning: true,
input: ["text", "image"],
cost: {
input: 1.9,
output: 8,
cacheRead: 0.38,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 4096,
} satisfies Model<"anthropic-messages">,
"nvidia/nemotron-3-super-120b-a12b": {
id: "nvidia/nemotron-3-super-120b-a12b",
name: "NVIDIA Nemotron 3 Super 120B A12B",

View File

@@ -490,7 +490,8 @@ function isGemini3ProModel(model: Model<"google-generative-ai">): boolean {
}
function isGemini3FlashModel(model: Model<"google-generative-ai">): boolean {
return /gemini-3(?:\.\d+)?-flash/.test(model.id.toLowerCase());
const id = model.id.toLowerCase();
return /gemini-3(?:\.\d+)?-flash/.test(id) || id === "gemini-flash-latest" || id === "gemini-flash-lite-latest";
}
function getDisabledThinkingConfig(model: Model<"google-vertex">): ThinkingConfig {

View File

@@ -406,7 +406,8 @@ function isGemini3ProModel(model: Model<"google-generative-ai">): boolean {
}
function isGemini3FlashModel(model: Model<"google-generative-ai">): boolean {
return /gemini-3(?:\.\d+)?-flash/.test(model.id.toLowerCase());
const id = model.id.toLowerCase();
return /gemini-3(?:\.\d+)?-flash/.test(id) || id === "gemini-flash-latest" || id === "gemini-flash-lite-latest";
}
function getDisabledThinkingConfig(model: Model<"google-generative-ai">): ThinkingConfig {

View File

@@ -4,6 +4,7 @@
### Fixed
- Fixed inherited Google and `google-vertex` Gemini model metadata to map `latest` aliases to the current models, add Gemini 3.5 Flash for Vertex, correct Gemini 2.5 Flash Vertex cache pricing, and remove shut-down Vertex preview models ([#5761](https://github.com/earendil-works/pi/issues/5761)).
- Fixed the session selector to stay open and show the all-sessions empty state when both current-folder and all-scope session lists are empty ([#5747](https://github.com/earendil-works/pi/issues/5747)).
- Fixed inherited Moonshot AI China model metadata to include Kimi K2.7 Code, and omitted unsupported thinking-off payloads for Kimi K2.7 Code models ([#5760](https://github.com/earendil-works/pi/issues/5760)).