Hot Reload
Edit an agent file while calls are in flight, and OpenRTC re-imports it and swaps every live session to the new class on its next turn. This is somethinglivekit-agents cannot do, because each of its sessions runs in its own OS
process. OpenRTC can, because in coroutine mode the agent class is an object in
shared memory.
Hot reload is coroutine-mode only (
isolation="coroutine", the default). Process
mode runs one subprocess per session and cannot swap a class in place. openrtc start never hot reloads; openrtc dev enables it by default.Enable it
How a reload happens
1
Detect
A debounced file watcher notices the edited module and hands the change to the reload coordinator.
2
Validate
The coordinator re-imports the file into a fresh module object and compiles it. Nothing is swapped until the import succeeds and a local
Agent subclass is found.3
Swap new sessions
The registered
AgentConfig.agent_cls is replaced, so every session that starts from now builds the new class.4
Re-bind live sessions
Each live session still on the old class is re-bound via livekit’s
AgentSession.update_agent, which blocks new turns and drains the in-flight one. The current turn finishes on the old class; the next turn runs the new. No WebSocket drop, no audio gap.Rollback safety
The whole point of hot reload is iteration speed, so a bad save must never poison the running pool.
A failed reload logs at
ERROR and leaves every live session exactly where it was.
Pinning critical flows
Some flows cannot tolerate a behavior change mid-session (payment confirmation, multi-step authentication). Wrap them so a reload skips that session until the block exits:is_pinned(session) reports the current
state.
Scope
- One agent is reloaded at a time.
- Only agents with a known
source_path(fromdiscover()oradd(..., source_path=...)) are watchable; agents registered with a bare class are not. - Pinning is per session and manual (no pin-by-predicate).

