Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/strands/experimental/bidi/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def __init__(
state: AgentState | dict | None = None,
session_manager: "SessionManager | None" = None,
tool_executor: ToolExecutor | None = None,
event_queue_size: int = 1,
**kwargs: Any,
):
"""Initialize bidirectional agent.
Expand All @@ -93,6 +94,11 @@ def __init__(
session_manager: Manager for handling agent sessions including conversation history and state.
If provided, enables session-based persistence and state management.
tool_executor: Definition of tool execution strategy (e.g., sequential, concurrent, etc.).
event_queue_size: Maximum size of the internal event queue between the model receive loop
and the output handler. Higher values provide more buffer for bursty audio delivery
(e.g., Gemini Live) at the cost of slightly higher memory usage. Lower values apply
more backpressure. Default of 32 provides ~640ms of audio buffer at typical chunk rates.
Set to 1 for legacy behavior (may cause choppy audio with fast-delivering models).
**kwargs: Additional configuration for future extensibility.

Raises:
Expand All @@ -108,6 +114,7 @@ def __init__(

self.system_prompt = system_prompt
self.messages = messages or []
self._event_queue_size = event_queue_size

# Agent identification
self.agent_id = _identifier.validate(agent_id or _DEFAULT_AGENT_ID, _identifier.Identifier.AGENT)
Expand Down
5 changes: 4 additions & 1 deletion src/strands/experimental/bidi/agent/loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class _BidiAgentLoop:
_invocation_state: Optional context to pass to tools during execution.
This allows passing custom data (user_id, session_id, database connections, etc.)
that tools can access via their invocation_state parameter.
_event_queue_size: Maximum size of the internal event queue. Controls backpressure
between the model receive loop and the output handler.
_send_gate: Gate the sending of events to the model.
Blocks when agent is reseting the model connection after timeout.
"""
Expand All @@ -65,6 +67,7 @@ def __init__(self, agent: "BidiAgent") -> None:
self._started = False
self._task_pool = _TaskPool()
self._event_queue: asyncio.Queue
self._event_queue_size = agent._event_queue_size
self._invocation_state: dict[str, Any]

self._send_gate = asyncio.Event()
Expand Down Expand Up @@ -94,7 +97,7 @@ async def start(self, invocation_state: dict[str, Any] | None = None) -> None:
messages=self._agent.messages,
)

self._event_queue = asyncio.Queue(maxsize=1)
self._event_queue = asyncio.Queue(maxsize=self._event_queue_size)

self._task_pool = _TaskPool()
self._task_pool.create(self._run_model())
Expand Down