Implementation:Anthropics Anthropic sdk python Thinking Stream Events
| Knowledge Sources | |
|---|---|
| Domains | Extended_Thinking, LLM, Reasoning |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
The Anthropic Python SDK implements streaming thinking through two high-level event types (ThinkingEvent and SignatureEvent), two raw delta types (ThinkingDelta and SignatureDelta), and the build_events / accumulate_event functions that transform raw SSE events into these high-level objects.
ThinkingEvent
Source: src/anthropic/lib/streaming/_types.py (Lines 46-53)
class ThinkingEvent(BaseModel):
type: Literal["thinking"]
thinking: str
"""The thinking delta"""
snapshot: str
"""The accumulated thinking so far"""
Fields:
| Field | Type | Description |
|---|---|---|
type |
Literal["thinking"] |
Discriminator field identifying this as a thinking event. |
thinking |
str |
The incremental thinking delta -- the new text since the last thinking event. |
snapshot |
str |
The full accumulated thinking text up to and including this delta. |
SignatureEvent
Source: src/anthropic/lib/streaming/_types.py (Lines 56-60)
class SignatureEvent(BaseModel):
type: Literal["signature"]
signature: str
"""The signature of the thinking block"""
Fields:
| Field | Type | Description |
|---|---|---|
type |
Literal["signature"] |
Discriminator field identifying this as a signature event. |
signature |
str |
The cryptographic signature of the completed thinking block, used for multi-turn conversation verification. |
Raw Delta Types
ThinkingDelta
Source: src/anthropic/types/thinking_delta.py (Lines 10-13)
class ThinkingDelta(BaseModel):
thinking: str
type: Literal["thinking_delta"]
SignatureDelta
Source: src/anthropic/types/signature_delta.py (Lines 10-13)
class SignatureDelta(BaseModel):
signature: str
type: Literal["signature_delta"]
build_events Function
Source: src/anthropic/lib/streaming/_messages.py (Lines 331-422)
The build_events function transforms raw SSE events into high-level stream events. The thinking-relevant portions are:
Thinking Delta Handling (Lines 382-391)
elif event.delta.type == "thinking_delta":
if content_block.type == "thinking":
events_to_fire.append(
build(
ThinkingEvent,
type="thinking",
thinking=event.delta.thinking,
snapshot=content_block.thinking,
)
)
When a thinking_delta arrives for a thinking content block, the function creates a ThinkingEvent with:
thinking: The delta text fromevent.delta.thinkingsnapshot: The full accumulated thinking fromcontent_block.thinking(already updated byaccumulate_event)
Signature Delta Handling (Lines 392-401)
elif event.delta.type == "signature_delta":
if content_block.type == "thinking":
events_to_fire.append(
build(
SignatureEvent,
type="signature",
signature=content_block.signature,
)
)
pass
When a signature_delta arrives for a thinking content block, the function creates a SignatureEvent with the block's accumulated signature.
accumulate_event Function
Source: src/anthropic/lib/streaming/_messages.py (Lines 433-518)
The accumulate_event function maintains the running message snapshot. The thinking-relevant portions are:
Thinking Delta Accumulation (Lines 489-491)
elif event.delta.type == "thinking_delta":
if content.type == "thinking":
content.thinking += event.delta.thinking
Each thinking delta's text is appended to the content block's thinking field. This ensures the snapshot always contains the complete accumulated thinking text.
Signature Delta Accumulation (Lines 492-494)
elif event.delta.type == "signature_delta":
if content.type == "thinking":
content.signature = event.delta.signature
The signature delta sets (rather than appends to) the content block's signature field.
MessageStreamEvent Union
Source: src/anthropic/lib/streaming/_types.py (Lines 92-107)
MessageStreamEvent = Annotated[
Union[
TextEvent,
CitationEvent,
ThinkingEvent,
SignatureEvent,
InputJsonEvent,
RawMessageStartEvent,
RawMessageDeltaEvent,
MessageStopEvent,
RawContentBlockStartEvent,
RawContentBlockDeltaEvent,
ContentBlockStopEvent,
],
PropertyInfo(discriminator="type"),
]
Both ThinkingEvent and SignatureEvent are members of the MessageStreamEvent union, making them available when iterating over a message stream.
Usage Example
Streaming Thinking Output
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=16000,
thinking={"type": "enabled", "budget_tokens": 10000},
messages=[{"role": "user", "content": "Explain quantum computing"}]
) as stream:
for event in stream:
if event.type == "thinking":
print(f"[thinking] {event.thinking}", end="", flush=True)
elif event.type == "signature":
print(f"\n[signature received]")
elif event.type == "text":
print(event.text, end="", flush=True)
Accessing the Final Snapshot
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=16000,
thinking={"type": "enabled", "budget_tokens": 10000},
messages=[{"role": "user", "content": "Solve: 2x + 5 = 15"}]
) as stream:
for event in stream:
pass # consume the stream
# Access the final accumulated message
final_message = stream.get_final_message()
for block in final_message.content:
if block.type == "thinking":
print(f"Full thinking: {block.thinking}")
print(f"Signature: {block.signature}")
elif block.type == "text":
print(f"Answer: {block.text}")
Processing Pipeline
The streaming pipeline for thinking events follows this flow:
- Raw SSE event arrives from the HTTP stream (
RawMessageStreamEvent) - accumulate_event updates the message snapshot by appending thinking deltas or setting signature
- build_events creates high-level
ThinkingEventorSignatureEventobjects using the updated snapshot - MessageStream iterator yields the high-level events to the developer
Both MessageStream (synchronous) and AsyncMessageStream (asynchronous) implement this same pipeline.
Dependencies
pydantic.BaseModel: Base class for all event and delta types.typing_extensions.Literal: Used for discriminatortypefields.anthropic._models.build: Factory function used bybuild_eventsto construct event objects.anthropic._models.construct_type_unchecked: Used byaccumulate_eventto deserialize raw events.httpx: Underlying HTTP client that provides the SSE stream.