diff --git a/src/hooks/anthropic-effort/hook.ts b/src/hooks/anthropic-effort/hook.ts index a545768d6..7d4eca99b 100644 --- a/src/hooks/anthropic-effort/hook.ts +++ b/src/hooks/anthropic-effort/hook.ts @@ -76,23 +76,35 @@ export function createAnthropicEffortHook() { const { agent, model, message } = input if (!model?.modelID || !model?.providerID) return if (isEffortUnsupportedModel(model.modelID)) return - if (message.variant !== "max") return if (!isClaudeProvider(model.providerID, model.modelID)) return if (shouldSkipForInternalAgent(agent?.name)) return - if (output.options.effort !== undefined) return const opus = isOpusModel(model.modelID) const constrained = isConstrainedProvider(model.providerID) + + if (output.options.effort !== undefined) { + if (output.options.effort === "max" && constrained) { + const clamped = clampVariant("max", opus, constrained) + output.options.effort = clamped + ;(message as { variant?: string }).variant = clamped + log("anthropic-effort: clamped pre-set effort max→high", { + sessionID: input.sessionID, + provider: model.providerID, + model: model.modelID, + reason: "constrained-provider", + }) + } + return + } + + if (message.variant !== "max") return + const clamped = clampVariant(message.variant, opus, constrained) output.options.effort = clamped const shouldOverrideMessageVariant = !opus || constrained if (shouldOverrideMessageVariant) { - // Override the variant so OpenCode doesn't pass "max" to the API. - // Non-Opus models cap at high; Anthropic OAuth (Claude Pro/Max) also - // caps at high even on Opus because the OAuth API only accepts - // low | medium | high. ;(message as { variant?: string }).variant = clamped log("anthropic-effort: clamped variant max→high", { sessionID: input.sessionID,