Architecture · Current architecture

Architecture

Trace a client action through authority, durable commit, independent delivery, work execution, and recovery.

Follow a customer sending a message while a transcript and task panel are open. The room records the message; each view consumes what it needs; a separate request can start background work.

Start with the system boundaries

RMC runs as a Go service backed by SQLite. The SDK connects the application to room APIs and subscriptions. Current native media integrations use LiveKit and OpenAI Realtime.

The application publishes through participant authority and room ordering to SQLite. Independent subscriptions receive committed history over one WebSocket. Browser tracks use separate LiveKit or OpenAI Realtime media connections. Async execution runs outside the logical room plane through direct adapters, returning durable progress and results.
The room coordinates durable facts and work. Native providers carry media; adapters connect work execution.Open SVG ↗Excalidraw source ↓
Component Responsibility
Room Identity, permissions, ordered history, shared context, and work coordination
Client SDK Publication, subscriptions, connection recovery, and processed cursors
Work implementation Execute a task or react to an event, then return an outcome
Native media Capture, transport, and playback of audio and video

These are responsibilities, not necessarily separate processes. An embedded Go agent runs in the RMC process.

1. Bootstrap an authorized room handle

Your backend authenticates the customer, creates or locates the room, and issues a scoped participant credential. The browser shares one RoomClient between its views. Each view creates its own subscription.

The transcript might read chat, while the task panel reads delegation events. Both act with the same participant's permissions.

2. Publish one logical action

TypeScript
const pending = {
  clientEventId: crypto.randomUUID(),
  channelId: "chat",
  type: "text.message.committed",
  payload: {text: "Summarize the shipment discussion."},
};
const accepted = await room.publish(pending);

RMC checks the participant's current permission and validates the publication. Keep pending for retries: if the response is lost, sending the same publication ID and content avoids recording a second fact. See publishers.

3. Cross the durable commit boundary

The client publishes with a stable client event ID. RMC rechecks current authority and idempotency, then SQLite commits the ordered event. Subscription delivery reads authorized committed history.
A commit precedes delivery. External application effects remain a separate boundary.Open SVG ↗Excalidraw source ↓

RMC stores the event before notifying readers. Its sequence orders it relative to other events in the room, across all channels. The publish response and a subscription callback can refer to the same event; the UI reconciles them by event ID.

Publication and storage define this commit behavior.

4. Deliver one log through independent views

One room journal feeds authorized, selected subscription frames over a shared WebSocket. Frames route to a transcript consumer and a work consumer. Each has its own selector, ordered callback queue, and processed cursor. The shared network and bounded queues still limit capacity.
Share transport and identity; keep consumer selection, callback order, and processed progress independent.Open SVG ↗Excalidraw source ↓

Each subscription reads the authorized events matching its selection. Replay and live delivery use the same history. The SDK advances a consumer's cursor after its handler succeeds.

A transcript waiting on a local write does not hold up the task panel's callback queue. Both still share network capacity. See multiplexing for ownership and delivery for failure behavior.

5. Request or react to work explicitly

A message does not start reasoning by itself. Your application chooses a trigger: request a delegation, register a room agent to react to events, or invoke a tool.

The room records requests, context basis, revisions, cancellation, and durable outcomes. Direct Go adapters carry authorized context across a logical responsibility boundary to reasoners, room agents, or tool handlers. Those implementations execute the work and return progress and results to the room. Embedded Go execution can share the RMC process.
The room owns work coordination and durable outcomes; execution is a separate responsibility.Open SVG ↗Excalidraw source ↓

For a delegation, RMC records the request and passes authorized context to an adapter. The adapter performs the task; RMC records progress and the accepted outcome. New messages can arrive while work runs, so the application decides whether a result still answers the current question.

6. Reconnect and rehydrate deliberately

A dropped connection resumes from each active subscription's processed cursor. After a page restart, restore the application's saved view and cursor, or replay its history.

For current state and artifacts, start from a snapshot and follow updates, accepting only newer resource versions. The hydration recipe handles overlap between snapshots and replay. The recovery table covers failed consumers and interrupted connections.

7. Keep native media on its own path

Native providers carry audio and video. RMC authorizes setup and records normalized outcomes such as transcript updates and visual observations. Your client owns capture, playback, and local cleanup.

For OpenAI Realtime voice, the browser exchanges audio directly with the provider over WebRTC while RMC uses a sideband connection for context, normalized transcript and lifecycle events, and authorized tool calls. A provider callback becomes durable only when the adapter normalizes it and the server publishes it through the room runtime. Follow one Realtime turn end to end and compare it with the ordinary event-creation paths.

A media disconnect and a room closure have different effects. See media integration for their lifetimes and LiveKit dependencies for provider-specific behavior.

Trace the running implementation

Use the quickstart to exercise this flow, the TypeScript guide to integrate a client, and the source map to inspect implementation and tests. Proposed platform changes are covered in design direction.

Search the documentation

Type to search all guides.

Diagram

100%Open original ↗