Public Daemon Protocol v4 Capability Negotiation: A Complete Technical Guide
Public daemon protocol v4 capability negotiation is a JSON‑L handshake mechanism where clients advertise desired features via the attach command, daemons respond with supported capabilities in daemon_hello, and both sides compute an intersection to determine which optional features are active for the session.
The PrimeIntellect-ai/prime-agent repository implements a versioned daemon protocol that enables robust client‑daemon communication. In protocol v4, capability negotiation establishes a forward‑compatible contract allowing clients and daemons to discover mutual support for optional behaviors—ranging from snapshot attachment to extension UI—without requiring version bumps for every new feature.
The Four-Step Capability Handshake
According to the source code in packages/coding-agent/src/modes/daemon/daemon-protocol.ts, the negotiation follows a strict four‑phase sequence during the initial connection lifecycle.
Step 1: Client Capability Advertisement
When initiating a session, the client sends an attach (or reattach) command containing a capabilities array of type DaemonClientCapability[]. This list explicitly declares which optional behaviors the client can handle.
The default capabilities defined in DAEMON_DEFAULT_CLIENT_CAPABILITIES typically include "attach_snapshot" and "event_sequence", though clients may request additional features like "extension_ui" or "session_input_admission":
const attachCmd: DaemonCommand = {
type: "attach",
activeSessionId: "sess-123",
capabilities: ["attach_snapshot", "event_sequence", "extension_ui"],
recoveryConfig: { maxRetries: 3 }
};
socket.write(JSON.stringify(createDaemonCommandEnvelope(attachCmd, "cmd-001")));
Step 2: Daemon Capability Advertisement
Upon receiving the attach command, the daemon responds with a daemon_hello event. The payload includes a serverCapabilities field (type DaemonServerCapability[]) that enumerates every optional feature the daemon can currently provide.
This list represents the union of client‑requested capabilities that the daemon supports plus daemon‑only capabilities such as "delete_rlm_subagent" and "heartbeat_catalog". The daemon constructs this list dynamically based on its internal configuration and the client’s request.
Step 3: Capability Intersection
The client inspects the serverCapabilities array returned in daemon_hello and computes the intersection with its original request. Only capabilities present in both lists become active for the session.
For example, if the client requested "extension_ui" and the daemon included it in serverCapabilities, the client may enable UI extensions. Conversely, if the daemon omitted "session_input_admission", the client must not send admission‑gated commands:
socket.on("data", (line) => {
const msg = JSON.parse(line);
if (msg.type === "daemon_hello") {
const usable = msg.serverCapabilities.filter(c =>
attachCmd.capabilities?.includes(c)
);
if (usable.includes("extension_ui")) enableExtensionUi();
}
});
Step 4: Runtime Compatibility Validation
Protocol v4 introduced granular compatibility checks via the DAEMON_COMMAND_COMPATIBILITY mapping and the meetsDaemonCommandCompatibility() function. Each command specifies its requirements—minimum protocol version, minimum schema revision, and required capabilities—within a DaemonCommandCompatibility object.
Before executing capability‑gated commands, the implementation validates that the negotiated session meets these requirements:
// Checking before sending a capability-gated command
if (usable.includes("session_input_admission")) {
const promptCmd: DaemonCommand = {
type: "prompt",
activeSessionId: "sess-123",
message: "What do you want to do?",
admissionId: "adm-456"
};
// Internally validated against DAEMON_COMMAND_COMPATIBILITY
socket.write(JSON.stringify(createDaemonCommandEnvelope(promptCmd, "cmd-002")));
}
Protocol v4 Schema Revisions and Version Gates
Protocol v4 established the DAEMON_SCHEMA_REVISION constant to enable fine‑grained feature gating independent of the protocol version. While DAEMON_PROTOCOL_VERSION was 4 in the historic v4 release (the current repository shows version 7), the schema revision mechanism allows backward‑compatible extensions.
Commands specify minSchemaRevision in their DaemonCommandCompatibility definition. This permits the introduction of new command variants or payload fields without incrementing the major protocol version, as long as clients gracefully ignore unrecognized capabilities.
Key Source Files and Implementation Details
The capability negotiation logic is centralized in packages/coding-agent/src/modes/daemon/daemon-protocol.ts, which exports:
DaemonClientCapabilityandDaemonServerCapability– Enum‑like type definitions for all known capabilitiesDAEMON_DEFAULT_CLIENT_CAPABILITIES– The baseline capability set for new connectionsDAEMON_SUPPORTED_CLIENT_CAPABILITIES– The complete universe of capabilities the daemon recognizesmeetsDaemonCommandCompatibility()– Runtime validator checking protocol version, schema revision, and capability requirements
Client‑side implementation resides in packages/coding-agent/src/modes/daemon/daemon-client.ts, which constructs the attach command and parses the daemon_hello response. The supervisor logic in packages/coding-agent/src/modes/daemon/daemon-supervisor.ts uses these capabilities to determine whether to expose optional features such as roster subscriptions.
Summary
- Public daemon protocol v4 capability negotiation uses a bidirectional handshake: clients announce wants via
attach, daemons respond withserverCapabilitiesindaemon_hello, and the intersection defines the active feature set. - The negotiation mechanism is version‑agnostic; while v4 used
DAEMON_PROTOCOL_VERSION = 4, the same logic persists in current versions (now at version 7). - Schema revisions (
DAEMON_SCHEMA_REVISION) introduced in v4 allow fine‑grained feature gating without protocol version bumps. - Runtime validation via
meetsDaemonCommandCompatibility()ensures commands execute only when both sides support the required capabilities. - Source definitions live in
packages/coding-agent/src/modes/daemon/daemon-protocol.ts, with client implementation indaemon-client.ts.
Frequently Asked Questions
What is the difference between DAEMON_PROTOCOL_VERSION and DAEMON_SCHEMA_REVISION in protocol v4?
DAEMON_PROTOCOL_VERSION indicates the major transport version (set to 4 in the v4 release), while DAEMON_SCHEMA_REVISION provides granular feature gating for individual commands. A command may require minSchemaRevision: 8 without requiring a protocol version bump, enabling backward‑compatible feature evolution.
How does a client know which capabilities the daemon actually supports?
After sending the attach command with its desired capabilities array, the client waits for the daemon_hello event. The serverCapabilities field in that response contains the definitive list of features available for the current session, computed as the intersection of client requests and daemon support.
What happens if a client sends a command requiring a capability not in the negotiated set?
The meetsDaemonCommandCompatibility() function in daemon-protocol.ts validates every command against the negotiated capabilities. If a command requires a capability absent from the current session, the validator rejects the operation before transmission, preventing protocol errors.
Are daemon‑only capabilities like "delete_rlm_subagent" available to all clients?
No. Daemon‑only capabilities such as "delete_rlm_subagent" and "heartbeat_catalog" appear in serverCapabilities only if the daemon supports them, but clients cannot request them in the attach command. The client discovers these capabilities through the daemon_hello response and may utilize them only if they appear in the intersection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →