-
+ {LockedProviderIcon ?
: null}
{PROVIDER_DISPLAY_NAMES[props.lockedProvider]}
diff --git a/apps/web/src/components/chat/ProviderModelPicker.browser.tsx b/apps/web/src/components/chat/ProviderModelPicker.browser.tsx
index 280e5322..55c97745 100644
--- a/apps/web/src/components/chat/ProviderModelPicker.browser.tsx
+++ b/apps/web/src/components/chat/ProviderModelPicker.browser.tsx
@@ -121,6 +121,7 @@ async function mountPicker(props: {
providers?: ReadonlyArray
;
keybindings?: ResolvedKeybindingsConfig;
triggerVariant?: "ghost" | "outline";
+ includeAutoModel?: boolean;
showAsAuto?: boolean;
}) {
const host = document.createElement("div");
@@ -141,6 +142,9 @@ async function mountPicker(props: {
providers={providers}
modelOptionsByProvider={modelOptionsByProvider}
{...(props.keybindings ? { keybindings: props.keybindings } : {})}
+ {...(props.includeAutoModel !== undefined
+ ? { includeAutoModel: props.includeAutoModel }
+ : {})}
{...(props.showAsAuto !== undefined ? { showAsAuto: props.showAsAuto } : {})}
triggerVariant={props.triggerVariant}
onProviderModelChange={onProviderModelChange}
@@ -287,6 +291,28 @@ describe("ProviderModelPicker", () => {
}
});
+ it("hides Auto when auto model selection is disabled", async () => {
+ const mounted = await mountPicker({
+ provider: "claudeAgent",
+ model: "claude-opus-4-6",
+ lockedProvider: "claudeAgent",
+ includeAutoModel: false,
+ });
+
+ try {
+ await page.getByRole("button").click();
+
+ await vi.waitFor(() => {
+ expect(getVisibleModelNames().some((name) => name.includes("Auto"))).toBe(false);
+ expect(getVisibleModelNames().some((name) => name.includes("Claude Sonnet 4.6"))).toBe(
+ true,
+ );
+ });
+ } finally {
+ await mounted.cleanup();
+ }
+ });
+
it("shows jump shortcut labels when keybindings are provided", async () => {
const mounted = await mountPicker({
provider: "codex",
diff --git a/apps/web/src/components/chat/ProviderModelPicker.tsx b/apps/web/src/components/chat/ProviderModelPicker.tsx
index 74db8970..c18511b0 100644
--- a/apps/web/src/components/chat/ProviderModelPicker.tsx
+++ b/apps/web/src/components/chat/ProviderModelPicker.tsx
@@ -33,6 +33,7 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: {
activeProviderIconClassName?: string;
compact?: boolean;
disabled?: boolean;
+ includeAutoModel?: boolean;
showAsAuto?: boolean;
terminalOpen?: boolean;
open?: boolean;
@@ -159,6 +160,9 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: {
{...(props.providers ? { providers: props.providers } : {})}
{...(props.keybindings ? { keybindings: props.keybindings } : {})}
modelOptionsByProvider={props.modelOptionsByProvider}
+ {...(props.includeAutoModel !== undefined
+ ? { includeAutoModel: props.includeAutoModel }
+ : {})}
{...(props.showAsAuto !== undefined ? { showAsAuto: props.showAsAuto } : {})}
terminalOpen={props.terminalOpen ?? false}
onRequestClose={() => setIsMenuOpen(false)}
diff --git a/apps/web/src/components/chat/modelPickerModelHighlights.ts b/apps/web/src/components/chat/modelPickerModelHighlights.ts
index 9afc33a5..35a81d7c 100644
--- a/apps/web/src/components/chat/modelPickerModelHighlights.ts
+++ b/apps/web/src/components/chat/modelPickerModelHighlights.ts
@@ -4,7 +4,7 @@ import type { ProviderKind } from "@t3tools/contracts";
* Keep release-callout logic centralized so future model launches do not need
* ad hoc badge checks spread across the picker rows.
*/
-const NEW_MODEL_KEYS = new Set([]);
+const NEW_MODEL_KEYS = new Set(["claudeAgent:claude-opus-4-7"]);
export function isModelPickerNewModel(provider: ProviderKind, slug: string): boolean {
return NEW_MODEL_KEYS.has(`${provider}:${slug}`);
diff --git a/apps/web/src/components/chat/providerIconUtils.ts b/apps/web/src/components/chat/providerIconUtils.ts
index ca530527..d78eacfa 100644
--- a/apps/web/src/components/chat/providerIconUtils.ts
+++ b/apps/web/src/components/chat/providerIconUtils.ts
@@ -10,7 +10,7 @@ export const PROVIDER_ICON_BY_PROVIDER: Record =
export const PROVIDER_TINT_CLASS_BY_PROVIDER: Record = {
codex: "text-neutral-900 dark:text-white",
- claudeAgent: "text-orange-500 dark:text-orange-300",
+ claudeAgent: "text-[#CC7C5E]",
cursor: "text-violet-500 dark:text-violet-400",
};
diff --git a/apps/web/src/components/settings/SettingsModelsSection.tsx b/apps/web/src/components/settings/SettingsModelsSection.tsx
index 5716dbce..05ece28e 100644
--- a/apps/web/src/components/settings/SettingsModelsSection.tsx
+++ b/apps/web/src/components/settings/SettingsModelsSection.tsx
@@ -22,7 +22,6 @@ import {
import { ensureNativeApi } from "../../nativeApi";
import { useServerProviders } from "../../rpc/serverState";
import type { SettingsUpdatePatch } from "../../hooks/useSettings";
-import { cn } from "../../lib/utils";
import { Button } from "../ui/button";
import { ClaudeAI, OpenAI } from "../Icons";
import { Select, SelectItem, SelectPopup, SelectTrigger } from "../ui/select";
@@ -237,8 +236,8 @@ const BUILT_IN_PRESET_MODE_SELECTIONS: Readonly<
},
planModelSelection: {
provider: "claudeAgent",
- model: "claude-sonnet-4-6",
- options: { effort: "low" },
+ model: "claude-haiku-4-5",
+ options: { thinking: true },
},
codeModelSelection: {
provider: "claudeAgent",
@@ -291,7 +290,7 @@ const BUILT_IN_PRESET_MODE_SELECTIONS: Readonly<
},
reviewModelSelection: {
provider: "claudeAgent",
- model: "claude-opus-4-6",
+ model: "claude-opus-4-7",
options: { effort: "high" },
},
},
@@ -325,10 +324,8 @@ function ProviderPresetLabel({ provider }: { provider: ProviderKind }) {
{PROVIDER_DISPLAY_NAMES[provider]}
diff --git a/apps/web/src/components/settings/SettingsPanelPrimitives.tsx b/apps/web/src/components/settings/SettingsPanelPrimitives.tsx
index 8f448695..6ee2172c 100644
--- a/apps/web/src/components/settings/SettingsPanelPrimitives.tsx
+++ b/apps/web/src/components/settings/SettingsPanelPrimitives.tsx
@@ -111,6 +111,7 @@ export function ModelSelectionControl({
lockedProvider={lockedProvider ?? null}
providers={providers}
modelOptionsByProvider={modelOptionsByProvider}
+ includeAutoModel={false}
triggerVariant="outline"
triggerClassName="min-w-0 max-w-none shrink-0 text-foreground/90 hover:text-foreground"
onProviderModelChange={onProviderModelChange}
diff --git a/packages/contracts/src/model.ts b/packages/contracts/src/model.ts
index e62a957e..db5b2b95 100644
--- a/packages/contracts/src/model.ts
+++ b/packages/contracts/src/model.ts
@@ -73,7 +73,9 @@ export const MODEL_SLUG_ALIASES_BY_PROVIDER: Record {
it("maps known aliases to canonical slugs", () => {
expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex");
expect(normalizeModelSlug("sonnet", "claudeAgent")).toBe("claude-sonnet-4-6");
+ expect(normalizeModelSlug("opus", "claudeAgent")).toBe("claude-opus-4-7");
+ expect(normalizeModelSlug("opus-4.6", "claudeAgent")).toBe("claude-opus-4-6");
});
it("normalizes auto model selection case-insensitively", () => {
@@ -319,29 +321,29 @@ describe("resolveApiModelId", () => {
expect(
resolveApiModelId({
provider: "claudeAgent",
- model: "claude-opus-4-6",
+ model: "claude-opus-4-7",
options: { contextWindow: "1m" },
}),
- ).toBe("claude-opus-4-6[1m]");
+ ).toBe("claude-opus-4-7[1m]");
});
it("returns the model as-is for 200k context window", () => {
expect(
resolveApiModelId({
provider: "claudeAgent",
- model: "claude-opus-4-6",
+ model: "claude-opus-4-7",
options: { contextWindow: "200k" },
}),
- ).toBe("claude-opus-4-6");
+ ).toBe("claude-opus-4-7");
});
it("returns the model as-is when no context window is set", () => {
- expect(resolveApiModelId({ provider: "claudeAgent", model: "claude-opus-4-6" })).toBe(
- "claude-opus-4-6",
+ expect(resolveApiModelId({ provider: "claudeAgent", model: "claude-opus-4-7" })).toBe(
+ "claude-opus-4-7",
);
expect(
- resolveApiModelId({ provider: "claudeAgent", model: "claude-opus-4-6", options: {} }),
- ).toBe("claude-opus-4-6");
+ resolveApiModelId({ provider: "claudeAgent", model: "claude-opus-4-7", options: {} }),
+ ).toBe("claude-opus-4-7");
});
it("returns the model as-is for Codex selections", () => {