Skip to content

strands.experimental.bidi.types.events

Bidirectional streaming types for real-time audio/text conversations.

Type definitions for bidirectional streaming that extends Strands’ existing streaming capabilities with real-time audio and persistent connection support.

Key features:

  • Audio input/output events with standardized formats
  • Interruption detection and handling
  • Connection lifecycle management
  • Provider-agnostic event types
  • Type-safe discriminated unions with TypedEvent
  • JSON-serializable events (audio/images stored as base64 strings)

Audio format normalization:

  • Supports PCM, WAV, Opus, and MP3 formats
  • Standardizes sample rates (16kHz, 24kHz, 48kHz)
  • Normalizes channel configurations (mono/stereo)
  • Abstracts provider-specific encodings
  • Audio data stored as base64-encoded strings for JSON compatibility

Number of audio channels.

  • Mono: 1
  • Stereo: 2

Audio encoding format.

Audio sample rate in Hz.

Role of a message sender.

  • “user”: Messages from the user to the assistant.
  • “assistant”: Messages from the assistant to the user.

Reason for the model ending its response generation.

  • “complete”: Model completed its response.
  • “error”: Model encountered an error.
  • “interrupted”: Model was interrupted by the user.
  • “tool_use”: Model is requesting a tool use.
class BidiTextInputEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:64

Text input event for sending text to the model.

Used for sending text content through the send() method.

Arguments:

  • text - The text content to send to the model.
  • role - The role of the message sender (default: “user”).
def __init__(text: str, role: Role = "user")

Defined in: src/strands/experimental/bidi/types/events.py:74

Initialize text input event.

@property
def text() -> str

Defined in: src/strands/experimental/bidi/types/events.py:85

The text content to send to the model.

@property
def role() -> Role

Defined in: src/strands/experimental/bidi/types/events.py:90

The role of the message sender.

class BidiAudioInputEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:95

Audio input event for sending audio to the model.

Used for sending audio data through the send() method.

Arguments:

  • audio - Base64-encoded audio string to send to model.
  • format - Audio format from SUPPORTED_AUDIO_FORMATS.
  • sample_rate - Sample rate from SUPPORTED_SAMPLE_RATES.
  • channels - Channel count from SUPPORTED_CHANNELS.
def __init__(audio: str, format: AudioFormat | str,
sample_rate: AudioSampleRate, channels: AudioChannel)

Defined in: src/strands/experimental/bidi/types/events.py:107

Initialize audio input event.

@property
def audio() -> str

Defined in: src/strands/experimental/bidi/types/events.py:126

Base64-encoded audio string.

@property
def format() -> AudioFormat

Defined in: src/strands/experimental/bidi/types/events.py:131

Audio encoding format.

@property
def sample_rate() -> AudioSampleRate

Defined in: src/strands/experimental/bidi/types/events.py:136

Number of audio samples per second in Hz.

@property
def channels() -> AudioChannel

Defined in: src/strands/experimental/bidi/types/events.py:141

Number of audio channels (1=mono, 2=stereo).

class BidiImageInputEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:146

Image input event for sending images/video frames to the model.

Used for sending image data through the send() method.

Arguments:

  • image - Base64-encoded image string.
  • mime_type - MIME type (e.g., “image/jpeg”, “image/png”).
def __init__(image: str, mime_type: str)

Defined in: src/strands/experimental/bidi/types/events.py:156

Initialize image input event.

@property
def image() -> str

Defined in: src/strands/experimental/bidi/types/events.py:171

Base64-encoded image string.

@property
def mime_type() -> str

Defined in: src/strands/experimental/bidi/types/events.py:176

MIME type of the image (e.g., “image/jpeg”, “image/png”).

class BidiConnectionStartEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:186

Streaming connection established and ready for interaction.

Arguments:

  • connection_id - Unique identifier for this streaming connection.
  • model - Model identifier (e.g., “gpt-realtime”, “gemini-2.0-flash-live”).
def __init__(connection_id: str, model: str)

Defined in: src/strands/experimental/bidi/types/events.py:194

Initialize connection start event.

@property
def connection_id() -> str

Defined in: src/strands/experimental/bidi/types/events.py:205

Unique identifier for this streaming connection.

@property
def model() -> str

Defined in: src/strands/experimental/bidi/types/events.py:210

Model identifier (e.g., ‘gpt-realtime’, ‘gemini-2.0-flash-live’).

class BidiConnectionRestartEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:215

Agent is restarting the model connection after timeout.

def __init__(timeout_error: "BidiModelTimeoutError")

Defined in: src/strands/experimental/bidi/types/events.py:218

Initialize.

Arguments:

  • timeout_error - Timeout error reported by the model.
@property
def timeout_error() -> "BidiModelTimeoutError"

Defined in: src/strands/experimental/bidi/types/events.py:232

Model timeout error.

class BidiResponseStartEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:237

Model starts generating a response.

Arguments:

  • response_id - Unique identifier for this response (used in response.complete).
def __init__(response_id: str)

Defined in: src/strands/experimental/bidi/types/events.py:244

Initialize response start event.

@property
def response_id() -> str

Defined in: src/strands/experimental/bidi/types/events.py:249

Unique identifier for this response.

class BidiAudioStreamEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:254

Streaming audio output from the model.

Arguments:

  • audio - Base64-encoded audio string.
  • format - Audio encoding format.
  • sample_rate - Number of audio samples per second in Hz.
  • channels - Number of audio channels (1=mono, 2=stereo).
def __init__(audio: str, format: AudioFormat, sample_rate: AudioSampleRate,
channels: AudioChannel)

Defined in: src/strands/experimental/bidi/types/events.py:264

Initialize audio stream event.

@property
def audio() -> str

Defined in: src/strands/experimental/bidi/types/events.py:283

Base64-encoded audio string.

@property
def format() -> AudioFormat

Defined in: src/strands/experimental/bidi/types/events.py:288

Audio encoding format.

@property
def sample_rate() -> AudioSampleRate

Defined in: src/strands/experimental/bidi/types/events.py:293

Number of audio samples per second in Hz.

@property
def channels() -> AudioChannel

Defined in: src/strands/experimental/bidi/types/events.py:298

Number of audio channels (1=mono, 2=stereo).

class BidiTranscriptStreamEvent(ModelStreamEvent)

Defined in: src/strands/experimental/bidi/types/events.py:303

Audio transcription streaming (user or assistant speech).

Supports incremental transcript updates for providers that send partial transcripts before the final version.

Arguments:

  • delta - The incremental transcript change (ContentBlockDelta).
  • text - The delta text (same as delta content for convenience).
  • role - Who is speaking (“user” or “assistant”).
  • is_final - Whether this is the final/complete transcript.
  • current_transcript - The accumulated transcript text so far (None for first delta).
def __init__(delta: ContentBlockDelta,
text: str,
role: Role,
is_final: bool,
current_transcript: str | None = None)

Defined in: src/strands/experimental/bidi/types/events.py:317

Initialize transcript stream event.

@property
def delta() -> ContentBlockDelta

Defined in: src/strands/experimental/bidi/types/events.py:338

The incremental transcript change.

@property
def text() -> str

Defined in: src/strands/experimental/bidi/types/events.py:343

The text content to send to the model.

@property
def role() -> Role

Defined in: src/strands/experimental/bidi/types/events.py:348

The role of the message sender.

@property
def is_final() -> bool

Defined in: src/strands/experimental/bidi/types/events.py:353

Whether this is the final/complete transcript.

@property
def current_transcript() -> str | None

Defined in: src/strands/experimental/bidi/types/events.py:358

The accumulated transcript text so far.

class BidiInterruptionEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:363

Model generation was interrupted.

Arguments:

  • reason - Why the interruption occurred.
def __init__(reason: Literal["user_speech", "error"])

Defined in: src/strands/experimental/bidi/types/events.py:370

Initialize interruption event.

@property
def reason() -> str

Defined in: src/strands/experimental/bidi/types/events.py:380

Why the interruption occurred.

class BidiResponseCompleteEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:385

Model finished generating response.

Arguments:

  • response_id - ID of the response that completed (matches response.start).
  • stop_reason - Why the response ended.
def __init__(response_id: str, stop_reason: StopReason)

Defined in: src/strands/experimental/bidi/types/events.py:393

Initialize response complete event.

@property
def response_id() -> str

Defined in: src/strands/experimental/bidi/types/events.py:408

Unique identifier for this response.

@property
def stop_reason() -> StopReason

Defined in: src/strands/experimental/bidi/types/events.py:413

Why the response ended.

class ModalityUsage(dict)

Defined in: src/strands/experimental/bidi/types/events.py:418

Token usage for a specific modality.

Attributes:

  • modality - Type of content.
  • input_tokens - Tokens used for this modality’s input.
  • output_tokens - Tokens used for this modality’s output.
class BidiUsageEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:432

Token usage event with modality breakdown for bidirectional streaming.

Tracks token consumption across different modalities (audio, text, images) during bidirectional streaming sessions.

Arguments:

  • input_tokens - Total tokens used for all input modalities.
  • output_tokens - Total tokens used for all output modalities.
  • total_tokens - Sum of input and output tokens.
  • modality_details - Optional list of token usage per modality.
  • cache_read_input_tokens - Optional tokens read from cache.
  • cache_write_input_tokens - Optional tokens written to cache.
def __init__(input_tokens: int,
output_tokens: int,
total_tokens: int,
modality_details: list[ModalityUsage] | None = None,
cache_read_input_tokens: int | None = None,
cache_write_input_tokens: int | None = None)

Defined in: src/strands/experimental/bidi/types/events.py:447

Initialize usage event.

@property
def input_tokens() -> int

Defined in: src/strands/experimental/bidi/types/events.py:472

Total tokens used for all input modalities.

@property
def output_tokens() -> int

Defined in: src/strands/experimental/bidi/types/events.py:477

Total tokens used for all output modalities.

@property
def total_tokens() -> int

Defined in: src/strands/experimental/bidi/types/events.py:482

Sum of input and output tokens.

@property
def modality_details() -> list[ModalityUsage]

Defined in: src/strands/experimental/bidi/types/events.py:487

Optional list of token usage per modality.

@property
def cache_read_input_tokens() -> int | None

Defined in: src/strands/experimental/bidi/types/events.py:492

Optional tokens read from cache.

@property
def cache_write_input_tokens() -> int | None

Defined in: src/strands/experimental/bidi/types/events.py:497

Optional tokens written to cache.

class BidiConnectionCloseEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:502

Streaming connection closed.

Arguments:

  • connection_id - Unique identifier for this streaming connection (matches BidiConnectionStartEvent).
  • reason - Why the connection was closed.
def __init__(connection_id: str,
reason: Literal["client_disconnect", "timeout", "error",
"complete", "user_request"])

Defined in: src/strands/experimental/bidi/types/events.py:510

Initialize connection close event.

@property
def connection_id() -> str

Defined in: src/strands/experimental/bidi/types/events.py:525

Unique identifier for this streaming connection.

@property
def reason() -> str

Defined in: src/strands/experimental/bidi/types/events.py:530

Why the interruption occurred.

class BidiErrorEvent(TypedEvent)

Defined in: src/strands/experimental/bidi/types/events.py:535

Error occurred during the session.

Stores the full Exception object as an instance attribute for debugging while keeping the event dict JSON-serializable. The exception can be accessed via the error property for re-raising or type-based error handling.

Arguments:

  • error - The exception that occurred.
  • details - Optional additional error information.
def __init__(error: Exception, details: dict[str, Any] | None = None)

Defined in: src/strands/experimental/bidi/types/events.py:547

Initialize error event.

@property
def error() -> Exception

Defined in: src/strands/experimental/bidi/types/events.py:566

The original exception that occurred.

Can be used for re-raising or type-based error handling.

@property
def code() -> str

Defined in: src/strands/experimental/bidi/types/events.py:574

Error code derived from exception class name.

@property
def message() -> str

Defined in: src/strands/experimental/bidi/types/events.py:579

Human-readable error message from the exception.

@property
def details() -> dict[str, Any] | None

Defined in: src/strands/experimental/bidi/types/events.py:584

Additional error context beyond the exception itself.

Union of different bidi input event types.

Union of different bidi output event types.