diff --git a/.github/workflows/auto-cleanup-fixup.yml b/.github/workflows/auto-cleanup-fixup.yml index 012dfc96b9..035ebca21b 100644 --- a/.github/workflows/auto-cleanup-fixup.yml +++ b/.github/workflows/auto-cleanup-fixup.yml @@ -118,6 +118,6 @@ jobs: FAILED_RUN_ID: ${{ github.event.workflow_run.id }} run: | bunx mux@next run \ - --model anthropic:claude-opus-4-7 \ + --model anthropic:claude-opus-4-8 \ --thinking xhigh \ < .github/prompts/auto-cleanup-fixup.md diff --git a/.github/workflows/auto-cleanup.yml b/.github/workflows/auto-cleanup.yml index b1acb4300f..b04fb07c57 100644 --- a/.github/workflows/auto-cleanup.yml +++ b/.github/workflows/auto-cleanup.yml @@ -71,6 +71,6 @@ jobs: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | bunx mux@next run \ - --model anthropic:claude-opus-4-7 \ + --model anthropic:claude-opus-4-8 \ --thinking xhigh \ < .github/prompts/auto-cleanup.md diff --git a/.github/workflows/nightly-terminal-bench.yml b/.github/workflows/nightly-terminal-bench.yml index 630736de7d..45ffe637a6 100644 --- a/.github/workflows/nightly-terminal-bench.yml +++ b/.github/workflows/nightly-terminal-bench.yml @@ -10,7 +10,7 @@ on: workflow_dispatch: inputs: models: - description: 'Models to test (comma-separated, or "all" for opus-4-7 + gpt-5.5 + google/gemini-3-pro-preview + google/gemini-3-flash-preview + google/gemini-3.5-flash)' + description: 'Models to test (comma-separated, or "all" for opus-4-8 + gpt-5.5 + google/gemini-3-pro-preview + google/gemini-3-flash-preview + google/gemini-3.5-flash)' required: false default: "all" type: string @@ -129,7 +129,7 @@ jobs: INPUT_MODELS: ${{ inputs.models }} run: | if [ "$INPUT_MODELS" = "all" ] || [ -z "$INPUT_MODELS" ]; then - echo 'models=["anthropic/claude-opus-4-7","openai/gpt-5.5","google/gemini-3-pro-preview","google/gemini-3-flash-preview","google/gemini-3.5-flash"]' >> "$GITHUB_OUTPUT" + echo 'models=["anthropic/claude-opus-4-8","openai/gpt-5.5","google/gemini-3-pro-preview","google/gemini-3-flash-preview","google/gemini-3.5-flash"]' >> "$GITHUB_OUTPUT" else # Convert comma-separated to JSON array models_json=$(echo "$INPUT_MODELS" | jq -R -s -c 'split(",") | map(gsub("^\\s+|\\s+$"; ""))') diff --git a/.github/workflows/terminal-bench.yml b/.github/workflows/terminal-bench.yml index 81d0b05ff4..9e9407dd8d 100644 --- a/.github/workflows/terminal-bench.yml +++ b/.github/workflows/terminal-bench.yml @@ -4,7 +4,7 @@ on: workflow_call: inputs: model_name: - description: "Model to use (e.g., anthropic/claude-opus-4-7, openai/gpt-5.5)" + description: "Model to use (e.g., anthropic/claude-opus-4-8, openai/gpt-5.5)" required: false type: string dataset: @@ -98,7 +98,7 @@ on: required: false type: string model_name: - description: "Model to use (e.g., anthropic/claude-opus-4-7, openai/gpt-5.5)" + description: "Model to use (e.g., anthropic/claude-opus-4-8, openai/gpt-5.5)" required: false type: string mux_run_args: diff --git a/docs/config/models.mdx b/docs/config/models.mdx index 9ef53563e9..70d77213a5 100644 --- a/docs/config/models.mdx +++ b/docs/config/models.mdx @@ -13,7 +13,7 @@ Mux ships with curated models kept up to date with the frontier. Use any custom | Model | ID | Aliases | Default | | ---------------------- | ----------------------------- | ------------------------------------------------------------ | ------- | -| Opus 4.7 | anthropic:claude-opus-4-7 | `opus` | ✓ | +| Opus 4.8 | anthropic:claude-opus-4-8 | `opus` | ✓ | | Sonnet 4.6 | anthropic:claude-sonnet-4-6 | `sonnet` | | | Haiku 4.5 | anthropic:claude-haiku-4-5 | `haiku` | | | GPT-5.5 | openai:gpt-5.5 | `gpt`, `gpt-5.5` | | diff --git a/docs/guides/github-actions.mdx b/docs/guides/github-actions.mdx index 066d5a1096..9e684c21e9 100644 --- a/docs/guides/github-actions.mdx +++ b/docs/guides/github-actions.mdx @@ -116,7 +116,7 @@ jobs: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | bunx mux@next run \ - --model anthropic:claude-opus-4-7 \ + --model anthropic:claude-opus-4-8 \ --thinking xhigh \ < .github/prompts/auto-cleanup.md ``` diff --git a/src/browser/features/ChatInput/useCreationWorkspace.test.tsx b/src/browser/features/ChatInput/useCreationWorkspace.test.tsx index 0750a96fc0..c99797e848 100644 --- a/src/browser/features/ChatInput/useCreationWorkspace.test.tsx +++ b/src/browser/features/ChatInput/useCreationWorkspace.test.tsx @@ -801,7 +801,7 @@ describe("useCreationWorkspace", () => { }); expect(onWorkspaceCreated.mock.calls[0][1]).toEqual({ autoNavigate: true, - pendingStreamModel: "anthropic:claude-opus-4-7", + pendingStreamModel: "anthropic:claude-opus-4-8", markPendingInitialSend: false, }); }); @@ -1196,7 +1196,7 @@ describe("useCreationWorkspace", () => { expect(onWorkspaceCreated.mock.calls.length).toBe(1); expect(onWorkspaceCreated.mock.calls[0][1]).toEqual({ autoNavigate: true, - pendingStreamModel: "anthropic:claude-opus-4-7", + pendingStreamModel: "anthropic:claude-opus-4-8", markPendingInitialSend: true, }); }); diff --git a/src/browser/hooks/useModelsFromSettings.test.ts b/src/browser/hooks/useModelsFromSettings.test.ts index 49f6fc2990..76d16cc241 100644 --- a/src/browser/hooks/useModelsFromSettings.test.ts +++ b/src/browser/hooks/useModelsFromSettings.test.ts @@ -586,7 +586,7 @@ describe("useModelsFromSettings provider availability gating", () => { apiKeySet: true, isEnabled: true, isConfigured: true, - models: ["claude-opus-4.7"], + models: ["claude-opus-4.8"], }, }; routePriority = ["github-copilot", "direct"]; diff --git a/src/cli/run.test.ts b/src/cli/run.test.ts index f2f6a1d14d..92fed0f050 100644 --- a/src/cli/run.test.ts +++ b/src/cli/run.test.ts @@ -167,7 +167,7 @@ describe("mux CLI", () => { test("shows default model as opus", async () => { const result = await runCli(["run", "--help"]); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain("anthropic:claude-opus-4-7"); + expect(result.stdout).toContain("anthropic:claude-opus-4-8"); }); test("--service-tier has no default auto", async () => { diff --git a/src/cli/run.ts b/src/cli/run.ts index 6cf8213b91..438343312f 100644 --- a/src/cli/run.ts +++ b/src/cli/run.ts @@ -91,7 +91,7 @@ import type { GoalRecordV1 } from "@/common/types/goal"; // Display labels for CLI help (OFF, LOW, MED, HIGH, MAX). // Deduplicate because xhigh and max both display as "MAX" for default/Anthropic -// models; the distinction only matters at the provider boundary (OpenAI / Opus 4.7). +// models; the distinction only matters at the provider boundary (OpenAI / Opus 4.7+). const THINKING_LABELS_LIST = [...new Set(Object.values(THINKING_DISPLAY_LABELS))].join(", "); type CLIMode = "plan" | "exec"; diff --git a/src/common/constants/knownModels.ts b/src/common/constants/knownModels.ts index 9a2185b5a4..55768a1618 100644 --- a/src/common/constants/knownModels.ts +++ b/src/common/constants/knownModels.ts @@ -29,10 +29,11 @@ interface KnownModel extends KnownModelDefinition { const MODEL_DEFINITIONS = { OPUS: { provider: "anthropic", - providerModelId: "claude-opus-4-7", + providerModelId: "claude-opus-4-8", aliases: ["opus"], warm: true, - // Opus 4.7 tokenizer not yet available upstream; reuse 4.6 for approximate counting + // Opus 4.8 tokenizer not yet available upstream; reuse 4.5 for approximate counting + // (Opus 4.6/4.7 also reused 4.5 — tokenization is unchanged across the 4.x line). tokenizerOverride: "anthropic/claude-opus-4.5", }, SONNET: { diff --git a/src/common/utils/ai/models.ts b/src/common/utils/ai/models.ts index 875156f5fe..a0e7a5fc04 100644 --- a/src/common/utils/ai/models.ts +++ b/src/common/utils/ai/models.ts @@ -120,6 +120,7 @@ export type Anthropic1MContextMode = "none" | "beta" | "native"; const OPTIONAL_VERSION_SUFFIX = String.raw`(?:-(?:\d{8}|\d{4}-\d{2}-\d{2}))?`; const ANTHROPIC_NATIVE_1M_PATTERNS = [ + new RegExp(`^claude-opus-4-8${OPTIONAL_VERSION_SUFFIX}$`, "i"), new RegExp(`^claude-opus-4-7${OPTIONAL_VERSION_SUFFIX}$`, "i"), new RegExp(`^claude-opus-4-6${OPTIONAL_VERSION_SUFFIX}$`, "i"), new RegExp(`^claude-sonnet-4-6${OPTIONAL_VERSION_SUFFIX}$`, "i"), diff --git a/src/common/utils/tokens/models-extra.ts b/src/common/utils/tokens/models-extra.ts index dfca2f7f5c..b3bffeb69c 100644 --- a/src/common/utils/tokens/models-extra.ts +++ b/src/common/utils/tokens/models-extra.ts @@ -55,6 +55,27 @@ export const modelsExtra: Record = { supports_pdf_input: true, }, + // Claude Opus 4.8 - Released May 28, 2026 + // Same pricing/shape as Opus 4.7: $5/M input, $25/M output, native 1M context, + // 128K max output, native xhigh effort level. Defaults to high effort on all + // surfaces; "fast mode" (separate provider tier) is billed at 2× standard rates + // ($10/$50) and is not exposed as its own first-class entry yet. + "claude-opus-4-8": { + max_input_tokens: 1000000, + max_output_tokens: 128000, + input_cost_per_token: 0.000005, // $5 per million input tokens + output_cost_per_token: 0.000025, // $25 per million output tokens + cache_creation_input_token_cost: 0.00000625, // $6.25 per million tokens + cache_read_input_token_cost: 0.0000005, // $0.50 per million tokens + litellm_provider: "anthropic", + mode: "chat", + supports_function_calling: true, + supports_vision: true, + supports_pdf_input: true, + supports_reasoning: true, + supports_response_schema: true, + }, + // Claude Opus 4.7 - Released April 2026 // Native 1M context at standard pricing: $5/M input, $25/M output. // 128K max output tokens. Supports native xhigh effort level. diff --git a/src/node/services/agentSkills/builtInSkillContent.generated.ts b/src/node/services/agentSkills/builtInSkillContent.generated.ts index 766a9bfa43..ea88f74f5e 100644 --- a/src/node/services/agentSkills/builtInSkillContent.generated.ts +++ b/src/node/services/agentSkills/builtInSkillContent.generated.ts @@ -2376,7 +2376,7 @@ export const BUILTIN_SKILL_FILES: Record> = { "", "| Model | ID | Aliases | Default |", "| ---------------------- | ----------------------------- | ------------------------------------------------------------ | ------- |", - "| Opus 4.7 | anthropic:claude-opus-4-7 | `opus` | ✓ |", + "| Opus 4.8 | anthropic:claude-opus-4-8 | `opus` | ✓ |", "| Sonnet 4.6 | anthropic:claude-sonnet-4-6 | `sonnet` | |", "| Haiku 4.5 | anthropic:claude-haiku-4-5 | `haiku` | |", "| GPT-5.5 | openai:gpt-5.5 | `gpt`, `gpt-5.5` | |", @@ -3834,7 +3834,7 @@ export const BUILTIN_SKILL_FILES: Record> = { " GH_TOKEN: ${{ steps.app-token.outputs.token }}", " run: |", " bunx mux@next run \\", - " --model anthropic:claude-opus-4-7 \\", + " --model anthropic:claude-opus-4-8 \\", " --thinking xhigh \\", " < .github/prompts/auto-cleanup.md", "```", diff --git a/src/node/services/providerService.test.ts b/src/node/services/providerService.test.ts index ebbe3599da..2259bc95e3 100644 --- a/src/node/services/providerService.test.ts +++ b/src/node/services/providerService.test.ts @@ -1169,7 +1169,7 @@ describe("ProviderService.setConfig", () => { const providersConfig = config.loadProvidersConfig(); expect(providersConfig?.["mux-gateway"]?.models).toEqual([ "anthropic/claude-sonnet-4-6", - "anthropic/claude-opus-4-7", + "anthropic/claude-opus-4-8", "openai/gpt-5.5", ]); expect(providersConfig?.["mux-gateway"]?.models).not.toContain("openai/gpt-5.2-codex"); diff --git a/src/node/services/providerService.ts b/src/node/services/providerService.ts index 4016f32da9..900e3b9546 100644 --- a/src/node/services/providerService.ts +++ b/src/node/services/providerService.ts @@ -1075,7 +1075,7 @@ export class ProviderService { if (existingModels.length === 0) { providerConfig.models = [ "anthropic/claude-sonnet-4-6", - "anthropic/claude-opus-4-7", + "anthropic/claude-opus-4-8", "openai/gpt-5.5", ]; } diff --git a/tests/e2e/scenarios/slashCommands.spec.ts b/tests/e2e/scenarios/slashCommands.spec.ts index 434db2f29c..ad3b433717 100644 --- a/tests/e2e/scenarios/slashCommands.spec.ts +++ b/tests/e2e/scenarios/slashCommands.spec.ts @@ -76,8 +76,8 @@ test.describe("slash command flows", () => { await ui.projects.openFirstWorkspace(); const modeToggles = page.locator('[data-component="ChatModeToggles"]'); - // Default model is Opus 4.7 - displayed as formatted name - await expect(modeToggles.getByText("Opus 4.7", { exact: true })).toBeVisible(); + // Default model is Opus 4.8 - displayed as formatted name + await expect(modeToggles.getByText("Opus 4.8", { exact: true })).toBeVisible(); await ui.chat.sendMessage("/model sonnet"); await ui.chat.expectStatusMessageContains("Model changed to anthropic:claude-sonnet-4-6");