From 5c1a2977bc5f22e497e4db4e67164bdc834d85d8 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 30 Jun 2026 22:12:48 +0200 Subject: [PATCH] fix(ai): update generated model catalogue --- packages/ai/CHANGELOG.md | 1 + packages/ai/scripts/generate-models.ts | 2 + .../ai/src/api/bedrock-converse-stream.ts | 1 + packages/ai/src/image-models.generated.ts | 60 +++-------- .../ai/src/providers/amazon-bedrock.models.ts | 102 ++++++++++++++++++ packages/ai/src/providers/anthropic.models.ts | 18 ++++ .../ai/src/providers/opencode-go.models.ts | 6 +- .../ai/src/providers/openrouter.models.ts | 66 ++++++------ .../src/providers/vercel-ai-gateway.models.ts | 18 ++++ ...anthropic-adaptive-thinking-models.test.ts | 6 +- .../test/anthropic-thinking-disable.test.ts | 7 ++ .../ai/test/bedrock-thinking-payload.test.ts | 10 ++ 12 files changed, 215 insertions(+), 82 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index dc180c8d..ce1fab74 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -12,6 +12,7 @@ ### Fixed +- Fixed Claude Sonnet 5 metadata to use adaptive thinking payloads for Anthropic-compatible and Bedrock requests. - Fixed generated Xiaomi MiMo model pricing to match current pay-as-you-go pricing from models.dev ([#6138](https://github.com/earendil-works/pi/issues/6138)). - Fixed `streamSimple()` to send a context-aware max-token cap so providers that count input and output against one context window do not reject long requests ([#5595](https://github.com/earendil-works/pi/issues/5595)). - Fixed OpenAI Responses streams to preserve reasoning replay state when output items finish out of order ([#6009](https://github.com/earendil-works/pi/issues/6009)). diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 3b0677b6..83a5441e 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -268,6 +268,8 @@ function isAnthropicAdaptiveThinkingModel(modelId: string): boolean { modelId.includes("opus-4.8") || modelId.includes("sonnet-4-6") || modelId.includes("sonnet-4.6") || + modelId.includes("sonnet-5") || + modelId.includes("sonnet.5") || modelId.includes("fable-5") ); } diff --git a/packages/ai/src/api/bedrock-converse-stream.ts b/packages/ai/src/api/bedrock-converse-stream.ts index fe01f872..997965a3 100644 --- a/packages/ai/src/api/bedrock-converse-stream.ts +++ b/packages/ai/src/api/bedrock-converse-stream.ts @@ -575,6 +575,7 @@ function supportsAdaptiveThinking(modelId: string, modelName?: string): boolean s.includes("opus-4-7") || s.includes("opus-4-8") || s.includes("sonnet-4-6") || + s.includes("sonnet-5") || s.includes("fable-5"), ); } diff --git a/packages/ai/src/image-models.generated.ts b/packages/ai/src/image-models.generated.ts index bd6a1e0b..57338661 100644 --- a/packages/ai/src/image-models.generated.ts +++ b/packages/ai/src/image-models.generated.ts @@ -155,6 +155,21 @@ export const IMAGE_MODELS = { cacheWrite: 0, }, } satisfies ImagesModel<"openrouter-images">, + "google/gemini-3.1-flash-lite-image": { + id: "google/gemini-3.1-flash-lite-image", + name: "Google: Nano Banana 2 Lite (Gemini 3.1 Flash Lite Image)", + api: "openrouter-images", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + input: ["image", "text"], + output: ["image", "text"], + cost: { + input: 0.25, + output: 1.5, + cacheRead: 0, + cacheWrite: 0, + }, + } satisfies ImagesModel<"openrouter-images">, "microsoft/mai-image-2.5": { id: "microsoft/mai-image-2.5", name: "Microsoft: MAI-Image-2.5", @@ -455,36 +470,6 @@ export const IMAGE_MODELS = { cacheWrite: 0, }, } satisfies ImagesModel<"openrouter-images">, - "sourceful/riverflow-v2-fast-preview": { - id: "sourceful/riverflow-v2-fast-preview", - name: "Sourceful: Riverflow V2 Fast Preview", - api: "openrouter-images", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - input: ["text", "image"], - output: ["image"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - } satisfies ImagesModel<"openrouter-images">, - "sourceful/riverflow-v2-max-preview": { - id: "sourceful/riverflow-v2-max-preview", - name: "Sourceful: Riverflow V2 Max Preview", - api: "openrouter-images", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - input: ["text", "image"], - output: ["image"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - } satisfies ImagesModel<"openrouter-images">, "sourceful/riverflow-v2-pro": { id: "sourceful/riverflow-v2-pro", name: "Sourceful: Riverflow V2 Pro", @@ -500,21 +485,6 @@ export const IMAGE_MODELS = { cacheWrite: 0, }, } satisfies ImagesModel<"openrouter-images">, - "sourceful/riverflow-v2-standard-preview": { - id: "sourceful/riverflow-v2-standard-preview", - name: "Sourceful: Riverflow V2 Standard Preview", - api: "openrouter-images", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - input: ["text", "image"], - output: ["image"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - } satisfies ImagesModel<"openrouter-images">, "sourceful/riverflow-v2.5-fast": { id: "sourceful/riverflow-v2.5-fast", name: "Sourceful: Riverflow V2.5 Fast", diff --git a/packages/ai/src/providers/amazon-bedrock.models.ts b/packages/ai/src/providers/amazon-bedrock.models.ts index f30ad72e..9cd20c7d 100644 --- a/packages/ai/src/providers/amazon-bedrock.models.ts +++ b/packages/ai/src/providers/amazon-bedrock.models.ts @@ -211,6 +211,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"bedrock-converse-stream">, + "anthropic.claude-sonnet-5": { + id: "anthropic.claude-sonnet-5", + name: "Claude Sonnet 5", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "au.anthropic.claude-haiku-4-5-20251001-v1:0": { id: "au.anthropic.claude-haiku-4-5-20251001-v1:0", name: "Claude Haiku 4.5 (AU)", @@ -298,6 +315,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 128000, } satisfies Model<"bedrock-converse-stream">, + "au.anthropic.claude-sonnet-5": { + id: "au.anthropic.claude-sonnet-5", + name: "Claude Sonnet 5 (AU)", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "deepseek.r1-v1:0": { id: "deepseek.r1-v1:0", name: "DeepSeek-R1", @@ -489,6 +523,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"bedrock-converse-stream">, + "eu.anthropic.claude-sonnet-5": { + id: "eu.anthropic.claude-sonnet-5", + name: "Claude Sonnet 5 (EU)", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.eu-central-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2.2, + output: 11, + cacheRead: 0.22, + cacheWrite: 2.75, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "global.anthropic.claude-fable-5": { id: "global.anthropic.claude-fable-5", name: "Claude Fable 5 (Global)", @@ -629,6 +680,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"bedrock-converse-stream">, + "global.anthropic.claude-sonnet-5": { + id: "global.anthropic.claude-sonnet-5", + name: "Claude Sonnet 5 (Global)", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "google.gemma-3-27b-it": { id: "google.gemma-3-27b-it", name: "Google Gemma 3 27B Instruct", @@ -733,6 +801,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"bedrock-converse-stream">, + "jp.anthropic.claude-sonnet-5": { + id: "jp.anthropic.claude-sonnet-5", + name: "Claude Sonnet 5 (JP)", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "meta.llama3-1-70b-instruct-v1:0": { id: "meta.llama3-1-70b-instruct-v1:0", name: "Llama 3.1 70B Instruct", @@ -1538,6 +1623,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"bedrock-converse-stream">, + "us.anthropic.claude-sonnet-5": { + id: "us.anthropic.claude-sonnet-5", + name: "Claude Sonnet 5 (US)", + api: "bedrock-converse-stream", + provider: "amazon-bedrock", + baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"bedrock-converse-stream">, "us.deepseek.r1-v1:0": { id: "us.deepseek.r1-v1:0", name: "DeepSeek-R1 (US)", diff --git a/packages/ai/src/providers/anthropic.models.ts b/packages/ai/src/providers/anthropic.models.ts index b95e2873..e4b19d6b 100644 --- a/packages/ai/src/providers/anthropic.models.ts +++ b/packages/ai/src/providers/anthropic.models.ts @@ -404,4 +404,22 @@ export const ANTHROPIC_MODELS = { contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"anthropic-messages">, + "claude-sonnet-5": { + id: "claude-sonnet-5", + name: "Claude Sonnet 5", + api: "anthropic-messages", + provider: "anthropic", + baseUrl: "https://api.anthropic.com", + compat: {"forceAdaptiveThinking":true}, + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"anthropic-messages">, } as const; diff --git a/packages/ai/src/providers/opencode-go.models.ts b/packages/ai/src/providers/opencode-go.models.ts index cb51ed53..955e6c98 100644 --- a/packages/ai/src/providers/opencode-go.models.ts +++ b/packages/ai/src/providers/opencode-go.models.ts @@ -179,9 +179,9 @@ export const OPENCODE_GO_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 0.1, - output: 0.4, - cacheRead: 0.02, + input: 0.3, + output: 1.2, + cacheRead: 0.06, cacheWrite: 0, }, contextWindow: 1000000, diff --git a/packages/ai/src/providers/openrouter.models.ts b/packages/ai/src/providers/openrouter.models.ts index 0b8bb914..55a544bb 100644 --- a/packages/ai/src/providers/openrouter.models.ts +++ b/packages/ai/src/providers/openrouter.models.ts @@ -369,6 +369,24 @@ export const OPENROUTER_MODELS = { contextWindow: 1000000, maxTokens: 128000, } satisfies Model<"openai-completions">, + "anthropic/claude-sonnet-5": { + id: "anthropic/claude-sonnet-5", + name: "Anthropic: Claude Sonnet 5", + api: "openai-completions", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + compat: {"thinkingFormat":"openrouter","cacheControlFormat":"anthropic"}, + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"openai-completions">, "arcee-ai/trinity-large-thinking": { id: "arcee-ai/trinity-large-thinking", name: "Arcee AI: Trinity Large Thinking", @@ -722,13 +740,13 @@ export const OPENROUTER_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", @@ -3066,24 +3084,6 @@ export const OPENROUTER_MODELS = { contextWindow: 1000000, maxTokens: 30000, } satisfies Model<"openai-completions">, - "openrouter/owl-alpha": { - id: "openrouter/owl-alpha", - name: "Owl Alpha", - api: "openai-completions", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"}, - reasoning: false, - input: ["text"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 1048756, - maxTokens: 262144, - } satisfies Model<"openai-completions">, "poolside/laguna-m.1": { id: "poolside/laguna-m.1", name: "Poolside: Laguna M.1", @@ -3310,13 +3310,13 @@ export const OPENROUTER_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.1, - output: 0.1, - cacheRead: 0.1, + input: 0.1495, + output: 1.495, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 262144, - maxTokens: 262144, + maxTokens: 4096, } satisfies Model<"openai-completions">, "qwen/qwen3-30b-a3b": { id: "qwen/qwen3-30b-a3b", @@ -3886,8 +3886,8 @@ export const OPENROUTER_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 0.2596, - output: 2.385, + input: 0.285, + output: 2.4, cacheRead: 0, cacheWrite: 0, }, @@ -4445,13 +4445,13 @@ export const OPENROUTER_MODELS = { thinkingLevelMap: {"xhigh":"xhigh"}, input: ["text"], cost: { - input: 0.94, + input: 0.93, output: 3, cacheRead: 0.18, cacheWrite: 0, }, contextWindow: 1048576, - maxTokens: 4096, + maxTokens: 32768, } satisfies Model<"openai-completions">, "z-ai/glm-5v-turbo": { id: "z-ai/glm-5v-turbo", @@ -4535,10 +4535,10 @@ export const OPENROUTER_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, }, contextWindow: 1000000, maxTokens: 128000, diff --git a/packages/ai/src/providers/vercel-ai-gateway.models.ts b/packages/ai/src/providers/vercel-ai-gateway.models.ts index 55cd5031..21a23082 100644 --- a/packages/ai/src/providers/vercel-ai-gateway.models.ts +++ b/packages/ai/src/providers/vercel-ai-gateway.models.ts @@ -691,6 +691,24 @@ export const VERCEL_AI_GATEWAY_MODELS = { contextWindow: 1000000, maxTokens: 128000, } satisfies Model<"anthropic-messages">, + "anthropic/claude-sonnet-5": { + id: "anthropic/claude-sonnet-5", + name: "Claude Sonnet 5", + api: "anthropic-messages", + provider: "vercel-ai-gateway", + baseUrl: "https://ai-gateway.vercel.sh", + compat: {"forceAdaptiveThinking":true}, + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 10, + cacheRead: 0.2, + cacheWrite: 2.5, + }, + contextWindow: 1000000, + maxTokens: 128000, + } satisfies Model<"anthropic-messages">, "arcee-ai/trinity-large-preview": { id: "arcee-ai/trinity-large-preview", name: "Trinity Large Preview", diff --git a/packages/ai/test/anthropic-adaptive-thinking-models.test.ts b/packages/ai/test/anthropic-adaptive-thinking-models.test.ts index 8d99ff18..3f5db476 100644 --- a/packages/ai/test/anthropic-adaptive-thinking-models.test.ts +++ b/packages/ai/test/anthropic-adaptive-thinking-models.test.ts @@ -5,9 +5,11 @@ import type { Api, Model } from "../src/types.ts"; const EXPECTED_CURRENT_ADAPTIVE_THINKING_MODELS = [ "anthropic/claude-fable-5", "anthropic/claude-opus-4-8", + "anthropic/claude-sonnet-5", "cloudflare-ai-gateway/claude-fable-5", "opencode/claude-opus-4-8", "vercel-ai-gateway/anthropic/claude-opus-4.8", + "vercel-ai-gateway/anthropic/claude-sonnet-5", ]; function getAllModels(): Model[] { @@ -24,7 +26,9 @@ describe("Anthropic adaptive thinking model metadata", () => { expect(flaggedModels).toEqual(expect.arrayContaining([...EXPECTED_CURRENT_ADAPTIVE_THINKING_MODELS].sort())); expect(flaggedModels).toEqual( - flaggedModels.filter((modelId) => /(opus[-.]4[-.][678]|sonnet[-.]4[-.]6|fable[-.]5)/.test(modelId)), + flaggedModels.filter((modelId) => + /(opus[-.]4[-.][678]|sonnet[-.]4[-.]6|sonnet[-.]5|fable[-.]5)/.test(modelId), + ), ); }); }); diff --git a/packages/ai/test/anthropic-thinking-disable.test.ts b/packages/ai/test/anthropic-thinking-disable.test.ts index 9ecfeb4f..3f55107c 100644 --- a/packages/ai/test/anthropic-thinking-disable.test.ts +++ b/packages/ai/test/anthropic-thinking-disable.test.ts @@ -145,6 +145,13 @@ describe("Anthropic thinking disable payload", () => { expect(payload.output_config).toEqual({ effort: "high" }); }); + it("uses adaptive thinking for Claude Sonnet 5 when reasoning is enabled", async () => { + const payload = await capturePayload(getModel("anthropic", "claude-sonnet-5"), { reasoning: "high" }); + + expect(payload.thinking).toEqual({ type: "adaptive", display: "summarized" }); + expect(payload.output_config).toEqual({ effort: "high" }); + }); + it("maps xhigh reasoning to effort=xhigh for Claude Opus 4.8", async () => { const payload = await capturePayload(getModel("anthropic", "claude-opus-4-8"), { reasoning: "xhigh" }); diff --git a/packages/ai/test/bedrock-thinking-payload.test.ts b/packages/ai/test/bedrock-thinking-payload.test.ts index d2de4913..ad58a4d9 100644 --- a/packages/ai/test/bedrock-thinking-payload.test.ts +++ b/packages/ai/test/bedrock-thinking-payload.test.ts @@ -93,6 +93,16 @@ describe("Bedrock thinking payload", () => { expect(payload.additionalModelRequestFields?.anthropic_beta).toBeUndefined(); }); + it("uses adaptive thinking for Claude Sonnet 5 when reasoning is enabled", async () => { + const model = getModel("amazon-bedrock", "global.anthropic.claude-sonnet-5"); + + const payload = await capturePayload(model); + + expect(payload.additionalModelRequestFields?.thinking).toEqual({ type: "adaptive", display: "summarized" }); + expect(payload.additionalModelRequestFields?.output_config).toEqual({ effort: "high" }); + expect(payload.additionalModelRequestFields?.anthropic_beta).toBeUndefined(); + }); + it("maps xhigh reasoning to effort=xhigh for Claude Fable 5", async () => { const model = getModel("amazon-bedrock", "global.anthropic.claude-fable-5");