Skip to content

feat(thinking): support Claude output_config.effort parameter (Opus 4.6) #1540

@kaitranntt

Description

@kaitranntt

Summary

Anthropic's Messages API now includes output_config.effort as a top-level parameter for controlling overall token spend. This is separate from thinking.type: "adaptive" (which was added in 938a799) and is currently silently dropped by all translators.

Context

With Opus 4.6, Anthropic recommends combining output_config.effort with thinking.type: "adaptive" for optimal behavior:

{
  "model": "claude-opus-4-6",
  "messages": [...],
  "thinking": {"type": "adaptive"},
  "output_config": {"effort": "medium"}
}
  • thinking.type: "adaptive" → Controls when Claude thinks (already handled by 938a799)
  • output_config.effort → Controls overall token spend including text, tool calls, AND thinking depth

Claude Code sends output_config.effort when users adjust the effort slider (/model UI or CLAUDE_CODE_EFFORT_LEVEL env var).

Reference: https://platform.claude.com/docs/en/build-with-claude/effort

Current Behavior

  1. Claude Code sends output_config: {effort: "low"} + thinking: {type: "adaptive"}
  2. extractClaudeConfig() in internal/thinking/apply.go only checks thinking.type and thinking.budget_tokens
  3. output_config.effort is silently dropped
  4. All requests resolve to thinkingLevel: "high" regardless of user's effort setting

Expected Behavior

output_config.effort should be extracted and mapped through the existing centralized thinking pipeline:

output_config.effort Expected mapping
low Low thinking level / small budget
medium Medium thinking level / moderate budget
high High thinking level (current default)
max XHigh / max budget (Opus 4.6 only)

The existing reasoning_effort → level/budget conversion pipeline already handles this mapping — it just needs a new extraction point in extractClaudeConfig().

Affected Users

All users routing Claude Code through CLIProxy with Opus 4.6 — effort slider has no effect.

Effort Levels (from Anthropic docs)

Level Description
max Maximum capability, no constraints. Opus 4.6 only — errors on other models
high Default. Complex reasoning, agentic tasks
medium Balanced token savings
low Most efficient. Speed/cost optimized

"For Claude Opus 4.6, effort replaces budget_tokens as the recommended way to control thinking depth. While budget_tokens is still accepted on Opus 4.6, it is deprecated and will be removed in a future model release."

Suggested Implementation

In extractClaudeConfig() (internal/thinking/apply.go:351), check output_config.effort before falling through to thinking.budget_tokens:

// Check output_config.effort (Opus 4.6+ recommended format)
if effort := gjson.GetBytes(body, "output_config.effort"); effort.Exists() {
    value := effort.String()
    if value == "none" {
        return ThinkingConfig{Mode: ModeNone, Budget: 0}
    }
    return ThinkingConfig{Mode: ModeLevel, Level: ThinkingLevel(value)}
}

This feeds into the existing ValidateConfig → provider Apply pipeline, which already converts levels to budgets for budget-based providers (Gemini, Antigravity).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions