Point your agent at a single duplex speech-to-speech model and skip the cascade entirely. Instead of chaining speech-to-text, a language model, and text-to-speech — three network hops, three queues, three places to add latency — the caller’s audio streams straight into one model that listens and speaks on the same bidirectional connection. Fewer hops means the agent starts replying sooner and interrupts feel instant. You wire it the same way you wire any other runtime: name a provider, a model, and a voice in the agent config. TeleQuick Voice opens the realtime session on the first inbound audio frame, forwards each PCM chunk, and streams the model’s spoken response back onto the call — resampling to and from the provider’s expected rate for you.

Speech-to-speech vs. cascade

Not every agent should be speech-to-speech. A duplex model is the fastest and most natural option, but a cascade (see BYO ASR / LLM / TTS) gives you independent control of each stage — swap the language model without touching the voice, run a fine-tuned transcriber, or mix vendors. Choose duplex for latency and naturalness; choose the cascade for control and model choice.

Supported models

ProviderConfig providerStatusNotes
OpenAI RealtimeopenaiShippedServer-side VAD, function calling, per-response greeting.
Gemini LivegeminiShippedPrebuilt voices (Aoede, Charon, Fenrir, Kore, Puck); function calling.
xAI Grok Voicexai / grokShippedOpenAI-Realtime-compatible; server VAD + function calling.
Self-hosted duplexomniPreviewBring your own open-weights duplex model over a realtime WebSocket on your GPUs — see Self-Hosted Inference.
The self-hosted duplex path is wired end-to-end in the runtime but has not yet been verified live against production carriers. Treat it as preview: validate turn-taking and latency on a staging number before you route real traffic.

Configure a duplex agent

1

Set the entry node to REALTIME

A duplex agent has a single node. Set entry_node: REALTIME and give it a provider, a model, and a voice. There is no separate ASR or TTS stage to configure.
# agent-config.yml
entry_node: REALTIME
pipeline:
  REALTIME:
    node_type: REALTIME
    provider: openai
    model: gpt-realtime          # sent via the dial URL, not session.update
    voice: shimmer               # alloy | shimmer | …
    instructions: |
      You are a friendly support agent for Acme. Keep replies short.
2

Supply per-tenant credentials

Each workspace supplies its own keys — they are stored per tenant and never shared across workspaces. Set them in the agent console at agent.telequick.dev, or via the control-plane API:
ProviderCredential
openaiOpenAI API key
geminiGemini API key
xai / grokxAI API key
omniEndpoint host (host[:port], default port 443) + optional bearer token
3

Deploy and test

Save the agent, point a number or trunk at it, and place a call. The runtime opens the realtime session on the first inbound frame; if the provider refuses the connection, the runtime logs it and the call falls back to a silent passthrough rather than dropping.

Turn-taking on a duplex model

For a REALTIME entry node, TeleQuick Voice defaults to server_vad — the provider does its own endpointing and emits speech_started / speech_stopped, which the runtime wires to barge-in so in-flight audio is cut the instant the caller talks. You do not add a local turn detector.
Some self-hosted duplex models have no server-side VAD. In that case the runtime owns the turn boundary with a local detector and commits the input buffer when the caller finishes — which also keeps backchannels (“ok”, “mhm”) from waking the model. See Turn Detection & Barge-In for the knobs.

Greeting on inbound calls

Some carrier SBCs will not send you RTP until they hear yours. On an inbound call the runtime asks the model to speak first so the carrier’s media path opens — the model greets from your instructions, or you can pin an exact opening line. This behavior is on by default for inbound direct-media calls; no extra config is required.

Tools mid-conversation

The shipped realtime adapters advertise your tools in the session bootstrap, so the model can call HTTP and MCP tools during a spoken turn and speak the result. Configure them exactly as you would for a cascade — see Tool Calling.

Session budgets

Every realtime session is bounded so a stuck provider can’t run forever:
  • Connect timeout — the handshake is given 5 seconds before the runtime gives up and falls back.
  • Max session — sessions are closed at a 15-minute ceiling even if the provider hasn’t. Tune lifetime, idle re-engage, and hangup budgets on Session Lifecycle.

Next steps

Cascade instead

Wire independent ASR, LLM, and TTS providers when you want per-stage control.

Turn detection

Tune barge-in, endpointing, and backchannel handling.

Self-hosted inference

Serve your own duplex model on-prem with the inference control plane.

All runtime knobs

Models, codecs, budgets, and guardrails in one reference.