> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AgentClient

> The browser/Node client — connect to a live agent over WebSocket, mirror its state, subscribe to messages and events, and make typed RPC calls.

`AgentClient` is the client SDK for connecting to a live agent over WebSocket. It
keeps a local mirror of the agent's persistent state — a snapshot on connect, incremental
RFC 7396 merge-patches as the agent changes state — and makes typed RPC calls to the
agent's remote-callable methods through `stub`. It ships at
`@telnyx/edge-runtime/client` with no server dependencies: it uses the platform's
native `WebSocket` (browser, or Node ≥ 22).

```ts theme={null}
import { AgentClient } from "@telnyx/edge-runtime/client";

type DeskStub = {
  humanReply(text: string): Promise<void>;
};
interface DeskState {
  status: string;
}

const agent = new AgentClient<DeskStub, DeskState>(
  "wss://my-func.telnyxcompute.com/agents/conversation/alice",
);
agent.onState((s) => render(s));
await agent.stub.humanReply("On it — give me a minute.");
```

The client reconnects automatically with jittered exponential backoff and heartbeats
the link, so a dead socket is detected and rebuilt. Calls made while the link is down
are buffered and flushed once it is back; calls in flight when the link drops reject.

Passing any of `token` / `subscribe` / `resume` switches the client into attach mode:
every (re)connect opens the session with an `attach` frame presenting the token, and
the server answers with the granted claims — readable via `claims` — and the accepted
streams (`"state"`, `"messages"`, `"events"`). With `resume: true`, the client
re-attaches after a drop with its last-seen `messages`/`events` cursors and the server
replays exactly what was missed — no full re-snapshot, no duplicates. Without any
attach option, the client speaks the plain protocol (snapshot + `hello`) and works
against servers that only speak that.

```ts theme={null}
const agent = new AgentClient<DeskStub, DeskState>(url, {
  token: sessionToken, // the server derives this connection's claims from it
  subscribe: ["state", "messages", "events"],
  resume: true, // replay exactly what was missed across reconnects
});
agent.onMessages(({ snapshot, appended }) => updateThread(snapshot, appended));
agent.onEvents((e) => progress(e.type, e.payload), { from: 1 });
// after the server's attached answer: agent.claims → e.g. ["read", "rpc"]
```

## new AgentClient()

> **new AgentClient**\<`TStub`, `TState`>(`url`, `opts?`): [`AgentClient`](/docs/agent-sdk/api-reference/agent-client)\<`TStub`, `TState`>

Create a client and start connecting immediately.

**Parameters**

| Parameter | Type                                                                                  | Description                                                 |
| --------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `url`     | `string`                                                                              | The agent's WebSocket endpoint (`wss://...` or `ws://...`). |
| `opts`    | [`AgentClientOptions`](/docs/agent-sdk/api-reference/agent-client#agentclientoptions) | Connection, heartbeat, and attach-mode options.             |

**Returns**

[`AgentClient`](/docs/agent-sdk/api-reference/agent-client)\<`TStub`, `TState`>

**Throws**

If no global `WebSocket` exists and none was injected via
`opts.WebSocketCtor`.

## stub

> `readonly` **stub**: `TStub`

The typed RPC proxy. `agent.stub.method(...args)` sends a `call` frame
and resolves with the agent method's return value, or rejects with the
server's error (e.g. `method_not_found`, or `method_error` when the
method threw).

## claims

> **get** **claims**(): readonly `Claim`\[]

The claims granted to this connection by the server's `attached` answer.
Empty until an `attached` frame arrives (always empty outside attach mode).

**Returns**

readonly `Claim`\[]

## onState()

> **onState**(`listener`): () => `void`

Subscribe to state updates; returns an unsubscribe function.

**Parameters**

| Parameter  | Type                       |
| ---------- | -------------------------- |
| `listener` | `StateListener`\<`TState`> |

**Returns**

() => `void`

## onMessages()

> **onMessages**(`listener`): () => `void`

Subscribe to conversation updates from the actor's `MessageLog`. A
`snapshot` replaces the local log; `appended` adds the new messages. Returns
an unsubscribe function.

**Parameters**

| Parameter  | Type            |
| ---------- | --------------- |
| `listener` | (`u`) => `void` |

**Returns**

() => `void`

## onEvents()

> **onEvents**(`listener`, `opts?`): () => `void`

Subscribe to the agent's event stream (attach mode with `"events"`
subscribed). Events arrive in `seq` order; pass `{ from }` to receive only
events with `seq >= from`. Returns an unsubscribe function.

**Parameters**

| Parameter    | Type                    |
| ------------ | ----------------------- |
| `listener`   | `EventListener`         |
| `opts`       | \{ `from?`: `number`; } |
| `opts.from?` | `number`                |

**Returns**

() => `void`

## isConnected()

> **isConnected**(): `boolean`

True once the first `hello` is received (and until closed).

**Returns**

`boolean`

## close()

> **close**(`code?`, `reason?`): `void`

Permanently close the client (no reconnect). Outstanding calls reject.

**Parameters**

| Parameter | Type     | Default value     |
| --------- | -------- | ----------------- |
| `code`    | `number` | `1000`            |
| `reason`  | `string` | `"client closed"` |

**Returns**

`void`

## AgentClientOptions

Options for [AgentClient](/docs/agent-sdk/api-reference/agent-client).

Setting any of `token` / `subscribe` / `resume` switches the client into
attach mode (see the [AgentClient](/docs/agent-sdk/api-reference/agent-client) class docs); the connection and
heartbeat options apply in both modes.

**Properties**

**pingIntervalMs?**

> `optional` **pingIntervalMs?**: `number`

Heartbeat: send a `ping` every `pingIntervalMs` (default 30\_000).

***

**pingTimeoutMs?**

> `optional` **pingTimeoutMs?**: `number`

Reconnect if a `ping` goes unanswered for `pingTimeoutMs` (default 10\_000).

***

**reconnectBackoffMs?**

> `optional` **reconnectBackoffMs?**: `number`

Base reconnect backoff in ms. Delays grow exponentially (factor 2, ±20%
jitter) from this base up to `reconnectMaxBackoffMs`.

**Default Value**

```ts theme={null}
250
```

***

**reconnectMaxBackoffMs?**

> `optional` **reconnectMaxBackoffMs?**: `number`

Upper bound on the reconnect backoff delay, in ms.

**Default Value**

```ts theme={null}
30_000
```

***

**resume?**

> `optional` **resume?**: `boolean`

Resume across reconnects: re-attach with the last-seen `messages`/`events`
cursors so the server replays exactly what was missed — no full
re-snapshot, no duplicates. The first connection carries no cursors (a
normal snapshot bootstrap is expected).

***

**subscribe?**

> `optional` **subscribe?**: readonly `Stream`\[]

Streams to subscribe to. Omitted = the server's default set.

***

**token?**

> `optional` **token?**: `string`

Opaque credential presented in the `attach` frame; the server derives this connection's grants from it.

***

**WebSocketCtor?**

> `optional` **WebSocketCtor?**: `AgentWebSocketCtor`

WebSocket constructor (defaults to the platform `globalThis.WebSocket`).
Inject one for environments without a global, or for tests.

## AgentEvent

One item of the agent's event stream, as delivered to `onEvents` listeners.

**Properties**

**at**

> `readonly` **at**: `Date`

Wall-clock stamp at emit time; informational (ordering is by `seq`).

***

**payload**

> `readonly` **payload**: `unknown`

The event's payload, exactly as the agent emitted it.

***

**seq**

> `readonly` **seq**: `number`

Monotonic position in the event stream; also the resume cursor.

***

**type**

> `readonly` **type**: `string`

The event kind the agent chose when emitting (e.g. `"progress"`).
