Skip to content

Commit a49273b

Browse files
committed
Update method names imports for io.py and audio.py and their dependencies
1 parent 73416d7 commit a49273b

5 files changed

Lines changed: 48 additions & 46 deletions

File tree

src/strands/experimental/bidirectional_streaming/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
# Main components - Primary user interface
44
from .agent.agent import BidirectionalAgent
55

6+
# IO channels - Hardware abstraction
7+
from .io.audio import AudioIO
8+
69
# Model interface (for custom implementations)
710
from .models.bidirectional_model import BidirectionalModel
811

@@ -27,7 +30,8 @@
2730
__all__ = [
2831
# Main interface
2932
"BidirectionalAgent",
30-
33+
# IO channels
34+
"AudioIO",
3135
# Model providers
3236
"GeminiLiveModel",
3337
"NovaSonicModel",
@@ -43,7 +47,6 @@
4347
"BidirectionalStreamEvent",
4448
"VoiceActivityEvent",
4549
"UsageMetricsEvent",
46-
4750
# Model interface
4851
"BidirectionalModel",
4952
]

src/strands/experimental/bidirectional_streaming/agent/agent.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
350350
for adapter in self._current_adapters:
351351
if hasattr(adapter, "cleanup"):
352352
try:
353-
adapter.cleanup()
353+
adapter.end()
354354
logger.debug(f"Cleaned up adapter: {type(adapter).__name__}")
355355
except Exception as adapter_error:
356356
logger.warning(f"Error cleaning up adapter: {adapter_error}")
@@ -386,7 +386,7 @@ async def run(self, io_channels: list[BidiIO | tuple[Callable, Callable]]) -> No
386386
387387
Args:
388388
io_channels: List containing either BidiIO instances or (sender, receiver) tuples.
389-
- BidiIO: IO channel instance with input_channel(), output_channel(), and cleanup() methods
389+
- BidiIO: IO channel instance with send(), receive(), and end() methods
390390
- tuple: (sender_callable, receiver_callable) for custom transport
391391
392392
Example:
@@ -410,7 +410,7 @@ async def run(self, io_channels: list[BidiIO | tuple[Callable, Callable]]) -> No
410410
transport = io_channels[0]
411411

412412
# Set IO channel tracking for cleanup
413-
if hasattr(transport, 'input_channel') and hasattr(transport, 'output_channel'):
413+
if hasattr(transport, 'send') and hasattr(transport, 'receive'):
414414
self._current_adapters = [transport] # IO channel needs cleanup
415415
elif isinstance(transport, tuple) and len(transport) == 2:
416416
self._current_adapters = [] # Tuple needs no cleanup
@@ -433,16 +433,16 @@ async def _run_with_transport(
433433
async def receive_from_agent():
434434
"""Receive events from agent and send to transport."""
435435
async for event in self.receive():
436-
if hasattr(transport, 'output_channel'):
437-
await transport.output_channel(event)
436+
if hasattr(transport, 'receive'):
437+
await transport.receive(event)
438438
else:
439439
await transport[0](event)
440440

441441
async def send_to_agent():
442442
"""Receive events from transport and send to agent."""
443443
while self.active:
444-
if hasattr(transport, 'input_channel'):
445-
event = await transport.input_channel()
444+
if hasattr(transport, 'send'):
445+
event = await transport.send()
446446
else:
447447
event = await transport[1]()
448448
await self.send(event)

src/strands/experimental/bidirectional_streaming/io/audio.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def __init__(
6666
self.output_stream = None
6767
self.interrupted = False
6868

69-
def _setup_audio(self) -> None:
69+
def start(self) -> None:
7070
"""Setup PyAudio streams for input and output."""
7171
if self.audio:
7272
return
@@ -103,33 +103,10 @@ def _setup_audio(self) -> None:
103103
self._cleanup_audio()
104104
raise
105105

106-
def _cleanup_audio(self) -> None:
107-
"""Clean up PyAudio resources."""
108-
try:
109-
if self.input_stream:
110-
if self.input_stream.is_active():
111-
self.input_stream.stop_stream()
112-
self.input_stream.close()
113-
114-
if self.output_stream:
115-
if self.output_stream.is_active():
116-
self.output_stream.stop_stream()
117-
self.output_stream.close()
118-
119-
if self.audio:
120-
self.audio.terminate()
121-
122-
self.input_stream = None
123-
self.output_stream = None
124-
self.audio = None
125-
126-
except Exception as e:
127-
logger.warning(f"Audio cleanup error: {e}")
128-
129-
async def input_channel(self) -> dict:
106+
async def send(self) -> dict:
130107
"""Read audio from microphone."""
131108
if not self.input_stream:
132-
self._setup_audio()
109+
self.start()
133110

134111
try:
135112
audio_bytes = self.input_stream.read(self.chunk_size, exception_on_overflow=False)
@@ -148,10 +125,10 @@ async def input_channel(self) -> dict:
148125
"channels": self.input_channels,
149126
}
150127

151-
async def output_channel(self, event: dict) -> None:
128+
async def receive(self, event: dict) -> None:
152129
"""Handle audio events with direct stream writing."""
153130
if not self.output_stream:
154-
self._setup_audio()
131+
self.start()
155132

156133
# Handle audio output
157134
if "audioOutput" in event and not self.interrupted:
@@ -199,6 +176,25 @@ async def output_channel(self, event: dict) -> None:
199176
elif role.upper() == "USER":
200177
print(f"User: {text}")
201178

202-
def cleanup(self) -> None:
179+
def end(self) -> None:
203180
"""Clean up IO channel resources."""
204-
self._cleanup_audio()
181+
try:
182+
if self.input_stream:
183+
if self.input_stream.is_active():
184+
self.input_stream.stop_stream()
185+
self.input_stream.close()
186+
187+
if self.output_stream:
188+
if self.output_stream.is_active():
189+
self.output_stream.stop_stream()
190+
self.output_stream.close()
191+
192+
if self.audio:
193+
self.audio.terminate()
194+
195+
self.input_stream = None
196+
self.output_stream = None
197+
self.audio = None
198+
199+
except Exception as e:
200+
logger.warning(f"Audio cleanup error: {e}")

src/strands/experimental/bidirectional_streaming/types/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Type definitions for bidirectional streaming."""
22

3-
from .audio_io import AudioIO
4-
from .bidirectional_io import BidirectionalIO
3+
from .io import BidiIO
54
from .bidirectional_streaming import (
65
DEFAULT_CHANNELS,
76
DEFAULT_SAMPLE_RATE,
@@ -22,8 +21,7 @@
2221
)
2322

2423
__all__ = [
25-
"AudioIO",
26-
"BidirectionalIO",
24+
"BidiIO",
2725
"AudioInputEvent",
2826
"AudioOutputEvent",
2927
"BidirectionalConnectionEndEvent",

src/strands/experimental/bidirectional_streaming/types/io.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,28 @@ class BidiIO(Protocol):
1616
WebSocket, etc.) while the agent handles model communication and logic.
1717
"""
1818

19-
async def input_channel(self) -> dict:
19+
async def start(self) -> dict:
20+
21+
"""Setup IO channels for input and output."""
22+
...
23+
24+
async def send(self) -> dict:
2025
"""Read input data from the IO channel source.
2126
2227
Returns:
2328
dict: Input event data to send to the model.
2429
"""
2530
...
2631

27-
async def output_channel(self, event: dict) -> None:
32+
async def receive(self, event: dict) -> None:
2833
"""Process output event from the model through the IO channel.
2934
3035
Args:
3136
event: Output event from the model to handle.
3237
"""
3338
...
3439

35-
def cleanup(self) -> None:
40+
def end(self) -> None:
3641
"""Clean up IO channel resources.
3742
3843
Called by the agent during shutdown to ensure proper

0 commit comments

Comments
 (0)