fix: clamp variant "max" to "high" for non-Opus Claude models on fallback

When an agent configured with variant: "max" falls back from Opus to
Sonnet (or Haiku), the "max" variant was passed through unchanged.
OpenCode sends this as level: "max" to the Anthropic API, which rejects
it with: level "max" not supported, valid levels: low, medium, high

The anthropic-effort hook previously only handled Opus (inject effort=max)
and skipped all other Claude models. Now it actively clamps "max" → "high"
for non-Opus Claude models and mutates message.variant so OpenCode
doesn't pass the unsupported level to the API.
This commit is contained in:
Ravi Tharuma
2026-03-16 07:49:55 +01:00
parent 1ef8d73ce5
commit 9346bc8379
2 changed files with 38 additions and 11 deletions
+5 -4
View File
@@ -143,8 +143,8 @@ describe("createAnthropicEffortHook", () => {
expect(output.options.effort).toBeUndefined()
})
it("should NOT inject effort for non-opus model", async () => {
//#given claude-sonnet-4-6 (not opus)
it("should clamp effort to high for non-opus claude model with variant max", async () => {
//#given claude-sonnet-4-6 (not opus) with variant max
const hook = createAnthropicEffortHook()
const { input, output } = createMockParams({
modelID: "claude-sonnet-4-6",
@@ -153,8 +153,9 @@ describe("createAnthropicEffortHook", () => {
//#when chat.params hook is called
await hook["chat.params"](input, output)
//#then effort should NOT be injected
expect(output.options.effort).toBeUndefined()
//#then effort should be clamped to high (not max)
expect(output.options.effort).toBe("high")
expect(input.message.variant).toBe("high")
})
it("should NOT inject effort for non-anthropic provider with non-claude model", async () => {