fix(ai): update generated model catalogue
This commit is contained in:
@@ -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)).
|
||||
|
||||
@@ -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")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Api>[] {
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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" });
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user