Summary
On Opus 4.7+, ThinkingBlock.thinking is always \"\" and no thinking_delta stream events arrive, even when thinking={\"type\": \"adaptive\"} is set on ClaudeAgentOptions. There is no supported SDK knob to fix this — the underlying CLI flag exists but isn't reachable.
Background
Opus 4.7 silently changed the default of the API's thinking.display field from \"summarized\" (Opus 4.6) to \"omitted\". With \"omitted\", the API deliberately returns:
content_block_start with empty thinking
- one or more
signature_delta events (encrypted envelope)
- no
thinking_delta events
- terminal
ThinkingBlock.thinking == \"\"
The bundled Claude Code CLI 2.1.111 accepts --thinking-display <summarized|omitted> to override this default. You can verify the flag exists (it's hidden from --help):
$ claude --thinking-display bogus
error: option '--thinking-display <display>' argument 'bogus' is invalid. Allowed choices are summarized, omitted.
The bug in the SDK
In claude-agent-sdk 0.1.60, two things combine to make this flag unreachable:
ThinkingConfigAdaptive and ThinkingConfigEnabled in src/claude_agent_sdk/types.py don't declare a display field. Passing {\"type\": \"adaptive\", \"display\": \"summarized\"} requires # type: ignore[typeddict-unknown-key].
SubprocessCLITransport._build_command at src/claude_agent_sdk/_internal/transport/subprocess_cli.py:303-316 only reads t[\"type\"]. Any other keys in the thinking dict are silently dropped, so display never reaches the CLI.
Workaround today: extra_args={\"thinking-display\": \"summarized\"}, which works but relies on a hidden flag and bypasses the typed API.
Reproduction
from claude_agent_sdk import ClaudeAgentOptions, query
options = ClaudeAgentOptions(
model=\"claude-opus-4-7\",
thinking={\"type\": \"adaptive\"},
effort=\"max\",
include_partial_messages=True,
)
async for msg in query(prompt=\"what is 2+2, think step by step\", options=options):
# Every ThinkingBlock returned has thinking == \"\" — only signatures come through
...
Verified against Opus 4.7 on Vertex: raising effort from default → \"max\" grows the signature payload (424 → 2852 bytes = more thinking is happening) but plaintext remains empty.
Proposed fix
Surface display on the TypedDicts and forward it to --thinking-display. PR: #830
# before
options = ClaudeAgentOptions(thinking={\"type\": \"adaptive\"}) # plaintext empty on Opus 4.7
# after
options = ClaudeAgentOptions(thinking={\"type\": \"adaptive\", \"display\": \"summarized\"}) # plaintext returned
Related
- TypeScript SDK (
@anthropic-ai/claude-agent-sdk) appears to have the same gap — happy to file a sibling issue/PR if useful.
- Worth confirming whether
--thinking-display is intended to be a public flag; if so, a docs entry would pair nicely with the SDK fix.
Summary
On Opus 4.7+,
ThinkingBlock.thinkingis always\"\"and nothinking_deltastream events arrive, even whenthinking={\"type\": \"adaptive\"}is set onClaudeAgentOptions. There is no supported SDK knob to fix this — the underlying CLI flag exists but isn't reachable.Background
Opus 4.7 silently changed the default of the API's
thinking.displayfield from\"summarized\"(Opus 4.6) to\"omitted\". With\"omitted\", the API deliberately returns:content_block_startwith emptythinkingsignature_deltaevents (encrypted envelope)thinking_deltaeventsThinkingBlock.thinking == \"\"The bundled Claude Code CLI 2.1.111 accepts
--thinking-display <summarized|omitted>to override this default. You can verify the flag exists (it's hidden from--help):The bug in the SDK
In
claude-agent-sdk0.1.60, two things combine to make this flag unreachable:ThinkingConfigAdaptiveandThinkingConfigEnabledinsrc/claude_agent_sdk/types.pydon't declare adisplayfield. Passing{\"type\": \"adaptive\", \"display\": \"summarized\"}requires# type: ignore[typeddict-unknown-key].SubprocessCLITransport._build_commandatsrc/claude_agent_sdk/_internal/transport/subprocess_cli.py:303-316only readst[\"type\"]. Any other keys in the thinking dict are silently dropped, sodisplaynever reaches the CLI.Workaround today:
extra_args={\"thinking-display\": \"summarized\"}, which works but relies on a hidden flag and bypasses the typed API.Reproduction
Verified against Opus 4.7 on Vertex: raising
effortfrom default →\"max\"grows the signature payload (424 → 2852 bytes = more thinking is happening) but plaintext remains empty.Proposed fix
Surface
displayon the TypedDicts and forward it to--thinking-display. PR: #830Related
@anthropic-ai/claude-agent-sdk) appears to have the same gap — happy to file a sibling issue/PR if useful.--thinking-displayis intended to be a public flag; if so, a docs entry would pair nicely with the SDK fix.