Chat model streaming event protocol.
Defines a content-block-centric event model for streaming chat model responses. Events carry LangChain ContentBlock types on lifecycle boundaries and explicit delta variants for incremental updates during streaming.
Content-block deltas have explicit merge semantics. Text, reasoning, and data deltas append to named fields. Generic block deltas shallow-merge fields onto the active content block.
Lifecycle completeness. Every streamable entity has explicit start and finish events. Consumers never need to infer boundaries from absence of events.
Interleaving allowed. Content blocks may interleave (e.g., parallel tool calls). The only invariant: a block's start precedes its deltas, and its deltas precede its finish. No ordering constraint between different blocks.
Provider passthrough. Native provider events that don't map to standard types are forwarded as ProviderEvent rather than silently dropped.
MessageStart
-> ContentBlockStart(index=0, content=...)
-> ContentBlockDelta(index=0, delta={ type: "text-delta", text: "Hello" })
-> ContentBlockDelta(index=0, delta={ type: "text-delta", text: " world" })
-> ContentBlockFinish(index=0, content=...)
-> UsageUpdate(...)
-> MessageFinish(reason, usage?)
import { ... } from "@langchain/core/language_models/event";Generic content block field update. Shallow-merge fields onto the active
content block.
Emitted for each incremental update within a content block.
The delta field carries the incremental content block update.
Accumulation rules:
text-delta ā append text to the active block's text fieldreasoning-delta ā append reasoning to the active block's reasoning fielddata-delta ā append data to the active block's data fieldtool-call-delta ā append args to the active tool-call block's args fieldblock-delta ā shallow-merge fields onto the active blockConsumers ignore delta types they don't recognize.
content-block-finish carries the complete block.
A tool call's args stream in one of two forms, never both in one block:
tool-call-delta slices, which append, or block-delta snapshots of the
args so far, which replace.
Emitted when a content block is complete.
Emitted when a new content block begins streaming.
Incremental encoded data. Append data to the active multimodal block's
data field.
Emitted once when the model response is complete.
Emitted once at the start of a model response.
Passthrough for native provider events that don't map to standard types.
Incremental reasoning content. Append reasoning to the active block's
reasoning field.
Emitted on unrecoverable stream errors.
Incremental text content. Append text to the active block's text field.
Incremental tool-call arguments. Append args to the active
tool_call_chunk or server_tool_call_chunk block's args field, treating
missing args as an empty string.
A slice need not be valid JSON on its own. The call's id and name arrive
on content-block-start, and content-block-finish carries the parsed call.
Emitted whenever the provider reports updated usage information. Each event carries a running snapshot (not an additive delta).
Union of all chat model stream event types.
Union of all content block delta types.
Finish reason for a model response.
"stop": Natural end of generation."length": Hit max token limit."tool_use": Model is requesting tool execution."content_filter": Content was filtered by safety systems.