fix(voice): skip committing late STT finals after a turn flush (#6504) - #6516
fix(voice): skip committing late STT finals after a turn flush (#6504)#6516SHAI-sambhav-suri wants to merge 1 commit into
Conversation
…it#6504) A late STT final transcript could arrive after VAD had already committed and flushed the turn. With no prediction future left in flight, the eou bounce logged "skipping eot prediction" but then fell through and committed a second turn with a null end_of_turn_probability, splitting one utterance into two conversation items where the second bypassed turn detection. Genuinely short-circuit that case: when a streaming detector has been flushed and there is no prediction in flight, skip the commit instead of shipping a null-probability turn. The transcript is left intact so the trailing words fold into the next turn rather than being lost. Fixes livekit#6504
|
What this fixes Fixes #6504. An utterance with a mid-phrase pause ("No." … ~1s … "Date needed Why it happens VAD detects the silence and commits the turn, which flushes the streaming turn The change Make the skip real. In if (
trigger == "stt"
and self._turn_detector_flushed
and self._turn_detector_prediction_fut is None
and isinstance(turn_detector, _StreamingTurnDetectorStream)
):
self._on_missing_eot_prediction()
returnNo null-probability commit, and the log is now truthful. We return before Tests |
|
Reporter of #6504 here — this matches what I observed. The four-condition guard covers the exact path from my logs: STT-triggered, detector already flushed, no prediction in flight, streaming detector. Returning before the commit means no phantom Preserving the transcript so it folds into the next turn is the right call. In my repro the trailing fragment became its own conversation item ("No. Date" then "needed now."), and the agent responded to the first half before the second arrived. Merging forward fixes the behaviour, not just the log. One question on coverage: the guard requires
Both ended with Happy to re-run my repro against this branch if that's useful. |
|
Following up on the coverage question - happy to just write it. I can push a commit to this branch adding the pending-future case, or open a separate PR if you'd rather keep this one focused. |
|
Re-ran the repro on LiveKit Cloud (1.6.5) — session with audio and support access enabled: Caught the null-probability turn again on an email input ("It's john at" commits via VAD, then "example dot com" STT final arrives after the flush): end_of_turn_probability: null, unlikely_threshold: null, with the "transcript arrives after turn has been committed" warning. This is variant 2 from my comment above — happy to dig into the in-flight _turn_detector_prediction_fut case if you want me to try to trigger it. |
A late STT final transcript could arrive after VAD had already committed and flushed the turn. With no prediction future left in flight, the eou bounce logged "skipping eot prediction" but then fell through and committed a second turn with a null end_of_turn_probability, splitting one utterance into two conversation items where the second bypassed turn detection.
Genuinely short-circuit that case: when a streaming detector has been flushed and there is no prediction in flight, skip the commit instead of shipping a null-probability turn. The transcript is left intact so the trailing words fold into the next turn rather than being lost.
Fixes #6504