Stream event types
Every way of consuming a Strands stream yields the same set of events: async iterators and, in Python, callback handlers. They differ in their execution model, not in what they emit. This page is the reference for every event type the stream produces: lifecycle signals, model output, tool activity, and multi-agent coordination, plus how to serialize events when forwarding them over the wire.
Event Types
Section titled “Event Types”Lifecycle Events
Section titled “Lifecycle Events”init_event_loop: True at the start of agent invocation initializingstart_event_loop: True when the event loop is startingevent_loop_throttled_delay: Delay, in seconds, that the agent loop waited before retrying a model call after a retryable failure (by default only throttling, see Retry Strategies)message: Present when a new message is createdevent: Raw event from the model streamforce_stop: True if the event loop was forced to stopforce_stop_reason: Reason for forced stop
result: The finalAgentResult
Each event emitted from the TypeScript agent is a class with a type attribute that has a unique value. When determining an event, you can use instanceof on the class, or an equality check on the event.type value. All events extend HookableEvent, making them both streamable and subscribable via hook callbacks.
BeforeInvocationEvent: Start of agent loop (before any iterations)cancel: Set by hook callbacks to cancel the invocation (boolean | string)
AfterInvocationEvent: End of agent loop (after all iterations complete)error?: Optional error if loop terminated due to exception
BeforeModelCallEvent: Before model invocationmessages: Array of messages being sent to modelcancel: Set by hook callbacks to cancel the model call (boolean | string)
AfterModelCallEvent: After model invocationmessage: Assistant message returned by modelstopReason: Why generation stopped
BeforeToolsEvent: Before tools executionmessage: Assistant message containing tool use blocks
AfterToolsEvent: After tools executionmessage: User message containing tool results
AgentResultEvent: Final agent resultresult: TheAgentResultwithstopReason,lastMessage, and optionalstructuredOutput
Model Stream Events
Section titled “Model Stream Events”data: Text chunk from the model’s outputdelta: Raw delta content from the modelreasoning: True for reasoning eventsreasoningText: Text from reasoning processreasoning_signature: Signature from reasoning processredactedContent: Reasoning content redacted by the model
ModelStreamUpdateEvent: Wraps transient model streaming deltas. Access the inner event via.event:ModelMessageStartEvent: Start of a message from the modelModelContentBlockStartEvent: Start of a content block (text, toolUse, reasoning, etc.)ModelContentBlockDeltaEvent: Content deltas for text, tool input, or reasoningModelContentBlockStopEvent: End of a content blockModelMessageStopEvent: End of a messageModelMetadataEvent: Usage and metrics metadata
ContentBlockEvent: Wraps a fully assembled content block (TextBlock, ToolUseBlock, ReasoningBlock). Access via.contentBlockModelMessageEvent: Wraps the complete model message after all blocks are assembled. Access via.message
Tool Events
Section titled “Tool Events”current_tool_use: Information about the current tool being used, including:toolUseId: Unique ID for this tool usename: Name of the toolinput: Tool input parameters (accumulated as streaming occurs)
tool_stream_event: Information about an event streamed from a tool, including:tool_use: TheToolUsefor the tool that streamed the eventdata: The data streamed from the tool
BeforeToolCallEvent: Before a tool is executedtoolUse: The tool use block withnameandinput
AfterToolCallEvent: After a tool finishes executiontoolUse: The tool use blockresult: The tool result block
ToolStreamUpdateEvent: Wraps streaming progress events from a tool. Access via.event:data: The data streamed from the tool
ToolResultEvent: Wraps a completed tool result. Access via.result
Multi-Agent Events
Section titled “Multi-Agent Events”Multi-agent systems (Graph and Swarm) emit additional coordination events:
multiagent_node_start: When a node begins executiontype:"multiagent_node_start"node_id: Unique identifier for the nodenode_type: Type of node ("agent","swarm","graph")
multiagent_node_stream: Forwarded events from agents/multi-agents with node contexttype:"multiagent_node_stream"node_id: Identifier of the node generating the eventevent: The original agent event (nested)
multiagent_node_stop: When a node completes executiontype:"multiagent_node_stop"node_id: Unique identifier for the nodenode_result: Complete NodeResult with execution details, metrics, and status
multiagent_handoff: When control is handed off between agents (Swarm) or batch transitions (Graph)type:"multiagent_handoff"from_node_ids: List of node IDs completing executionto_node_ids: List of node IDs beginning executionmessage: Optional handoff message (typically used in Swarm)
multiagent_result: Final multi-agent resulttype:"multiagent_result"result: The final GraphResult or SwarmResult
See Graph streaming and Swarm streaming for usage examples.
Multi-agent systems (Graph and Swarm) emit additional coordination events. Each event is a class with a type attribute, extending HookableEvent for both streaming and hook subscription.
MultiAgentInitializedEvent: When a multi-agent orchestrator has finished initializationorchestrator: TheMultiAgentBaseinstance
BeforeMultiAgentInvocationEvent: Before orchestrator execution startsorchestrator: TheMultiAgentBaseinstancestate: The currentMultiAgentState
BeforeNodeCallEvent: Before a node begins executionnodeId: Unique identifier for the nodeorchestrator: TheMultiAgentBaseinstancestate: The currentMultiAgentStatecancel: Set by hook callbacks to cancel node execution (boolean | string)
NodeStreamUpdateEvent: Forwarded events from agents or nested orchestrators with node contextnodeId: Identifier of the node generating the eventnodeType: Type of node ("agentNode","multiAgentNode")state: The currentMultiAgentStateevent: The innerAgentStreamEventorMultiAgentStreamEvent
NodeCancelEvent: When a node is cancelled viaBeforeNodeCallEvent.cancelnodeId: Unique identifier for the nodestate: The currentMultiAgentStatemessage: Cancel reason
AfterNodeCallEvent: After a node completes executionnodeId: Unique identifier for the nodeorchestrator: TheMultiAgentBaseinstancestate: The currentMultiAgentStateerror?: Optional error if the node failed
NodeResultEvent: When a node finishes executionnodeId: Unique identifier for the nodenodeType: Type of node ("agentNode","multiAgentNode")state: The currentMultiAgentStateresult: TheNodeResultwithstatus,duration,content, and optionalerror
MultiAgentHandoffEvent: When execution transitions between nodessource: Node ID completing executiontargets: Array of node IDs beginning executionstate: The currentMultiAgentState
AfterMultiAgentInvocationEvent: After orchestrator execution completesorchestrator: TheMultiAgentBaseinstancestate: The currentMultiAgentState
MultiAgentResultEvent: Final event in the multi-agent streamresult: TheMultiAgentResultwithstatus,results,content, andduration
See Graph streaming and Swarm streaming for usage examples.
Event Serialization
Section titled “Event Serialization”Python streaming events are plain dictionaries. The SDK does not include a built-in serialization filter, so you control which events and fields to forward from your processes and servers.
When serving streamed responses (for example, over SSE or WebSockets), you can filter the yielded events to keep payloads compact:
import json
def filter_event(event: dict) -> dict | None: """Filter streaming events to only forward relevant data over the wire.""" # Forward text deltas for real-time display if "data" in event: return {"type": "text", "data": event["data"]}
# Forward tool usage for progress indicators if "current_tool_use" in event and event["current_tool_use"].get("name"): return {"type": "tool", "name": event["current_tool_use"]["name"]}
# Forward the final result if "result" in event: return {"type": "result", "stop_reason": str(event["result"].stop_reason)}
# Skip everything else (lifecycle signals, raw deltas, reasoning, etc.) return None
async for event in agent.stream_async("Hello"): filtered = filter_event(event) if filtered: await response.write(f"data: {json.dumps(filtered)}\n\n")This approach lets you tailor the streamed output to your use case, for example forwarding only text deltas for a chat UI or including tool events for a progress dashboard.
Every event class implements a toJSON() method that JSON.stringify() calls automatically. Each serialized event retains its type discriminator and the relevant data fields (matching the general shape of the class) while excluding in-memory runtime references (agent, orchestrator, state, tool) and mutable hook properties (cancel, retry). Error objects are converted to { message: string }. This applies to single-agent, multi-agent, and A2A events alike.
You can filter which events to forward to the client:
for await (const event of agent.stream('Hello')) { switch (event.type) { // Forward text deltas for real-time display case 'modelStreamUpdateEvent': if ( event.event.type === 'modelContentBlockDeltaEvent' && event.event.delta.type === 'textDelta' ) { console.log( `data: ${JSON.stringify({ type: 'text', text: event.event.delta.text })}` ) } break
// Forward tool names for progress indicators case 'beforeToolCallEvent': console.log(`data: ${JSON.stringify({ type: 'tool', name: event.toolUse.name })}`) break
// Forward the final result case 'agentResultEvent': console.log(`data: ${JSON.stringify(event)}`) break }}Next Steps
Section titled “Next Steps”- Consume these events in async frameworks with Async Iterators.
- Intercept them with a function in synchronous Python via Callback Handlers.
- See the Agent API Reference for complete method documentation: Python | TypeScript