Per-model effort level configuration (modelEffort block)

Resolved 💬 1 comment Opened Apr 20, 2026 by Jonathan-7 Closed May 26, 2026

Summary

Expose a way to configure effortLevel per model. Today, CLAUDE_CODE_EFFORT_LEVEL / effortLevel are global, which doesn't compose well with the mixed-model precedence rules (e.g. xhigh is Opus-4.7-only; other models silently fall back to high rather than max).

Problem

Given the current single-knob behaviour:

  • Set max globally -> all models run at max, so Opus 4.7 never uses xhigh.
  • Set xhigh globally -> Opus 4.7 gets xhigh as desired, but Sonnet 4.6 / Haiku 4.5 silently fall back to high (not max).

There's no way today to express \"xhigh on Opus 4.7, max on Sonnet 4.6, high on Haiku 4.5\" without wrapping the CLI in a shell function that inspects --model before launch. That wrapper approach:

  • breaks when switching models mid-session with /model
  • doesn't apply to the desktop/IDE entrypoints
  • can't be shared via settings.json

Proposed solution: modelEffort block in settings.json

{
  \"effortLevel\": \"high\",
  \"modelEffort\": {
    \"claude-opus-4-7\": \"xhigh\",
    \"claude-sonnet-4-6\": \"max\",
    \"claude-haiku-4-5\": \"high\"
  }
}

Resolution order (highest wins):

  1. --effort CLI flag (session override)
  2. modelEffort[<active-model>]
  3. effortLevel / CLAUDE_CODE_EFFORT_LEVEL (global default)
  4. Model default

This should apply at session start and when the active model changes via /model mid-session.

Alternative: expose CLAUDE_MODEL env var

Export CLAUDE_MODEL (or similar) into the session's process env so SessionStart / PreCompact hooks can read it and set CLAUDE_CODE_EFFORT_LEVEL dynamically. Less clean but more general -- hooks could use it for other model-dependent config (different system prompt patches, different tool allowlists, etc.). Doesn't solve mid-session /model switches on its own.

Why this matters

Users who deliberately mix models (e.g. randomised launch between Opus 4.6 and 4.7, or /model switching during a session based on task type) can't currently get the right effort per model without brittle wrappers. The gap is small in code but surprising in behaviour -- \"I set xhigh globally and my Sonnet session got worse than max\" is easy to miss.

Related: --effort as a per-invocation flag already works well -- this proposal just makes it declarative in settings.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗