---
title: Continuations
description: Persist and resume Eve client sessions with continuation tokens, session IDs, and stream cursors.
---

# Continuations



Every Eve client turn returns two handles, and mixing them up is a common mistake. The TypeScript client tracks both for you:

* `continuationToken`: the resume handle. Use it to send the next user turn.
* `sessionId`: the stream-and-inspect handle. Use it to attach to event history.

`ClientSession` also tracks `streamIndex`, the count of events already consumed. Together these three fields make a `SessionState`.

## Read and persist state

After a streamed turn finishes, read `session.state`:

```ts
const session = client.session();

const response = await session.send("Create a launch checklist.");
await response.result();

await saveSessionState(session.state);
```

Store the full state object:

```ts
interface SessionState {
  continuationToken?: string;
  sessionId?: string;
  streamIndex: number;
}
```

The continuation token resumes the conversation. The session ID and stream index let the client reconnect to the right stream position without replaying events it already consumed.

## Resume a saved session

Pass the saved state back into `client.session()`:

```ts
import type { SessionState } from "eve/client";

const saved = (await loadSessionState()) as SessionState;
const session = client.session(saved);

const response = await session.send("Now shorten it.");
const result = await response.result();
console.log(result.message);
```

If all you have is a continuation token, pass it as shorthand:

```ts
const session = client.session(continuationToken);
const response = await session.send("Continue where we left off.");
await response.result();
```

The shorthand can send a follow-up, but it doesn't know the previous stream cursor. Prefer full `SessionState` when you control persistence.

## Waiting, completed, and failed sessions

When a turn ends with `session.waiting`, the client preserves the state so the next send continues the conversation.

When a turn ends with `session.completed` or `session.failed`, the client resets its local state. The next send starts a fresh durable session:

```ts
const response = await session.send("Do this one-shot task.");
const result = await response.result();

if (result.status === "completed") {
  // session.state is now a fresh cursor: { streamIndex: 0 }
}
```

This matches the runtime contract, where only waiting sessions can accept the next user input.

## Multiple sessions

Create a separate `ClientSession` per conversation:

```ts
const research = client.session();
const support = client.session();

const researchResponse = await research.send("Research competitors.");
await researchResponse.result();

const supportResponse = await support.send("Draft a support reply.");
await supportResponse.result();

await save("research", research.state);
await save("support", support.state);
```

The shared `Client` only owns host, auth, headers, and reconnect settings. Conversation state lives on each `ClientSession`.

## Reconnect an existing stream

When a session already has a `sessionId`, `session.stream()` reattaches to its stream from the saved cursor. Resuming a saved `SessionState` after a restart is the common reason to do this:

```ts
const session = client.session(savedState);

for await (const event of session.stream()) {
  console.log(event.type);
}
```

`stream()` attaches to an existing run; to send new user input, use `send()`. For overriding the cursor with `startIndex` and the full reconnection model, see [Streaming](./streaming#open-a-stream-manually).

## What to read next

* [Streaming](./streaming): stream events and reconnect by index
* [Sessions, runs & streaming](../../concepts/sessions-runs-and-streaming): the raw HTTP contract
* [Eve channel](../../channels/eve): where continuation tokens come from


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)