From 033b9ea56070c3e24cc20935165d20148e80d5e7 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Thu, 1 Oct 2026 13:20:54 -0500 Subject: [PATCH] fix(ai): make Claude capability defaults forward-compatible (#52535) --- packages/ai/src/protocols/anthropic-messages.ts | 17 +++++++---------- packages/ai/test/effort-updates.test.ts | 6 ++++++ .../ai/test/provider/anthropic-messages.test.ts | 3 +++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/ai/src/protocols/anthropic-messages.ts b/packages/ai/src/protocols/anthropic-messages.ts index 1e64f2a9a63..f1646b1727c 100644 --- a/packages/ai/src/protocols/anthropic-messages.ts +++ b/packages/ai/src/protocols/anthropic-messages.ts @@ -807,15 +807,12 @@ const requireThinkingSignature = (request: LLMRequest) => { // Mid-conversation system messages became available with Opus 4.8 and version // 5 of the other supported Claude families. Treat later family versions as // compatible without assuming that every Anthropic Messages model is Claude. +// Opus 4.8 and every Claude 5 model accept mid-conversation system messages; later versions inherit support. const supportsNativeSystemUpdates = (request: LLMRequest) => { - const match = /(?:^|[./])claude-(fable|haiku|mythos|opus|sonnet)-(\d+)(?:[.-](\d+))?/.exec( - String(request.model.id).toLowerCase(), - ) - if (!match) return false - const major = Number(match[2]) - if (match[1] !== "opus") return major >= 5 - if (major !== 4) return major >= 5 - return match[3] !== undefined && match[3].length <= 2 && Number(match[3]) >= 8 + const version = claudeVersion(String(request.model.id)) + if (version === undefined) return false + if (version.family === "opus" && version.major === 4) return version.minor >= 8 + return version.major >= 5 } const endsInServerToolUse = (message: LLMRequest["messages"][number]) => { @@ -992,13 +989,13 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* ( return messages }) +// Per-turn effort started with Claude Opus 5 and every Claude 5.1 model; later versions of any family inherit it. const supportsEffortUpdates = (model: LLMRequest["model"]) => { const override = model.compatibility?.supportsEffortUpdates if (override !== undefined) return override const version = claudeVersion(model.id) if (version === undefined) return false - if (version.family === "opus") return version.major >= 5 - if (version.family !== "fable" && version.family !== "mythos") return false + if (version.family === "opus" && version.major >= 5) return true return version.major > 5 || (version.major === 5 && version.minor >= 1) } diff --git a/packages/ai/test/effort-updates.test.ts b/packages/ai/test/effort-updates.test.ts index c7095c538c7..70745bff8b9 100644 --- a/packages/ai/test/effort-updates.test.ts +++ b/packages/ai/test/effort-updates.test.ts @@ -197,9 +197,15 @@ describe("Anthropic Messages effort updates", () => { ["anthropic/claude-opus-5", true], ["claude-fable-5-1", true], ["claude-mythos-5-1", true], + ["claude-opus-5-5", true], + ["claude-sonnet-5-5", true], + ["anthropic/claude-sonnet-5-5", true], + ["claude-sonnet-6", true], + ["claude-haiku-6", true], ["claude-fable-5", false], ["claude-opus-4-8", false], ["claude-sonnet-5", false], + ["claude-sonnet-5-20260801", false], ["kimi-k2.5", false], ] as const) { it.effect(`${supported ? "lowers" : "strips"} markers for ${id}`, () => diff --git a/packages/ai/test/provider/anthropic-messages.test.ts b/packages/ai/test/provider/anthropic-messages.test.ts index 46b1fdc9d6a..a2d03c884b5 100644 --- a/packages/ai/test/provider/anthropic-messages.test.ts +++ b/packages/ai/test/provider/anthropic-messages.test.ts @@ -314,6 +314,9 @@ describe("Anthropic Messages route", () => { "claude-haiku-5-1", "claude-fable-6", "anthropic/claude-mythos-7.2", + "claude-sonnet-5-5", + "claude-opus-4-8@20260101", + "claude-nova-6", ] const prepared = yield* Effect.forEach(ids, (id) =>