How the AgentConnection Client Handles Session Reconnection in Prime Agent

The AgentConnection client in Prime Agent detects WebSocket closures via the onclose event, triggers an exponential backoff retry loop, and regenerates the connection with a fresh UUID before restoring pending RPC calls and channel subscriptions to maintain session continuity.

The AgentConnection client in the PrimeIntellect-ai/prime-agent repository provides a resilient RPC layer between the UI and the Prime Agent daemon. Located at packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts, this client ensures that temporary network interruptions do not terminate active coding sessions. When the underlying WebSocket transport drops, the client executes a sophisticated reconnection sequence that preserves the session identifier and message ordering.

Step-by-Step Session Reconnection Flow

Detecting Transport Loss

When the WebSocket closes, the client's onclose handler immediately marks the connection as disconnected and queues a reconnection task. This prevents any new outbound messages from attempting to use the dead socket and ensures that the isConnected flag reflects the actual transport state.

Exponential Backoff and Retry Logic

The client implements a defensive backoff strategy defined by INITIAL_RECONNECT_DELAY_MS and MAX_RECONNECT_DELAY_MS. The reconnectDelay value doubles after each failed attempt, capped at the maximum threshold, to avoid overwhelming the daemon or network with reconnection storms. This logic resides in the reconnectLoop implementation within the connection class.

Creating a New Socket with Fresh Identity

Upon each retry, the createSocket method instantiates a fresh WebSocket to the same endpoint. To prevent collision with stale server-side sessions, the client generates a new unique identifier using the pattern daemon-agent-connection:${randomUUID()}. This ensures the daemon treats each reconnection attempt as a distinct client instance while the session ID remains constant.

Restoring Session State

Once the socket opens (onopen), the handleOpen method re-issues the handshake containing the original sessionId, re-sends any queued RPC requests, and re-subscribes to channels like agents-view and session-status. This state restoration guarantees that the user interface receives all pending events as if no interruption occurred.

Resuming API Operations

Higher-level code awaits the awaitConnected promise, which resolves only after the socket is fully re-established and the handshake completes. This abstraction allows UI components to remain agnostic to transient disconnections, continuing operations seamlessly once the transport recovers.

Implementation Details from the Source Code

The following example demonstrates how to instantiate the connection and wait for stability:

import { DaemonAgentConnection } from 'packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.js';

async function initializeAgent() {
  const conn = new DaemonAgentConnection({
    url: process.env.PRIME_AGENT_WS_URL!,
    sessionId: 'persistent-session-001',
    authToken: process.env.PRIME_AGENT_TOKEN!,
  });

  await conn.awaitConnected(); // Resolves after initial connect or any reconnection
  console.log('Agent ready for RPC calls');
}

Internally, the client manages the reconnection lifecycle with exponential backoff:

private onClose = (event: CloseEvent) => {
  this.log('Socket closed, reason:', event.reason);
  this.isConnected = false;
  this.scheduleReconnect(); // Triggers exponential backoff
};

private async scheduleReconnect() {
  while (!this.isConnected) {
    await delay(this.reconnectDelay);
    this.reconnectDelay = Math.min(
      this.reconnectDelay * 2,
      MAX_RECONNECT_DELAY_MS,
    );
    try {
      this.createSocket(); // Fresh WebSocket with new clientId
    } catch (err) {
      // Continue retry loop until successful
    }
  }
}

Validation Through Testing

The reconnection behavior is rigorously verified in packages/coding-agent/test/daemon-agent-connection-reconnect-park.test.ts. This test suite simulates abrupt network failures and validates that the client correctly re-establishes the WebSocket transport, restores the session context identified by sessionId, and maintains message ordering without dropping pending RPC operations.

Summary

  • Transport Detection: The onclose handler immediately marks the socket as disconnected and halts outbound traffic.
  • Backoff Strategy: Exponential delay prevents reconnection storms, respecting INITIAL_RECONNECT_DELAY_MS and MAX_RECONNECT_DELAY_MS limits.
  • Identity Management: Each attempt uses createSocket with a regenerated UUID (daemon-agent-connection:${randomUUID()}) to avoid session collisions.
  • State Restoration: The handleOpen method re-subscribes to channels and re-sends pending RPCs after the handshake.
  • Consumer Interface: The awaitConnected promise provides a seamless abstraction, masking transient failures from higher-level code.

Frequently Asked Questions

Does the AgentConnection client lose pending RPC calls during reconnection?

No. The client maintains an internal queue for all pending RPC requests during the disconnected state. Once handleOpen completes the handshake with the daemon, these requests are automatically re-sent in their original order, ensuring no operations are lost during transient network failures.

How does the client prevent duplicate sessions on the daemon side?

The createSocket method generates a unique clientId using the template daemon-agent-connection:${randomUUID()} for every new WebSocket instance. This prevents the daemon from confusing the new connection with a potentially stale, lingering session from the previous socket, while the persistent sessionId maintains continuity.

What is the maximum delay between reconnection attempts?

The backoff delay is capped at MAX_RECONNECT_DELAY_MS, which puts an upper bound on the reconnectDelay regardless of how many consecutive failures occur. This balances recovery speed with network resource conservation according to the implementation in daemon-agent-connection.ts.

How can I verify that my integration handles reconnections correctly?

You can run the integration tests in packages/coding-agent/test/daemon-agent-connection-reconnect-park.test.ts, which simulate connection drops and assert that the client restores the session and resumes normal operation without manual intervention.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →