> ## 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.

# Agent Class

> The Agent base class — type parameters, construction, override hooks, and what's reserved.

`Agent<E, State>` extends `StatefulActor<E>`. Subclass it, declare async methods for
your inbound surface, and use the protected members inside them.

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

interface MyState extends Record<string, unknown> {
  status: "idle" | "processing";
}

export class SupportAgent extends Agent<MyEnv, MyState> {
  protected override initialState(): MyState {
    return { status: "idle" };
  }

  async receive(text: string): Promise<void> {
    await this.messages.add("user", text);
    await this.queue("process");
  }
}
```

## Type parameters

| Parameter | Constraint                        | Default                   | Meaning                                             |
| --------- | --------------------------------- | ------------------------- | --------------------------------------------------- |
| `E`       | `extends Env`                     | `Env`                     | Your environment/bindings type — becomes `this.env` |
| `State`   | `extends Record<string, unknown>` | `Record<string, unknown>` | Your persistent state shape                         |

## Construction

You don't construct agents yourself — the runtime does. On every activation the base
constructor also **re-arms the task scheduler** to the earliest pending task (inside
`ctx.blockConcurrencyWhile`), which is what makes timers survive crashes and restarts.

If you need your own one-shot init, override the constructor and call
`super(ctx, env)` first, exactly as with a
[StatefulActor](/docs/edge-compute/stateful-actors/api-reference/base).

## Override hooks

| Hook                         | Fires                                                                                                                                |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `initialState(): State`      | When state is read and nothing has been stored yet — return the default for a fresh actor                                            |
| `onStateChanged(next, prev)` | After every `setState()` **and `replaceState()`** resolves, with the new state and the state before the change                       |
| `onTask(name, payload, ctx)` | When a due task's `name` matches no method on the class — `ctx.attempt` carries the delivery attempt                                 |
| `onConnect(conn)`            | When a client connection is established — the socket layer is [AgentSocketServer](/docs/agent-sdk/api-reference/agent-socket-server) |
| `now(): number`              | Time source for the scheduler (defaults to `Date.now()`) — override in tests for a deterministic clock                               |

## Reserved: `alarm()`

The SDK claims the actor's alarm slot to drive the task scheduler: when the alarm
fires, `Agent.alarm()` drains every due task, dispatches each to the method it names,
and re-arms to the next deadline. **Overriding `alarm()` in an `Agent` subclass breaks
`queue`/`schedule`/`every`.** If you need timed work, schedule a task.
