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

# Turn Tracking Observer

> Track conversation turns and events in your Pipecat pipeline

The `TurnTrackingObserver` monitors and tracks conversational turns in your Pipecat pipeline, providing events when turns start and end. It intelligently identifies when a user-bot interaction cycle begins and completes.

## Turn Lifecycle

A turn represents a complete user-bot interaction cycle:

1. **Start**: When the user starts speaking (or pipeline starts for first turn)
2. **Processing**: User speaks, bot processes and responds
3. **End**: After the bot finishes speaking and either:
   * The user starts speaking again
   * A timeout period elapses with no further activity

## Events

The observer emits two main events:

* **`on_turn_started`**: When a new turn begins
  * Parameters: `turn_number` (int)
* **`on_turn_ended`**: When a turn completes
  * Parameters: `turn_number` (int), `duration` (float, in seconds), `was_interrupted` (bool)

## Usage

The observer is automatically created when you initialize a `PipelineTask` with `enable_turn_tracking=True` (which is the default):

```python theme={null}
task = PipelineTask(
    pipeline,
    # Turn tracking is enabled by default
)

# Access the observer
turn_observer = task.turn_tracking_observer

# Register event handlers
@turn_observer.event_handler("on_turn_started")
async def on_turn_started(observer, turn_number):
    logger.info(f"Turn {turn_number} started")

@turn_observer.event_handler("on_turn_ended")
async def on_turn_ended(observer, turn_number, duration, was_interrupted):
    status = "interrupted" if was_interrupted else "completed"
    logger.info(f"Turn {turn_number} {status} in {duration:.2f}s")
```

## Configuration

You can configure the observer's behavior when creating a `PipelineTask`:

```python theme={null}
from pipecat.observers.turn_tracking_observer import TurnTrackingObserver

# Create a custom observer instance
custom_turn_tracker = TurnTrackingObserver(
    turn_end_timeout_secs=3.5,     # Turn end timeout (default: 2.5)
)

# Add it as a regular observer
task = PipelineTask(
    pipeline,
    observers=[custom_turn_tracker],
    # Disable the default one if adding your own
    enable_turn_tracking=False,
)
```

## Interruptions

The observer automatically detects interruptions when the user starts speaking while the bot is still speaking. In this case:

* The current turn is marked as interrupted (`was_interrupted=True`)
* A new turn begins immediately

## How It Works

The observer monitors specific frame types to track conversation flow:

* **StartFrame**: Initiates the first turn
* **UserStartedSpeakingFrame**: Starts user speech or triggers a new turn
* **BotStartedSpeakingFrame**: Marks bot speech beginning
* **BotStoppedSpeakingFrame**: Starts the turn end timeout

After a bot stops speaking, the observer waits for the configured timeout period. If no further bot speech occurs, the turn ends; otherwise, it continues as part of the same turn.

## Use Cases

* **Analytics**: Measure turn durations, interruption rates, and conversation flow
* **Logging**: Record turn-based logs for diagnostics and analysis
* **Visualization**: Show turn-based conversation timelines in UIs
* **Tracing**: Group spans and metrics by conversation turns
