# How Prime Agent's Message Queue Handles Steering vs Follow-Up Messages

> Discover how Prime Agent's message queue prioritizes steering messages over follow-up messages to optimize agent responsiveness and control conversational flow. Learn about steering modes.

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

---

**Prime Agent maintains separate steering and follow-up sub-queues within `AgentConnectionQueueState`, delivering high-priority steering messages before turn boundaries while deferring follow-up messages until the current turn completes, with behavior controlled by configurable steering modes.**

The PrimeIntellect-ai/prime-agent repository implements a sophisticated message queue system that distinguishes between **steering** (interrupt) messages and **follow-up** (post-turn) messages. Understanding how the message queue handles steering vs follow-up messages is essential for building responsive agent applications that require real-time user intervention capabilities.

## Core Queue Architecture

The message queue uses a dual-queue structure that separates messages by priority and delivery timing. The `AgentConnectionQueueState` interface defines two distinct arrays:

- **Steering queue**: Stores high-priority messages that can interrupt the current turn (e.g., direction changes while tool calls are active)
- **Follow-up queue**: Stores standard messages processed only after the current turn completes (e.g., answers to questions the agent asked)

## Queueing Messages: Steering vs Follow-Up

### Adding Steering Messages

Use `session.steer()` to queue high-priority interrupt messages that populate `connectionQueue.steering`:

```typescript
// packages/coding-agent/src/core/agent-session.ts
// Lines 4874-4875
await harness.session.steer("active steering", undefined, { 
  resumeIfIdle: true 
});

```

The `resumeIfIdle` option ensures the message delivers as soon as the current turn ends.

### Adding Follow-Up Messages

Use `session.addFollowUp()` for standard messages that should wait for turn completion:

```typescript
await session.addFollowUp("The answer is 42");

```

These messages populate `connectionQueue.followUp` and remain pending until all steering messages are drained.

## Inspecting and Managing the Queue

### Retrieving Queue Contents

The `getAllQueuedMessages()` method returns immutable copies of both sub-queues:

```typescript
// packages/coding-agent/src/modes/interactive/interactive-mode.ts
// Lines 7117-7127
private getAllQueuedMessages(): { steering: string[]; followUp: string[] } {
    return {
        steering: [...this.connectionQueue.steering],
        followUp: [...this.connectionQueue.followUp],
    };
}

```

### Clearing the Queue

The `clearQueue()` method removes entries from both sub-queues simultaneously:

```typescript
// packages/coding-agent/src/core/agent-session.ts
// Lines 6011-6038
clearQueue(): { steering: string[]; followUp: string[] } {
    const steering = clearable ? this._actionStore.clearQueuedSteering() : [];
    const followUp = clearable ? this._actionStore.clearQueuedFollowUps() : [];
    return { steering, followUp };
}

```

## Steering Modes and Delivery Policy

The **steering mode** determines when queued steering messages are delivered relative to the current turn boundary.

### Mode: "one-at-a-time"

In this mode, only the **first** steering message is delivered. The agent waits for a response before processing subsequent steering messages, preventing interrupt flooding.

### Mode: "all"

In this mode, **all** pending steering messages are delivered in a batch before any follow-up messages, allowing multiple corrections to be processed together.

### Mode Selection Logic

The delivery decision occurs at turn boundaries based on message type:

```typescript
// packages/coding-agent/src/core/agent-session.ts
// Line 5458
const mode = first.delivery === "next_turn_boundary" ? this.steeringMode : this.followUpMode;

```

## Remote Control via RPC

Remote clients can dynamically change the steering mode using RPC commands:

```typescript
// packages/coding-agent/src/modes/rpc/rpc-client.ts
// Lines 284-287
await this.send({ type: "set_steering_mode", mode });

```

This updates `session.steeringMode` in the running agent session, allowing external tools to adjust interrupt behavior without restarting the agent.

## Complete Working Example

```typescript
// Queue a steering message to interrupt current processing
await session.steer("Switch to a simpler model", undefined, {
  resumeIfIdle: true,
});

// Queue a follow-up answer for after the turn completes
await session.addFollowUp("The answer is 42");

// Inspect current queue state
const { steering, followUp } = session.getAllQueuedMessages();

// Clear both queues if needed
const cleared = session.clearQueue();

```

## Summary

- Prime Agent uses a **dual-queue architecture** separating steering (interrupt) from follow-up (post-turn) messages in `AgentConnectionQueueState`
- **Steering messages** are stored in `connectionQueue.steering` and can interrupt active turns based on the current steering mode
- **Follow-up messages** are stored in `connectionQueue.followUp` and process only after steering messages complete
- **Steering modes** (`"one-at-a-time"` vs `"all"`) control whether steering messages are delivered individually or batched at turn boundaries
- The **RPC interface** exposes `set_steering_mode` for remote queue behavior adjustment via [`packages/coding-agent/src/modes/rpc/rpc-client.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/rpc/rpc-client.ts)

## Frequently Asked Questions

### What is the difference between steering and follow-up messages in Prime Agent?

Steering messages are high-priority prompts designed to interrupt the agent's current turn for real-time course corrections, such as changing models or stopping execution. Follow-up messages are standard user inputs that wait for the current turn to complete before processing, suitable for answering questions or providing information the agent requested.

### How does the "one-at-a-time" steering mode affect message delivery?

When configured to `"one-at-a-time"`, the agent delivers only the first queued steering message and waits for the agent's response before delivering the next. This sequential processing prevents message flooding and ensures the agent fully processes each interrupt before handling additional steering input, as implemented in the turn-selection logic at line 5458 of [`agent-session.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/agent-session.ts).

### Can I clear specific messages from only one queue?

The `clearQueue()` method in [`packages/coding-agent/src/core/agent-session.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/agent-session.ts) clears both the steering and follow-up queues simultaneously, returning the cleared messages from each. To selectively clear individual messages, you must first use `getAllQueuedMessages()` to inspect contents, then implement custom filtering logic before calling the clear methods on the underlying action store.

### How do remote clients change the steering mode?

Remote clients send an RPC command `set_steering_mode` through the connection defined in [`packages/coding-agent/src/modes/rpc/rpc-client.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/rpc/rpc-client.ts). The daemon forwards this to update `session.steeringMode`, immediately affecting how subsequent steering messages are delivered without requiring a session restart.