Frameworks
OpenRTC is a thin operational layer (registration, routing, shared prewarm, observability, drain) over a voice runtime. That runtime is a backend, chosen when you build the pool:import openrtc pulls neither framework. Each backend lives behind its own
extra and is imported only when you select it:
| Backend | Install | Agent shape |
|---|---|---|
livekit (default) | openrtc[livekit] | livekit.agents.Agent subclass |
pipecat | openrtc[pipecat] | pipeline builder callable |
pip install openrtc[...] hint.
What every backend shares
Whichever runtime you pick, OpenRTC gives you the same operator control plane:- Registration and routing.
pool.add(name, ...)registers an agent; each call is routed to one by the same precedence (custom router, then job / room metadata, then room-name prefix, then first registered). See Routing. - Shared prewarm. The worker loads the VAD and turn model once and shares them across every session, instead of building them per call.
- Observability. Every session emits the same start / end signals to the observers you pass to the pool, so metrics and cost / quality lanes stay wired across frameworks.
add, get, remove, and
list_agents.
livekit backend (default)
Agents are standardlivekit.agents.Agent subclasses, and the provider arguments
pass through to the session. This is the model in
Getting Started and
Coming from livekit-agents.
pipecat backend
A pipecat agent registers as a pipeline builder: a callable that, given the call’s view, returns the pipecat processors for that call. The builder owns the transport and the STT / LLM / TTS services (so the pool’s provider arguments, which are livekit-only, do not apply here). OpenRTC wraps routing, shared prewarm, and observability around it. The call view (PipecatCallView) carries the worker’s shared prewarm, so the
builder attaches the shared VAD and turn analyzer instead of building its own:
Registration side by side
- livekit
- pipecat
Status and boundaries
The pipecat backend’s per-call path (registration, routing, shared prewarm, dispatch, and observability) is complete and verified against real pipecat pipelines. The transport-serving front (accepting live calls over a transport and running a session per connection) is not yet wired:AgentPool(backend="pipecat").run() raises NotImplementedError documenting that
boundary. The livekit backend is complete and is the default.
Hot reload requires the livekit backend (requesting it on pipecat raises a clear
error). Session introspection is a livekit-backend feature as well; see
Hot reload and
Session introspection.