Summary
ClaudeAgentOptions.effort documents a model-dependent fallback, but the SDK gives callers no way to detect when it happens.
From types.py at v0.2.94:
"xhigh" — Extended reasoning depth (Opus 4.7 only; falls back to "high" on other models).
The SDK forwards --effort <value> to the CLI verbatim (_internal/transport/subprocess_cli.py), and nothing in the resulting message stream reports the effort that was actually applied. So a caller who requests xhigh on a non-Opus-4.7 model gets a silently downgraded session that is indistinguishable from an honored one.
Why this matters
We operate a service that fronts the SDK and offers callers a per-conversation effort setting with the contract "an explicit value is honored or refused, never silently changed." We can enforce that for the vocabulary (create-time validation against EffortLevel, and #834 covers surfacing CLI rejections), but not for the model-dependent half: the fallback documented above is invisible at the API surface, so the contract cannot be implemented on top of the SDK today. Maintaining our own model→supported-efforts table is not a real option — it goes stale with every model release.
Note the constraint that makes this non-trivial: one subprocess spans multiple models (subagents, per-turn model switches), so failing at spawn time for an unsupported (effort, model) pair may be the wrong shape. Observability may fit better than strictness.
Ask (any of these would close the gap)
- Report effective effort — include the applied effort level in the init and/or result messages (alongside the model that ran), so a downgrade is at least detectable per turn.
- Opt-in strict mode — an option that turns the documented fallback into an error when the requested effort cannot apply to the resolved primary model.
- Queryable capability surface — a way to ask the SDK/CLI which effort levels the selected model supports, so integrators can refuse up front without hand-maintaining a model table.
Affected version
claude-agent-sdk==0.2.94 (SDK-bundled CLI)
Related
Summary
ClaudeAgentOptions.effortdocuments a model-dependent fallback, but the SDK gives callers no way to detect when it happens.From
types.pyat v0.2.94:The SDK forwards
--effort <value>to the CLI verbatim (_internal/transport/subprocess_cli.py), and nothing in the resulting message stream reports the effort that was actually applied. So a caller who requestsxhighon a non-Opus-4.7 model gets a silently downgraded session that is indistinguishable from an honored one.Why this matters
We operate a service that fronts the SDK and offers callers a per-conversation effort setting with the contract "an explicit value is honored or refused, never silently changed." We can enforce that for the vocabulary (create-time validation against
EffortLevel, and #834 covers surfacing CLI rejections), but not for the model-dependent half: the fallback documented above is invisible at the API surface, so the contract cannot be implemented on top of the SDK today. Maintaining our own model→supported-efforts table is not a real option — it goes stale with every model release.Note the constraint that makes this non-trivial: one subprocess spans multiple models (subagents, per-turn model switches), so failing at spawn time for an unsupported (effort, model) pair may be the wrong shape. Observability may fit better than strictness.
Ask (any of these would close the gap)
Affected version
claude-agent-sdk==0.2.94(SDK-bundled CLI)Related