Skip to content

Commit 9f57e30

Browse files
feat(models): add Claude Sonnet 5 to available models (#3036)
Co-authored-by: Charles Vien <charles.v@posthog.com>
1 parent d8a6f73 commit 9f57e30

6 files changed

Lines changed: 85 additions & 31 deletions

File tree

.github/workflows/mobile-build.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,5 @@ jobs:
8989
with:
9090
platform: all
9191
profile: production
92-
secrets: inherit
92+
secrets:
93+
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}

apps/mobile/src/features/tasks/composer/options.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ export const MODELS: ModelOption[] = [
4848
description: "Most capable, slower",
4949
supportsReasoning: true,
5050
},
51+
{
52+
value: "claude-sonnet-5",
53+
label: "Claude Sonnet 5",
54+
description: "Balanced, fast",
55+
supportsReasoning: true,
56+
},
5157
{
5258
value: "claude-sonnet-4-6",
5359
label: "Claude Sonnet 4.6",

packages/agent/src/adapters/claude/session/models.test.ts

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ describe("toSdkModelId", () => {
2626
expect(toSdkModelId("claude-fable-5")).toBe("claude-fable-5");
2727
});
2828

29+
it("passes claude-sonnet-5 through unchanged (no SDK alias)", () => {
30+
expect(toSdkModelId("claude-sonnet-5")).toBe("claude-sonnet-5");
31+
});
32+
2933
it("passes deprecated gateway IDs through unchanged", () => {
3034
expect(toSdkModelId("claude-opus-4-6")).toBe("claude-opus-4-6");
3135
expect(toSdkModelId("claude-sonnet-4-5")).toBe("claude-sonnet-4-5");
@@ -34,36 +38,72 @@ describe("toSdkModelId", () => {
3438
});
3539

3640
describe("model capability flags", () => {
37-
it("flags 1M context support", () => {
38-
expect(supports1MContext("claude-opus-4-6")).toBe(false);
39-
expect(supports1MContext("claude-opus-4-7")).toBe(true);
40-
expect(supports1MContext("claude-sonnet-4-6")).toBe(true);
41-
expect(supports1MContext("claude-haiku-4-5")).toBe(false);
42-
});
43-
44-
it("flags effort support and xhigh-effort support", () => {
45-
expect(supportsEffort("claude-opus-4-5")).toBe(false);
46-
expect(supportsEffort("claude-opus-4-6")).toBe(false);
47-
expect(supportsXhighEffort("claude-opus-4-7")).toBe(true);
48-
expect(supportsXhighEffort("claude-opus-4-6")).toBe(false);
49-
expect(supportsEffort("claude-haiku-4-5")).toBe(false);
50-
});
51-
52-
it("flags claude-fable-5 as a flagship model", () => {
53-
expect(supports1MContext("claude-fable-5")).toBe(true);
54-
expect(supportsEffort("claude-fable-5")).toBe(true);
55-
expect(supportsXhighEffort("claude-fable-5")).toBe(true);
56-
expect(supportsMcpInjection("claude-fable-5")).toBe(true);
57-
});
58-
59-
it("allows MCP injection for supported Claude models", () => {
60-
expect(supportsMcpInjection("claude-opus-4-7")).toBe(true);
61-
expect(supportsMcpInjection("claude-sonnet-4-6")).toBe(true);
62-
});
63-
64-
it("keeps deprecated Haiku sessions excluded from MCP injection", () => {
65-
expect(supportsMcpInjection("claude-haiku-4-5")).toBe(false);
66-
});
41+
it.each([
42+
{
43+
modelId: "claude-opus-4-5",
44+
oneMContext: false,
45+
effort: false,
46+
xhighEffort: false,
47+
mcpInjection: true,
48+
},
49+
{
50+
modelId: "claude-opus-4-6",
51+
oneMContext: false,
52+
effort: false,
53+
xhighEffort: false,
54+
mcpInjection: true,
55+
},
56+
{
57+
modelId: "claude-opus-4-7",
58+
oneMContext: true,
59+
effort: true,
60+
xhighEffort: true,
61+
mcpInjection: true,
62+
},
63+
{
64+
modelId: "claude-opus-4-8",
65+
oneMContext: true,
66+
effort: true,
67+
xhighEffort: true,
68+
mcpInjection: true,
69+
},
70+
{
71+
modelId: "claude-sonnet-4-6",
72+
oneMContext: true,
73+
effort: true,
74+
xhighEffort: false,
75+
mcpInjection: true,
76+
},
77+
{
78+
modelId: "claude-sonnet-5",
79+
oneMContext: true,
80+
effort: true,
81+
xhighEffort: true,
82+
mcpInjection: true,
83+
},
84+
{
85+
modelId: "claude-fable-5",
86+
oneMContext: true,
87+
effort: true,
88+
xhighEffort: true,
89+
mcpInjection: true,
90+
},
91+
{
92+
modelId: "claude-haiku-4-5",
93+
oneMContext: false,
94+
effort: false,
95+
xhighEffort: false,
96+
mcpInjection: false,
97+
},
98+
])(
99+
"$modelId capability flags",
100+
({ modelId, oneMContext, effort, xhighEffort, mcpInjection }) => {
101+
expect(supports1MContext(modelId)).toBe(oneMContext);
102+
expect(supportsEffort(modelId)).toBe(effort);
103+
expect(supportsXhighEffort(modelId)).toBe(xhighEffort);
104+
expect(supportsMcpInjection(modelId)).toBe(mcpInjection);
105+
},
106+
);
67107
});
68108

69109
describe("resolveEffortForModel", () => {
@@ -77,12 +117,14 @@ describe("resolveEffortForModel", () => {
77117
["claude-opus-4-8", undefined, "high"],
78118
["claude-opus-4-7", undefined, "high"],
79119
["claude-sonnet-4-6", undefined, "high"],
120+
["claude-sonnet-5", undefined, "high"],
80121
// Models without effort support stay unset (SDK disables thinking).
81122
["claude-haiku-4-5", undefined, undefined],
82123
["claude-opus-4-6", undefined, undefined],
83124
// An explicit choice is always honored, including on adaptive-only models.
84125
["claude-opus-4-8", "low", "low"],
85126
["claude-fable-5", "max", "max"],
127+
["claude-sonnet-5", "max", "max"],
86128
] as const)(
87129
"resolveEffortForModel(%s, %s) === %s",
88130
(modelId, effort, expected) => {

packages/agent/src/adapters/claude/session/models.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const MODELS_WITH_1M_CONTEXT = new Set([
2121
"claude-opus-4-7",
2222
"claude-opus-4-8",
2323
"claude-sonnet-4-6",
24+
"claude-sonnet-5",
2425
"claude-fable-5",
2526
]);
2627

@@ -32,12 +33,14 @@ const MODELS_WITH_EFFORT = new Set([
3233
"claude-opus-4-7",
3334
"claude-opus-4-8",
3435
"claude-sonnet-4-6",
36+
"claude-sonnet-5",
3537
"claude-fable-5",
3638
]);
3739

3840
const MODELS_WITH_XHIGH_EFFORT = new Set([
3941
"claude-opus-4-7",
4042
"claude-opus-4-8",
43+
"claude-sonnet-5",
4144
"claude-fable-5",
4245
]);
4346

packages/agent/src/gateway-models.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ describe("getClaudeModelRecency", () => {
7979
["claude-sonnet-4-6", 4006],
8080
["claude-opus-4-7", 4007],
8181
["claude-opus-4-8", 4008],
82+
["claude-sonnet-5", 5000],
8283
["claude-fable-5", 5000],
8384
])("ranks %s by its embedded version (%i)", (modelId, rank) => {
8485
expect(getClaudeModelRecency(modelId)).toBe(rank);

packages/ui/src/features/message-editor/components/PromptInput.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const mockModelOption = {
2424
name: "Recommended",
2525
options: [
2626
{ value: "gpt-5.5", name: "gpt-5.5" },
27+
{ value: "claude-sonnet-5", name: "Claude Sonnet 5" },
2728
{ value: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
2829
],
2930
},

0 commit comments

Comments
 (0)