# Understanding Generation-Aware Event Cursors in Prime Agent

> Discover generation-aware event cursors in Prime Agent. Learn how these { generation, sequence } pairs uniquely identify stream events, preventing gaps and duplicates for seamless client resumption.

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

---

**Generation-aware event cursors are `{ generation, sequence }` pairs that uniquely identify events in a stream, enabling clients to resume without gaps or duplicates.**

Prime Agent models assistant messages, tool calls, and state snapshots as an ordered event stream. To support reliable reconnection after network drops or daemon restarts, the system uses **generation-aware event cursors**—composite identifiers that track both snapshot boundaries and in-snapshot ordering.

## What Are Generation-Aware Event Cursors?

A **generation-aware event cursor** consists of two numeric fields:

| Field | Purpose |
|-------|---------|
| `generation` | Increments each time a **snapshot** of the full session state is taken. All events within the same snapshot share this value. |
| `sequence` | Zero-based counter that increments for every event **within** a generation, providing exact positional ordering. |

Together, `{ generation, sequence }` creates a lexicographically sortable key. A cursor with higher `generation` is always newer; if `generation` is equal, higher `sequence` is newer.

This design decouples **snapshot recovery** (large state boundaries) from **incremental streaming** (individual events), giving the protocol both durability and granularity.

## How Cursors Enable Reliable Resumption

When a client reconnects to a Prime Agent daemon, it passes its last observed cursor. The server then streams only events with strictly greater `(generation, sequence)` pairs. This guarantees three properties:

- **No gaps**: Every event after the client's cursor is delivered.
- **No duplicates**: Events at or before the cursor are skipped.
- **Deterministic ordering**: Events arrive in exact emission order, even across snapshot boundaries.

The cursor mechanism is defined in the [daemon protocol documentation](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/docs/daemon.md) and implemented in [[`packages/ai/src/utils/event-stream.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/utils/event-stream.ts)](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/utils/event-stream.ts).

## Practical Usage Examples

### Basic Cursor Tracking

```typescript
import { Agent } from '@primeintellect/agent';

const agent = new Agent();

// Track the last seen cursor for resumption
let lastCursor: { generation: number; sequence: number } | undefined;

agent.on('assistantMessage', (msg) => {
  // Each event carries its generation-aware cursor
  lastCursor = msg.cursor;
  console.log(`Received message at generation ${msg.cursor.generation}, sequence ${msg.cursor.sequence}`);
});

```

### Resuming After Interruption

```typescript
// After disconnect, restart from saved cursor
await agent.connection.start({
  cursor: lastCursor,  // Daemon skips all events <= this cursor
});

```

### Requesting Specific Historical Range

```typescript
// Manually construct cursor to fetch from a known point
const cursor = { generation: 5, sequence: 12 };

await agent.connection.start({ cursor });
// Receives events starting from generation 5, sequence 13 onward

```

## Implementation Architecture

The **Prime Agent** codebase implements generation-aware cursors across two key locations:

| File | Role |
|------|------|
| [`packages/coding-agent/docs/daemon.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/docs/daemon.md) | Protocol specification defining cursor semantics |
| [`packages/ai/src/utils/event-stream.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/utils/event-stream.ts) | Stream utilities attaching cursors and performing comparisons |

In [`event-stream.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/event-stream.ts), each `AssistantMessageEvent` receives its cursor at emission time. The stream-merge logic compares incoming cursors against client-supplied values using lexicographic ordering:

```typescript
// Conceptual comparison from event-stream.ts
function isNewer(candidate: Cursor, reference: Cursor): boolean {
  if (candidate.generation > reference.generation) return true;
  if (candidate.generation < reference.generation) return false;
  return candidate.sequence > reference.sequence;
}

```

## When to Use Generation-Aware Cursors

Consider explicit cursor management when:

- Building **long-running agents** that must survive process restarts
- Implementing **multi-device synchronization** where clients join mid-stream
- Creating **audit trails** requiring precise event positioning
- Developing **custom clients** outside the official SDK

For typical ephemeral sessions, the SDK handles cursor persistence automatically.

## Summary

- **Generation-aware event cursors** combine `generation` (snapshot ID) and `sequence` (in-snapshot position) to uniquely identify any event.
- Cursors enable **exactly-once delivery semantics** on reconnection by filtering events newer than the supplied cursor.
- The `{ generation, sequence }` structure is **lexicographically comparable**, simplifying server-side filtering logic.
- Prime Agent implements this protocol in [`daemon.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon.md) and [`event-stream.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/event-stream.ts), with cursors attached to all `AssistantMessageEvent` objects.

## Frequently Asked Questions

### How does the generation number get incremented?

The `generation` increments each time the daemon captures a **snapshot** of the full session state. This typically occurs at tool call boundaries or explicit checkpoint requests, persisting the current event log to durable storage.

### Can I construct cursors manually for debugging?

Yes. Cursors are plain objects with `generation` and `sequence` number fields. You can construct them for targeted debugging, though production code should derive cursors from received events to ensure validity.

### What happens if I pass a future cursor?

The daemon validates the cursor against its event log. If the cursor refers to a generation or sequence beyond known events, the connection will error or await new events depending on your client's configuration.

### Are cursors stable across server restarts?

Yes. Because `generation` correlates with persisted snapshots and `sequence` is deterministic within each snapshot, cursors remain valid even if the daemon process restarts—provided the snapshot store is intact.