Architecture Overview
At a high level:
- Client streams audio/text to
VoiceSession. - Transport handles live model IO (Gemini/OpenAI).
- Main agent decides tool calls and transfers.
- Tool layer executes inline/background work.
- Subagents handle long-running tasks.
- Events/hooks expose observability and integration points.
Realtime links: client media vs LLM transport
Two legs on the wire (Leg 1 = what integrators often build; Leg 2 = always inside your Bodhi server to the vendor):
text
[Browser or device] ─── Leg 1 ───> [App server / VoiceSession] ─── Leg 2 ───> [Gemini or OpenAI]There are three links in a typical deployment — not one monolithic “voice socket”:
- Client or device ↔ your Bodhi app server — capture, playback, and JSON control (and optional WebRTC signaling) on paths you own.
- App server ↔
VoiceSession— your server forwards WebSocket binary/JSON (or decoded PCM from an RTC bridge) into the framework. VoiceSession/LLMTransport↔ Gemini or OpenAI realtime — the vendor WebSocket(s); unchanged when you change how the browser talks to your server.
Framework option clientMedia: { kind: 'direct_rtc' } only affects link (1) (optional Opus RTP for audio when rtcAudio: 'werift_opus'). It does not replace link (3). See Transport and VoiceSession.
Key runtime modes
legacy: classic router-based orchestrationactor: actor-runtime orchestration
See Actor Runtime Pattern for details.
Main components
VoiceSession(session lifecycle and wiring)LLMTransportimplementationsToolExecutor+ routerAgentRouter/ transfer flow- Memory + history stores
- EventBus + hooks