diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 46465b66f..cd6b0eda0 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -19,6 +19,7 @@ - Added a runtime chat-model check to the `Models` stream entry points so non-chat models fail with a clear `ModelsError` instead of a missing-api stream error. - Added array-based `models.all.json` and `providers/{id}.all.json` variants to the generated and published JSON catalog, allowing the same upstream ID once per model type; the existing keyed `models.json` and `providers/{id}.json` stay chat-only for released clients. - Added `onProviderStreamEvent` to observe parsed provider stream events before normalization, including provider-specific fields not retained in assistant messages ([#9784](https://github.com/earendil-works/pi/issues/9784)). +- Added Claude Sonnet 5.5 to the built-in Anthropic model catalog with adaptive thinking, mid-conversation effort, 1M context, and official pricing metadata. ### Fixed diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 96300189e..93ba057b5 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -591,6 +591,7 @@ function supportsAnthropicMidConvoEffort(modelId: string): boolean { const id = modelId.toLowerCase().replace(/^~?anthropic\//, ""); return ( /^claude-opus-(?:5|5[.-]5)(?:-\d{8})?$/.test(id) || + /^claude-sonnet-5[.-]5(?:-\d{8})?$/.test(id) || /^claude-(?:fable|mythos)-5(?:[.-]1)(?:-\d{8})?$/.test(id) ); } @@ -598,6 +599,7 @@ function supportsAnthropicMidConvoEffort(modelId: string): boolean { function supportsAnthropicMidConvoSystemMessages(modelId: string): boolean { return ( /^claude-opus-(?:4[.-]8|5(?:[.-]5)?)(?:-\d{8})?$/.test(modelId) || + /^claude-sonnet-5[.-]5(?:-\d{8})?$/.test(modelId) || /^claude-(?:fable|mythos)-5(?:[.-]1)?(?:-\d{8})?$/.test(modelId) ); } @@ -629,7 +631,9 @@ function isAnthropicTemperatureUnsupportedModel(modelId: string): boolean { id.includes("opus-4-8") || id.includes("opus-4.8") || id.includes("opus-5") || - id.includes("opus.5") + id.includes("opus.5") || + id.includes("sonnet-5-5") || + id.includes("sonnet-5.5") ); } @@ -2720,6 +2724,32 @@ async function generateModels() { }); } + // Add Claude Sonnet 5.5 until models.dev includes it. + // https://platform.claude.com/docs/en/models/sonnet-5-5/overview + if (!allModels.some((model) => model.provider === "anthropic" && model.id === "claude-sonnet-5-5")) { + allModels.push({ + id: "claude-sonnet-5-5", + name: "Claude Sonnet 5.5", + api: "anthropic-messages", + provider: "anthropic", + baseUrl: "https://api.anthropic.com", + reasoning: true, + thinkingLevelMap: { + off: null, + minimal: null, + low: "low", + medium: "medium", + high: "high", + xhigh: "xhigh", + max: "max", + }, + input: ["text", "image"], + cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + contextWindow: 1000000, + maxTokens: 128000, + }); + } + // The authenticated Copilot catalog advertised these models on 2026-09-22, // but models.dev did not include them yet. const missingCopilotModels: Model[] = [ @@ -2771,9 +2801,10 @@ async function generateModels() { candidate.contextWindow = 1000000; } - // models.dev may list Opus 5.5 before its effort metadata is complete. + // models.dev may list Opus 5.5 and Sonnet 5.5 before their effort metadata is complete. if ( - (candidate.provider === "anthropic" && candidate.id === "claude-opus-5-5") || + (candidate.provider === "anthropic" && + (candidate.id === "claude-opus-5-5" || candidate.id === "claude-sonnet-5-5")) || (candidate.provider === "github-copilot" && candidate.id === "claude-opus-5.5") ) { mergeThinkingLevelMap(candidate, { diff --git a/packages/ai/test/supports-xhigh.test.ts b/packages/ai/test/supports-xhigh.test.ts index 90bf3b8ae..5c3a61a21 100644 --- a/packages/ai/test/supports-xhigh.test.ts +++ b/packages/ai/test/supports-xhigh.test.ts @@ -39,6 +39,23 @@ describe("getSupportedThinkingLevels", () => { expect(getSupportedThinkingLevels(model)).toEqual(["low", "medium", "high", "xhigh", "max"]); }); + it("includes Claude Sonnet 5.5 with managed effort levels and official pricing", () => { + const model = getModel("anthropic", "claude-sonnet-5-5"); + expect(model).toMatchObject({ + cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + contextWindow: 1_000_000, + maxTokens: 128_000, + compat: { + forceAdaptiveThinking: true, + supportsMidConvoEffort: true, + supportsMidConvoSystemMessages: true, + supportsMidConvoToolChanges: true, + supportsTemperature: false, + }, + }); + expect(getSupportedThinkingLevels(model)).toEqual(["low", "medium", "high", "xhigh", "max"]); + }); + it("includes max but not xhigh for Anthropic Sonnet 4.6 on anthropic-messages API", () => { const model = getModel("anthropic", "claude-sonnet-4-6"); expect(model).toBeDefined(); diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 08d40d3a9..5766db7a9 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -10,6 +10,7 @@ - Added `types=chat,image,classifier` to pi.dev model catalog requests so remote refreshes overlay every supported model type; entries of unknown model types are ignored. - Added the `provider_stream_event` extension event for observing parsed provider events before normalization, with an opt-in `/debug-provider` example viewer ([#9784](https://github.com/earendil-works/pi/issues/9784)). - Added a show/hide toggle (`H`) in HTML exports for custom messages marked `display: false`. Messages remain hidden by default and can also be revealed from the sidebar ([#8896](https://github.com/earendil-works/pi/issues/8896)). +- Added inherited Claude Sonnet 5.5 support for Anthropic with adaptive thinking and a 1M context window. ### Changed