History

Add Claude Sonnet 5 as the default Claude model (#3620)

Julius Marminge committed 4 months agov0.0.29-nightly.20260630.695

Commit 9d66b101 parent 51ea0844 files · +43 −92Browse files

Unified · Split

4 files
  1. apps/server/src/provider/Layers/ClaudeProvider.ts +36 −1
  2. apps/web/src/components/settings/ProviderModelsSection.tsx +1 −1
  3. packages/contracts/src/model.ts +5 −2
  4. packages/shared/src/model.test.ts +1 −88
apps/server/src/provider/Layers/ClaudeProvider.ts+36−1
@@ -193,6 +193,36 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [ · 192 unmodified lines
193193 ],
194194 }),
195195 },
196+ {
197+ slug: "claude-sonnet-5",
198+ name: "Claude Sonnet 5",
199+ isCustom: false,
200+ capabilities: createModelCapabilities({
201+ optionDescriptors: [
202+ buildSelectOptionDescriptor({
203+ id: "effort",
204+ label: "Reasoning",
205+ options: [
206+ { value: "low", label: "Low" },
207+ { value: "medium", label: "Medium" },
208+ { value: "high", label: "High", isDefault: true },
209+ { value: "xhigh", label: "Extra High" },
210+ { value: "max", label: "Max" },
211+ { value: "ultrathink", label: "Ultrathink" },
212+ ],
213+ promptInjectedValues: ["ultrathink"],
214+ }),
215+ buildSelectOptionDescriptor({
216+ id: "contextWindow",
217+ label: "Context Window",
218+ options: [
219+ { value: "200k", label: "200k", isDefault: true },
220+ { value: "1m", label: "1M" },
221+ ],
222+ }),
223+ ],
224+ }),
225+ },
196226 {
197227 slug: "claude-sonnet-4-6",
198228 name: "Claude Sonnet 4.6",
@@ -322,7 +352,12 @@ export function normalizeClaudeCliEffort( · 123 unmodified lines
322352 if (effort === "ultracode") {
323353 return "xhigh";
324354 }
325− if (effort === "xhigh" && model !== "claude-fable-5" && model !== "claude-opus-4-8") {
355+ if (
356+ effort === "xhigh" &&
357+ model !== "claude-fable-5" &&
358+ model !== "claude-opus-4-8" &&
359+ model !== "claude-sonnet-5"
360+ ) {
326361 return "max";
327362 }
328363 if (effort === "max" && model === "claude-sonnet-4-6") {
apps/web/src/components/settings/ProviderModelsSection.tsx+1−1
@@ -32,7 +32,7 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; · 31 unmodified lines
3232 */
3333 const CUSTOM_MODEL_PLACEHOLDER_BY_KIND: Partial<Record<ProviderDriverKind, string>> = {
3434 [ProviderDriverKind.make("codex")]: "gpt-6.7-codex-ultra-preview",
35− [ProviderDriverKind.make("claudeAgent")]: "claude-sonnet-5-0",
35+ [ProviderDriverKind.make("claudeAgent")]: "claude-sonnet-5",
3636 [ProviderDriverKind.make("cursor")]: "claude-sonnet-4-6",
3737 [ProviderDriverKind.make("opencode")]: "openai/gpt-5",
3838 };
packages/contracts/src/model.ts+5−2
@@ -138,7 +138,7 @@ export const DEFAULT_GIT_TEXT_GENERATION_MODEL = "gpt-5.4-mini"; · 137 unmodified lines
138138
139139 export const DEFAULT_MODEL_BY_PROVIDER: Partial<Record<ProviderDriverKind, string>> = {
140140 [CODEX_DRIVER_KIND]: DEFAULT_MODEL,
141− [CLAUDE_DRIVER_KIND]: "claude-sonnet-4-6",
141+ [CLAUDE_DRIVER_KIND]: "claude-sonnet-5",
142142 [CURSOR_DRIVER_KIND]: "auto",
143143 [GROK_DRIVER_KIND]: "grok-build",
144144 [OPENCODE_DRIVER_KIND]: "openai/gpt-5",
@@ -174,7 +174,10 @@ export const MODEL_SLUG_ALIASES_BY_PROVIDER: Partial< · 29 unmodified lines
174174 "opus-4.6": "claude-opus-4-6",
175175 "claude-opus-4.6": "claude-opus-4-6",
176176 "claude-opus-4-6-20251117": "claude-opus-4-6",
177− sonnet: "claude-sonnet-4-6",
177+ sonnet: "claude-sonnet-5",
178+ "sonnet-5": "claude-sonnet-5",
179+ "claude-sonnet-5.0": "claude-sonnet-5",
180+ "claude-sonnet-5-0": "claude-sonnet-5",
178181 "sonnet-4.6": "claude-sonnet-4-6",
179182 "claude-sonnet-4.6": "claude-sonnet-4-6",
180183 "claude-sonnet-4-6-20251117": "claude-sonnet-4-6",
packages/shared/src/model.test.ts+1−88
@@ -1,13 +1,7 @@
11 import { describe, expect, it } from "vite-plus/test";
2−import {
3− DEFAULT_MODEL,
4− ProviderDriverKind,
5− ProviderInstanceId,
6− type ModelCapabilities,
7−} from "@t3tools/contracts";
2+import { ProviderInstanceId, type ModelCapabilities } from "@t3tools/contracts";
83
94 import {
10− applyClaudePromptEffortPrefix,
115 buildProviderOptionSelectionsFromDescriptors,
126 createModelCapabilities,
137 createModelSelection,
@@ -16,11 +10,6 @@ import { · 2 unmodified lines
1610 getProviderOptionDescriptors,
1711 getProviderOptionBooleanSelectionValue,
1812 getProviderOptionStringSelectionValue,
19− isClaudeUltrathinkPrompt,
20− normalizeModelSlug,
21− resolveModelSlugForProvider,
22− resolveSelectableModel,
23− trimOrNull,
2413 } from "./model.ts";
2514
2615 const codexCaps: ModelCapabilities = createModelCapabilities({
@@ -70,82 +59,6 @@ const claudeCaps: ModelCapabilities = createModelCapabilities({ · 43 unmodified lines
7059 ],
7160 });
7261
73−describe("normalizeModelSlug", () => {
74− it("maps known aliases to canonical slugs", () => {
75− const claude = ProviderDriverKind.make("claudeAgent");
76− expect(normalizeModelSlug("gpt-5-codex")).toBe("gpt-5.4");
77− expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex");
78− expect(normalizeModelSlug("sonnet", claude)).toBe("claude-sonnet-4-6");
79− });
80−
81− it("returns null for empty or missing values", () => {
82− expect(normalizeModelSlug("")).toBeNull();
83− expect(normalizeModelSlug(" ")).toBeNull();
84− expect(normalizeModelSlug(null)).toBeNull();
85− expect(normalizeModelSlug(undefined)).toBeNull();
86− });
87−});
88−
89−describe("resolveModelSlugForProvider", () => {
90− it("returns defaults when the model is missing", () => {
91− expect(resolveModelSlugForProvider(ProviderDriverKind.make("codex"), undefined)).toBe(
92− DEFAULT_MODEL,
93− );
94− expect(resolveModelSlugForProvider(ProviderDriverKind.make("ollama"), undefined)).toBe(
95− DEFAULT_MODEL,
96− );
97− expect(resolveModelSlugForProvider(ProviderDriverKind.make("grok"), undefined)).toBe(
98− "grok-build",
99− );
100− });
101−
102− it("preserves normalized unknown models", () => {
103− expect(
104− resolveModelSlugForProvider(ProviderDriverKind.make("codex"), "custom/internal-model"),
105− ).toBe("custom/internal-model");
106− });
107−});
108−
109−describe("resolveSelectableModel", () => {
110− it("resolves exact slugs, labels, and aliases", () => {
111− const options = [
112− { slug: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
113− { slug: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
114− ];
115− expect(resolveSelectableModel(ProviderDriverKind.make("codex"), "gpt-5.3-codex", options)).toBe(
116− "gpt-5.3-codex",
117− );
118− expect(resolveSelectableModel(ProviderDriverKind.make("codex"), "gpt-5.3 codex", options)).toBe(
119− "gpt-5.3-codex",
120− );
121− expect(resolveSelectableModel(ProviderDriverKind.make("claudeAgent"), "sonnet", options)).toBe(
122− "claude-sonnet-4-6",
123− );
124− });
125−});
126−
127−describe("misc helpers", () => {
128− it("detects ultrathink prompts", () => {
129− expect(isClaudeUltrathinkPrompt("Please ultrathink about this")).toBe(true);
130− expect(isClaudeUltrathinkPrompt("Ultrathink:\nInvestigate")).toBe(true);
131− expect(isClaudeUltrathinkPrompt("Investigate")).toBe(false);
132− });
133−
134− it("prefixes ultrathink prompts once", () => {
135− expect(applyClaudePromptEffortPrefix("Investigate", "ultrathink")).toBe(
136− "Ultrathink:\nInvestigate",
137− );
138− expect(applyClaudePromptEffortPrefix("Ultrathink:\nInvestigate", "ultrathink")).toBe(
139− "Ultrathink:\nInvestigate",
140− );
141− });
142−
143− it("trims strings to null", () => {
144− expect(trimOrNull(" hi ")).toBe("hi");
145− expect(trimOrNull(" ")).toBeNull();
146− });
147−});
148−
14962 describe("descriptor helpers", () => {
15063 it("applies selection values to capability descriptors", () => {
15164 expect(