-
Notifications
You must be signed in to change notification settings - Fork 0
api daemon protocol
The daemon protocol is the versioned JSONL wire contract between a client and the headless Prime Agent daemon. It is the transport used by DaemonAgentConnection today and is intentionally JSON-serializable so a future remote gateway can proxy it without leaking transport details back into interactive mode. The wire contract lives in packages/coding-agent/src/modes/daemon/daemon-protocol.ts.
This page is a reference for the protocol mechanics and version history. The daemon architecture (socket ownership, workers, supervisor) is on the Daemon page.
Defined in packages/coding-agent/src/modes/daemon/daemon-protocol.ts.
| Constant | Value | Meaning |
|---|---|---|
DAEMON_PROTOCOL_NAME |
prime-agent.daemon |
Protocol identity |
DAEMON_PROTOCOL_VERSION |
8 |
Wire protocol version |
DAEMON_SCHEMA_REVISION |
15 |
Monotonic wire-schema revision for field-sensitive compatibility checks |
DAEMON_SCHEMA_ID |
protocol-8-schema-15-d28eaade1789 |
Canonical schema identity used for stale-daemon detection |
DAEMON_COMMAND_ENVELOPE_MIN_PROTOCOL_VERSION |
7 |
Version at which commands are wrapped in an envelope |
DAEMON_PROTOCOL_VERSION is bumped for incompatible changes or when startup begins requiring behavior an older daemon cannot provide. DAEMON_SCHEMA_REVISION is bumped for additive schema changes (see the revision history). DAEMON_SCHEMA_ID is checked by prime-agent status to classify a daemon as current or stale (packages/coding-agent/src/cli/daemon-ps.ts).
Recorded as comments in packages/coding-agent/src/modes/daemon/daemon-protocol.ts.
| Revision | Change |
|---|---|
| 9 | Published persisted RLM spawn depth on passive session rows |
| 10 | Published persisted RLM spawn depth on all session catalog rows |
| 11 | Added immediate get/set commands for active-session RLM max depth |
| 12 | Published idle-residency metadata on session summary rows |
| 13 | Narrowed agent-origin reach and roster wire shapes to the nuclear family |
| 14 | Carried the client's monotonic telemetry opt-out on attach and reattach |
| 15 | Added optional seedMessages on new_session (protocol 8) |
Commands and events travel as JSON lines over the Unix socket.
Commands at protocol >= 7 use a DaemonCommandEnvelope:
{ "type": "command", "id": "...", "protocol": { "name": "prime-agent.daemon", "version": 8 }, "clientId": "...", "command": { "type": "list" } }Events use a parallel DaemonEventEnvelope carrying an id, protocol, activeSessionId, sequence, cursor, and emittedAt, with the payload nested under event. Every event carries a monotonic sequence and a per-session cursor (generation + sequence) used for replay and resync.
On connect, the server immediately sends a daemon_hello frame with the protocol name/version, schemaId, schemaRevision, app version, runtime identity, a per-connection clientId, and the serverCapabilities list. The client advertises its own capabilities in attach/reattach.
- The client sends its protocol version inside each command envelope and the hello advertises the server's version.
-
isDaemonCommandEnvelopeaccepts a command only when the envelope protocol version is betweenDAEMON_COMMAND_ENVELOPE_MIN_PROTOCOL_VERSION(7) andDAEMON_PROTOCOL_VERSION(8). - Rejected command lines are salvaged for their
id(salvageDaemonCommandId) so parse failures still reach the sender as correlatable responses. -
DaemonClient.requestchecks the negotiated hello againstDAEMON_COMMAND_COMPATIBILITYbefore sending, and throwsDaemonCapabilityUnavailableErrorwhen the server cannot honor the command.
Optional features go behind a negotiated server capability. Clients must check the capability before sending the command or depending on the event. Server capabilities are listed in DAEMON_DEFAULT_SERVER_CAPABILITIES in packages/coding-agent/src/modes/daemon/daemon-protocol.ts:
-
attach_snapshot,event_sequence(default client capabilities) -
extension_ui,slim_attach,chunked_snapshot,client_owned_sessions -
delete_rlm_subagent,heartbeat_catalog,heartbeat_management,model_catalog -
side_question_transcript,transient_bash,session_input_admission,prompt_admission_cancellation,seed_messages
The command compatibility map, DAEMON_COMMAND_COMPATIBILITY, assigns each command a minProtocol, an optional minSchemaRevision, and an optional capability gate. The outbound event map, DAEMON_OUTBOUND_COMPATIBILITY, does the same for events. getDaemonCommandCompatibilities returns the effective gates for a command, folding in telemetry-policy and prompt-admission-cancellation gates when the command carries those optional fields.
| Capability | Command(s) / event |
|---|---|
client_owned_sessions |
complete_owned_session, promote_owned_session
|
delete_rlm_subagent |
delete_rlm_subagent |
heartbeat_catalog |
heartbeats_list, heartbeats_changed event |
heartbeat_management |
heartbeat_manage |
model_catalog |
get_model_catalog |
session_input_admission |
prompt, prompt_and_wait, steer, follow_up, resume_queue
|
prompt_admission_cancellation |
cancel_prompt_admission (also minSchemaRevision: 8) |
seed_messages |
seedMessages on new_session (also minProtocol: 8, minSchemaRevision: 15) |
| Gate | Command |
|---|---|
minSchemaRevision: 11 |
get_rlm_max_depth_status, set_rlm_max_depth
|
minSchemaRevision: 14 |
attach/reattach/create carrying a telemetry opt-out |
Every daemon command, event, and response-shape change is classified as one of:
- Backward-compatible: additive and safe for old daemons/clients to ignore. Most commands default to
minProtocol: 7(LEGACY_DAEMON_COMMAND). - Capability-gated: optional features behind a negotiated server capability; clients must check before sending.
- Incompatible: requires bumping
DAEMON_PROTOCOL_VERSION, orminProtocol/minSchemaRevisiongates, and updating both compatibility maps plus both new-client/old-daemon and old-client/new-daemon tests.
The policy is documented in Patterns and conventions. Compatibility metadata is verified by tests in packages/coding-agent/test/daemon-protocol.test.ts, which assert the per-command gates and cover both version skew directions.
At protocol >= 8 (schema revision >= 15), the new_session command accepts an optional seedMessages array of { role: "user" | "assistant", text: string } entries appended to the fresh SessionManager before the swap resolves. Older daemons ignore unknown fields, so a client must not send seedMessages unless the negotiated hello meets the minProtocol: 8/minSchemaRevision: 15/seed_messages floor. getDaemonCommandCompatibilities adds the NEW_SESSION_SEED_MESSAGES_COMMAND gate only when seedMessages is present and non-empty, keeping bare new_session available on protocol 7. This is covered by the version-gates new_session seedMessages test in packages/coding-agent/test/daemon-protocol.test.ts.
- Responses are
{ id, type: "response", command, success: true, data? }or{ id, type: "response", command, success: false, error, errorInfo? }. - Attach returns a
DaemonAttachResultwith aDaemonSessionSnapshot,lastEventSequence, and aDaemonReplayInfocomputed from the client'sresumeCursor(verdictcomplete,partial, orunavailable). - Slim (
slim_attach) clients skip the legacysession_attachedframe; chunked (chunked_snapshot) clients stream the transcript assession_snapshot_begin/chunk/end.
- API index, the three wire surfaces
- Daemon, daemon architecture
-
CLI,
status,doctor,pscommands - Patterns and conventions, daemon protocol change policy