- Speech input Deepgram
- Response OpenAI
- Speech output ElevenLabs
A state manager coordinates listening, processing, playback, and idle time.
The problem
A voice interface has to coordinate several independent services. A transcript can arrive while speech is playing, an idle timer can fire at the wrong time, and a spoken reply can accidentally trigger the assistant again.
How it works
The Python application separates listening, processing, speaking, idle, wake, and sleep behavior. A central state manager routes transcript and wake events through queues, while injected interfaces keep the model and speech services separate from conversation control.
How the states fit together
Select a state to see its responsibility.
Wait for a wake event. The orchestrator keeps listening for the configured phrase while the conversation is inactive.
Illustration of responsibilities, not a running assistant. No microphone access or API requests.
Design decisions
- Explicit state transitions: entry and exit hooks make the conversation lifecycle visible in code.
- Speech cooldowns: post-speech timing helps reduce accidental reactions to the assistant’s own output.
- Test doubles: fake speech and model services exercise conversation flows without calling paid APIs.
- Service boundaries: speech recognition, response generation, and synthesis can be inspected separately.
Status and next steps
The repository includes regression tests for goodbye, satisfaction, and transcript-driven transitions, plus tests for speech-service response parsing. The next steps are a recorded live demonstration, latency measurements, and more outage and cancellation tests.