---
title: "Configuring turn detection and interruptions in LiveKit Agents"
date: "2026-06-30"
authors: "Darryn Campbell"
tags: "guide"
---

# Configuring turn detection and interruptions in LiveKit Agents

A LiveKit voice agent gives you many related but distinct turn-taking controls: turn detection modes, endpointing delays, interruption modes, VAD thresholds, and your choice of models. They all shape how natural a conversation feels, and this guide helps you choose the right configuration for your use case.

This is a configuration guide, not a primer. It assumes you already know what turn detection, VAD, endpointing, and barge-in *are*. If any of those terms are new, this [earlier post](/blog/turn-detection-voice-agents-vad-endpointing-model-based-detection) and the [LiveKit turn detection docs](https://docs.livekit.io/agents/logic/turns) are both good introductions. The focus here is how to configure these features, including new features such as LiveKit's audio-based turn detector, adaptive interruption handling, and STT-native endpointing models.

## Table of contents

- [Pipeline architecture](#pipeline-architecture)

- [VAD configuration](#vad-configuration)

- [Turn detection configuration](#turn-detection-configuration)
  - [Choosing a mode](#choosing-a-mode)
  - [LiveKit turn detector](#livekit-turn-detector)
  - [STT endpointing (`turn_detection="stt"`)](#stt-endpointing-turn_detectionstt)
  - [Realtime LLM (`turn_detection="realtime_llm"`)](#realtime-llm-turn_detectionrealtime_llm)
  - [VAD only (`turn_detection="vad"`)](#vad-only-turn_detectionvad)
  - [Manual (`turn_detection="manual"`)](#manual-turn_detectionmanual)

- [Interruption configuration](#interruption-configuration)
  - [Enabling interruption handling](#enabling-interruption-handling)
  - [Configuring interruption handling](#configuring-interruption-handling)
  - [User turn limits](#user-turn-limits)

- [Other related configuration](#other-related-configuration)

- [Common issues and resolutions](#common-issues-and-resolutions)

## Pipeline architecture

These features are stages in a single pipeline that user audio flows through, and each is configurable. The pipeline exists to answer three questions:

1. **Is there speech right now?** This is what **VAD** determines.
2. **Has the user finished speaking?** If so, the agent can safely respond. **Turn detection** makes this call, and **endpointing** configures the time to wait before committing the turn.
3. **Is the user interrupting the agent?** When speech arrives while the agent is talking, the agent has to decide whether to stop and yield the floor. This is **interruption handling**.

VAD, where present, runs first on every frame. Which of the next two questions the pipeline asks depends on whether the agent is already speaking, as illustrated below:

<Mermaid
  chart={`flowchart TD
A["User audio in"] --> B["VAD detects speech"]
B --> C{"Agent currently speaking?"}
C -->|"No"| D{"Has the user<br/>finished speaking?"}
C -->|"Yes"| E{"Is the user<br/>interrupting?"}
D -->|"Yes"| F["Endpointing waits,<br/>then agent responds"]
D -->|"No"| G["Keep listening"]
E -->|"Yes"| H["Stop agent, yield turn"]
E -->|"No"| I["Keep speaking"]
classDef key fill:#1FD5F9,stroke:#00BFFF,color:#1a1a1a;
class B,D,E key;
`}
/>

The remaining pieces (noise cancellation, preemptive generation) exist to make those two decisions better, faster, or cleaner. Refer to the [Turns overview](https://docs.livekit.io/agents/logic/turns) and [Turn-taking tuning](https://docs.livekit.io/agents/logic/turns/tuning) documentation for more information.

## VAD configuration

VAD is the first stage in the pipeline. The framework auto-provisions a VAD for you through the `AgentSession`, so you don't normally specify one. For advanced cases you can pass a `vad` argument yourself, but be aware that the new LiveKit turn detector imposes its own timing requirements when active (such as a minimum silence window).

As you browse the docs and examples, you'll see VAD specified in different ways:

**Bundled inference VAD (default, recommended)**

`AgentSession` auto-provisions `inference.VAD(model="silero")` for you, a Silero model bundled with the Agents SDK. You can override it by passing a `vad` argument, which accepts [these options](https://docs.livekit.io/reference/python/livekit/agents/inference/vad.html), though most deployments should leave them unchanged.

**Silero VAD plugin**

The standalone Silero VAD plugin is the older, separately installed option. You may see this listed in older examples and it still works, with fully [documented configuration](https://docs.livekit.io/agents/logic/turns/vad), but it should not be used when creating new agents.

**ai-coustics VAD adapter**

If you already run [ai-coustics noise cancellation](https://docs.livekit.io/transport/media/noise-cancellation#vad-adapter), its plugin ships a built-in VAD adapter. The ai-coustics VAD adapter is not required in order to use ai-coustics noise cancellation. Note that the LiveKit turn detector is not designed to run with this VAD, though it's fine for other configurations (for example, VAD-only or STT endpointing).

**Alternative VADs**

You can also bring your own: any object that implements the SDK's VAD interface can be passed as `vad`, so you can wrap a different VAD model if you have one. To turn VAD off entirely (for example, with a realtime model that does its own detection), pass `vad=None` in Python or `vad: null` in Node.js.

## Turn detection configuration

Turn detection decides when the user has finished their turn so the agent knows when to respond. This section covers the modes you can choose and how to configure each one; for the concepts behind it, see the [Turns overview](https://docs.livekit.io/agents/logic/turns) and the [earlier post](/blog/turn-detection-voice-agents-vad-endpointing-model-based-detection).

### Choosing a mode

The [`turn_detection`](https://docs.livekit.io/reference/agents/turn-handling-options#turnhandlingoptions) option accepts either a turn-detector model object or one of several string modes. Decide this first, since it determines which other settings apply.

| Mode                                                                                                           | How it decides when a turn ends                | Use it when                                                                                                          |
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [`TurnDetector()`](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-turn-detector) (audio model) | Semantic and acoustic prediction on top of VAD | The default, and the best choice for most pipeline agents.                                                           |
| [`"stt"`](https://docs.livekit.io/agents/logic/turns#stt-endpointing)                                          | Your STT provider's native endpointing model   | You're using an STT with strong built-in turn detection (Deepgram Flux, AssemblyAI).                                 |
| [`"realtime_llm"`](https://docs.livekit.io/agents/logic/turns#realtime-models)                                 | The realtime model's own server-side detection | You're on a realtime LLM (OpenAI Realtime, Gemini Live) and want its built-in detection.                             |
| [`"vad"`](https://docs.livekit.io/agents/logic/turns#vad-only)                                                 | Pure speech-start and speech-stop cues         | A language the turn detector doesn't cover, or simple command-style interactions that don't need semantic detection. |
| [`"manual"`](https://docs.livekit.io/agents/logic/turns#manual)                                                | You commit turns explicitly in code            | Push-to-talk, or any flow where you control turn boundaries directly.                                                |

The rest of this section covers each mode in turn.

### LiveKit turn detector

This is the default turn detector, and is recommended for most developers.

The [`TurnDetector`](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-turn-detector) is an audio model that reasons over the user's speech directly, combining the words with acoustic cues like intonation and rhythm. Because it doesn't wait for a transcript, it decides faster and avoids the mid-turn-pause mistakes of transcript-only approaches.

For how the model works and how it was evaluated, see the [turn detector docs](https://docs.livekit.io/agents/logic/turns/turn-detector) and the [deep-dive blog post](/blog/solving-end-of-turn-detection). (An older text-based detector also exists but is deprecated and slated for removal in Agents SDK 2.0, so use the audio model for anything new.)

You configure it through two surfaces: the detector model itself, and the endpointing timing layer that controls how long to wait after detection before committing the turn.   Most agents leave these at their defaults. For more detail, see the [EndpointingOptions reference](https://docs.livekit.io/reference/agents/turn-handling-options#endpointingoptions).

| Option                                 | Description                                                                                                                                                                                                                                                      |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `endpointing.min_delay`                | Minimum wait after detected silence before the turn closes.                                                                                                                                                                                                      |
| `endpointing.max_delay`                | Maximum the agent waits before forcing the turn closed, so it never hangs forever.                                                                                                                                                                               |
| `endpointing.mode` (default `"fixed"`) | `"fixed"` always uses the configured delays; `"dynamic"` adapts within the `min_delay`/`max_delay` range based on the user's pause patterns, so fast talkers get snappier responses and slower talkers get more patience.                                        |
| Per-language thresholds                | The detector supports 14 languages and picks a per-language confidence threshold from the STT-reported language. Override it per language with a custom [unlikely\_threshold](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-custom-thresholds). |
| Model version (`v1` / `v1-mini`)       | v1 is the full model served on LiveKit Inference while v1-mini runs locally on CPU. See the [turn detector docs](https://docs.livekit.io/agents/logic/turns/turn-detector/) for more information.                                                                |

A typical configuration looks like this:

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions, inference

session = AgentSession(
    turn_handling=TurnHandlingOptions(
        turn_detection=inference.TurnDetector(),  # the default if omitted
        endpointing={"mode": "dynamic", "min_delay": 0.3, "max_delay": 2.5}, # secs
    ),
    # ... stt, tts, llm, etc.
)
```

**Node.js**

```typescript
import { inference, voice } from '@livekit/agents';

const session = new voice.AgentSession({
  turnHandling: {
    turnDetection: new inference.TurnDetector(), // the default if omitted
    endpointing: { mode: 'dynamic', minDelay: 300, maxDelay: 2500 }, // ms
  },
  // ... stt, tts, llm, etc.
});
```

### STT endpointing (`turn_detection="stt"`)

Setting `turn_detection="stt"` hands the end-of-turn decision to your STT provider's own endpointing model instead of running the LiveKit turn detector. Use it when your STT has strong built-in turn detection, such as [Deepgram Flux](https://docs.livekit.io/agents/models/stt/deepgram#turn-detection) or [AssemblyAI Universal-3 Pro](https://docs.livekit.io/agents/models/stt/assemblyai#turn-detection). Even in this mode you still need a VAD to handle interruptions; if you don't provide one, the default is auto-provisioned.

It's worth understanding how LiveKit's [endpointing options](https://docs.livekit.io/reference/agents/turn-handling-options/#endpointingoptions) interact with STT mode. `endpointing.min_delay` acts as a floor measured from when the user last stopped speaking, so it adds latency on top of the provider's own decision, but `endpointing.max_delay` has no effect. In practice, set `min_delay` to `0`, leave endpointing in its default `fixed` mode (avoid `dynamic`, which can let the floor drift above `0` over a session), and let the provider's own settings control the timing, such as AssemblyAI's `min_turn_silence` or Deepgram Flux's `eot_timeout_ms`.

The configuration options for STT mode:

| Option                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `turn_detection="stt"`  | Hands end-of-turn detection to the STT provider instead of the LiveKit turn detector.                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `endpointing.min_delay` | Set to `0` in STT mode (see above).                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| STT provider parameters | The provider's own end-of-turn timing. With LiveKit Inference, pass them via `extra_kwargs` (Python) or `modelOptions` (Node.js); with the standalone STT plugin classes, pass them as named constructor arguments. See the individual model docs, e.g. [Deepgram Flux](https://docs.livekit.io/agents/models/stt/deepgram/#parameters) or [AssemblyAI](https://docs.livekit.io/agents/models/stt/assemblyai#turn-detection) for the available params and more recommendations specific to that provider. |

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions, inference

session = AgentSession(
    turn_handling=TurnHandlingOptions(
        turn_detection="stt",
        endpointing={"min_delay": 0},
    ),
    stt=inference.STT(
        model="assemblyai/u3-rt-pro",
        extra_kwargs={"min_turn_silence": 100, "max_turn_silence": 1000},
    ),
    # ... vad (auto-provisioned), llm, tts, etc.
)
```

**Node.js**

```typescript
import { inference, voice } from '@livekit/agents';

const session = new voice.AgentSession({
  turnHandling: {
    turnDetection: 'stt',
    endpointing: { minDelay: 0 },
  },
  stt: new inference.STT({
    model: 'assemblyai/u3-rt-pro',
    modelOptions: { min_turn_silence: 100, max_turn_silence: 1000 },
  }),
  // ... vad (auto-provisioned), llm, tts, etc.
});
```

### Realtime LLM (`turn_detection="realtime_llm"`)

[Realtime models](https://docs.livekit.io/agents/models/realtime/) consume and produce speech directly, and most of them do their own server-side turn detection as part of that. You can choose to either use that model's built-in detection, or hand turn detection to LiveKit's turn detector instead.  **LiveKit recommends using the model's built-in detection where possible**.

**Use the model's built-in detection**

Turn detection settings should be applied to the model itself, not on the `AgentSession`. There's no standard set of realtime configuration parameters, and capabilities vary from provider to provider. Consult your provider's documentation for the specifics (for example, [Gemini Live](https://docs.livekit.io/agents/models/realtime/gemini/#turn-detection) or [OpenAI Realtime](https://docs.livekit.io/agents/models/realtime/openai/#turn-detection)).

| Option                                   | Description                                                    |
| ---------------------------------------- | -------------------------------------------------------------- |
| `turn_detection="realtime_llm"`          | Hands end-of-turn detection to the realtime provider (default) |
| Realtime model turn detection parameters | Each provider has its own turn detection configuration.        |

Note: when the model handles detection, most of LiveKit's interruption options are ignored, so they should not be specified.

The example below configures the OpenAI Realtime API's server VAD:

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions
from livekit.plugins.openai import realtime
from openai.types.beta.realtime.session import TurnDetection

session = AgentSession(
    turn_handling=TurnHandlingOptions(
        # the default for realtime models; shown for clarity
        turn_detection="realtime_llm",
    ),
    llm=realtime.RealtimeModel(
        turn_detection=TurnDetection(
            type="server_vad",
            threshold=0.7,
            prefix_padding_ms=300,
            silence_duration_ms=400,
        ),
    ),
    # ... tts, etc.
)
```

**Node.js**

```typescript
import { voice } from '@livekit/agents';
import * as openai from '@livekit/agents-plugin-openai';

const session = new voice.AgentSession({
  turnHandling: {
    // the default for realtime models; shown for clarity
    turnDetection: 'realtime_llm',
  },
  llm: new openai.realtime.RealtimeModel({
    turnDetection: {
      type: 'server_vad',
      threshold: 0.7,
      prefix_padding_ms: 300,
      silence_duration_ms: 400,
    },
  }),
  // ... tts, etc.
});
```

**Use the LiveKit turn detector**

If your realtime model lets you disable its internal turn detection, you can use LiveKit's [audio-based turn detector](#livekit-turn-detector) instead (described earlier in this guide). As noted in the [turn detector docs](https://docs.livekit.io/agents/logic/turns/turn-detector/#audio-realtime), it works on audio directly, so it does not need a separate STT, unlike the older text-based detector. The mechanism for disabling the model's own detection is provider-specific; for the OpenAI Realtime API, for example, you set `turn_detection=None`.

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions, inference
from livekit.plugins import openai

session = AgentSession(
    turn_handling=TurnHandlingOptions(
        turn_detection=inference.TurnDetector(),
    ),
    llm=openai.realtime.RealtimeModel(
        voice="alloy",
        turn_detection=None,  # hand turn detection to the LiveKit audio model
    ),
)
```

**Node.js**

```typescript
import { inference, voice } from '@livekit/agents';
import * as openai from '@livekit/agents-plugin-openai';

const session = new voice.AgentSession({
  turnHandling: {
    turnDetection: new inference.TurnDetector(),
  },
  llm: new openai.realtime.RealtimeModel({
    voice: 'alloy',
    turnDetection: null, // hand turn detection to the LiveKit audio model
  }),
});
```

### VAD only (`turn_detection="vad"`)

Use this mode when your language isn't among the [LiveKit turn detector's supported languages](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-turn-detector), or for simple, command-style interactions where short, predictable utterances do not need semantic end-of-turn detection. Outside those cases it's usually not the right choice: VAD-only detection relies on silence alone to decide the user has finished.

To understand more about which VAD is used, see the earlier section on [VAD configuration](#vad-configuration).

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions

session = AgentSession(
    turn_handling=TurnHandlingOptions(turn_detection="vad"),
    # VAD is auto-provisioned; ... stt, tts, llm, etc.
)
```

**Node.js**

```typescript
import { voice } from '@livekit/agents';

const session = new voice.AgentSession({
  turnHandling: { turnDetection: 'vad' },
  // VAD is auto-provisioned; ... stt, tts, llm, etc.
});
```

**VAD configuration options**

Specifying `endpointing.min_delay` acts as a floor on top of the VAD's own silence window, so the effective wait after the user stops is `max(VAD silence, min_delay)`. The other endpointing options have no effect in this mode.

The VAD-specific configuration for the bundled inference VAD is provided in the [API reference](https://docs.livekit.io/reference/python/livekit/agents/inference/vad.html).

### Manual (`turn_detection="manual"`)

Use manual turn detection only when you need full control over when turns start and end, for example a push-to-talk workflow. You're responsible for committing and clearing turns and for interrupting the agent, so it requires extra code on your side. The [manual turn control docs](https://docs.livekit.io/agents/logic/turns#manual) include a complete example to build from.

## Interruption configuration

[Interruption handling](https://docs.livekit.io/agents/logic/turns#interruptions) decides what the agent does when the user starts speaking over it. Handling this well makes an agent feel natural, so it's worth configuring carefully.

### Enabling interruption handling

By default, the agent can be interrupted when the user speaks, but you can disable interruptions entirely if needed. When enabled, there are two modes: `"adaptive"` and `"vad"`.

| Option                     | Description                                                                                                                                                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled` (default `True`) | Whether the agent can be interrupted at all. Set to `False` to make it uninterruptible.                                                                                                                                               |
| `mode: "adaptive"`         | [Adaptive mode](https://docs.livekit.io/agents/logic/turns/adaptive-interruption-handling) uses an audio model that distinguishes real barge-ins from backchannels using acoustic cues. Recommended, and the default where available. |
| `mode: "vad"`              | Any detected speech ([VAD](https://docs.livekit.io/agents/logic/turns/vad)) interrupts the agent. Simple and always available, but will feel less natural compared with adaptive mode.                                                |

<div className="text-sm">
  **Caveats:**

  - If you are using a realtime model running its own server-side detection, you must not disable interruption handling.
  - Refer to the [adaptive interruption handling](https://docs.livekit.io/agents/logic/turns/adaptive-interruption-handling/) documentation for the default mode used, which depends on how you host your agent.
</div>

### Configuring interruption handling

Interruptible agents have a few more options to fine-tune behavior. A **false interruption** is when VAD hears speech and stops the agent but no transcript materializes (a cough, or background noise); by default the agent waits out a silence window and then resumes where it left off.

For further detail on these configuration options, see the [documentation](https://docs.livekit.io/reference/agents/turn-handling-options#interruptionoptions):

| Option                                              | Applies to             | Description                                                                                                                                                                                                                                                |
| --------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `false_interruption_timeout`                        | VAD                    | Silence to wait after an interruption before classifying it as false.                                                                                                                                                                                      |
| `resume_false_interruption` (default `True`)        | VAD                    | Whether to resume the agent's speech after a false interruption.                                                                                                                                                                                           |
| `backchannel_boundary`                              | Adaptive only          | A cooldown window at each turn edge so genuine corrections and late-arriving transcripts aren't discarded as backchannels. See [turn boundary cooldown](https://docs.livekit.io/agents/logic/turns/adaptive-interruption-handling#turn-boundary-cooldown). |
| `min_words` (requires STT)                          | VAD and Adaptive       | Minimum word count before interrupting. Set above `0` to require actual content.                                                                                                                                                                           |
| `min_duration`                                      | VAD and Adaptive       | Minimum speech duration to register as an interruption, filtering brief sounds.                                                                                                                                                                            |
| `discard_audio_if_uninterruptible` (default `True`) | Uninterruptible agents | Drop buffered user audio while the agent is speaking and can't be interrupted.                                                                                                                                                                             |

<div className="text-sm">
  **Caveat:** Although adaptive mode is designed to avoid false interruptions in the first place, there's a nuance here. Some options that apply only to **VAD** are technically applicable to the adaptive model in the event of a misclassification.
</div>

A typical adaptive configuration looks like this:

**Python**

```python
from livekit.agents import AgentSession, TurnHandlingOptions, inference

session = AgentSession(
    turn_handling=TurnHandlingOptions(
        turn_detection=inference.TurnDetector(),
        interruption={
            "enabled": True,  # the default; can be omitted
            "mode": "adaptive",
        },
    ),
    # ... stt, llm, tts, vad
)
```

**Node.js**

```typescript
import { inference, voice } from '@livekit/agents';

const session = new voice.AgentSession({
  turnHandling: {
    turnDetection: new inference.TurnDetector(),
    interruption: {
      enabled: true, // the default; can be omitted
      mode: 'adaptive',
    },
  },
  // ... stt, llm, tts, vad
});
```

### User turn limits

Interruptions are user-initiated; user turn limits are the mirror image, letting the agent cut in on the user. [User turn limits](https://docs.livekit.io/agents/logic/turns#user-turn-limit) are disabled by default, but you can configure them to stop a user from monologuing and monopolizing the conversation.

| Option                       | Description                                                                                                                                                                                                                                                                                                         |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user_turn_limit`            | Specify this key to enable user turn limits. Counts accumulate across consecutive user turns and reset only when the agent starts speaking. When a limit is crossed, the framework calls the agent's customizable [`on_user_turn_exceeded`](https://docs.livekit.io/agents/logic/nodes#on_user_turn_exceeded) hook. |
| `max_words` (default off)    | Maximum accumulated word count before the agent cuts in.                                                                                                                                                                                                                                                            |
| `max_duration` (default off) | Maximum accumulated speaking time before the agent cuts in. Python uses seconds, Node.js uses milliseconds.                                                                                                                                                                                                         |

**Python**

```python
session = AgentSession(
    turn_handling={"user_turn_limit": {"max_words": 100, "max_duration": 30.0}},
)
```

**Node.js**

```typescript
const session = new voice.AgentSession({
  turnHandling: { userTurnLimit: { maxWords: 100, maxDuration: 30_000 } },
});
```

***

## Other related configuration

The following settings are related to turn detection and interruption handling but don't control them directly. For more on any of these, follow the associated docs link.

| Setting                    | Description                                                                                                                                                           | Docs                                                                                           |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Noise cancellation         | Cleaning the input audio before VAD and STT improves both turn detection and transcription quality; see also our [noise cancellation blog](/blog/noise-cancellation). | [More information](https://docs.livekit.io/transport/media/noise-cancellation)                 |
| Preemptive generation      | The LLM (and optionally TTS) starts generating before the turn is confirmed to shave latency, cancelling if the turn continues. On by default.                        | [More information](https://docs.livekit.io/agents/multimodality/audio#preemptive-generation)   |
| STT language               | The language the STT reports selects the LiveKit turn detector's per-language threshold; pin it to force a specific language.                                         | [More information](https://docs.livekit.io/agents/models/stt#language-codes)                   |
| Diarization                | Speaker labels for multi-party rooms, available on Deepgram and AssemblyAI and used with `MultiSpeakerAdapter`.                                                       | [More information](https://docs.livekit.io/agents/models/stt#speaker-diarization)              |
| VAD `activation_threshold` | When using STT endpointing, align it with the STT's own VAD threshold so barge-in and turn-end behavior stay consistent.                                              | [More information](https://docs.livekit.io/reference/python/livekit/agents/inference/vad.html) |

***

## Common issues and resolutions

If your issue isn't covered by the [Turn-taking tuning troubleshooting table](https://docs.livekit.io/agents/logic/turns/tuning#troubleshooting) in our docs, some additional issues and resolutions are given below.

<Collapsible name="faq" summary="With turn_detection set to stt, the agent pauses several seconds before responding, even after a simple 'hello'" defaultOpen={false}>
  If you are using `turn_detection="stt"`, be sure to set `endpointing.min_delay` to `0`. As detailed earlier in this article, the `min_delay` you specify here will interfere with the STT's own minimum endpointing delay. Alternatively, switch to the LiveKit [turn detector](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-turn-detector) to see if you have better results.
</Collapsible>

<Collapsible name="faq" summary="Does LiveKit's audio-based turn detector work on 8 kHz telephony audio?" defaultOpen={false}>
  Yes. The [audio-based turn detector](https://docs.livekit.io/agents/logic/turns/turn-detector#audio-turn-detector) resamples input to 16 kHz internally, so narrowband PSTN audio is supported, though it's worth validating on your own call traffic. Noise cancellation runs before the detector, so, if using Krisp, be sure to use their telephony-tuned model for phone calls.
</Collapsible>

<Collapsible name="faq" summary="The agent repeats the same phrase twice within a single turn" defaultOpen={false}>
  On noisy lines this is usually false-interruption pause-and-resume, not preemptive generation. VAD detects speech mid-response (a cough, line noise) but no transcript materializes, so the framework pauses, waits out `false_interruption_timeout`, then resumes, replaying part of the utterance. Switch `interruption.mode` to [`"adaptive"`](https://docs.livekit.io/agents/logic/turns/adaptive-interruption-handling) so stray noise doesn't trigger the pause, raise `interruption.min_duration` / `min_words` to filter brief sounds, and add telephony-tuned noise cancellation.
</Collapsible>

<Collapsible name="faq" summary="On a realtime model, my turn detection and interruption settings seem to be ignored" defaultOpen={false}>
  When a realtime model runs its own server-side turn detection, most of LiveKit's [`InterruptionOptions`](https://docs.livekit.io/reference/agents/turn-handling-options#interruptionoptions) are ignored; tune detection on the model instead.
</Collapsible>

<Collapsible name="faq" summary="A turn-taking problem is hard to reproduce by feel. How do I debug it?" defaultOpen={false}>
  Replay the session in [agent observability](https://docs.livekit.io/testing/observability/insights) and inspect the trace. It shows exactly when turns were committed and interruptions fired, which is usually faster than examining logs.
</Collapsible>