Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Anthropics Anthropic sdk python Thinking Stream Events

From Leeroopedia
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 from event.delta.thinking
  • snapshot: The full accumulated thinking from content_block.thinking (already updated by accumulate_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:

  1. Raw SSE event arrives from the HTTP stream (RawMessageStreamEvent)
  2. accumulate_event updates the message snapshot by appending thinking deltas or setting signature
  3. build_events creates high-level ThinkingEvent or SignatureEvent objects using the updated snapshot
  4. 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 discriminator type fields.
  • anthropic._models.build: Factory function used by build_events to construct event objects.
  • anthropic._models.construct_type_unchecked: Used by accumulate_event to deserialize raw events.
  • httpx: Underlying HTTP client that provides the SSE stream.

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment