Summary
When working with ThinkingConfig variants and SyncHookJSONOutput, it's not immediately clear from the type annotations or docstrings that these are TypedDict classes — meaning they behave as plain dict objects at runtime, not as dataclass/object instances.
Observed behaviour
from claude_agent_sdk import ThinkingConfigEnabled, SyncHookJSONOutput
# Looks like a constructor call — but returns a plain dict
config = ThinkingConfigEnabled(type="enabled", budget_tokens=20000)
print(type(config)) # <class 'dict'>
print(config) # {'type': 'enabled', 'budget_tokens': 20000}
# Attribute access FAILS at runtime (works only under type checkers)
config.budget_tokens # AttributeError: 'dict' object has no attribute 'budget_tokens'
config["budget_tokens"] # ✅ correct way
Same applies to:
SyncHookJSONOutput — access via result["hookSpecificOutput"], not result.hookSpecificOutput
AsyncHookJSONOutput
PreToolUseHookSpecificOutput and all other HookSpecificOutput variants
McpStdioServerConfig, McpSSEServerConfig, McpHttpServerConfig
SandboxSettings, SandboxNetworkConfig
Why it matters
Developers (and LLMs writing integration code) naturally write:
# Common mistake — attribute access on a TypedDict
output = SyncHookJSONOutput(continue_=True, hookSpecificOutput={...})
print(output.continue_) # AttributeError at runtime
This is especially subtle because dataclass types in the same file (AgentDefinition, HookMatcher, TextBlock, etc.) do support attribute access. The mix of @dataclass and TypedDict in types.py creates inconsistent expectations.
Suggested fix
Add a note to the module docstring or the affected TypedDict classes:
class ThinkingConfigEnabled(TypedDict):
"""Enabled thinking configuration with a token budget.
Note: This is a TypedDict — instances are plain dicts at runtime.
Use dict key access: config["budget_tokens"], not config.budget_tokens.
"""
type: Literal["enabled"]
budget_tokens: int
Alternatively, a note in the README / SDK guide comparing TypedDict vs @dataclass types in this SDK would prevent the confusion.
Environment
claude-agent-sdk v0.1.44
- Python 3.11
Summary
When working with
ThinkingConfigvariants andSyncHookJSONOutput, it's not immediately clear from the type annotations or docstrings that these areTypedDictclasses — meaning they behave as plaindictobjects at runtime, not as dataclass/object instances.Observed behaviour
Same applies to:
SyncHookJSONOutput— access viaresult["hookSpecificOutput"], notresult.hookSpecificOutputAsyncHookJSONOutputPreToolUseHookSpecificOutputand all otherHookSpecificOutputvariantsMcpStdioServerConfig,McpSSEServerConfig,McpHttpServerConfigSandboxSettings,SandboxNetworkConfigWhy it matters
Developers (and LLMs writing integration code) naturally write:
This is especially subtle because
dataclasstypes in the same file (AgentDefinition,HookMatcher,TextBlock, etc.) do support attribute access. The mix of@dataclassandTypedDictintypes.pycreates inconsistent expectations.Suggested fix
Add a note to the module docstring or the affected
TypedDictclasses:Alternatively, a note in the README / SDK guide comparing
TypedDictvs@dataclasstypes in this SDK would prevent the confusion.Environment
claude-agent-sdkv0.1.44