AgentPool API
Imports
ProviderValue is str | Any: provider ID strings (for example
openai/gpt-4.1-mini) or concrete LiveKit plugin instances (for example
openai.STT(...)).
AgentConfig
AgentConfig is returned from AgentPool.add() and represents a registered
LiveKit agent configuration.
source_path is set when an agent is registered via discover() (path to
the module file) or when add(..., source_path=...) is used. It enables
tooling such as the openrtc list --resources footprint output and is included
in pickle state for worker processes.
AgentDiscoveryConfig
AgentDiscoveryConfig stores optional metadata attached to an agent class with
@agent_config(...).
agent_config(...)
agent_config(...) to attach discovery metadata to a standard LiveKit
Agent subclass.
AgentPool(...)
Create a pool that manages multiple LiveKit agents in one worker process.
Constructor kwargs
| Argument | Type | Default | Notes |
|---|---|---|---|
default_stt / default_llm / default_tts | ProviderValue | None | None | Provider used when add() / discover() omits one. |
default_greeting | str | None | None | Greeting used when none is configured per agent. |
isolation | Literal["coroutine", "process"] | "coroutine" | Worker isolation mode. "coroutine" is the v0.1 default and runs every session as an asyncio.Task in one worker process; "process" preserves v0.0.17 behavior (one OS subprocess per session via livekit-agents’s ProcPool). See Architecture → Coroutine-mode lifecycle. |
max_concurrent_sessions | int | 50 | Coroutine-mode backpressure threshold. The worker reports current_load >= 1.0 to LiveKit dispatch once this many sessions are in flight, so new jobs route elsewhere. Must be >= 1. Ignored in process mode (livekit-agents’ own load math applies there). |
consecutive_failure_limit | int | 5 | After this many non-SUCCESS session terminations in a row, the coroutine pool’s supervisor schedules aclose() so the deployment platform restarts the worker (bounded blast radius for systemic bugs). Must be >= 1. Ignored in process mode. |
Read-only properties
| Property | Returns | Notes |
|---|---|---|
pool.isolation | Literal["coroutine", "process"] | The configured isolation mode (set in the constructor). |
pool.max_concurrent_sessions | int | The configured backpressure threshold. |
pool.consecutive_failure_limit | int | The configured supervisor threshold. |
Migration note
Existing code that doespool = AgentPool() keeps working but now runs every
session in coroutine mode by default. Pass isolation="process" to stay on the
v0.0.17 process-per-session model. The full migration block lives in the v0.1.0
section of the changelog.
server
AgentServer instance. Under
isolation="coroutine", this is an internal _CoroutineAgentServer subclass
that swaps livekit.agents.ipc.proc_pool.ProcPool for an openrtc.execution.coroutine.CoroutinePool
during run(). Under isolation="process", this is the vanilla
livekit.agents.AgentServer.
add()
Agent subclass.
Optional source_path records the filesystem path to the agent’s module
(used for discovery metadata and footprint reporting).
Validation rules
namemust be a non-empty string after trimming whitespace- names must be unique
agent_clsmust be a subclass oflivekit.agents.Agentagent_clsmust be defined at module scope for spawn-based worker runtimes
Session options
session_kwargsforwards a mapping of keyword arguments toAgentSession- direct
**session_optionsare also forwarded toAgentSession - when the same key appears in both places, the direct keyword argument wins
- by default, OpenRTC supplies
turn_handlingwith multilingual turn detection and VAD-based interruption unless you override it explicitly
Returns
AnAgentConfig instance for the registration.
Raises
ValueErrorfor an empty or duplicate nameTypeErrorifagent_clsis not a LiveKitAgentsubclass
discover()
Agent
subclass, and registers it.
Discovery behavior:
- skips
__init__.py - skips files whose stem starts with
_ - uses
@agent_config(...)metadata when present - otherwise uses the filename stem as the agent name
- falls back to pool defaults for omitted provider and greeting fields
- preserves file-backed agent loading so discovered agents work with
livekit dev
Raises
FileNotFoundErrorif the directory does not existNotADirectoryErrorif the path is not a directoryRuntimeErrorif a module cannot be imported or defines no localAgentsubclass
list_agents()
get()
AgentConfig.
Raises
KeyErrorif the agent name is unknown
remove()
AgentConfig.
Raises
KeyErrorif the agent name is unknown
run()
server to livekit.agents.cli.run_app. Under
isolation="coroutine" (the v0.1 default), the worker hosts every session as
an asyncio.Task inside one process; under isolation="process" it spawns
one OS subprocess per session, matching v0.0.17 behavior.
Raises
RuntimeErrorif called before any agents are registered. The same guard fires inside_prewarm_workerif a worker process spawns with an empty registry.
runtime_snapshot()
--metrics-json-file, and kind: "snapshot" lines
in --metrics-jsonl output. It includes:
- resident memory metadata
- registered and active session counts
- per-agent active session counts
- total sessions started
- session failure count
- last routed agent
- a best-effort shared-worker savings estimate
drain_metrics_stream_events()
session_started, session_finished, session_failed). The OpenRTC CLI calls
this when writing --metrics-jsonl; most applications can ignore it.
Routing behavior
AgentPool resolves the active agent in this order:
ctx.job.metadata["agent"]ctx.job.metadata["demo"]ctx.room.metadata["agent"]ctx.room.metadata["demo"]- room-name prefix matching such as
restaurant-call-123 - the first registered agent
ValueError.
Example
See also
- Architecture → Coroutine-mode lifecycle
for the per-session task lifecycle, supervisor, drain, and
current_loadsemantics. - Density benchmark (v0.1) for the
≥50-sessions-per-worker numbers backing the default
max_concurrent_sessions. - Changelog for the v0.1.0 migration block.
