from __future__ import annotations from collections.abc import Callable, Iterable, Sequence from typing import Protocol from .models import ( AudioFrame, AudioSegment, Message, PlaybackResult, ReplyDelta, Transcript, TransportHealth, VadResult, WakeEvent, ) class AudioTransport(Protocol): def start_input( self, device_id: str | None = None, sample_rate: int = 16000, channels: int = 1 ) -> None: ... def read_frames(self, timeout_ms: int) -> list[AudioFrame]: ... def play_pcm(self, segment: AudioSegment, interrupt: bool = False) -> PlaybackResult: ... def play_pcm_chunks( self, segment: AudioSegment, *, chunk_ms: int, after_chunk: Callable[[AudioSegment, int], bool] | None = None, should_stop: Callable[[], bool] | None = None, ) -> PlaybackResult: ... def flush_input(self) -> int: ... def stop(self) -> None: ... def health(self) -> TransportHealth: ... class WakeWordProvider(Protocol): def load(self) -> None: ... def detect(self, frame: AudioFrame) -> WakeEvent | None: ... def reset(self) -> None: ... class AudioPreprocessor(Protocol): def load(self) -> None: ... def reset(self) -> None: ... def process_frame(self, frame: AudioFrame) -> AudioFrame: ... def flush(self) -> list[AudioFrame]: ... class VadProvider(Protocol): def load(self) -> None: ... def analyze(self, frame: AudioFrame) -> VadResult: ... def reset(self) -> None: ... class SttProvider(Protocol): def load(self) -> None: ... def transcribe(self, segment: AudioSegment) -> Transcript: ... class RealtimeTranscriptSession(Protocol): def accept_frame(self, frame: AudioFrame) -> Transcript | None: ... def finish(self) -> Transcript | None: ... class RealtimeSttProvider(SttProvider, Protocol): def start_stream(self) -> RealtimeTranscriptSession: ... class LlmProvider(Protocol): def stream_reply(self, messages: Sequence[Message]) -> Iterable[ReplyDelta]: ... class TtsProvider(Protocol): def load(self) -> None: ... def synthesize(self, text: str) -> AudioSegment: ...