Skip to main content

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 something livekit-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

Programmatically:

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.
Each reload logs a line you can watch on the dev console:

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:
A pinned session that missed a reload catches up to the newest class the next time it re-binds after being unpinned. is_pinned(session) reports the current state.

Scope

  • One agent is reloaded at a time.
  • Only agents with a known source_path (from discover() or add(..., source_path=...)) are watchable; agents registered with a bare class are not.
  • Pinning is per session and manual (no pin-by-predicate).
For the API surface, see AgentPool.