# Session Lifecycle

> From connect to teardown: the runtime session state machine, its timeouts and budgets, and the idle guardrails that hang up a stuck call.

A **session** is one run of the conversational loop. The runtime picks up a
connected call and greets the caller. It then cycles through listen → think →
speak. The caller can interrupt at any point. The loop runs until someone
hangs up or a guardrail fires. You describe the agent. The runtime drives the
states. This page maps those states, the clocks that bound them, and the
guardrails. The guardrails prevent a session that runs forever or sits silent
on your bill.

Everything here runs **inside the voice gateway**, in the process that
terminates the call's media, pinned to the core that owns the call. Each
session gets its own state, local to that core. Nothing is shared across
calls, and turn-taking never waits on a lock. Audio flows through the runtime
as a single **8 kHz PCM16** stream. This is true for a caller on a phone
trunk and for a caller on a browser QUIC connection.

## The state machine

```
        ┌──────────────┐
        │  Connecting  │  media negotiated, session allocated
        └──────┬───────┘
               ▼
        ┌──────────────┐
        │   Greeting   │  agent speaks first (optional opening line)
        └──────┬───────┘
               ▼
   ┌─▶ ┌──────────────┐
   │   │  Listening   │  VAD watches for end-of-utterance
   │   └──────┬───────┘
   │          ▼
   │   ┌──────────────┐
   │   │   Thinking   │  model runs (cascade LLM, or duplex model)
   │   └──────┬───────┘        ▲
   │          ▼                │  caller speaks over the agent
   │   ┌──────────────┐        │  → confirmed barge-in cancels
   │   │   Speaking   │────────┘     and jumps back to Listening
   │   └──────┬───────┘
   │          │ turn complete
   └──────────┘
               │  hangup, transfer, or guardrail
               ▼
        ┌──────────────┐
        │   Ending     │  cancel in-flight work, flush, emit events
        └──────────────┘
```

Listening, Thinking, and Speaking form the turn loop. A **duplex**
speech-to-speech model collapses Thinking and Speaking into one streaming
step. But the states around it — greeting, barge-in, guardrails, and
teardown — are identical.

## Walking a session

  1. **Connecting**
The call arrives from a phone caller on a SIP trunk, or from a browser
    microphone over QUIC. The gateway negotiates the call's media and decodes
    it to the 8 kHz PCM16 contract. The runtime allocates a session on the
    call's core. It loads the agent definition. It opens the provider
    connection (a streaming ASR/LLM/TTS cascade, or a single duplex realtime
    session). If the provider connection does not open within its timeout,
    the session ends here and the runtime releases the call.
  2. **Greeting**
If the agent has an opening line, the agent speaks first. The runtime
    enters **Speaking** before it hears anything. If you leave the greeting
    empty, the agent starts in **Listening** and waits for the caller to talk
    first. This is the usual shape for inbound support lines, where the
    caller already knows why they called.
  3. **Listening**
The runtime watches the inbound audio for end-of-utterance. On a cascade
    pipeline, an **on-device VAD** marks the boundary. On a cloud duplex
    model, the provider's own end-of-turn detection can mark it. A
    minimum-duration gate filters out backchannels ("mhm", "yeah"). Thus a
    caller's acknowledgement never counts as a turn. When the caller
    finishes, the runtime hands the turn's audio to the model. The session
    moves to **Thinking**. See
    [turn detection & barge-in](/modalities/voice/concepts/turn-detection)
    for how the runtime detects and tunes the boundary.
  4. **Thinking**
The model runs. In a cascade, this is the language-model call, fed by the
    transcript. In a duplex model, the audio streams straight in. Each stage
    has its own timeout budget. If a model stalls past its budget, the
    runtime cancels the stage. It does not leave the caller in dead air. See
    [Timeouts and budgets](#timeouts-and-budgets).
  5. **Speaking**
The runtime synthesises the reply (cascade TTS) or streams it out
    (duplex) as 8 kHz PCM16. It paces the audio into 20 ms frames. It encodes
    the audio for the caller's transport: G.711 back to a phone trunk, Opus
    back to a browser. The runtime stays ready to interrupt. The caller can
    barge in at any moment during Speaking.
  6. **Loop or end**
When the turn completes, the session returns to **Listening** for the
    next turn. The session leaves the loop only when the caller hangs up,
    when the call transfers to a human, or when a guardrail fires. At that
    point, it enters **Ending**.

## Barge-in cancels a turn in flight

A caller who talks over the agent is not a new turn that waits politely. It
is an interrupt. When a barge-in is **confirmed**, the runtime cancels
whatever the agent does at that moment (Thinking or Speaking). It clears the
outbound audio buffer, so the agent goes quiet immediately. It jumps back to
**Listening** to catch what the caller actually says.

"Confirmed" is the important word. The runtime uses **hold-and-confirm**. The
onset of caller speech arms a *pending* barge. The barge fires only if speech
sustains past `barge_confirm_ms` (default **300 ms**). A short backchannel
ends before the window elapses, so it never cancels the agent. Set
`barge_confirm_ms: 0` for legacy immediate barge-in. The agent then cuts out
on the very first audio frame.

> **NOTE:**
> Whether a barge-in can actually cancel work already sent to a provider
>   depends on the provider. Cloud realtime and streaming TTS support
>   mid-flight cancel. A plain HTTP language model runs to completion
>   server-side, and the runtime can only silence the playback. The honest
>   per-provider scorecard lives in
>   [turn detection & barge-in](/modalities/voice/concepts/turn-detection#know-where-barge-in-actually-works).

## Timeouts and budgets

Every session runs against a set of clocks. The clocks make sure that one
stuck model, one runaway response, or one caller who wandered off never turns
into an open connection that bills forever.

| Budget | What it bounds | Default |
|--------|----------------|---------|
| Per-stage timeout | How long any single ASR / LLM / TTS or realtime step may run before the runtime cancels it | Tunable (millisecond budgets) |
| `max_output_tokens` | The ceiling on a single model response, so one turn cannot generate without bound | **4096** |
| `max_session` | The hard ceiling on total session wall-clock; the runtime tears the session down when the call hits it | **15 minutes** |

`max_output_tokens` was previously unbounded on the realtime path. It is now
capped by default. A single turn cannot run away. `max_session` is a hard
stop, not a warning. When the clock hits it, the runtime tears the session
down regardless of state.

> **WARNING:**
> A hard `max_session` ceiling ends a genuinely long call (a detailed
>   onboarding, a patient walkthrough) at the ceiling. Raise the ceiling for
>   agents that legitimately need longer sessions. But keep it finite. The
>   whole point is that no session runs forever.

### Changing budgets doesn't disturb live calls

The per-stage timeout budgets are runtime tunables. You can adjust and reload
them without a gateway restart and without dropped calls. Reloads are
**additive**. A session captures its timeout budgets at the moment of its
creation and keeps them for its whole life. Thus a reload only affects
sessions that start *after* it. No in-flight call ever has a clock changed
underneath it.

## Idle hangup guardrails

The most common way a voice session gets stuck is silence. The caller stops
talking, and the agent has nothing to respond to. Without a guardrail, the
session would sit there until `max_session` finally reaps it. The **idle
watchdog** handles this gracefully. It nudges the caller first. It then hangs
up.

When the caller is silent for `soft_prompt_s`, the runtime injects a
re-engagement prompt ("Are you still there?") and keeps listening. If silence
then continues to `hangup_s`, the runtime ends the session cleanly. Configure
the watchdog under the agent's turn-detection block:

```yaml
turn_detection:
  idle:
    soft_prompt_s: 20                      # nudge after this much silence
    hangup_s: 60                           # end the call after this much
    soft_prompt_text: "Are you still there?"
```

The idle watchdog is **on by default** on both pipeline shapes: the cascade
path and the cloud duplex (server-VAD) path. The defaults are above
(re-engage at 20 s, hang up at 60 s). Set the timings per agent. Lengthen
them for flows where a caller is expected to go quiet while they look
something up.

> **NOTE:**
> Default-on idle guardrails on the duplex realtime path are a recent
>   addition. The behaviour ships and is enabled by default. If you run a
>   duplex agent and want certainty about the exact re-engage and hangup
>   moments for your provider, check them against a test call before you rely
>   on them in production.

## Ending and teardown

A session leaves the loop for one of three reasons:

1. The caller hangs up.
2. The call is [handed off to a human](/modalities/voice/concepts/handoffs)
   or transferred.
3. A guardrail (`max_session` or the idle watchdog) fires.

Teardown is the same in each case. The runtime cancels any in-flight model
work. It closes the provider session. It flushes and stops the outbound audio
pacer. It releases the media leg. It frees the session's per-core state.

During teardown, the runtime emits the call's lifecycle transitions to the
events pipeline: answer, holds and resumes, transfer or REFER, and the final
end. It tags each event with the handler (AI or human) that owned that
segment. Those events power your call timelines and CDRs. See
[call lifecycle](/modalities/voice/transport-telephony/call-lifecycle) for
the telephony view. See
[call traces](/modalities/voice/observability/call-traces) for the
per-session timeline that you read after the fact.

## Related

  - **[Turn detection & barge-in](/modalities/voice/concepts/turn-detection)** — Learn how the runtime detects and tunes end-of-utterance and confirmed
    barge-in.
  - **[Runtime configuration](/modalities/voice/runtime/configuration)** — Every knob for budgets, guardrails, and turn timing in one reference.
  - **[Tool calling](/modalities/voice/runtime/tool-calling)** — Learn what happens to the loop when the model calls a tool mid-turn.
  - **[Call traces](/modalities/voice/observability/call-traces)** — Read a finished session's timeline, segment by segment.
