| from __future__ import annotations | |
| from collections.abc import Iterable, Iterator | |
| from typing import Protocol | |
| from time_machine.domain.events import TemporalEvent, TranscriptEvent | |
| from time_machine.domain.models import ( | |
| AudioResult, | |
| ConversationHistory, | |
| Destination, | |
| Persona, | |
| Transcript, | |
| VoiceProfile, | |
| ) | |
| class STTAdapter(Protocol): | |
| def transcribe(self, audio: object) -> Transcript: | |
| ... | |
| def stream_transcript(self, audio_chunks: Iterable[bytes]) -> Iterator[TranscriptEvent]: | |
| ... | |
| class TTSAdapter(Protocol): | |
| def prepare_voice(self, persona: Persona) -> VoiceProfile: | |
| ... | |
| def synthesize( | |
| self, | |
| text: str, | |
| voice_profile: VoiceProfile, | |
| prosody_hint: str | None = None, | |
| ) -> AudioResult: | |
| ... | |
| def stream_audio( | |
| self, | |
| text: str, | |
| voice_profile: VoiceProfile, | |
| prosody_hint: str | None = None, | |
| ) -> Iterator[TemporalEvent]: | |
| ... | |
| class SpeechConversationAdapter(Protocol): | |
| def stream_conversation( | |
| self, | |
| persona: Persona, | |
| destination: Destination, | |
| audio_chunks: Iterable[bytes], | |
| history: ConversationHistory, | |
| ) -> Iterator[TemporalEvent]: | |
| ... | |