> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipecat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# User Turn Strategies

> Configure how user turns are detected and managed in conversations

## 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.

<Note>
  In Pipecat >=1.0.0, the `turn_analyzer` must be specified in the
  `TurnAnalyzerUserTurnStopStrategy`. See the [migration
  guide](/pipecat/migration/migration-1.0#3-vad-&-turn-analyzer-configuration)
  for more information.
</Note>

## How It Works

1. **Turn Start Detection**: When any start strategy triggers, the user aggregator:
   * Marks the start of a user turn
   * Optionally emits `UserStartedSpeakingFrame`
   * Optionally emits an interruption frame (if the bot is speaking)

2. **During User Turn**: The aggregator collects transcriptions and audio frames.

3. **Turn Stop Detection**: When a stop strategy triggers, 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 no stop strategy triggers within `user_turn_stop_timeout` seconds (default: 5.0), the turn is automatically ended. This timeout is configurable via `LLMUserAggregatorParams` (see [Configuration](#configuration) below). When the timeout fires, the [`on_user_turn_stop_timeout`](/api-reference/server/utilities/turn-management/turn-events#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.** Every stop strategy waits for the STT service to transcribe what the user said (`wait_for_transcript`, on by default). 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](https://github.com/pipecat-ai/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

| Strategy                             | How it decides the turn is complete                                                           |
| ------------------------------------ | --------------------------------------------------------------------------------------------- |
| `SpeechTimeoutUserTurnStopStrategy`  | A fixed silence window (`user_speech_timeout`, default `0.6s`) elapses after the user pauses. |
| `TurnAnalyzerUserTurnStopStrategy`   | A turn-detection ("smart turn") model predicts end-of-turn from the audio and transcript.     |
| `FilterIncompleteUserTurnStrategies` | An LLM assesses whether the user's utterance is semantically complete.                        |
| Custom                               | Your own logic implementing the stop-strategy interface.                                      |

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.

<Note>
  Extra silence users notice usually isn't one tunable value — it's VAD silence
  plus transcription latency plus the strategy's own window stacking up. 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](https://github.com/pipecat-ai/stt-benchmark) if transcription is
  the bottleneck.
</Note>

`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`:

```python theme={null}
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import (
    LLMContextAggregatorPair,
    LLMUserAggregatorParams,
)
from pipecat.turns.user_turn_strategies import UserTurnStrategies

context = LLMContext(messages)
user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=UserTurnStrategies(
            start=[...],  # List of start strategies
            stop=[...],   # List of stop strategies
        ),
    ),
)
```

### Additional Parameters

In addition to `user_turn_strategies`, `LLMUserAggregatorParams` accepts these turn-related parameters:

<ParamField path="user_turn_stop_timeout" type="float" default="5.0">
  Safety-net timeout in seconds. If a user turn starts but no stop strategy
  triggers within this duration, the turn is automatically ended and the
  [`on_user_turn_stop_timeout`](/api-reference/server/utilities/turn-management/turn-events#on_user_turn_stop_timeout)
  event is emitted.
</ParamField>

```python theme={null}
user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_stop_timeout=4.0,  # Decrease timeout to 4 seconds
    ),
)
```

<ParamField path="vad_analyzer" type="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.
</ParamField>

## Start Strategies

Start strategies determine when a user's turn begins. Multiple strategies can be provided, and the first one to trigger will signal the start of a user turn.

### Base Parameters

All start strategies inherit these parameters:

<ParamField path="enable_interruptions" type="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.
</ParamField>

<ParamField path="enable_user_speaking_frames" type="bool" default="True">
  If True, the user aggregator will emit frames indicating when the user starts
  speaking. Disable this if another component (e.g., an STT service) already
  generates these frames.
</ParamField>

### 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.

```python theme={null}
from pipecat.turns.user_start import VADUserTurnStartStrategy

strategy = VADUserTurnStartStrategy()
```

### 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.

<ParamField path="use_interim" type="bool" default="True">
  Whether to trigger on interim (partial) transcription frames for earlier
  detection.
</ParamField>

```python theme={null}
from pipecat.turns.user_start import TranscriptionUserTurnStartStrategy

strategy = TranscriptionUserTurnStartStrategy(use_interim=True)
```

### 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.

<ParamField path="min_words" type="int" required>
  Minimum number of spoken words required to trigger the start of a user turn.
</ParamField>

<ParamField path="use_interim" type="bool" default="True">
  Whether to consider interim transcription frames for earlier detection.
</ParamField>

```python theme={null}
from pipecat.turns.user_start import MinWordsUserTurnStartStrategy

# Require at least 3 words to start a turn
strategy = MinWordsUserTurnStartStrategy(min_words=3)
```

<Note>
  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.
</Note>

### WakePhraseUserTurnStartStrategy

Requires a wake phrase to be detected before allowing interaction. This strategy blocks subsequent strategies until a wake phrase is detected in a transcription, then allows interaction for a configurable timeout period.

<ParamField path="phrases" type="List[str]" required>
  List of wake phrases to detect (e.g., `["hey pipecat", "ok pipecat"]`).
</ParamField>

<ParamField path="timeout" type="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.
</ParamField>

<ParamField path="single_activation" type="bool" default="False">
  If True, the wake phrase is required before every turn. The strategy returns
  to IDLE after each turn completes.
</ParamField>

```python theme={null}
from pipecat.turns.user_start import WakePhraseUserTurnStartStrategy

# Timeout mode: wake phrase unlocks interaction for 10 seconds
strategy = WakePhraseUserTurnStartStrategy(
    phrases=["hey pipecat", "ok pipecat"],
    timeout=10.0,
)

# Single activation: wake phrase required before every turn
strategy = WakePhraseUserTurnStartStrategy(
    phrases=["hey pipecat"],
    single_activation=True,
)
```

**Event Handlers**

The strategy provides event handlers for wake phrase detection:

| Event                     | Signature                                  | Description                                                    |
| ------------------------- | ------------------------------------------ | -------------------------------------------------------------- |
| `on_wake_phrase_detected` | `async def handler(strategy, phrase: str)` | Called when a wake phrase is matched                           |
| `on_wake_phrase_timeout`  | `async def handler(strategy)`              | Called when the inactivity timeout expires (timeout mode only) |

```python theme={null}
@strategy.event_handler("on_wake_phrase_detected")
async def on_wake_phrase_detected(strategy, phrase):
    print(f"Wake phrase detected: {phrase}")

@strategy.event_handler("on_wake_phrase_timeout")
async def on_wake_phrase_timeout(strategy):
    print("Wake phrase timeout, returning to IDLE")
```

<Note>
  This strategy should be placed **first** in the start strategies list to
  properly gate all subsequent strategies. Use
  `default_user_turn_start_strategies()` to extend the defaults with wake phrase
  detection.
</Note>

### 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).

<ParamField path="model_path" type="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.
</ParamField>

<ParamField path="threshold" type="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.
</ParamField>

<ParamField path="frame_duration_ms" type="int" default="20">
  Frame duration in milliseconds for IP processing. Supported values: 10, 15,
  20, 30, 32.
</ParamField>

<ParamField path="api_key" type="str" default="&#x22;&#x22;">
  Krisp SDK API key. If empty, falls back to the `KRISP_VIVA_API_KEY`
  environment variable.
</ParamField>

```python theme={null}
from pipecat.turns.user_start import (
    KrispVivaIPUserTurnStartStrategy,
    TranscriptionUserTurnStartStrategy,
)

strategy = KrispVivaIPUserTurnStartStrategy(
    model_path="/path/to/ip_model.kef",
    threshold=0.5,
)

# Use with a fallback strategy
strategies = UserTurnStrategies(
    start=[
        KrispVivaIPUserTurnStartStrategy(threshold=0.5),
        TranscriptionUserTurnStartStrategy(),  # Fallback
    ],
)
```

<Note>
  Requires the Krisp Python SDK. See the [Krisp VIVA
  guide](/pipecat/features/krisp-viva) for installation instructions.
</Note>

### ExternalUserTurnStartStrategy

Delegates turn start detection to an external processor. This strategy listens for `UserStartedSpeakingFrame` frames emitted by other components in the pipeline (such as speech-to-speech services).

```python theme={null}
from pipecat.turns.user_start import ExternalUserTurnStartStrategy

strategy = ExternalUserTurnStartStrategy()
```

<Note>
  This strategy automatically sets `enable_interruptions=False` and
  `enable_user_speaking_frames=False` since these are expected to be handled by
  the external processor.
</Note>

## Stop Strategies

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

### Base Parameters

All stop strategies inherit these parameters:

<ParamField path="enable_user_speaking_frames" type="bool" default="True">
  If True, the aggregator will emit frames indicating when the user stops
  speaking. Disable this if another component already generates these frames.
</ParamField>

### 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.

For STT services that support finalization (Speechmatics, Soniox, Deepgram Flux, AssemblyAI), user turns now end as soon as `user_speech_timeout` elapses after VAD stop, rather than waiting for both timers.

<ParamField path="user_speech_timeout" type="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.
</ParamField>

<ParamField path="wait_for_transcript" type="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`](/api-reference/server/utilities/turn-management/external-turn-management#realtime-speech-to-speech-services)
  flips this to `False` for you when `realtime_service_mode=True`.
</ParamField>

```python theme={null}
from pipecat.turns.user_stop import SpeechTimeoutUserTurnStopStrategy

strategy = SpeechTimeoutUserTurnStopStrategy(user_speech_timeout=0.6)
```

<Note>
  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](https://github.com/pipecat-ai/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.
</Note>

### 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.

<ParamField path="turn_analyzer" type="BaseTurnAnalyzer" required>
  The turn detection analyzer instance to use for end-of-turn detection.
</ParamField>

<ParamField path="wait_for_transcript" type="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`](/api-reference/server/utilities/turn-management/external-turn-management#realtime-speech-to-speech-services)
  flips this to `False` for you when `realtime_service_mode=True`.
</ParamField>

```python theme={null}
from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3
from pipecat.turns.user_stop import TurnAnalyzerUserTurnStopStrategy

strategy = TurnAnalyzerUserTurnStopStrategy(
    turn_analyzer=LocalSmartTurnAnalyzerV3()
)
```

<Tip>
  See the [Smart Turn
  Detection](/api-reference/server/utilities/turn-detection/smart-turn-overview)
  documentation for more information on available turn analyzers.
</Tip>

<Note>
  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](https://github.com/pipecat-ai/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.
</Note>

### ExternalUserTurnStopStrategy

Delegates turn stop detection to an external processor. This strategy listens for `UserStoppedSpeakingFrame` frames emitted by other components in the pipeline.

<ParamField path="timeout" type="float" default="0.5">
  A short delay in seconds used to handle consecutive or slightly delayed
  transcriptions.
</ParamField>

<ParamField path="wait_for_transcript" type="bool" default="True">
  When `True` (default), turn-stop signaling waits for a transcript to arrive
  after the external `UserStoppedSpeakingFrame`. When `False`, the strategy
  signals turn-stop as soon as that frame arrives, independent of transcripts —
  useful when local turn detection drives a realtime (speech-to-speech) service.
  [`LLMContextAggregatorPair`](/api-reference/server/utilities/turn-management/external-turn-management#realtime-speech-to-speech-services)
  flips this to `False` for you when `realtime_service_mode=True`.
</ParamField>

```python theme={null}
from pipecat.turns.user_stop import ExternalUserTurnStopStrategy

strategy = ExternalUserTurnStopStrategy()
```

### ExternalUserTurnCompletionStopStrategy

Finalizes the user turn whenever a `UserTurnInferenceCompletedFrame` arrives, regardless of which component produced it. Use this when an external component — an LLM with completion markers, an STT service with built-in turn detection, a dedicated end-of-turn classifier, or custom code — decides when a turn is semantically complete and emits that frame.

Pair it with one or more detector strategies wrapped in [`deferred(...)`](#deferring-finalization), which drive inference but leave finalization to this strategy:

```python theme={null}
from pipecat.turns.user_stop import (
    ExternalUserTurnCompletionStopStrategy,
    TurnAnalyzerUserTurnStopStrategy,
    deferred,
)

stop = [
    deferred(TurnAnalyzerUserTurnStopStrategy(turn_analyzer=...)),
    ExternalUserTurnCompletionStopStrategy(),
]
```

<Note>
  If the producer never emits `UserTurnInferenceCompletedFrame`, the
  `user_turn_stop_timeout` watchdog finalizes the turn after no activity. Tune
  that timeout if your producer can take longer than the default to respond.
</Note>

### LLMTurnCompletionUserTurnStopStrategy

A subclass of `ExternalUserTurnCompletionStopStrategy` that adds the LLM-specific setup for the marker-based completion protocol. On `StartFrame` it enables turn-completion filtering on the LLM; finalization then happens when the LLM emits a `✓` marker. This is the finalizer used by [`FilterIncompleteUserTurnStrategies`](#filterincompleteuserturnstrategies).

<ParamField path="config" type="UserTurnCompletionConfig" default="None">
  Configuration applied to the LLM (turn-completion instructions,
  incomplete-turn timeouts, and re-prompts). Defaults to
  `UserTurnCompletionConfig()`.
</ParamField>

```python theme={null}
from pipecat.turns.user_stop import LLMTurnCompletionUserTurnStopStrategy

strategy = LLMTurnCompletionUserTurnStopStrategy()
```

<Tip>
  See [Filter Incomplete User
  Turns](/api-reference/server/utilities/turn-management/filter-incomplete-turns)
  for the full LLM-gated turn-completion feature.
</Tip>

### Deferring finalization

Some stop strategies should trigger LLM inference without ending the turn — finalization is owned by another strategy in the chain (such as the two above). Wrap a detector strategy with `deferred(...)` to suppress its `on_user_turn_stopped` event while keeping its [`on_user_turn_inference_triggered`](/api-reference/server/utilities/turn-management/turn-events#on_user_turn_inference_triggered) trigger:

```python theme={null}
from pipecat.turns.user_stop import (
    LLMTurnCompletionUserTurnStopStrategy,
    TurnAnalyzerUserTurnStopStrategy,
    deferred,
)

stop = [
    deferred(TurnAnalyzerUserTurnStopStrategy(turn_analyzer=...)),
    LLMTurnCompletionUserTurnStopStrategy(),
]
```

## 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, such as adding wake phrase detection before the standard strategies.

```python theme={null}
from pipecat.turns.user_start import WakePhraseUserTurnStartStrategy
from pipecat.turns.user_turn_strategies import default_user_turn_start_strategies

# Add wake phrase detection before the defaults
start_strategies = [
    WakePhraseUserTurnStartStrategy(phrases=["hey pipecat"]),
    *default_user_turn_start_strategies(),
]
```

### 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.

```python theme={null}
from pipecat.turns.user_turn_strategies import default_user_turn_stop_strategies

# Use the defaults
stop_strategies = default_user_turn_stop_strategies()
```

## UserTurnStrategies

Container for configuring user turn start and stop strategies.

<ParamField path="start" type="List[BaseUserTurnStartStrategy]" default="[VADUser...(), TranscriptionUser...()]">
  List of strategies used to detect when the user starts speaking. The first
  strategy to trigger will signal the start of the user's turn.
</ParamField>

<ParamField path="stop" type="List[BaseUserTurnStopStrategy]" default="[TurnAnalyzerUserTurnStopStrategy(turn_analyzer=LocalSmartTurnAnalyzerV3())]">
  List of strategies used to detect when the user stops speaking and expects a
  response. Defaults to AI-powered turn detection using
  `LocalSmartTurnAnalyzerV3`.
</ParamField>

## 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.

```python theme={null}
from pipecat.turns.user_turn_strategies import ExternalUserTurnStrategies

user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=ExternalUserTurnStrategies(),
    ),
)
```

<Note>
  When an STT service acts as the turn controller, you can optionally include a
  VAD (such as `SileroVADAnalyzer`) in your transport. 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.
</Note>

## FilterIncompleteUserTurnStrategies

A convenience class that preconfigures `UserTurnStrategies` for LLM-gated turn completion. It wraps your detector chain with `deferred(...)` and appends an `LLMTurnCompletionUserTurnStopStrategy`, so the public `on_user_turn_stopped` event fires only when the LLM confirms the turn is complete (`✓`). Detector strategies still drive LLM inference via `on_user_turn_inference_triggered`.

```python theme={null}
from pipecat.turns.user_turn_strategies import FilterIncompleteUserTurnStrategies

user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=FilterIncompleteUserTurnStrategies(),
    ),
)
```

<ParamField path="config" type="UserTurnCompletionConfig" default="None">
  Optional turn-completion configuration (instructions, incomplete-turn
  timeouts, and re-prompts) applied to the LLM. Defaults are used if not
  provided.
</ParamField>

The `start` and `stop` strategies default to the standard detector chain; override either to customize the detectors that trigger inference.

<Tip>
  See [Filter Incomplete User
  Turns](/api-reference/server/utilities/turn-management/filter-incomplete-turns)
  for the full feature documentation, markers, and timeout behavior.
</Tip>

## Usage Examples

### Default Behavior

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

```python theme={null}
from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3
from pipecat.turns.user_turn_strategies import UserTurnStrategies

# This is equivalent to the default behavior
strategies = UserTurnStrategies(
    start=[VADUserTurnStartStrategy(), TranscriptionUserTurnStartStrategy()],
    stop=[TurnAnalyzerUserTurnStopStrategy(turn_analyzer=LocalSmartTurnAnalyzerV3())],
)
```

### Minimum Words for Interruption

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

```python theme={null}
from pipecat.turns.user_start import MinWordsUserTurnStartStrategy
from pipecat.turns.user_stop import SpeechTimeoutUserTurnStopStrategy
from pipecat.turns.user_turn_strategies import UserTurnStrategies

user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=UserTurnStrategies(
            start=[MinWordsUserTurnStartStrategy(min_words=3)],
            stop=[SpeechTimeoutUserTurnStopStrategy()],
        ),
    ),
)
```

### Wake Phrase Detection

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

```python theme={null}
from pipecat.turns.user_start import WakePhraseUserTurnStartStrategy
from pipecat.turns.user_turn_strategies import (
    UserTurnStrategies,
    default_user_turn_start_strategies,
)

user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=UserTurnStrategies(
            start=[
                WakePhraseUserTurnStartStrategy(phrases=["hey pipecat"]),
                *default_user_turn_start_strategies(),
            ],
        ),
    ),
)
```

### Local Smart Turn Detection

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

```python theme={null}
from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3
from pipecat.turns.user_stop import TurnAnalyzerUserTurnStopStrategy
from pipecat.turns.user_turn_strategies import UserTurnStrategies

user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
    context,
    user_params=LLMUserAggregatorParams(
        user_turn_strategies=UserTurnStrategies(
            stop=[
                TurnAnalyzerUserTurnStopStrategy(
                    turn_analyzer=LocalSmartTurnAnalyzerV3()
                )
            ]
        ),
    ),
)
```

## Related

* [User Input Muting](/pipecat/fundamentals/user-input-muting) - Control when user input is ignored
* [Smart Turn Detection](/api-reference/server/utilities/turn-detection/smart-turn-overview) - AI-powered turn detection
