# How the AgentConnection Client Handles Session Reconnection in Prime Agent

> Learn how the AgentConnection client in Prime Agent handles session reconnection. Discover its automatic retry, UUID regeneration, and state restoration for seamless continuity.

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

---

**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](https://github.com/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`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/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:

```typescript
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:

```typescript
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`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/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`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/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`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/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.