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

# Turn Detection

> Understand when a user is truly finished speaking with semantic turn-detection models.

Timing matters. VAD detects silence; turn detection reads meaning so your agent knows when to respond and when to keep listening.

## Echo Turn Detector

Zero Runtime's turn detector is **Echo**, a server-hosted model you pass to your `Pipeline` as the `turn_detector`. It runs on the **Zero Runtime Inference Gateway** through the `TurnDetector` class, so nothing is downloaded to your machine. Authentication requires `ZERORUNTIME_AUTH_TOKEN`.

Pick `echo-small` for speed, `echo-large` for accuracy, or `echo-omni` for the widest language support.

<Note>
  VAD detects **that** speech is happening; the turn detector decides **when** the turn is over.
</Note>

### How It Works

As the user speaks, VAD detects the speech and STT produces a transcript. After each user utterance, the latest transcript is sent to the Inference Gateway, where the selected Echo model classifies the turn into one of four states:

| State | Meaning |
| :- | :- |
| `Complete` | The user has finished their turn. |
| `Incomplete` | The user is still mid-sentence or not finished yet. |
| `Backchannel` | A short acknowledgement (e.g. "uh-huh", "okay okay"). |
| `Wait` | The user wants the agent to hold (e.g. "wait a minute", "hold on"). |

`echo-omni` works the same way, but it also listens to the audio. It reads the speech and the transcript of the same turn together, so it catches what was said and how it was said at once: the trailing pitch, the hesitation, the clipped "mm-hm" that was never a turn at all. It returns one prediction per turn, with a confidence score, in under 80 ms.

Per turn it takes:

| Input | Description |
| :- | :- |
| `Audio` | The speech segment for the turn |
| `Transcript` | The finalized transcript of that same segment |
| `Language` | One of the 27 supported codes |

### Models

All three share the same four states. They differ in what they read and in the speed/accuracy trade-off:

| Model ID | Reads | Languages | Best For |
| :- | :- | :- | :- |
| `echo-small` | Text | 12 | Lowest latency, most responsive |
| `echo-large` | Text | 12 | Highest accuracy on the transcript |
| `echo-omni` | Audio + text | 27 | Widest language coverage |

### Supported Languages

`echo-small` and `echo-large` take no `language` parameter; they work across their 12 languages as they are. Only `echo-omni` needs one: pass a code from the table below to its `language` parameter.

| Language | Code | Echo Small | Echo Large | Echo Omni |
| :- | :- | :- | :- | :- |
| Arabic | `ar` | - | - | Yes |
| Bengali | `bn` | Yes | Yes | Yes |
| Chinese | `zh` | - | - | Yes |
| Danish | `da` | - | - | Yes |
| Dutch | `nl` | - | - | Yes |
| English | `en` | Yes | Yes | Yes |
| Finnish | `fi` | - | - | Yes |
| French | `fr` | Yes | Yes | Yes |
| German | `de` | Yes | Yes | Yes |
| Gujarati | `gu` | Yes | Yes | Yes |
| Hindi | `hi` | Yes | Yes | Yes |
| Indonesian | `id` | - | - | Yes |
| Italian | `it` | Yes | Yes | Yes |
| Japanese | `ja` | - | - | Yes |
| Korean | `ko` | - | - | Yes |
| Marathi | `mr` | Yes | Yes | Yes |
| Norwegian | `no` | - | - | Yes |
| Polish | `pl` | - | - | Yes |
| Portuguese | `pt` | - | - | Yes |
| Russian | `ru` | - | - | Yes |
| Spanish | `es` | Yes | Yes | Yes |
| Tamil | `ta` | Yes | Yes | Yes |
| Telugu | `te` | Yes | Yes | Yes |
| Turkish | `tr` | - | - | Yes |
| Ukrainian | `uk` | - | - | Yes |
| Urdu | `ur` | Yes | Yes | Yes |
| Vietnamese | `vi` | - | - | Yes |

### Usage

Set your auth token, then construct `TurnDetector` with the model you want. Only `echo-omni` takes a `language`:

<CodeGroup>
  ```python Python theme={null}
  # Set ZERORUNTIME_AUTH_TOKEN in your environment.

  from zeroruntime.inference import TurnDetector

  # Fastest, lowest latency
  turn_detector = TurnDetector(model="echo-small")

  # Higher accuracy
  turn_detector = TurnDetector(model="echo-large")

  # Audio + text, 27 languages
  turn_detector = TurnDetector(model="echo-omni", language="en")
  ```

  ```typescript Node JS theme={null}
  // Set ZERORUNTIME_AUTH_TOKEN in your environment.

  import { TurnDetector } from '@zeroruntime/js-sdk/inference';

  // Fastest, lowest latency
  const turn_detector = TurnDetector({ model: 'echo-small' });

  // Higher accuracy
  const turn_detector = TurnDetector({ model: 'echo-large' });

  // Audio + text, 27 languages
  const turn_detector = TurnDetector({ model: 'echo-omni', language: 'en' });
  ```
</CodeGroup>

### Performance

`echo-small` and `echo-large` are benchmarked on the [TURNS2K](https://huggingface.co/datasets/latishab/turns-2k) dataset against a leading third-party model, called **Baseline** here. Each sample is labeled **Complete** (user finished) or **Incomplete** (user still speaking).

| Metric | Echo-Small | Echo-Large | Baseline |
| :- | :- | :- | :- |
| Accuracy | 93.60% | 96.20% | 61.13% |
| Recall (Complete) | 97.31% | 96.50% | 32.83% |
| Specificity | 88.91% | 95.81% | 96.83% |
| F1 Score (Complete) | 0.9443 | 0.9659 | 0.4851 |

`echo-omni` is measured separately, on a multilingual set of 25,000+ utterances covering all four states. Accuracy holds across all 27 languages.

| Metric | Echo-Omni |
| :- | :- |
| Accuracy | 95.39% |
| Macro F1 | 0.9712 |
| F1 Score (Complete) | 0.9508 |

<Note>
  Results are measured on the benchmark datasets described above. Performance may vary depending on language, deployment configuration, user behavior, and application requirements.
</Note>

## End-of-Utterance Handling

End-of-Utterance (EOU) handling decides when the pipeline treats the user as finished speaking. In `ADAPTIVE` mode, the wait timeout adjusts based on confidence scores, so the agent waits longer when the user is hesitant and responds faster when intent is clear.

Configure it with `EOUConfig` in your pipeline options:

<CodeGroup>
  ```python Python theme={null}
  from zeroruntime import Pipeline, EOUConfig

  pipeline = Pipeline(
      # ... other config
      eou_config=EOUConfig(
          mode="ADAPTIVE",
          min_max_speech_wait_timeout=[0.5, 0.8]
      )
  )
  ```

  ```typescript Node JS theme={null}
  import { Pipeline, EOUConfig } from '@zeroruntime/js-sdk';

  const pipeline = Pipeline({
    // ... other config
    eou_config: EOUConfig({
      mode: 'ADAPTIVE',
      min_max_speech_wait_timeout: [0.5, 0.8],
    }),
  });
  ```
</CodeGroup>

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `mode` | `"DEFAULT"` \| `"ADAPTIVE"` | `"DEFAULT"` | `ADAPTIVE` uses LLM confidence to adjust wait time. |
| `min_max_speech_wait_timeout` | `[float, float]` | `[0.5, 0.8]` | Min and max wait time in seconds after speech ends. |

### How the modes behave

* `DEFAULT`: Fixed wait within your min–max range. For clear utterances you respond near the minimum; for hesitations you wait near the maximum.
* `ADAPTIVE`: The wait scales with confidence. Low confidence (hesitation) increases wait; high confidence shortens it, always clamped to your min–max.

## What's Next

<CardGroup cols={2}>
  <Card title="VAD and Interruptions" icon="waveform-lines" href="/runtime-sdk/build/turn-detection-and-interruptions/vad-and-interruptions">
    Pair turn detection with Silero VAD.
  </Card>

  <Card title="De-noise" icon="headphones" href="/runtime-sdk/build/turn-detection-and-interruptions/denoise">
    Feed the detector cleaner input audio.
  </Card>
</CardGroup>

## References

<Tabs>
  <Tab title="Python">
    #### Examples

    <CardGroup cols={2}>
      <Card title="Cascade Basic" icon="github" href="https://github.com/ZeroRuntimeAI/zeroruntime-python-examples/blob/main/getting_started/cascade_basic.py">
        Voice agent with a turn detector configured.
      </Card>
    </CardGroup>
  </Tab>

  <Tab title="Node JS">
    #### Examples

    <CardGroup cols={2}>
      <Card title="Cascade Basic" icon="github" href="https://github.com/ZeroRuntimeAI/zeroruntime-js-examples/blob/main/getting_started/cascade_basic.ts">
        Voice agent with a turn detector configured.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.