# How Prime Agent's Daemon Supervisor Handles Cross-Agent Message Routing

> Discover how Prime Agent's daemon supervisor routes cross-agent messages using AgentRoster and DaemonWorkerClient for efficient communication via Unix sockets.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: internals
- Published: 2026-09-06

---

**Prime Agent's daemon supervisor routes cross-agent messages through an in-memory AgentRoster that maps session IDs to ResidentWorkers, using DaemonWorkerClient to forward commands over private Unix sockets.**

The [PrimeIntellect-ai/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent) repository implements a sophisticated **daemon supervisor** as the central message routing hub. Located in [`packages/coding-agent/src/modes/daemon/daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts), this component mediates all communication between clients (TUI, CLI consumers) and session workers running LLM models.

## Core Routing Architecture

The cross-agent message routing system relies on three interconnected components:

- **AgentRoster** — Mutable in-memory index mapping session IDs to their owning `ResidentWorker` instances
- **DaemonWorkerClient** — Thin RPC client for worker communication over private Unix sockets
- **Server capabilities** — Protocol advertisements enabling roster subscriptions and direct peer transport

### AgentRoster: The Session-to-Worker Index

The `AgentRoster` is imported at lines 71-78 of [`daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon-supervisor.ts) and maintained through the `roster_subscribe` / `roster_unsubscribe` protocol:

```typescript
// AgentRoster keeps live mappings: sessionId → ResidentWorker
// Synchronized via worker lifecycle events (create, detach, resume)

```

This roster enables **O(1) worker lookup** for any command targeting a specific session.

### DaemonWorkerClient: Worker Communication Bridge

The `DaemonWorkerClient` (lines 37-39) provides the RPC interface to individual workers:

```typescript
// From daemon-supervisor.ts
import { DaemonWorkerClient } from "./daemon-worker-client";

```

Each `ResidentWorker` maintains a `client` instance connected to the worker's private socket.

## Command Routing Flow

### Step 1: Client Command Reception

When a client connects via the public supervisor socket, the supervisor creates a `DaemonSocketClient` and registers it. The `handleCommand` dispatcher parses incoming JSON-L lines and matches against `DAEMON_COMMAND_TYPES` (starting at line 200).

### Step 2: Target Worker Resolution

For session-scoped commands, the supervisor invokes `matchWorkers(sessionId)`:

```typescript
// Simplified excerpt from the command dispatcher
case "send_message":
case "append_custom_message":
  const target = command.sessionId ?? command.activeSessionId;
  const [match] = this.matchWorkers(target);
  if (!match) throw new Error(`No worker for session ${target}`);
  await match.worker.client!.requestWorker(command, /* timeout */ 30_000);
  break;

```

This lookup occurs in the full dispatcher implementation (approximately lines 3000-3500).

### Step 3: Worker Forwarding and Response

The `DaemonWorkerClient.requestWorker` method writes the command JSON to the worker's socket. The worker interprets commands via the **session-worker protocol** ([`daemon-worker-protocol.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon-worker-protocol.ts)) and returns responses over the same connection.

## Roster Change Propagation

Workers notify the supervisor of session lifecycle events. The supervisor updates `AgentRoster` and pushes `roster_update` messages to subscribed clients:

```typescript
// Client subscribes
await daemonClient.sendCommand({ type: "roster_subscribe" });

// Supervisor broadcasts changes to promptAdmissions subscribers
for (const client of this.clients) {
  if (this.promptAdmissions.has(client)) {
    client.sendMessage({ type: "roster_update", entries: rosterDelta });
  }
}

```

This **publish-subscribe pattern** eliminates polling overhead and ensures consistent client views.

## Direct Peer-to-Peer Transport

For high-throughput scenarios, the supervisor supports **bypass routing** through `direct_peer_transport` capability (advertised at lines 182-186):

```typescript
// Capability list in daemon-supervisor.ts
const capabilities = [
  "agent_roster",
  "direct_peer_transport",  // Enables low-latency streaming
  // ... baseline capabilities
];

```

### Obtaining a Transport Ticket

```typescript
const ticket = await daemonClient.sendCommand({
  type: "get_direct_worker_transport",
  sessionId: "session-xyz789",
});

```

The supervisor generates a `DaemonPeerTransportTicket` encoding:
- Worker's private socket path
- Short-lived authentication token

This allows clients to connect **directly** to workers for streaming tool-call results without supervisor intermediation.

## Practical Routing Examples

### Sending a Chat Message

```typescript
// Client sends message
await daemonClient.sendCommand({
  type: "send_message",
  sessionId: "session-abc123",
  content: "What is the weather tomorrow?",
});

```

The supervisor resolves `session-abc123` through the roster and forwards via `DaemonWorkerClient`.

### Cross-Agent Message Pattern

When sub-agents need to communicate, messages flow:
1. **Sub-agent A** → supervisor socket
2. Supervisor **roster lookup** → identifies Sub-agent B's worker
3. **Command forward** → Sub-agent B's private socket
4. Response traverses reverse path

## Source Code Reference

| File | Responsibility |
|------|---------------|
| [`packages/coding-agent/src/modes/daemon/daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts) | Core routing, roster management, command dispatch |
| [`packages/coding-agent/src/modes/daemon/daemon-worker-client.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-worker-client.ts) | RPC client for worker communication |
| [`packages/coding-agent/src/modes/daemon/agent-roster.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/agent-roster.ts) | Session-to-worker index with subscription support |
| [`packages/coding-agent/src/modes/daemon/daemon-protocol.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-protocol.ts) | Command envelopes, capabilities, transport tickets |
| [`packages/coding-agent/src/modes/daemon/daemon-worker-protocol.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-worker-protocol.ts) | Worker-side command interpretation |
| [`packages/coding-agent/src/modes/daemon/daemon-socket.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-socket.ts) | Public socket handling and identity verification |

## Summary

- **Message routing** is centralized through the daemon supervisor with O(1) session-to-worker lookup via `AgentRoster`
- **Command forwarding** uses `DaemonWorkerClient` over private Unix sockets with 30-second default timeouts
- **Roster subscriptions** enable real-time client synchronization without polling
- **Direct peer transport** provides optional low-latency paths for high-throughput scenarios
- All routing logic is implemented TypeScript in [`daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon-supervisor.ts) with clear separation between public client and private worker protocols

## Frequently Asked Questions

### How does the supervisor locate the correct worker for a session?

The supervisor maintains an in-memory `AgentRoster` that maps every active session ID to its owning `ResidentWorker`. When a command arrives with a `sessionId` or `activeSessionId` field, the supervisor calls `matchWorkers(sessionId)` to retrieve the target worker reference. This lookup is synchronized with worker lifecycle events through the roster subscription protocol.

### What happens if a command targets a non-existent session?

The `matchWorkers` method returns an empty array when no worker owns the requested session. The command dispatcher throws an explicit error: `No worker for session ${target}`. This fail-fast behavior prevents commands from being silently dropped and allows clients to handle session resolution failures appropriately.

### Can clients communicate directly with workers without the supervisor?

Yes, through the `direct_peer_transport` capability. Clients request a transport ticket via `get_direct_worker_transport`, receiving a `DaemonPeerTransportTicket` containing the worker's socket path and authentication token. This bypass path reduces latency for streaming responses but requires the supervisor's initial coordination to establish trust and addressing.