How Prime Agent's Message Queue Handles Steering vs Follow-Up Messages
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:
// 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:
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:
// 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:
// 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:
// 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:
// 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
// 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.steeringand can interrupt active turns based on the current steering mode - Follow-up messages are stored in
connectionQueue.followUpand 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_modefor remote queue behavior adjustment viapackages/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.
Can I clear specific messages from only one queue?
The clearQueue() method in 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. The daemon forwards this to update session.steeringMode, immediately affecting how subsequent steering messages are delivered without requiring a session restart.
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 →