A single event from the Claude CLI's NDJSON streaming output.
When using --output-format stream-json, the CLI emits one JSON object
per line. Each event has a type and associated data.
Event types
Common event types include:
"system"-- system initialization"assistant"-- assistant message content"tool_use"-- tool invocation"tool_result"-- tool execution result"result"-- final result with cost/session info"error"-- error during execution
Summary
Types
The incremental payload carried by a :block_delta partial message.
The kind of content block reported by a :block_start partial message.
A decoded partial-message event from a streaming claude call.
Functions
Extract cost in USD, if present.
Parse a single NDJSON line into a stream event.
Decode a partial-message event into a typed, tagged view.
Whether this is the final result event.
Extract the result text, if this is a result event.
Extract the session ID, if present.
Types
@type block_delta() :: {:text, String.t()} | {:thinking, String.t()} | {:input_json, String.t()} | :other
The incremental payload carried by a :block_delta partial message.
Mirrors the delta.type field from the Anthropic streaming API. Less
common delta kinds (signature, citations, ...) collapse to :other;
callers that need them can fall back to the struct's :data field.
@type block_type() :: :text | :thinking | {:tool_use, id :: String.t(), name :: String.t()} | {:other, String.t()}
The kind of content block reported by a :block_start partial message.
Mirrors the content_block.type field from the Anthropic streaming API.
Block kinds not modelled here surface as {:other, raw_type} -- callers
can still recover the type name from the carried string.
@type partial_message() :: {:block_start, index :: non_neg_integer(), block_type()} | {:block_delta, index :: non_neg_integer(), block_delta()} | {:block_stop, index :: non_neg_integer()}
A decoded partial-message event from a streaming claude call.
Returned by partial_message/1. The three variants correspond to the
Anthropic streaming content-block lifecycle: a block starts, gets one
or more deltas, then stops.
Functions
Extract cost in USD, if present.
@spec parse(String.t()) :: {:ok, t()} | {:error, ClaudeWrapper.Error.t()}
Parse a single NDJSON line into a stream event.
@spec partial_message(t()) :: partial_message() | nil
Decode a partial-message event into a typed, tagged view.
Returns the tagged tuple when the event is one of the content-block
lifecycle events surfaced with --include-partial-messages -- start,
delta, or stop. Returns nil for any other event (system, assistant,
result, message-level stream events, etc.).
The CLI wraps each raw streaming event as
%{"type" => "stream_event", "event" => %{...}}; this accessor unwraps
that envelope. A raw (unwrapped) content-block event is also accepted.
Unknown block types and unknown delta types fall through to
{:other, type} / :other rather than returning nil, so future
content-block kinds remain accessible (just untyped).
Examples
iex> {:ok, event} =
...> ClaudeWrapper.StreamEvent.parse(
...> ~s({"type":"stream_event","event":{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}})
...> )
iex> ClaudeWrapper.StreamEvent.partial_message(event)
{:block_delta, 0, {:text, "Hi"}}
iex> {:ok, event} = ClaudeWrapper.StreamEvent.parse(~s({"type":"result","result":"done"}))
iex> ClaudeWrapper.StreamEvent.partial_message(event)
nil
Whether this is the final result event.
Extract the result text, if this is a result event.
Extract the session ID, if present.