Interruption Handling
Handle barge-in on the Flux TTS WebSocket — stop playback, send Interrupt, and use the server’s text_spoken / text_remaining report to keep your LLM context in sync.
When a user speaks over the agent (a barge-in), you need to do two things: stop the audio immediately, and tell your LLM what the user actually heard so the conversation stays coherent. Flux TTS handles the second part for you — Interrupt returns the exact text that was spoken before the cut. This page covers the full pattern.
For the message references, see Interrupt and SpeechInterrupted.
The pattern
- Detect barge-in — typically from your STT (e.g. Flux STT’s
StartOfTurn) or a VAD. - Stop playback locally, now. Don’t wait for the server. The
Interruptround-trip is for context reconciliation, not for stopping audio. - Send
Interruptwith how far playback got, so the server can compute what was heard precisely. - Discard in-flight audio — frames that arrive after you send
Interruptbut beforeSpeechInterruptedwere already on the wire. Drop them. - Use
SpeechInterrupted— appendtext_spokento your LLM context so the next turn doesn’t repeat what the user already heard.
Sending Interrupt
Include playback_offset whenever you can — it’s how the server aligns text_spoken to the audio the user actually heard. Without it, the server can’t compute the split: SpeechInterrupted omits text_spoken and text_remaining, and audio_played_ms falls back to the server’s own generated-audio total.
playback_offset is measured from the start of the session’s audio, not the current turn, and each interrupt’s offset must advance past the position the previous interrupt established. An offset that doesn’t advance is rejected with an INVALID_INTERRUPT_OFFSET warning and the interrupt is ignored — track one session-wide playback counter rather than resetting per turn. Interrupt always cancels the currently-active turn — there is no per-turn targeting.
The response
text_spoken— what the user heard. Feed this back into the LLM context. Present only when yourInterruptcarried aplayback_offset.text_remaining— what they didn’t hear. Useful if you want to resume or summarize what was cut. Present only when yourInterruptcarried aplayback_offset.metadata— per-turn billing/timing, same shape asSpeechMetadata.
Interrupt does not reset the voice
Interrupt stops synthesis and clears the buffer, but it does not reset the model’s conversational state — so the agent’s voice stays consistent into the next turn. See Cross-Turn Context.
Edge cases
In a voice agent loop
This snippet focuses on message flow. For the concrete SDK calls, see Getting Started and the template apps — the Python (deepgram-sdk) and JavaScript (@deepgram/sdk) SDKs expose a speak.v2 client for /v2/speak.
Related resources
- Interrupt (client message)
- SpeechInterrupted (server message)
- The Speech Lifecycle — where interrupts sit in the state machine
- Build a Flux TTS Voice Agent — barge-in inside the full loop