feat(ai): add Claude Sonnet 5.5 (#3970)

Add claude-sonnet-5-5 ($2/$10 per MTok, 1M context, 128K output) and move
the bare claude-sonnet / claude-sonnet-latest aliases to it. Sonnet 5.5
rejects non-default sampling params and disabled thinking, so it joins the
temperature-omit, effort, and adaptive-thinking gates.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Filip KujundžićandClaude Opus 5.5 authored and GitHub committed 2026-09-28 15:29:21 -07:00
1 parent 12e6bc3d71
commit 42e0c28d0a
3 files changed
+67 -10

No files matched your search

@@ -790,7 +790,12 @@ describe('ClaudeProvider.complete request shape', () => {
});
});
it.each(['claude-fable-5-1', 'claude-opus-5-5', 'claude-sonnet-5'])(
it.each([
'claude-fable-5-1',
'claude-opus-5-5',
'claude-sonnet-5-5',
'claude-sonnet-5',
])(
'omits temperature for %s',
async (model) => {
const { provider } = makeProvider();
@@ -809,7 +814,12 @@ describe('ClaudeProvider.complete request shape', () => {
},
);
it.each(['claude-fable-5-1', 'claude-opus-5-5', 'claude-sonnet-5'])(
it.each([
'claude-fable-5-1',
'claude-opus-5-5',
'claude-sonnet-5-5',
'claude-sonnet-5',
])(
'uses adaptive thinking and output effort on %s',
async (model) => {
const { provider } = makeProvider();
@@ -941,7 +951,23 @@ describe('ClaudeProvider model resolution', () => {
);
});
it('falls back to the default model when given an unknown id', async () => {
it('routes the bare claude-sonnet alias to sonnet 5.5 rather than sonnet 5', async () => {
const { provider } = makeProvider();
messagesCreateMock.mockResolvedValueOnce(baseResponse);
await withTestActor(() =>
provider.complete({
model: 'claude-sonnet',
messages: [{ role: 'user', content: 'hi' }],
}),
);
expect(messagesCreateMock.mock.calls[0]![0].model).toBe(
'claude-sonnet-5-5',
);
});
it('falls back to the default model when given an unknown id', async () => {
const { provider } = makeProvider();
messagesCreateMock.mockResolvedValueOnce(baseResponse);
@@ -975,6 +1001,9 @@ describe('ClaudeProvider.complete non-stream output', () => {
['claude-opus', 'claude-opus-5-5', 400, 500, 800, 20, 2000],
['claude-opus-latest', 'claude-opus-5-5', 400, 500, 800, 20, 2000],
['claude-opus-5-latest', 'claude-opus-5', 500, 625, 1000, 50, 2500],
['claude-sonnet-5-5', 'claude-sonnet-5-5', 200, 250, 400, 20, 1000],
['claude-sonnet', 'claude-sonnet-5-5', 200, 250, 400, 20, 1000],
['claude-sonnet-latest', 'claude-sonnet-5-5', 200, 250, 400, 20, 1000],
['claude-sonnet-5', 'claude-sonnet-5', 200, 250, 400, 20, 1000],
])(
'resolves and meters %s at its current rates',
@@ -358,11 +358,12 @@ export class ClaudeProvider implements IChatProvider {
reasoningEffort: requestedReasoningEffort,
maxTokens: max_tokens,
});
// Fable 5/5.1, Sonnet 5, and Opus 4.7+ reject non-default sampling; omit temperature entirely.
// Fable 5/5.1, Sonnet 5/5.5, and Opus 4.7+ reject non-default sampling; omit temperature entirely.
// Other models require temperature=1 when thinking is enabled.
const omitsTemperature = [
'claude-fable-5-1',
'claude-fable-5',
'claude-sonnet-5-5',
'claude-sonnet-5',
'claude-opus-4-7',
'claude-opus-4-8',
@@ -377,6 +378,7 @@ export class ClaudeProvider implements IChatProvider {
const supportsEffort = [
'claude-fable-5-1',
'claude-fable-5',
'claude-sonnet-5-5',
'claude-sonnet-5',
'claude-opus-5-5',
'claude-opus-5',
@@ -811,6 +813,7 @@ export class ClaudeProvider implements IChatProvider {
if (
modelId === 'claude-fable-5-1' ||
modelId === 'claude-fable-5' ||
modelId === 'claude-sonnet-5-5' ||
modelId === 'claude-sonnet-5' ||
modelId === 'claude-opus-5-5' ||
modelId === 'claude-opus-5' ||
@@ -74,6 +74,36 @@ export const CLAUDE_MODELS: IChatModel[] = [
context: 1000000,
max_tokens: 128000,
},
{
puterId: 'anthropic:anthropic/claude-sonnet-5-5',
id: 'claude-sonnet-5-5',
modalities: { input: ['text', 'image', 'pdf'], output: ['text'] },
open_weights: false,
tool_call: true,
knowledge: '2026-06',
release_date: '2026-09-28',
aliases: [
'claude-sonnet',
'claude-sonnet-latest',
'claude-sonnet-5-5-latest',
'claude-sonnet-5.5',
'anthropic/claude-sonnet-5-5',
],
name: 'Claude Sonnet 5.5',
costs_currency: 'usd-cents',
input_cost_key: 'input_tokens',
output_cost_key: 'output_tokens',
costs: {
tokens: 1_000_000,
input_tokens: 200,
ephemeral_5m_input_tokens: 200 * 1.25,
ephemeral_1h_input_tokens: 200 * 2,
cache_read_input_tokens: 200 * 0.1,
output_tokens: 1000,
},
context: 1000000,
max_tokens: 128000,
},
{
puterId: 'anthropic:anthropic/claude-sonnet-5',
id: 'claude-sonnet-5',
@@ -82,12 +112,7 @@ export const CLAUDE_MODELS: IChatModel[] = [
tool_call: true,
knowledge: '2026-01',
release_date: '2026-06-30',
aliases: [
'claude-sonnet',
'claude-sonnet-latest',
'claude-sonnet-5-latest',
'anthropic/claude-sonnet-5',
],
aliases: ['claude-sonnet-5-latest', 'anthropic/claude-sonnet-5'],
name: 'Claude Sonnet 5',
costs_currency: 'usd-cents',
input_cost_key: 'input_tokens',