Skip to content

Stream Events

Use stream events to react to a conversation as it unfolds. BidiAgent emits events that carry new content or signal a change in state. An event can deliver an audio chunk, add text to a transcript, mark the start or end of a response, or report a tool result.

Your application consumes these events to play audio, display text, and track ongoing work. A single response can produce many events, while user transcripts and background tool results can arrive independently. All of them flow through the same event stream.

Read events with agent.receive() after starting the agent. To forward events to output streams, use agent.run(), which manages the agent lifecycle and sends each event to every configured output stream.

Use isinstance() to access typed properties, or check the type string and read dictionary fields. The example below demonstrates both styles by sending a text prompt and printing completed transcripts until the first model response ends:

import asyncio
from strands.bidi.agent import BidiAgent
from strands.bidi.types import (
BidiResponseStopEvent,
BidiTranscriptBlockEvent,
)
async def main() -> None:
async with BidiAgent() as agent:
await agent.send("Say hello in one sentence.")
async for event in agent.receive():
if isinstance(event, BidiTranscriptBlockEvent):
print(f"{event.role}: {event.transcript}")
elif isinstance(event, BidiResponseStopEvent):
break
asyncio.run(main())

Model adapters emit connection starts, response boundaries, content streams, barge-in signals, tool requests, and usage reports. The agent adds completed blocks, tool results, restart notifications, and connection stops.

Provider support and configuration determine which events appear. See the event API reference for complete class definitions and fields.

Use connection events to track when the model is ready, a restart is approaching, or the agent is shutting down.

EventMeaning
BidiConnectionStartEventThe model connection is ready. Includes its connection_id and model.
BidiConnectionWarningEventA scheduled restart is approaching. time_left_s estimates the time remaining.
BidiConnectionRestartEventThe agent is replacing the connection. reason identifies a scheduled restart or timeout.
BidiConnectionStopEventThe agent is shutting down. Includes connection_id.

Use response events to track a model response to user input, conceptually similar to a single Agent invocation. Match the start and stop events by response_id.

EventMeaning
BidiResponseStartEventA model response begins.
BidiResponseStopEventThe response’s output ends. Buffered audio may still be playing.

Background tool execution can continue after response stop, and tool results can trigger a follow-up model response.

Use audio events to play the assistant’s speech. Events for one audio stream share a content_id.

EventMeaning
BidiAudioStartEventAn audio stream begins.
BidiAudioDeltaEventThe next audio chunk is in audio, encoded as base64.
BidiAudioStopEventThe audio stream ends.

Each delta also includes the audio format, sample_rate, and channels. Buffered audio may still be playing when BidiAudioStopEvent arrives. See AudioIO for playback handling.

Use transcript events to display user or assistant speech as text. Each event includes the speaker’s role ("user" or "assistant") and the stream’s content_id.

EventMeaning
BidiTranscriptStartEventA transcript stream begins.
BidiTranscriptDeltaEventThe next transcript fragment is in delta.
BidiTranscriptStopEventThe transcript stream ends.
BidiTranscriptBlockEventThe complete transcript is in transcript.

Use text events for written assistant output. Events for one text stream share a content_id.

EventMeaning
BidiTextStartEventA text stream begins.
BidiTextDeltaEventThe next text fragment is in delta.
BidiTextStopEventThe text stream ends.
BidiTextBlockEventThe complete text is in text.

Use reasoning events for reasoning text or thought summaries exposed by the model. Events for one reasoning stream share a content_id.

EventMeaning
BidiReasoningStartEventA reasoning stream begins.
BidiReasoningDeltaEventThe next reasoning fragment is in delta.
BidiReasoningStopEventThe reasoning stream ends.
BidiReasoningBlockEventThe complete reasoning is in text.

Use tool events to track requests, intermediate output, and completed results.

EventMeaning
BidiToolUseBlocksEventThe model requests a group of tool calls in tool_uses. Each call includes toolUseId, name, and input.
ToolStreamEventA running tool yields intermediate output. tool_stream_event contains tool_use and data.
ToolResultEventA tool finishes. tool_result contains its toolUseId, status, and result content.
ToolResultMessageEventThe agent records all results from a tool group in a history message.

BidiBargeInEvent signals an interruption to model output, whether audio, text, or other content. It carries no fields beyond type. See Barge-in for responding to interrupted output.

Use BidiUsageEvent to track token usage during a conversation. Each event reports additional input_tokens, output_tokens, and total_tokens; sum these counts to track conversation totals.

Optional input_token_details and output_token_details provide breakdowns by modality, cache, or reasoning, depending on the provider. See Tracking token usage for an example.

Follow these ordering rules when consuming events or implementing a custom model. The diagram illustrates an audio response with an assistant transcript and a separate user transcript.

Audio and transcript event orderingTwo columns show a user transcript and an assistant response containing audio and transcript events. Each content stream follows its own start, delta, and stop sequence. Transcript blocks follow transcript stop. All assistant content finishes before response stop, with token usage shown immediately before it. Nova Sonic can report usage outside response boundaries. User transcripts can interleave independently; aligned rows do not imply timing. Breaks in the lifelines indicate that the conversation can continue before a connection-stop event signals the end of the conversation.User transcriptAssistant responseBidiConnectionStartEventBidiConnectionStopEventBidiTranscriptStartEventBidiTranscriptDeltaEventBidiTranscriptStopEventBidiTranscriptBlockEventBidiResponseStartEventBidiAudioStartEventBidiTranscriptStartEventBidiAudioDeltaEventBidiTranscriptDeltaEventBidiAudioStopEventBidiTranscriptStopEventBidiTranscriptBlockEventBidiUsageEventBidiResponseStopEventConversation continues

User transcripts have their own lifecycle and can start or finish before, during, or after an assistant response. Aligned rows do not imply timing, and a transcript start does not mark the exact moment speech began. Process assistant audio and tool requests without waiting for a completed user transcript.

  1. Connection starts. BidiConnectionStartEvent precedes output from that model connection. Track the connection by connection_id. A connection can contain multiple responses.
  2. Response starts. BidiResponseStartEvent precedes the response’s assistant content and tool requests. Match response start and stop by response_id.
  3. Content streams. Each stream emits a start, zero or more deltas, and a stop. Text, reasoning, and other streams can interleave with the audio and transcripts shown, and streams can finish in a different order from their starts. Track each stream by its content_id, unique within the connection. A response can contain multiple streams and tool groups.
  4. Completed blocks follow. The agent emits each completed block after its content stop, such as BidiTextBlockEvent after BidiTextStopEvent. Custom models supply start, delta, and stop events; the agent assembles the block. Audio has no completed block event.
  5. Usage is reported. BidiUsageEvent provides token counts before response stop.
  6. Response stops. BidiResponseStopEvent follows all assistant content stops and completed blocks in that response. User transcripts and background tool results are independent of this boundary.
  7. Connection stops. BidiConnectionStopEvent signals the end of the conversation; the event iterator then ends.

Use deltas for live updates. A completed block contains the full text for its stream, so replace the displayed partial text when it arrives. See Messages for how this content becomes conversation history.

The model’s events stay in order, but background tool results and restart notifications can appear between them, even between a content stop and its block. Correlate events by their identifiers rather than adjacency.

A stop, connection failure, or forced restart can leave content or a response unfinished. Clean up application state without requiring a final content stop, block, or response stop event.

Track tool calls by toolUseId; results can arrive out of order or during another response. In this example, the tool group finishes after the response that requested it:

Tool execution can continue after response stopAn assistant response requests a group of tools, which run concurrently. Tools can emit intermediate output. In this example the response stops before the tools finish. Each tool emits a result, then the agent records all results in a tool result message.Assistant responseTool executionBidiResponseStartEventBidiToolUseBlocksEventToolStreamEventZero or more per toolBidiResponseStopEventToolResultEventOne per toolToolResultMessageEventAll results recordedStart requested tools
  1. Request the group. BidiToolUseBlocksEvent contains complete calls in provider order. The agent starts them concurrently.
  2. Receive tool output. Tools can emit intermediate output through ToolStreamEvent. Each ToolResultEvent arrives as a tool finishes.
  3. Record the results. After all calls finish, ToolResultMessageEvent exposes their results in request order. It confirms the history update, not delivery to the model.

Tool errors reported through ToolResultEvent use status: "error". Failures that escape the tool runner raise from receive().

Use BidiBargeInEvent to stop presenting the current model output while the conversation and any background tools continue. The example below shows interrupted audio, but the same signal applies to text and other output:

Barge-in during a responseBarge-in signals interrupted model output, including audio, text, or other content. This audio example shows response start, audio start, and audio delta events, followed by BidiBargeInEvent, audio stop, and response stop. For audio output, clear buffered audio when barge-in arrives. Barge-in must occur between response start and response stop.Assistant responseBidiResponseStartEventBidiAudioStartEventBidiAudioDeltaEventBidiBargeInEventBidiAudioStopEventBidiResponseStopEvent

Clear buffered audio as soon as the event arrives so playback stops promptly. AudioIO.output() does this automatically; a custom output stream must clear its own playback queue.

Use restart events to track connection replacement and identify interrupted turns. With automatic restart enabled, the agent can replace its model connection on a schedule or after a timeout. It emits BidiConnectionRestartEvent before replacement and BidiConnectionStartEvent when the new connection is ready:

Scheduled and timeout connection restartsTwo alternative paths lead to a replacement connection. A scheduled restart is preceded by a warning. A timeout restart needs no warning. Either path emits a restart event before replacing the connection. A successful replacement emits a connection start with a new connection ID.Scheduled restartTimeoutBidiConnectionWarningEventBidiConnectionRestartEventreason: "scheduled"BidiConnectionRestartEventreason: "timeout"BidiConnectionStartEventNew connection_idReplace connection
  • Scheduled restart. A warning estimates the time remaining in time_left_s; conversation events can occur before the restart. The restart event has reason: "scheduled" and timeout_error: None.
  • Timeout. No warning is required. The restart event has reason: "timeout", and timeout_error contains the model’s ConnectionTimeoutError.

When turn_interrupted is True, the restart cut off an active response or an unanswered turn. Replayed history supplies context but does not request an answer to that turn, so notify the user or send another prompt once the new connection is ready.

If your application tracks unfinished content streams, stop treating them as active when the new connection starts. You can keep partial content for display, but treat new streams separately. Background tools can continue across the restart.

BidiAgent builds conversation state in agent.messages as it processes streamed events. For each text, reasoning, or transcript stream, it groups events by content_id and assembles a separate message:

  1. Start. The agent appends a placeholder message with an empty content list and a status of "pending".
  2. Delta. It accumulates text in an internal buffer while the pending message stays empty.
  3. Stop. It fills the placeholder with the accumulated content, marks it "complete", and emits the corresponding completed block event.

Reserving each message at stream start keeps history in that order, even when streams finish in a different order. A single response can contribute several messages.

For these streamed messages, message["metadata"]["custom"]["bidi"] records the content kind ("text", "reasoning", or "transcript") and completion status.

If a connection ends before a stream stops, the agent marks its message "incomplete". Text and reasoning retain their partial content; unfinished transcripts contain [Transcript unavailable.]. The agent does not emit completed blocks for unfinished streams.

The messages list stores assembled content alongside user input and tool exchanges:

ContentRepresentation in history
User input sent as text or imagesA user message containing those blocks.
User or assistant transcriptA user or assistant message containing a text block.
Assistant textAn assistant message containing a text block.
ReasoningAn assistant message containing a reasoningContent block.
Tool activityAssistant messages containing toolUse blocks, paired with user messages containing toolResult blocks.

Audio chunks are not stored in history. Speech appears as transcript text when the model provides it.

Tool requests add an exchange containing the calls and dispatch acknowledgements. After all calls in the group finish, the agent appends a second exchange with the same calls and their results, then emits ToolResultMessageEvent.