Fix LLMFullResponseEndFrame racing ahead of final TTSTextFrame

Route LLMFullResponseEndFrame through the serialization queue instead
of pushing it directly downstream when push_text_frames is enabled.
This ensures the frame is emitted only after the audio context is
fully drained, preserving correct ordering relative to TTSTextFrames.

Previously, the final sentence TTSTextFrame would arrive at the
LLMAssistantAggregator after LLMFullResponseEndFrame, causing it to
be dropped from the conversation context (especially with RTVI text
input where no subsequent interruption would flush the orphaned text).
This commit is contained in:
Mark Backman
2026-03-24 15:09:42 -04:00
parent 28eb4544d3
commit 5d71de8aad
2 changed files with 100 additions and 1 deletions

View File

@@ -745,7 +745,11 @@ class TTSService(AIService):
self._processing_text = False
if isinstance(frame, LLMFullResponseEndFrame):
if self._push_text_frames:
await self.push_frame(frame, direction)
# Route through the serialization queue so the frame is
# emitted only after the audio context has been fully
# drained (including the final TTSTextFrame). Pushing
# directly would let it race ahead of queued text frames.
await self._serialization_queue.put(frame)
else:
await self.push_frame(frame, direction)