diff --git a/src/hooks/anthropic-effort/hook.ts b/src/hooks/anthropic-effort/hook.ts index 76fba5245..fb5a9a209 100644 --- a/src/hooks/anthropic-effort/hook.ts +++ b/src/hooks/anthropic-effort/hook.ts @@ -1,6 +1,7 @@ import { log, normalizeModelID } from "../../shared" const OPUS_PATTERN = /claude-.*opus/i +const EFFORT_UNSUPPORTED_PATTERN = /claude-.*haiku/i const INTERNAL_SKIP_AGENTS = new Set(["title", "summary", "compaction"]) function isClaudeProvider(providerID: string, modelID: string): boolean { @@ -14,6 +15,11 @@ function isOpusModel(modelID: string): boolean { return OPUS_PATTERN.test(normalized) } +function isEffortUnsupportedModel(modelID: string): boolean { + const normalized = normalizeModelID(modelID) + return EFFORT_UNSUPPORTED_PATTERN.test(normalized) +} + function shouldSkipForInternalAgent(agentName: string | undefined): boolean { if (!agentName) return false return INTERNAL_SKIP_AGENTS.has(agentName.trim().toLowerCase()) @@ -60,6 +66,7 @@ export function createAnthropicEffortHook() { if (!isClaudeProvider(model.providerID, model.modelID)) return if (shouldSkipForInternalAgent(agent?.name)) return if (output.options.effort !== undefined) return + if (isEffortUnsupportedModel(model.modelID)) return const opus = isOpusModel(model.modelID) const clamped = clampVariant(message.variant, opus) diff --git a/src/hooks/anthropic-effort/index.test.ts b/src/hooks/anthropic-effort/index.test.ts index 056ff0a28..5ca923cd2 100644 --- a/src/hooks/anthropic-effort/index.test.ts +++ b/src/hooks/anthropic-effort/index.test.ts @@ -147,6 +147,30 @@ describe("createAnthropicEffortHook", () => { expect(output.options.effort).toBeUndefined() }) + + describe("#given haiku models (effort unsupported)", () => { + const haikuModels = [ + "claude-haiku-4-5", + "claude-haiku-4.6", + "claude-haiku", + "claude-haiku-20240307", + ] + + for (const modelID of haikuModels) { + it(`skips effort injection for ${modelID}`, async () => { + // given + const hook = createAnthropicEffortHook() + const { input, output } = createMockParams({ modelID }) + + // when + await hook["chat.params"](input, output) + + // then + expect(output.options.effort).toBeUndefined() + expect(input.message.variant).toBe("max") + }) + } + }) }) describe("existing options", () => {