-
Notifications
You must be signed in to change notification settings - Fork 712
Description
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 waySame applies to:
SyncHookJSONOutput— access viaresult["hookSpecificOutput"], notresult.hookSpecificOutputAsyncHookJSONOutputPreToolUseHookSpecificOutputand all otherHookSpecificOutputvariantsMcpStdioServerConfig,McpSSEServerConfig,McpHttpServerConfigSandboxSettings,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 runtimeThis 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: intAlternatively, a note in the README / SDK guide comparing TypedDict vs @dataclass types in this SDK would prevent the confusion.
Environment
claude-agent-sdkv0.1.44- Python 3.11