Architecture
How the runtime loop works — async messaging, cloud-brokered LLM calls, tools, and the home directory.
The runtime is a local HTTP/WebSocket server. Your application drives it through its REST API; results arrive as WebSocket events. It never calls LLM providers directly — every model call is brokered through the control plane.
The messaging model (read this first)
Sending a message is asynchronous. There is no "give me the answer" request. Instead:
POST /conversations/:id/messagesreturns202with aqueueItemimmediately.- The agent processes the message in the background.
- You receive the response over WebSocket — streaming token deltas, then a
run.completedevent when done.
Your app --POST /messages--> runtime (202 Accepted, queueItem)
^ |
| | processes async (LLM + tools)
<--WebSocket events-------------+
message.delta ... run.completed
You can run many conversations in parallel; each streams independently.
The loop
HTTP POST /conversations/{id}/messages
↓
Queue message in SQLite
↓
RuntimeManager picks up from the queue
↓
ConversationRunner — the main loop:
LLM call → control plane /api/runtime/chat → vLLM backend
tool execution (bash, browser, cron, delegate)
re-plan until complete
↓
Response → WebSocket event
The loop runs until the agent stops calling tools. Long conversations are auto-compacted to fit the context window, producing checkpoints you can inspect.
Tools
During a run the agent can use:
- bash — execute shell commands in the workspace.
- browser — web automation, form fills, screenshots, and data extraction via
an anti-detection Playwright fork (
rebrowser-playwright). - cron — create, list, update, delete, and toggle scheduled recurring tasks. Say "check my site every 10 minutes" and the agent creates the job itself.
- delegate — spawn an isolated subagent for a subtask. Subagents cannot re-delegate (prevents infinite recursion).
Tool calls are streamed as events so your UI can show what the agent is doing.
The home directory
All persistent state lives under one directory you choose with --home. One
home directory = one isolated agent. Run multiple agents by giving each its own.
<home>/
agent22.db SQLite (conversations, messages, queue, cron jobs)
cloud.json Cloud session tokens (sensitive — don't commit)
runtime.json Runtime configuration (hot-reloaded)
soul.md / agents.md / user.md / memory/ Identity, behavior, persistent memory
context/ Shared reference files (agent reads on demand)
skills/ Custom skills/capability docs
logs/ System + conversation logs
browser/
profiles/ Per-conversation browser profiles
screenshots/ Captured screenshots
Back up or migrate an agent by copying the whole home dir while the process is stopped.
Cloud-brokered LLM
The runtime authenticates with the control plane via JWT tokens obtained from
/api/runtime/session/*. All LLM calls are proxied through the control plane so
LLM API keys never leave it. The control plane routes each call to a vLLM
backend (see Models & routing).
Hot-reload
runtime.json and cloud.json are re-read when their modification time changes,
and the prompt markdown files (soul.md, agents.md, user.md,
memory/memory.md) are re-read on every agent turn. You rarely need to restart
the runtime to apply config or prompt edits.
Workspaces and AGENTS.md
When a conversation has a workspacePath, the runtime loads that directory's
AGENTS.md into the system prompt and operates in that directory. Upload one
through the dashboard's project file browser to steer the agent's behavior for a
given project.
Where to go next
- Run it reliably: Deployment.
- Drive it in code: Agent API: Getting started.
- The full endpoint list: Agent HTTP reference.