Skip to content

api daemon protocol

Zachary BENSALEM edited this page Sep 4, 2026 · 6 revisions

Daemon protocol

Active contributors: Zachary BENSALEM

What the daemon exposes (as Fleet uses it)

The Prime Agent runtime ships a per-user daemon: a long-lived engine process that owns sessions on a local socket. Fleet consumes it through the public SDK surface of the checksum-pinned prime-agent package, not through private runtime internals. The parts Fleet uses:

  • Identity handshake. DaemonClient.connect(socketPath) followed by waitForHello() returns the daemon's protocol identity. Fleet accepts a daemon only when its identity exactly matches DAEMON_PROTOCOL_NAME@DAEMON_PROTOCOL_VERSION, imported from the pinned prime-agent package. matchesPinnedDaemon in web/server/src/daemon-runtime.ts rejects a different daemon on the same socket.
  • Session worker requests. Four request types cross the wire:
  • { type: "create", sessionPath?, config, lifecycle: "resident" } creates or reopens a worker and returns its active session id and session file.
  • { type: "list", all: true, sessionDir, cwd? } enumerates persisted sessions.
  • { type: "kill", activeSessionId } stops a worker before reconfiguration or termination.
  • { type: "delete_saved_session", sessionPath } removes a saved transcript without an active session context.
  • Streaming turns. AgentConnection.promptAndWait(text, { images, streamingBehavior, queueIfBusy }) resolves when the turn settles. steer, followUp, abort, and waitForIdle cover interruption and admission control.
  • Session state and transcript. Fleet reads state, messages, session tree, headers, system prompts, stats, and exports. It also sets model, thinking level, service tier, and session name, and calls reload, tree navigation, and saved-session deletion where the browser API exposes those operations.
  • Extension UI dialogs. The daemon forwards extension_ui_request connection events such as select, confirm, input, questions, editor, notify, and setStatus. Fleet answers through respondToExtensionUiRequest after surfacing a tool-Question card.
  • Session events. session_event carries agent, turn, compaction, retry, RLM, bash, refinement, goal, recap, and session-info events. Connection events include session_replaced, session_resynced, side_question_event, extension_ui_request, extension_error, closed, and connection_status. The event mapper converts supported events to browser frames.

Discovery, spawn, and attach

web/server/src/daemon-runtime.ts implements the whole flow:

  1. Socket discovery. defaultDaemonSocketPath() resolves the per-user socket, normally $TMPDIR/prime-agent-<UID>/daemon.sock. A daemon already listening there is used only after the protocol probe succeeds.
  2. Probe. probeDaemon connects with a one-second DAEMON_PROBE_TIMEOUT_MS timeout and checks the hello identity. A compatible daemon is attached, an incompatible daemon produces a hard error, and an unreachable socket triggers spawn.
  3. Spawn. daemonCliEntrypoint resolves the CLI inside the pinned runtime. Fleet starts it with --mode daemon --daemon-socket <socket>, detached and unref'd, then polls every 50 ms until the 30-second DAEMON_STARTUP_TIMEOUT_MS deadline. Per-socket promises deduplicate concurrent startup attempts.
  4. Attach. A create request opens or reopens the worker. DaemonAgentConnection.attach binds it with daemon recovery, extension UI support, and client environment forwarding disabled.
  5. Reconfiguration. The daemon fixes appendSystemPrompt at worker creation, but Fleet changes the OpenUI prompt per request. createReconfigurableConnection waits for a safe idle boundary, disposes and kills the worker, reopens the same session file with the new prompt, and resubscribes the bridge listeners.
  6. Session directory. sessionDirectoryForCwd checks PRIME_AGENT_SESSION_DIR, then PRIME_AGENT_CODING_AGENT_SESSION_DIR, then the settings-configured directory, and finally <agent dir>/sessions.

What Fleet deliberately does not use

  • The in-process connection adapter in production. It exists only behind the bridge's test seam in web/server/src/in-process-test-connection.ts.
  • Vendoring, patching, or republishing the engine. The daemon protocol and engine behavior belong upstream.
  • TUI-only affordances such as update, fullscreen, quit, Gist upload for share, and unsupported terminal UI context methods.

Upstream-change policy

The daemon protocol is upstream-owned. docs/guides/upstream-runtime.md is the upgrade runbook. When a runtime upgrade changes the protocol or schema, review docs/reference/adapter-contract.md, update web/server, and run the daemon-runtime and bridge parity tests in the same change. Never patch upstream code inside this repository.

Key source files

File Role
web/server/src/daemon-runtime.ts Probe/spawn/attach, session requests, reconfigurable connection, listDaemonSessions, deleteDaemonSavedSession.
web/server/src/prime-bridge.ts The only daemon client: session registry, event subscription, dialogs, forks, presentation persistence.
web/server/src/event-mapper.ts Daemon/session events → browser frames.
web/server/src/prime-config.ts agentDir, settings, auth, model registry, project registry — the config seam shared with the daemon.
docs/guides/upstream-runtime.md Upgrade and advisory policy for the pinned runtime.

Where next

  • Web API — the browser-facing half of the same data.
  • PrimeBridge — the bridge internals.
  • Daemon runtime — the module that probes and attaches to the daemon.
  • Dependencies — how the runtime pin makes this protocol version exact.

Clone this wiki locally