docs: tighten wait_for_transcript_to_end_user_turn docstring + test docstring

Reframes the strategy mutations as part of configuring the flag
(not an "also" aside), and the ordering invariant in the test
docstring as flush-timing (not arrival-timing).
This commit is contained in:
Paul Kompfner
2026-05-15 15:16:39 -04:00
parent 8631518388
commit 4479a3a6af
2 changed files with 20 additions and 25 deletions

View File

@@ -130,28 +130,21 @@ class LLMUserAggregatorParams:
vad_analyzer: Voice Activity Detection analyzer instance. vad_analyzer: Voice Activity Detection analyzer instance.
wait_for_transcript_to_end_user_turn: Defaults to True. Set to wait_for_transcript_to_end_user_turn: Defaults to True. Set to
False when using local turn detection to drive a realtime False when using local turn detection to drive a realtime
service like Gemini Live, where the LLM consumes user audio service (e.g. Gemini Live), where waiting for the transcript
directly and doesn't need the transcript in context to respond before ending the turn is pure latency. When False:
— so waiting for the transcript before ending the turn is pure
latency. When False, the aggregator:
- drops ``TranscriptionUserTurnStartStrategy`` from the start - the user turn ends as soon as the user stops speaking,
strategies (so late-arriving realtime transcripts don't without waiting for transcripts: ``on_user_turn_stopped``
trigger new turns), fires immediately with empty content
- sets ``wait_for_transcript=False`` on any stop strategy that - the user-text flush to context and the
supports it (so the turn ends without waiting for a ``on_user_turn_message_finalized`` event are deferred
transcript), and until a backstop timer expires
- defers the context flush and public ``on_user_turn_stopped``
event until the (late) transcript arrives or a backstop timer
fires (so the user's words still land in the LLM context).
Adjustments to user-provided strategies are logged. The As part of configuring this behavior, the aggregator drops
precondition for the deferred-context path: every user turn ``TranscriptionUserTurnStartStrategy`` from start strategies
produces one transcript in conversational order — turn N's (so late transcripts don't spuriously start new turns) and
transcript arrives before any of turn N's assistant content, and flips ``wait_for_transcript=False`` on supporting stop
before turn N+1 starts. Violations are logged and strategies.
best-effort-recovered by force-flushing the pending turn before
starting the next one.
filter_incomplete_user_turns: [DEPRECATED] Use filter_incomplete_user_turns: [DEPRECATED] Use
``user_turn_strategies=FilterIncompleteUserTurnStrategies()`` ``user_turn_strategies=FilterIncompleteUserTurnStrategies()``
instead. When enabled, the LLM outputs a turn-completion instead. When enabled, the LLM outputs a turn-completion

View File

@@ -964,9 +964,11 @@ class TestLLMUserAggregator(unittest.IsolatedAsyncioTestCase):
message lands in context *before* the assistant message, even though message lands in context *before* the assistant message, even though
the user transcript arrives after the audible turn end. the user transcript arrives after the audible turn end.
Models the documented precondition: the transcript arrives before Correct ordering requires the user aggregator's deferred
the assistant content begins streaming. The user aggregator must ``push_aggregation`` to run before the assistant aggregator's
flush before the assistant aggregator does. ``push_aggregation`` (which fires on ``LLMFullResponseEndFrame``).
The patched-short backstop plus the sleep between LLM start and end
make that constraint hold here.
""" """
from unittest.mock import patch from unittest.mock import patch
@@ -1001,8 +1003,8 @@ class TestLLMUserAggregator(unittest.IsolatedAsyncioTestCase):
# User transcript arrives after audible stop (the realtime # User transcript arrives after audible stop (the realtime
# service has finally emitted it). # service has finally emitted it).
TranscriptionFrame(text="What's the weather?", user_id="", timestamp="now"), TranscriptionFrame(text="What's the weather?", user_id="", timestamp="now"),
# Bot starts responding. By the precondition, transcripts # Bot starts responding. Ordering correctness depends on the
# arrive before assistant content begins streaming. # user backstop firing before LLMFullResponseEndFrame below.
LLMFullResponseStartFrame(), LLMFullResponseStartFrame(),
LLMTextFrame("It's sunny."), LLMTextFrame("It's sunny."),
# Allow time for the user backstop to fire (flushing the # Allow time for the user backstop to fire (flushing the