# How Subagent Lifecycle Events Like `agentMessage.send` Enable Parent-Child Coordination in Prime Agent

> Learn how Prime Agent subagent lifecycle events like agentMessage.send facilitate parent-child coordination through unique IDs and a bidirectional event system for monitoring and commanding subagents.

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

---

**Subagent lifecycle events in Prime Agent—specifically `agentMessage.send`—enable parent-child coordination by attaching unique child IDs to messages and routing them through a bidirectional event system that allows parents to monitor, command, and synchronize their spawned subagents.**

The Prime Agent framework implements a hierarchical agent architecture where parent sessions spawn isolated child sessions. This coordination relies on a precisely defined event protocol centered on `AgentMessage` objects, with `agentMessage.send` serving as the primary communication primitive between layers of the agent hierarchy.

## Subagent Initialization and Session Registry

When a parent agent spawns a subagent, Prime Agent creates a fully independent `AgentSession` while maintaining registry linkage through the `SubagentRuntimeHost`.

In [`packages/coding-agent/src/subagents.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/subagents.ts), the runtime host instantiates child sessions and registers them in the parent's internal tracking map:

```ts
// From packages/coding-agent/src/AgentSession.ts
// Parent session maintains subagentRuntimes registry
subagentRuntimes: Map<string, SubagentRuntimeHost> = new Map();

```

Each child receives a unique **child-ID** (`rlmChildId`) persisted in both the parent's metadata and the child's session state. This identifier becomes the routing key for all subsequent `agentMessage` events. The relationship between parent and child is explicitly managed through the `agentMessageRelationship` helper, which categorizes connections as `"parent"`, `"child"`, or `undefined` based on stored ID pairs.

## The `agentMessage.send` Event Mechanism

The `agentMessage.send` function in [`packages/coding-agent/src/agentMessageController.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/agentMessageController.ts) implements the core emission logic:

```ts
// Conceptual implementation from agentMessageController.ts
export const send = (msg: AgentMessage) => {
  // Normalize message and attach originating session context
  const enrichedMsg = {
    ...msg,
    rlmChildId: this.session.id,      // Source identification
    agentMessageId: generateId(),      // Correlation tracking
  };
  
  // Forward to parent session's message handler
  parentSession.handleAgentMessage(enrichedMsg);
};

```

Key properties attached to every sent message:

- **`rlmChildId`** – Identifies the originating child session
- **`rlmParentId`** – Present when messages flow parent-to-child
- **`agentMessageId`** – Unique correlation identifier for request-response matching

## Parent-Side Message Handling and Routing

When a parent session receives a message via `handleAgentMessage`, it executes a three-phase routing sequence:

1. **Relationship lookup** – Query `agentMessageRelationship` using the IDs embedded in the message
2. **Validation** – Verify the sender is a known child or legitimate parent
3. **Dispatch** – Route to appropriate handlers based on message type and relationship

The parent can perform three distinct coordination actions:

- **Observe** – Track child progress through `agentMessageId` correlation
- **Command** – Send directive messages back to specific children
- **Broadcast** – Propagate messages across multiple child sessions simultaneously

## Coordination Patterns: Spawn, Monitor, Control

### Spawning and Initial Handshake

```ts
// Parent session spawning a subagent
const sub = await session.spawnSubagent({
  prompt: "Analyze the following file",
  model: "gpt-4o-mini",
});
await sub.waitForReady();  // Parent synchronizes on child initialization

```

### Monitoring via Event Subscription

```ts
// Parent registers handler for child messages
session.on("agentMessage", (msg: AgentMessage) => {
  if (msg.rlmChildId === sub.id) {
    console.log(`Child ${sub.id} reports:`, msg.content);
  }
});

```

### Termination and Cleanup Lifecycle

When a child completes execution, it emits a terminal message with `type: "stop"`:

```ts
// Child session signaling completion
await this.session.agentMessageController.send({
  role: "assistant",
  content: "Analysis complete",
  type: "stop",                      // Lifecycle termination signal
  rlmChildId: this.session.id,
});

```

The parent responds by removing the child entry from `subagentRuntimes` and emitting disposal confirmations. This prevents orphaned sessions and resource leaks.

## Error Boundaries and Lifecycle Constraints

The framework enforces strict parent-child lifecycle integrity. Attempting to spawn or message from a child whose parent has been disposed triggers an explicit error:

```

Cannot spawn a subagent after its parent was disposed

```

This constraint—validated in regression test [`packages/coding-agent/test/suite/regressions/617-subagent-terminal-agent-message.test.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/suite/regressions/617-subagent-terminal-agent-message.test.ts)—ensures that message routing never targets destroyed session hierarchies.

## Persistence and Session Restoration

Subagent metadata including `rlmChildId`, model configuration, and effort level is serialized in [`packages/coding-agent/src/agent-session-serialized.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/agent-session-serialized.ts). On session restoration:

1. Parent re-instantiates child sessions from persisted state
2. `SubagentRuntimeHost` re-registers children in `subagentRuntimes`
3. Message routing resumes transparently using restored ID mappings

## Performance Characteristics

- **Message latency** – Direct memory reference between co-located sessions
- **Routing overhead** – O(1) map lookup via `agentMessageRelationship`
- **Memory scaling** – Linear with active subagent count; terminal children garbage-collected post-`stop` acknowledgment

## Summary

- **Subagent spawning** creates isolated `AgentSession` instances with unique `rlmChildId` identifiers stored in the parent's `subagentRuntimes` registry
- **`agentMessage.send`** attaches source identification and correlation IDs, then routes through `handleAgentMessage` in the parent session
- **Parent coordination** includes observation (progress tracking), command injection (directed messages), and broadcast synchronization (multi-child operations)
- **Lifecycle termination** uses `type: "stop"` messages triggering cleanup and preventing orphaned sessions
- **Persistence layer** stores subagent metadata enabling full session restoration with intact message routing

## Frequently Asked Questions

### How does Prime Agent prevent message routing to disposed parent sessions?

The `SubagentRuntimeHost` checks parent session validity before processing any `agentMessage.send` call. If the parent has been disposed, it throws `Cannot spawn a subagent after its parent was disposed`. This constraint is enforced in [`packages/coding-agent/test/suite/regressions/617-subagent-terminal-agent-message.test.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/suite/regressions/617-subagent-terminal-agent-message.test.ts).

### Can a subagent communicate with sibling subagents directly?

No. All inter-subagent communication is mediated through the common parent. Sibling sessions have no direct reference to each other; they exchange messages by emitting to the parent, which may then broadcast to selected children based on `agentMessageRelationship` lookups.

### What happens to in-flight messages during parent session restoration?

Messages queued during serialization are persisted with the session snapshot. On restoration, the parent session's `agentMessageController` reinitializes its routing tables from [`agent-session-serialized.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/agent-session-serialized.ts), and pending messages resume processing through the restored `subagentRuntimes` map.

### How does `agentMessageId` enable request-response correlation?

Each `agentMessage.send` generates a unique `agentMessageId` stored in both the sent message and the sender's pending promise registry. When the recipient responds, it includes the original `agentMessageId` in its reply, allowing the sender to resolve the correct promise via `session.promptAndWait` or equivalent async handlers.