Skip to main content

Overview

User turn strategies provide fine-grained control over how user speaking turns are detected in conversations. They determine when a user’s turn starts (user begins speaking) and when it stops (user finishes speaking and expects a response). By default, Pipecat uses a combination of VAD (Voice Activity Detection) and AI-powered turn detection:
  • Start: VAD detection or transcription received
  • Stop: AI-powered turn detection using LocalSmartTurnAnalyzerV3
You can customize this behavior by providing your own strategies for more sophisticated turn detection, such as requiring a minimum number of words before triggering a turn, or using AI-powered turn detection models.
In Pipecat >=1.0.0, the turn_analyzer must be specified in the TurnAnalyzerUserTurnStopStrategy. See the migration guide for more information.

How It Works

  1. Turn Start Detection: When the start strategies decide the user started speaking (by default, when the first one does), the user aggregator:
    • Marks the start of a user turn
    • Optionally emits UserStartedSpeakingFrame
    • Optionally emits an interruption frame (when the strategy’s enable_interruptions is True)
  2. During User Turn: The aggregator collects transcriptions and audio frames.
  3. Turn Stop Detection: When the stop strategies decide the user is done (by default, when every one has), the turn controller runs the turn’s inference, and the user aggregator:
    • Marks the end of the user turn
    • Emits UserStoppedSpeakingFrame
    • Pushes the aggregated user message to the LLM context
  4. Timeout Handling: If a turn stays open for user_turn_stop_timeout seconds (default: 5.0) while the user isn’t speaking, with no speech, transcription, or turn activity in that time, the turn is automatically ended, unless a stop strategy has a decision of its own scheduled, in which case the timeout waits for it. This timeout is configurable via LLMUserAggregatorParams (see Configuration below). When the timeout fires, the on_user_turn_stop_timeout event is emitted.

When a user turn ends

A user turn stop strategy decides when the user is done talking and the bot should respond. You choose the strategy; the rest of the timing follows from it. If you want to adjust how long the bot waits before responding, do it in the stop strategy — that’s the knob built for it. Whatever the strategy, closing a turn takes two ingredients:
  1. A transcript. The stop strategies that take wait_for_transcript (on by default) wait for the STT service to transcribe what the user said. This is usually the largest and most variable part of the delay, and it’s dominated by your STT provider’s latency. See the STT benchmark to compare services.
  2. The strategy’s own end-of-turn criteria. Once the transcript is in, the strategy applies its logic to decide whether the turn is actually complete.
The turn closes only when both are satisfied.

Choosing a strategy

This is also where you tune responsiveness. For example, raise or lower user_speech_timeout on SpeechTimeoutUserTurnStopStrategy to give users more or less time to resume before the bot replies.

Where the latency comes from

Before any strategy can act, two things have to happen:
  • VAD silence (stop_secs): The VAD waits a short, fixed interval (default 0.2s) after audio goes quiet before reporting that the user stopped speaking. This is a low-level detection threshold — leave it alone. To change wait time, use the stop strategy, not stop_secs.
  • Transcription: STT returns a transcript. Latency here is mostly your STT provider’s; strategies use the provider’s reported p99 latency as a fallback timer and short-circuit it the moment a finalized transcript arrives.
Then the strategy’s criteria run (the silence window, the turn model, or the LLM check) to finalize the turn.
These don’t stack. The fallback timer is an absolute deadline — the end of the user’s speech plus the STT service’s ttfs_p99_latency — so the VAD’s stop_secs and the time a turn model spends on inference both fall inside that budget rather than extending it. What a user notices is the deadline itself, or a finalized transcript arriving sooner. The exception is the SpeechTimeoutUserTurnStopStrategy silence window, which starts when the VAD reports the stop, so the shortest wait after the user pauses is stop_secs plus user_speech_timeout (0.8s by default).If your STT service is slow to return transcripts, that delay shows up in every turn regardless of which strategy you use. Adjust responsiveness in the stop strategy, and check the STT benchmark if transcription is the bottleneck.
user_turn_stop_timeout (default 5.0s, on LLMUserAggregatorParams) is a backstop, not part of normal timing: if a turn somehow never finalizes, it forces the turn to end so the bot isn’t stuck waiting.

Configuration

User turn strategies are configured via LLMUserAggregatorParams when creating an LLMContextAggregatorPair:

Additional Parameters

In addition to user_turn_strategies, LLMUserAggregatorParams accepts these turn-related parameters:
UserTurnStrategiesParams
default:"UserTurnStrategiesParams()"
How the strategies combine and decide. See UserTurnStrategiesParams. UserTurnProcessor and UserTurnController take the same parameter.
float
default:"5.0"
Safety-net timeout in seconds. If a user turn stays open this long while the user isn’t speaking, with no speech, transcription, or turn activity, the turn is automatically ended and the on_user_turn_stop_timeout event is emitted.
VADAnalyzer
default:"None"
The Voice Activity Detection analyzer instance used to produce VAD signals for turn detection. In Pipecat 1.x, VAD is configured on the aggregator rather than the transport. This is separate from VADUserTurnStartStrategy: the analyzer produces the VAD signals; the start strategy decides what to do with them.
EmptyUserTurnConfig | None
default:"EmptyUserTurnConfig()"
How to respond to a user turn that ends with no transcript — a cough, background noise, or speech the STT could not recognize. By default, the bot answers such a turn when it interrupted the bot, and leaves it unanswered otherwise. Set to None to leave every such turn unanswered.The config distinguishes two cases:
  • Interrupted: the turn cut the bot off while it was thinking, speaking or running a function call. Unanswered, the bot stays silent mid-response, so by default the LLM runs once and the bot asks the user to repeat or picks up where it left off.
  • Idle: the bot had finished and was waiting for the user. The conversation isn’t stuck, and answering what may be noise would be intrusive, so by default the turn gets no answer.
EmptyUserTurnConfig has three fields:
  • interrupted_prompt (str | None): Developer message for an empty turn that interrupted the bot. Defaults to a prompt asking the user to repeat. Set to None to leave interrupted empty turns unanswered.
  • idle_prompt (str | None): Developer message for an empty turn while the bot was idle. Defaults to None, leaving such turns unanswered.
  • max_consecutive_recoveries (int): How many empty turns in a row are answered (default 1). Further ones are left unanswered until the user says something that is transcribed.
No recovery runs while the user is muted or a function call is pending, since the function call’s result runs the LLM anyway. An empty turn is ended by user_turn_stop_timeout, so the recovery follows that long after the user stops speaking.Ignored with a realtime LLM service, which hears the user’s audio directly.

Start Strategies

Start strategies determine when a user’s turn begins. Multiple strategies can be provided. With the default start_mode=StrategyMode.FIRST, the first one to decide the user started signals the start of a user turn. See UserTurnStrategiesParams.

Base Parameters

All start strategies inherit these parameters:
bool
default:"True"
If True, the user aggregator will emit an interruption frame when the user turn starts, allowing the user to interrupt the bot.
bool | None
default:"None"
deprecated
Deprecated since 1.8.0, removed in 2.0.0. Whether a turn is announced is a per-turn decision: pass enable_user_speaking_frames to report_user_turn_started() where the strategy decides the turn.

VADUserTurnStartStrategy

Triggers a user turn start based on Voice Activity Detection. This is the most responsive strategy, detecting speech as soon as the VAD indicates the user has started speaking.

TranscriptionUserTurnStartStrategy

Triggers a user turn start when a transcription is received. This serves as a fallback for scenarios where VAD-based detection fails (e.g., when the user speaks very softly) but the STT service still produces transcriptions.
bool
default:"True"
Whether to trigger on interim (partial) transcription frames for earlier detection.

MinWordsUserTurnStartStrategy

Requires the user to speak a minimum number of words before triggering a turn start. This is useful for preventing brief utterances like “okay” or “yeah” from triggering responses.
int
required
Minimum number of spoken words required to trigger the start of a user turn.
bool
default:"True"
Whether to consider interim transcription frames for earlier detection.
When the bot is not speaking, this strategy will trigger after just 1 word. The min_words threshold only applies when the bot is actively speaking, preventing short affirmations from interrupting the bot. A shorter transcript while the bot is speaking is discarded, so it doesn’t reach the context.

WakePhraseUserTurnStartStrategy

Requires a wake phrase to be detected before allowing interaction. Once it hears a wake phrase in a final transcription, it starts a turn, and for a configurable timeout period afterward it starts a turn whenever the user speaks or a final transcription arrives. Speech before the wake phrase is dropped from the aggregation.
List[str]
required
List of wake phrases to detect (e.g., ["hey pipecat", "ok pipecat"]).
float
default:"10.0"
Inactivity timeout in seconds before returning to IDLE state. In timeout mode, the timer resets on activity. In single activation mode, acts as a keepalive window after wake phrase detection.
bool
default:"False"
If True, activity doesn’t extend the wake window: the strategy returns to IDLE timeout seconds after the wake phrase, and turns that start within that window don’t need the wake phrase again.
Event Handlers The strategy provides event handlers for wake phrase detection:
This strategy starts turns on its own, so use it as the only start strategy: start=[WakePhraseUserTurnStartStrategy(...)]. In a StrategyMode.FIRST list, the start strategies after it don’t decide once it’s awake. To combine it with others, such as MinWordsUserTurnStartStrategy, use start_mode=StrategyMode.ALL.

KrispVivaIPUserTurnStartStrategy

Uses Krisp’s Interruption Prediction (IP) model to distinguish genuine user interruptions from backchannels (e.g., “uh-huh”, “yeah”). When VAD detects user speech, this strategy feeds audio frames into the Krisp VIVA IP model, which outputs a probability indicating whether the speech is a genuine interruption. A user turn is triggered only when this probability exceeds the configured threshold. This strategy is designed to work alongside other start strategies (e.g., TranscriptionUserTurnStartStrategy as a fallback).
Optional[str]
default:"None"
Path to the Krisp VIVA IP model file (.kef extension). If None, uses the KRISP_VIVA_IP_MODEL_PATH environment variable. Raises ValueError if neither is set or the path doesn’t end in .kef, and FileNotFoundError if the file doesn’t exist.
float
default:"0.5"
IP probability threshold (0.0 to 1.0). When the model’s output exceeds this value, the speech is classified as a genuine interruption.
int
default:"20"
Frame duration in milliseconds for IP processing. Supported values: 10, 15, 20, 30, 32.
str
default:"\"\""
Krisp SDK API key. If empty, falls back to the KRISP_VIVA_API_KEY environment variable.
Requires the Krisp Python SDK. Without it, KrispVivaIPUserTurnStartStrategy imports as None, so constructing it raises TypeError. See the Krisp VIVA guide for installation instructions.

ExternalUserTurnStartStrategy

Delegates turn start detection to another component in the pipeline. It handles two signals, which differ in how much the emitter has already done:
  • ProposedUserStartedSpeakingFrame: a service with its own turn detection proposing a turn boundary. This strategy makes the decision, emitting the UserStartedSpeakingFrame and broadcasting the interruption itself. Subclass it to adjust when, or whether, a proposal opens a turn.
  • UserStartedSpeakingFrame: the turn was already decided and announced elsewhere, typically by a shared UserTurnProcessor fanning turns out to several aggregators. This strategy adopts that decision and emits nothing, so the turn isn’t announced twice.
bool
default:"True"
Whether to broadcast an interruption when a proposal opens a turn. Turn-detecting services route their should_interrupt setting here. Ignored when a UserStartedSpeakingFrame drives the turn, since the emitter has already broadcast one.

Stop Strategies

Stop strategies determine when a user’s turn ends and the bot should respond.

Base Parameters

All stop strategies inherit these parameters:
bool | None
default:"None"
deprecated
Deprecated since 1.8.0, removed in 2.0.0. Whether a turn is announced is a per-turn decision: pass enable_user_speaking_frames to report_user_turn_stopped() where the strategy decides the turn.

SpeechTimeoutUserTurnStopStrategy

Signals the end of a user turn using two independent timers after VAD detects silence. The user turn stop is triggered only when both timers have finished and at least one transcript has been received:
  • user_speech_timeout: Policy floor — the window in which the user may resume speaking after a pause. Always runs to completion.
  • stt_timeout: Safety net for STT latency — the P99 time for the STT service to return a final transcript after VAD stop. Short-circuited when the STT service emits a finalized transcript (TranscriptionFrame.finalized=True), since finalization means STT has nothing more to send.
When a service finalizes, the turn ends as soon as user_speech_timeout elapses after VAD stop, rather than waiting for both timers. Support varies by service and can be conditional — see TranscriptionFrame.finalized for how a service reports it, and the service’s own page for whether it does.
float
default:"0.6"
How long to wait (in seconds) after VAD detects silence before finalizing the user turn. This is the minimum wait time and always runs to completion.
bool
default:"True"
When True (default), turn-stop signaling waits for a transcript to arrive after VAD silence. When False, the strategy signals turn-stop as soon as its timing requirements are met, without waiting for transcripts — useful when local turn detection drives a realtime (speech-to-speech) service, where waiting for transcripts is unnecessary latency. LLMContextAggregatorPair flips this to False for you in realtime mode.
Built-in STT P99 latency values assume VADParams.stop_secs=0.2 (the recommended default). If you change stop_secs, the strategy will log a warning suggesting you re-run the stt-benchmark with your VAD settings and pass the measured TTFS P99 latency to your STT service constructor via ttfs_p99_latency. The strategy will also warn if `stop_secs
= STT p99 latency`, which collapses the STT wait timeout to 0s and may cause delayed turn detection.

TurnAnalyzerUserTurnStopStrategy

Uses an AI-powered turn detection model to determine when the user has finished speaking. This provides more intelligent end-of-turn detection that can understand conversational context.
BaseTurnAnalyzer
required
The turn detection analyzer instance to use for end-of-turn detection.
bool
default:"True"
When True (default), turn-stop signaling waits for a transcript to arrive after the analyzer reports end-of-speech. When False, the strategy signals turn-stop as soon as the analyzer fires, without waiting for transcripts — useful when local turn detection drives a realtime (speech-to-speech) service. LLMContextAggregatorPair flips this to False for you in realtime mode.
See the Smart Turn Detection documentation for more information on available turn analyzers.
Built-in STT P99 latency values assume VADParams.stop_secs=0.2 (the recommended default). If you change stop_secs, the strategy will log a warning suggesting you re-run the stt-benchmark with your VAD settings and pass the measured TTFS P99 latency to your STT service constructor via ttfs_p99_latency. The strategy will also warn if `stop_secs
= STT p99 latency`, which collapses the STT wait timeout to 0s and may cause delayed turn detection.

ExternalUserTurnStopStrategy

Delegates turn stop detection to another component in the pipeline. The end-of-turn counterpart to ExternalUserTurnStartStrategy, taking the same two signals:
  • ProposedUserStoppedSpeakingFrame: a service proposing that the turn has ended. This strategy decides, and emits the UserStoppedSpeakingFrame itself. It may also hold the turn open past the proposal, which is what wait_for_transcript does.
  • UserStoppedSpeakingFrame: the turn end was already decided and announced elsewhere, typically by a shared UserTurnProcessor. This strategy adopts that decision and emits nothing.
To shift the timing further, subclass it and override report_user_turn_stopped(), which both paths reach once they decide the turn is over.
float
default:"0.5"
A short delay in seconds used to handle consecutive or slightly delayed transcriptions.
bool
default:"True"
When True (default), turn-stop signaling waits for a transcript to arrive after the external stop signal. When False, the strategy signals turn-stop as soon as that signal arrives, independent of transcripts — useful when local turn detection drives a realtime (speech-to-speech) service. LLMContextAggregatorPair flips this to False for you in realtime mode.

EagerUserTurnStopStrategy

Answers an eager end of turn while the turn is still open. Some STT services predict the end of a turn before committing to it, and withdraw the prediction if the user turns out to be mid-sentence. This strategy starts generating a response on that prediction (an EagerTranscriptionFrame), so the gap between it and the committed end of turn is spent generating rather than waiting. The prediction can be wrong in three ways, and each withdraws the response:
  • The user resumes speaking, and the service withdraws the eager end of turn with a UserTurnResponseCancelFrame.
  • The committed transcript differs from the eager one, per match_policy.
  • The turn never commits within speculation_timeout.
Nothing the speculation produces reaches the user or the context. The response is held by the LLM service until the turn is confirmed, and the user message written to the context is always the committed transcript, never the eager one. The user aggregator also broadcasts the eager turn as an LLMContextUserTurnFrame with speculation=True, so processors after the LLM can see it early. A subclass of ExternalUserTurnStopStrategy, so it takes the same base parameters. Install it with EagerUserTurnStrategies rather than directly: the service owns turn detection here, so it replaces the detector chain instead of running alongside it.
EagerMatchPolicy | None
default:"None"
Decides whether the committed transcript is close enough to the eager one to keep the speculative response. None uses NormalizedMatch(), which ignores the capitalization and punctuation services commonly add when they commit a transcript. Pass ExactMatch to require the two to be identical.
float
default:"5.0"
Seconds a prediction may go unresolved before it is withdrawn. A service that stops sending turn signals mid-speculation would otherwise leave the response held and the bot silent for the rest of the session.

ExternalUserTurnCompletionStopStrategy

Deprecated since 1.15.0, removed in 2.0.0. Use ExternalUserTurnStopStrategy instead, and push a ProposedUserStoppedSpeakingFrame once the user is done. For the LLM’s turn-completion markers, use LLMTurnCompletionUserTurnStopStrategy.
Finalizes the user turn whenever a UserTurnInferenceCompletedFrame arrives, regardless of which component produced it.

LLMTurnCompletionUserTurnStopStrategy

Decides the user is done only when the LLM marks the turn complete. On StartFrame it enables turn-completion markers on the LLM, which then starts every response with ● (complete), ◐ (the user will continue shortly), or ○ (the user needs more time). This is the strategy FilterIncompleteUserTurnStrategies adds. The strategy waits for the turn’s inference instead of listening to the user, so it needs other stop strategies to decide the user stopped. Once they have, the inference runs, and this strategy decides the user is done on its ●, on a tool call, or on a response with no marker. ◐ and ○ leave the turn open. If the user then stays quiet for incomplete_short_timeout or incomplete_long_timeout, the strategy decides the user is done and asks the LLM to re-engage them. The turn’s stop timeout waits for that decision.
UserTurnCompletionConfig
default:"None"
Configuration applied to the LLM (turn-completion instructions, incomplete-turn timeouts, and re-prompts). Defaults to UserTurnCompletionConfig().
See Filter Incomplete User Turns for the full LLM-gated turn-completion feature.

ClassifierUserTurnStopStrategy

Asks a classifier whether the user’s turn is complete each time the user pauses with new words transcribed. It asks once the pause’s words are in: when the STT finalizes the transcript, or when the STT’s p99 latency has passed since the user stopped. The classifier sees the user’s words so far and, when context is given, the assistant’s last message. It answers one of:
  • complete: the strategy reports that the user is done.
  • short: the user stopped mid-sentence. The strategy reports after short_timeout seconds unless the user continues.
  • long: the user asked for time or only acknowledged the question. The strategy reports after long_timeout seconds unless the user continues.
If the classifier raises an error or takes longer than classification_timeout, the strategy reports right away. A pause with no words transcribed isn’t classified. Next to a turn analyzer in a StrategyMode.ALL list (the default), the turn ends once both have decided. As the only stop strategy, it ends the turn as soon as the classifier finds it complete.
BaseClassifier
required
The classifier that decides whether the turn is complete.
LLMContext | None
default:"None"
The conversation, so the classifier sees the assistant’s last message along with the user’s turn.
float
default:"5.0"
Seconds to wait after a short verdict before reporting that the user is done.
float
default:"10.0"
Seconds to wait after a long verdict before reporting that the user is done.
float
default:"1.0"
Seconds to wait for the classifier before reporting without it.

deferred()

Deprecated since 1.15.0, removed in 2.0.0. No replacement. Pass the wrapped strategy itself: once the stop strategies have decided, the turn’s inference runs, and strategies such as LLMTurnCompletionUserTurnStopStrategy decide on it. DeferredUserTurnStopStrategy is deprecated the same way.

Custom stop strategies

A stop strategy reports that the user is done with report_user_turn_stopped(). The turn controller combines the strategies’ reports and runs the turn’s inference itself. A strategy calls start_user_turn_speculation() only to answer ahead of the turn ending, and cancel_user_turn_speculation() to withdraw that answer. Two properties tell the controller how to treat a strategy:
  • waits_for_inference (default False): return True when the strategy decides from the turn’s inference rather than from the user. The controller runs the inference once the other stop strategies have decided, and this strategy then decides from it. A strategy that decides from the inference but doesn’t return True is treated as one that listens to the user: with StrategyMode.ALL the inference doesn’t run until user_turn_stop_timeout ends the turn, and with StrategyMode.FIRST the turn ends without waiting for it.
  • decision_scheduled (default False): return True while the strategy is sure to decide soon on its own, such as while a timer of its own is pending. user_turn_stop_timeout then waits instead of ending the turn.
BaseUserTurnStartStrategy and BaseUserTurnStopStrategy have deprecated methods with replacements: All are deprecated since 1.15.0 and removed in 2.0.0. A subclass that overrides trigger_user_turn_started() or trigger_user_turn_stopped() keeps receiving the reports until then. trigger_user_turn_inference_triggered() ignores a call that isn’t a speculation.

Helper Functions

Pipecat provides helper functions to compose custom strategy lists that extend the defaults.

default_user_turn_start_strategies()

Returns the default user turn start strategies: [VADUserTurnStartStrategy, TranscriptionUserTurnStartStrategy]. Useful when building a custom strategy list that extends the defaults.

default_user_turn_stop_strategies()

Returns the default user turn stop strategies: [TurnAnalyzerUserTurnStopStrategy(LocalSmartTurnAnalyzerV3)]. Useful when building a custom strategy list that extends or replaces the defaults.

UserTurnStrategies

Container for configuring user turn start and stop strategies.
list[BaseUserTurnStartStrategy] | None
default:"None"
List of strategies used to detect when the user starts speaking. With start_mode=StrategyMode.FIRST, the first strategy to decide signals the start of the user’s turn. None or an empty list uses [VADUserTurnStartStrategy(), TranscriptionUserTurnStartStrategy()].
list[BaseUserTurnStopStrategy] | None
default:"None"
List of strategies used to detect when the user stops speaking and expects a response. With stop_mode=StrategyMode.ALL, every strategy has to decide before the turn ends. None or an empty list uses AI-powered turn detection: [TurnAnalyzerUserTurnStopStrategy(turn_analyzer=LocalSmartTurnAnalyzerV3())].

UserTurnStrategiesParams

Chooses how user turn strategies combine and decide. Pass it as user_turn_strategies_params to LLMUserAggregatorParams, UserTurnProcessor, or UserTurnController.
StrategyMode
default:"StrategyMode.FIRST"
FIRST starts the turn on the first start strategy that decides the user started. ALL waits until every start strategy has. In an ALL list each strategy is a condition the turn needs, so a fallback such as TranscriptionUserTurnStartStrategy belongs in a FIRST list.
StrategyMode
default:"StrategyMode.ALL"
ALL ends the turn once every stop strategy has decided the user is done. FIRST ends it on the first one that does. For example, TurnAnalyzerUserTurnStopStrategy next to SpeechTimeoutUserTurnStopStrategy ends the turn only once both say the user is done in ALL mode. A stop strategy that waits for the turn’s inference, such as LLMTurnCompletionUserTurnStopStrategy, decides on it in either mode. The user speaking again clears the decisions made so far. A list with a single stop strategy behaves the same in both modes.
MergeMode
default:"MergeMode.REPLACE"
How the bot’s start strategies combine with the ones a service recommends. REPLACE uses the bot’s strategies instead of the service’s. EXTEND adds them to the service’s list, or to the defaults when no service recommends any.
MergeMode
default:"MergeMode.REPLACE"
How the bot’s stop strategies combine with the ones a service recommends, with the same values as start_merge_mode.
ProcessFrameResult is deprecated since 1.15.0 and removed in 2.0.0. Use StrategyMode instead: strategies don’t return anything from process_frame(), and every strategy sees every frame. Until 2.0.0, a StrategyMode.FIRST list still honors ProcessFrameResult.STOP, with a deprecation warning.

ExternalUserTurnStrategies

A convenience class that preconfigures UserTurnStrategies with external strategies for both start and stop detection. Use this when an external processor (such as a speech-to-speech service) controls turn management. What these strategies emit depends on which frame drives the turn:
  • A proposal (ProposedUserStartedSpeakingFrame / ProposedUserStoppedSpeakingFrame, sent by a turn-detecting STT service): the decision is left to these strategies, so they push UserStartedSpeakingFrame / UserStoppedSpeakingFrame and broadcast the interruption themselves.
  • A real turn frame (UserStartedSpeakingFrame / UserStoppedSpeakingFrame, sent by a shared UserTurnProcessor or a third-party service): the turn was already announced, so these strategies emit nothing and enable_interruptions does not apply.

Constructor Parameters

bool
default:"True"
Whether to broadcast an interruption when a proposal starts a turn. This is where a turn-detecting STT service sends its should_interrupt setting, so the two are the same knob. Set it to False to stop the bot being interrupted when the user starts speaking. Ignored when a real turn frame drives the turn.
When an STT service acts as the turn controller, you can optionally set a VAD (such as SileroVADAnalyzer) with LLMUserAggregatorParams.vad_analyzer. The VAD is not required for core turn management functionality, but it does enable useful STT metrics. Omit it if you don’t need those metrics.
Passing user_turn_strategies by hand replaces whatever the service recommended, and should_interrupt is part of the recommended start strategy. start_merge_mode=MergeMode.EXTEND keeps it. If you set should_interrupt=False on the service and pin user_turn_strategies=ExternalUserTurnStrategies() yourself, interruptions come back on. Either drop the manual user_turn_strategies (the service recommends the right ones on its own) or pass ExternalUserTurnStrategies(enable_interruptions=False). The aggregator logs a warning naming both fixes when it spots this.

EagerUserTurnStrategies

Strategies for a service that predicts the end of a turn before committing. Answers the prediction while the turn is still open, so the gap before the committed end of turn is spent generating a response instead of waiting for one. The response is discarded if the user resumes speaking or the committed transcript differs from the eager one. See EagerUserTurnStopStrategy. The response is held by the LLM service until the turn is confirmed, so no extra processor is needed in the pipeline. The service owns turn detection here, so this replaces the detector chain rather than extending it: a local detector running alongside would trigger a second inference for the same turn.

Constructor Parameters

EagerMatchPolicy | None
default:"None"
Decides whether the committed transcript is close enough to the eager one to keep the speculative response. None uses NormalizedMatch(), since services commonly format the transcript they commit (capitalization, punctuation) while leaving the eager one raw. Pass ExactMatch to require the two to be identical.
float
default:"5.0"
Seconds a prediction may go unresolved before it is withdrawn and the turn falls back to answering the committed transcript. Guards against a service that stops sending turn signals mid-speculation, which would otherwise leave the response held and the bot silent.
bool
default:"True"
Whether to broadcast an interruption when a proposal starts a turn. Services route their should_interrupt setting here, so the two are the same knob.

FilterIncompleteUserTurnStrategies

A convenience class that preconfigures UserTurnStrategies for LLM-gated turn completion. It keeps your stop strategies and appends an LLMTurnCompletionUserTurnStopStrategy. Once the other stop strategies decide the user stopped, the turn’s inference runs, and the turn ends only when the LLM confirms it is complete (●). It works with either stop_mode. To add the LLM gate and any stop strategies you pass to the ones a service recommends, such as an STT service’s own turn detection, set stop_merge_mode=MergeMode.EXTEND:
UserTurnCompletionConfig
default:"None"
Optional turn-completion configuration (instructions, incomplete-turn timeouts, and re-prompts) applied to the LLM. Defaults are used if not provided.
The start and stop strategies default to the standard detector chain; override either to customize the detectors that trigger inference.
See Filter Incomplete User Turns for the full feature documentation, markers, and timeout behavior.

ClassifierUserTurnStrategies

Preconfigures UserTurnStrategies so a classifier decides whether the user’s turn is complete. It suits an LLM that doesn’t follow the turn-completion markers of FilterIncompleteUserTurnStrategies well: the classifier decides, and the LLM only answers complete turns. It adds a ClassifierUserTurnStopStrategy after the stop strategies given, or after the default ones when none are given, and the turn ends once all of them have decided. For the classifier alone, pass UserTurnStrategies(stop=[ClassifierUserTurnStopStrategy(...)]).
BaseClassifier
required
The classifier that decides whether a turn is complete. Raises ValueError if omitted.
LLMContext | None
default:"None"
The conversation, so the classifier sees the assistant’s last message along with the user’s turn.
float
default:"5.0"
Seconds to wait after a short verdict before the classifier strategy decides the user is done.
float
default:"10.0"
Seconds to wait after a long verdict before the classifier strategy decides the user is done.
float
default:"1.0"
Seconds to wait for the classifier before leaving the decision to the other stop strategies.
The start and stop strategies take the same values as on UserTurnStrategies. With UserTurnStrategiesParams(stop_merge_mode=MergeMode.EXTEND), the classifier strategy and any stop strategies given join the ones a service recommends instead.

Usage Examples

Default Behavior

The default configuration uses VAD for turn start detection and AI-powered Smart Turn for turn end detection:

Minimum Words for Interruption

Require users to speak at least 3 words before they can interrupt the bot:

Wake Phrase Detection

Require a wake phrase before allowing interaction, then use the default stop strategies:

Local Smart Turn Detection

Use a local turn detection model instead of a cloud service: