Skip to main content
Experimental Feature: This feature is currently in testing, so stability is not guaranteed.
Traditional Voice Activity Detection (VAD) is excellent for segmenting speech based on pauses, but it can often break a single cohesive idea into multiple smaller transcripts if the speaker pauses to think. Many LLMs are hot to interrupt and respond to a user when a transcription is sent even when turn skipping tools are enabled. The Thought Detection feature solves this by analyzing the semantic and vocal content of the speech in real-time to determine when a user has finished expressing a complete thought, leading to less interruptions and a better voice assistant interaction.

How It Works

  1. Enable Thought Detection by sending a JSON start message on the WebSocket that includes detect_thoughts: true. You can also tune end_thought_eagerness and force_complete_time here.
  2. As you stream audio, the server transcribes it internally but does not immediately send back a transcript after every pause. Instead, it buffers these transcripts and keeps them as one longer string.
  3. Only when the model determines a thought is complete does the server send a single message of type complete_thought containing the full text of that idea.
The moment a thought is considered “complete” is tunable. Use end_thought_eagerness to make the detector more or less willing to close a thought, and force_complete_time to set a drop-dead timeout (in seconds) that will force emission of the current buffered thought after silence. This is helpful if a finished turn is incorrectly identified as an unfinished turn.

Enabling the Feature

Start Message Fields

Tuning When a Thought Ends

These fields belong in the initial start message you send after opening the WebSocket. end_thought_eagerness (string, default: “medium”) Controls how aggressively the model closes a thought. Allowed values: “low”, “medium”, “high”. force_complete_time (number, default: 2.0) A drop-dead timer in seconds. If the model has not marked the current thought complete and the user has gone silent, the server will force-emit the buffered text once this many seconds have elapsed. Range: 1.0–60.0 seconds. Values outside this range are rejected. Note: You still enable the feature with detect_thoughts: true. These extra fields only tune when the thought ends.

Getting Started

Install the SDK mic addon

Python SDK Example

An SDK Example (mic_ws_continuous_thought_detection_sdk.py)
Don’t want to use the SDK? Here are some full code samples:
This client script includes a simple ENABLE_THOUGHT_DETECTION flag. When set to true, it automatically adjusts the WebSocket URL and the VAD settings, then listens for the specific complete_thought message from the server.
A Full Example (mic_ws_thought_detection.py)

Example Interaction

Here is how the experience differs when speaking the same sentence: “I was thinking about the quarterly report… and it seems like the numbers for Q3 are a bit lower than we expected.”

Without Thought Detection

The application receives multiple, fragmented transcripts based purely on pauses.Received Transcripts:

With Thought Detection

The application receives a single, semantically complete transcript after the user finishes their entire point.Received Transcript:

Why is this useful?

Thought Detection helps AI voice agents to be more intuitive and realistic. It’s annoying for users to be interrupted by an overly enthusiastic LLM, and this is a simple solution to eliminate that from the start. It’s also useful for live transcriptions that have beautiful spacing out of the box. No more blocks of text!