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

# Entry Points

The platform invokes the class at a few known points, and the class returns within a budget on each. The `Agent` class extends Edge Compute's [`StatefulActor`](/docs/edge-compute/stateful-actors/api-reference/base), and the platform calls it through the actor's entries.

| Entry point | Invoked by | Contract |
| - | - | - |
| [`fetch(req)`](/docs/edge-compute/stateful-actors/guides/project-structure#two-exports) on the function | Every request to the address | Answered by `mountAgents`, which resolves the instance and picks the transport. [The Address and Transports](/docs/agent-sdk/contract/address-and-transports) has the three. |
| Any method marked `@rpc` | `POST …/rpc/<method>` on the conversation's address, and the socket's RPC frames | One call, JSON in and out, within the [30-second budget](/docs/edge-compute/stateful-actors/api-reference/errors). Work that needs longer goes to a queued task. |
| A public method | A call through an [`ActorStub`](/docs/edge-compute/stateful-actors/api-reference/stub), from the function or from another instance | Actor RPC, under the [dispatch rules](/docs/edge-compute/stateful-actors/api-reference/base#dispatch-rules) of `StatefulActor`. `@rpc` does not apply to it. |
| [`webSocket(ws, req)`](/docs/edge-compute/stateful-actors/api-reference/base#websocket-ws-req) | A WebSocket upgrade on the conversation's address | The class owns the socket. The default runs the agent socket protocol, and the `voice()` mixin takes a call's media stream. The mixin is the `@telnyx/edge-runtime/voice` export of [The Agent Runtime SDK](/docs/agent-sdk/runtime-sdk). |
| `onTask(name, payload, ctx)` | The task scheduler, when a due task names no method on the class | Delivered at least once, inside the [alarm handler](/docs/edge-compute/stateful-actors/alarms), with a budget on the order of minutes. A task that names a method on the class is delivered to that method. [`queue()`](/docs/agent-sdk/interface/queue) creates a task. |
| `authorize(token, req)` | Every connection, once | Resolve the credential into claims. [`authorize`](/docs/agent-sdk/interface/authorize) is the reference, and [Mounting Agents](/docs/agent-sdk/mounting-agents#authorization-composes-—-it-does-not-replace) has both gates. |
| `onConnect(conn)`, `onAttach(att)` | A connection, as it is established and as it is admitted | Hooks. |
| [`alarm(info)`](/docs/edge-compute/stateful-actors/api-reference/base#alarm-alarminfo) | The platform's alarm | Reserved by the SDK, which drives the task scheduler with it. |

One instance runs one of these [at a time](/docs/edge-compute/stateful-actors/concepts/execution-model), so a handler never interleaves with another on the same conversation. [Execution Model](/docs/agents/model/execution-model) has the rest of the rules. A webhook is a request to `fetch` like any other, and what the function does with it is the function's own code.

## Activation

The platform constructs the class on every activation. The constructor opens the instance's stores and re-arms the task scheduler before the instance takes a call.

```ts theme={null}
// agent/agent.ts
constructor(ctx, env, options = {}) {
  super(ctx, env);
  // …
  this._tasks = new TaskScheduler(ctx.storage, () => randomUUID());
  this._state = new StateStore(ctx.storage, () => this.initialState());
  ctx.blockConcurrencyWhile(async () => {
    await beginActivation(ctx.storage);
    await this._tasks.rearm(this.now());
  });
}
```

* [`StatefulActor`](/docs/edge-compute/stateful-actors/api-reference/base#construction) receives `ctx` and `env` through `super(ctx, env)`. It keeps them as `this.ctx` and `this.env`.
* [`ctx.storage`](/docs/edge-compute/stateful-actors/api-reference/storage) backs the task scheduler and the state store. The message log and the event log are built on it too.
* [`ctx.blockConcurrencyWhile`](/docs/edge-compute/stateful-actors/api-reference/context#ctx-blockconcurrencywhile-fn) runs the store setup and the re-arm. Every other call waits until both finish. The callback has a 30-second budget.

## The Fetch Entry

The class does not override the actor's `fetch`. It inherits the default.

```ts theme={null}
// stateful-actor.ts
async fetch(_req) {
  return new Response("Not Found", { status: 404 });
}
```

* [`fetch(req)`](/docs/edge-compute/stateful-actors/api-reference/base#fetch-req) receives every request to the instance that is not an upgrade. A class that serves the streams and RPC over HTTP overrides it and passes the request to an [`AgentHttpServer`](/docs/agent-sdk/internals/the-http-server).

## The WebSocket Entry

The class overrides the actor's `webSocket` and hands each socket to its [socket server](/docs/agent-sdk/internals/the-socket-server).

```ts theme={null}
// agent/agent.ts
webSocket(ws, req) {
  if (!this._overridesSeam("authorize") &&
    !this._overridesSeam("onAttach") &&
    !this._overridesSeam("webSocket")) {
    throw new AgentSocketsNotEnabledError();
  }
  return this._socketServer().attach(ws, req);
}
```

* [`webSocket(ws, req)`](/docs/edge-compute/stateful-actors/api-reference/base#websocket-ws-req) receives the accepted socket and the handshake request. A class that overrides none of the three seams throws before it touches the socket, so the socket is refused.

## The Alarm Entry

The instance has one alarm. The task scheduler sets it through `ctx.storage`, to the earliest due task.

```ts theme={null}
// agent/tasks.ts
async rearm(_now) {
  const due = await taskEarliestDue(this.storage);
  if (due === undefined) {
    await this.storage.deleteAlarm();
    return;
  }
  await this.storage.setAlarm(due);
}
```

* [`ctx.storage.setAlarm`](/docs/edge-compute/stateful-actors/alarms) receives the earliest due time, in milliseconds since the epoch. Setting it again replaces the previous time, so every task shares the one alarm.
* [`ctx.storage.deleteAlarm`](/docs/edge-compute/stateful-actors/alarms) clears the alarm when no task is pending.

When the alarm fires, the class's `alarm` drains every due task and re-arms.

```ts theme={null}
// agent/agent.ts
async alarm(_info) {
  const dispatch = (task) => this._dispatch(task);
  // …
  for (;;) {
    const now = this.now();
    const earliest = await taskEarliestDue(this.ctx.storage);
    if (earliest === undefined || earliest > now)
      break;
    // …
    await this._tasks.runDue(now, dispatch);
  }
  // …
  await this._tasks.rearm(this.now());
}
```

* [`alarm(info)`](/docs/edge-compute/stateful-actors/api-reference/base#alarm-alarminfo) is the entry the platform calls when the alarm fires. Every task the drain dispatches runs inside it, under the alarm's [time budget](/docs/edge-compute/stateful-actors/alarms#limits).
