From be5e1d3869e0cb5fabeebc5c7a1aaaed1e3a8cb9 Mon Sep 17 00:00:00 2001 From: Bharadwaj Date: Sun, 6 Sep 2026 13:10:38 -0500 Subject: [PATCH] fix(anthropic): stop inventing (latest) display-name suffix in sync Anthropic retired the alias model after 4.6: dateless IDs are now pinned snapshots, so every frozen pre-4.6 alias kept a permanent (latest) tag (Opus 4/4.1/4.5, Sonnet 4/4.5) while newer pinned models got none. Use the API display_name verbatim (stripping any stale suffix) instead of appending (latest) to every alias. This matches all other providers, where a rolling -latest pointer is owned upstream rather than hardcoded in names. Also sweeps the six stale canonical names. Supersedes #6433. --- models/anthropic/claude-haiku-4-5.toml | 2 +- models/anthropic/claude-opus-4-0.toml | 2 +- models/anthropic/claude-opus-4-1.toml | 2 +- models/anthropic/claude-opus-4-5.toml | 2 +- models/anthropic/claude-sonnet-4-0.toml | 2 +- models/anthropic/claude-sonnet-4-5.toml | 2 +- packages/core/src/sync/providers/anthropic.ts | 4 +--- packages/core/test/sync.test.ts | 16 +++++++++++++--- 8 files changed, 20 insertions(+), 12 deletions(-) diff --git a/models/anthropic/claude-haiku-4-5.toml b/models/anthropic/claude-haiku-4-5.toml index f914d285f0f..57b90aa9edd 100644 --- a/models/anthropic/claude-haiku-4-5.toml +++ b/models/anthropic/claude-haiku-4-5.toml @@ -1,4 +1,4 @@ -name = "Claude Haiku 4.5 (latest)" +name = "Claude Haiku 4.5" description = "Fast Claude lane for lightweight agents, office tasks, and responsive chat" family = "claude-haiku" release_date = "2025-10-15" diff --git a/models/anthropic/claude-opus-4-0.toml b/models/anthropic/claude-opus-4-0.toml index ec82d370901..172862187cf 100644 --- a/models/anthropic/claude-opus-4-0.toml +++ b/models/anthropic/claude-opus-4-0.toml @@ -1,4 +1,4 @@ -name = "Claude Opus 4 (latest)" +name = "Claude Opus 4" description = "Flagship Claude model for deep reasoning, coding, and long-horizon agents" family = "claude-opus" release_date = "2025-05-22" diff --git a/models/anthropic/claude-opus-4-1.toml b/models/anthropic/claude-opus-4-1.toml index cd3fb3a0724..4b188112f09 100644 --- a/models/anthropic/claude-opus-4-1.toml +++ b/models/anthropic/claude-opus-4-1.toml @@ -1,4 +1,4 @@ -name = "Claude Opus 4.1 (latest)" +name = "Claude Opus 4.1" description = "Flagship Claude model for deep reasoning, coding, and long-horizon agents" family = "claude-opus" release_date = "2025-08-05" diff --git a/models/anthropic/claude-opus-4-5.toml b/models/anthropic/claude-opus-4-5.toml index 6be4cf593c2..82cc015dcb1 100644 --- a/models/anthropic/claude-opus-4-5.toml +++ b/models/anthropic/claude-opus-4-5.toml @@ -1,4 +1,4 @@ -name = "Claude Opus 4.5 (latest)" +name = "Claude Opus 4.5" description = "Flagship Claude model for deep reasoning, coding, and long-horizon agents" family = "claude-opus" release_date = "2025-11-24" diff --git a/models/anthropic/claude-sonnet-4-0.toml b/models/anthropic/claude-sonnet-4-0.toml index 48ab1bd47a5..cdbc8a3ca7f 100644 --- a/models/anthropic/claude-sonnet-4-0.toml +++ b/models/anthropic/claude-sonnet-4-0.toml @@ -1,4 +1,4 @@ -name = "Claude Sonnet 4 (latest)" +name = "Claude Sonnet 4" description = "Balanced Claude model for coding, analysis, agent workflows, and cost control" family = "claude-sonnet" release_date = "2025-05-22" diff --git a/models/anthropic/claude-sonnet-4-5.toml b/models/anthropic/claude-sonnet-4-5.toml index 941a171eb3f..c22dfe295c0 100644 --- a/models/anthropic/claude-sonnet-4-5.toml +++ b/models/anthropic/claude-sonnet-4-5.toml @@ -1,4 +1,4 @@ -name = "Claude Sonnet 4.5 (latest)" +name = "Claude Sonnet 4.5" description = "Balanced Claude model for coding, analysis, agent workflows, and cost control" family = "claude-sonnet" release_date = "2025-09-29" diff --git a/packages/core/src/sync/providers/anthropic.ts b/packages/core/src/sync/providers/anthropic.ts index af568337ce0..a599683c75b 100644 --- a/packages/core/src/sync/providers/anthropic.ts +++ b/packages/core/src/sync/providers/anthropic.ts @@ -296,9 +296,7 @@ export function buildAnthropicModel( existing: ExistingModel | undefined, baseModel?: string, ): SyncedModel { - const name = model.canonical_id !== undefined && !model.display_name.endsWith("(latest)") - ? `${model.display_name} (latest)` - : model.display_name; + const name = model.display_name.replace(/\s*\(latest\)\s*$/i, ""); const reasoning = model.capabilities.thinking?.supported ?? existing?.reasoning ?? false; const input = [ "text" as const, diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index 0e51e85cfe1..9374a617dcb 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -994,19 +994,29 @@ test("adds manual budget control for new Anthropic models", () => { expect(model.reasoning_options).toEqual([{ type: "budget_tokens" }]); }); -test("labels Anthropic aliases as latest", () => { +test("never invents latest tags for Anthropic aliases", () => { const model = buildAnthropicModel(anthropicModel({ id: "claude-sonnet-5", canonical_id: "claude-sonnet-5-20260630", }), undefined, "anthropic/claude-sonnet-5"); - expect(model.name).toBe("Claude Sonnet 5 (latest)"); + expect(model.name).toBe("Claude Sonnet 5"); +}); + +test("strips stale latest suffix from Anthropic display names", () => { + const model = buildAnthropicModel(anthropicModel({ + id: "claude-opus-4-5", + canonical_id: "claude-opus-4-5-20251101", + display_name: "Claude Opus 4.5 (latest)", + }), undefined, "anthropic/claude-opus-4-5"); + + expect(model.name).toBe("Claude Opus 4.5"); }); test("Anthropic sync preserves base model inheritance", () => { const resolved = { base_model: "anthropic/claude-opus-4-5", - name: "Claude Opus 4.5 (latest)", + name: "Claude Opus 4.5", description: "Flagship Claude model", release_date: "2025-11-24", last_updated: "2025-11-24",