Agent is a StatefulActor — understanding four
properties of that execution model explains why the SDK looks the way it does.
One actor per conversation
You address an agent by name:env.CONVOS.idFromName("+15550001111") always routes to
the same actor instance, anywhere in the fleet. That makes the phone number (or user id,
or session id) the unit of isolation — each conversation gets its own history, state,
and timers, with no cross-talk and no shared database to partition. See
Addressing.
Turns are serialized
An actor runs one method call at a time. Whileprocess() is thinking, a second
inbound message waits — it never interleaves. That is what makes the read-modify-write
patterns in agent code safe without locks: this.messages.add() then
this.queue("process") can’t race another webhook for the same customer. See
Execution model.
Think in the background
Inbound RPC methods run under a 30-second wall-clock budget — fine forreceive(), tight for an LLM round-trip plus tool calls. That’s why the quickstart acks
the webhook and defers the thinking:
alarm() handler, which has a
larger budget — on the order of minutes — and retries on
failure. Put LLM calls, tool use, and outbound API
work there.