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.
wait_for_transcript_to_end_user_turn: Defaults to True. Set to
False when using local turn detection to drive a realtime
service like Gemini Live, where the LLM consumes user audio
directly and doesn't need the transcript in context to respond
— so waiting for the transcript before ending the turn is pure
latency. When False, the aggregator:
service (e.g. Gemini Live), where waiting for the transcript
before ending the turn is pure latency. When False:
- drops ``TranscriptionUserTurnStartStrategy`` from the start
strategies (so late-arriving realtime transcripts don't
trigger new turns),
- sets ``wait_for_transcript=False`` on any stop strategy that
supports it (so the turn ends without waiting for a
transcript), and
- 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).
- the user turn ends as soon as the user stops speaking,
without waiting for transcripts: ``on_user_turn_stopped``
fires immediately with empty content
- the user-text flush to context and the
``on_user_turn_message_finalized`` event are deferred
until a backstop timer expires
Adjustments to user-provided strategies are logged. The
precondition for the deferred-context path: every user turn
produces one transcript in conversational order — turn N's
transcript arrives before any of turn N's assistant content, and
before turn N+1 starts. Violations are logged and
best-effort-recovered by force-flushing the pending turn before
starting the next one.
As part of configuring this behavior, the aggregator drops
``TranscriptionUserTurnStartStrategy`` from start strategies
(so late transcripts don't spuriously start new turns) and
flips ``wait_for_transcript=False`` on supporting stop
strategies.
filter_incomplete_user_turns: [DEPRECATED] Use
``user_turn_strategies=FilterIncompleteUserTurnStrategies()``
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
the user transcript arrives after the audible turn end.
Models the documented precondition: the transcript arrives before
the assistant content begins streaming. The user aggregator must
flush before the assistant aggregator does.
Correct ordering requires the user aggregator's deferred
``push_aggregation`` to run before the assistant aggregator's
``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
@@ -1001,8 +1003,8 @@ class TestLLMUserAggregator(unittest.IsolatedAsyncioTestCase):
# User transcript arrives after audible stop (the realtime
# service has finally emitted it).
TranscriptionFrame(text="What's the weather?", user_id="", timestamp="now"),
# Bot starts responding. By the precondition, transcripts
# arrive before assistant content begins streaming.
# Bot starts responding. Ordering correctness depends on the
# user backstop firing before LLMFullResponseEndFrame below.
LLMFullResponseStartFrame(),
LLMTextFrame("It's sunny."),
# Allow time for the user backstop to fire (flushing the