← Knowledge

Agent Wake Policies

A vocabulary for deciding when a persistent agent should run and what evidence should trigger it.

An agent is a persistent entity with memory, a conversation is a thread on that agent, and a session is the active connection used to send messages and stream events. Agent memory and conversation history persist beyond an individual SDK connection.

This model separates availability into two mechanisms: retained state and a cause for the next turn. A wake policy turns evidence into finite executions; it does not require the model to run continuously.

A wake policy decides what evidence may start an agent turn, where the work executes, which prior state it receives, and how completion is recorded. An evidence source is an observable occurrence such as a deadline, an inbound message, or an environment change. A bounded wake execution begins from one identified evidence item and ends with a terminal turn result. One turn may start zero, one, or multiple Letta runs.

Wake policy supplies the start condition around persistent agent execution. The agent trajectory then records what happened after the wake.

Match the mechanism to the evidence

The schedule documentation defines one-time and recurring agent prompts. Cloud schedules use a server-side timer, while local schedules fire only while a Letta application, CLI, or server process is running. A task targeted to a specific connected computer can fall back to a Cloud sandbox when that computer is offline; a strictly local task never falls back.

Schedules fit temporal reasons for running: preparing a weekday briefing, inspecting a system once per hour, or issuing a reminder at a known time.

A Letta schedule starts agent execution on every firing, even if the external source has not changed. A fast schedule therefore trades detection delay against repeated agent runs; it does not provide a pre-run change detector.

By default, every scheduled Letta run starts a new conversation. The documentation describes this as protection against recurring tasks bloating the main context or cluttering its history. A schedule can instead target the default conversation, a specific conversation ID, or the conversation in which the task was created. Fresh conversations fit independent inspections, while a continuing conversation fits work that depends on an accumulating thread.

Inbound work has a different mechanism. The documented Letta mechanism begins when an application calls send(). If another turn is active, the runtime queues the message rather than dropping it. The session documentation describes application-initiated turns through send(); it does not describe a native webhook or delivered-record trigger. An external application may receive a webhook, command, or record and then call send() with the evidence itself or an immutable reference to it.

When arrival already identifies a change, avoid adding a timer between receipt and send(). The external receiver supplies the event interface; the SDK supplies the turn.

When a source cannot announce changes, there are two distinct polling designs:

  • A Letta schedule invokes an agent prompt at every firing. This fits checks that require agent judgment each time.
  • An external timer can run an application-level detector over a cursor, version, timestamp, or content identifier. Place that detector in the external application and call send() only after it observes changed evidence.

The second design avoids spending an agent run on unchanged state. The Letta schedule itself cannot provide that pre-agent filter because its firing has already started the scheduled agent prompt.

Some environments advance through explicit ticks. The Generative Agents study populated a sandbox with twenty-five agents, and at each sandbox time step each agent output a natural-language statement describing its current action. The architecture combined a memory stream and retrieval with reflection and planning. The researchers report that ablations restricting memory, reflection, or planning reduced the believability of agent behavior.

The experiment demonstrates discrete, environment-driven agent execution inside a simulation rather than a general requirement for uninterrupted model activity. A world tick can serve as wake evidence when the simulated environment has advanced enough to require perception or action.

Turn each wake into one bounded execution

The session documentation defines a turn as one send() followed by one pass through stream(). The stream terminates after a result message carrying the final text, success status, stop reason, and duration. If the turn starts one or more Letta runs, result.runIds lists them; if it fails before any run starts, that field is absent.

That terminal result provides an outer control boundary. An application-level contract can add three parts:

  1. Evidence address. Record the deadline, message, environment step, or observed version that caused the wake. Attempts carrying the same address can then be recognized as competing executions of the same work.
  2. Execution scope. Declare the conversation, computer or sandbox, tools, and permitted effects for the turn. Session-scoped controls include cwd, environment variables, computer or sandbox selection, client tools, and permission behavior.
  3. Terminal receipt. Preserve the turn result and any separate evidence that an external effect occurred. The SDK result is a receipt for the turn, not proof that every requested external mutation became visible.

When a typed stream message belongs to a run, assistant text, reasoning, tool calls, tool results, errors, and retries carry a runId. An application-level record can attach the triggering evidence and external effect receipts to those identifiers. The resulting chain is inspectable: evidence arrived, particular runs handled it, and an intended effect was or was not observed.

Design for misses and ambiguous delivery

Timer failures and connection failures create different uncertainty.

A local schedule fires only while its owning Letta process is active. A one-time local task overdue by more than five minutes may be marked as missed. Cloud schedules use a server-side timer, but a task targeted to a connected computer may fall back to a Cloud sandbox when that computer is offline.

Fallback availability can change the execution context of the run. A task that requires local files or tools should verify that the selected environment satisfies those requirements before producing effects.

The SDK does not replay stream events missed during a disconnect. After resuming, a client can reconcile through conversation history with listMessages() or fetch a consolidated state snapshot with bootstrapState().

The documentation also warns against blindly retrying after a connection fails following a successful send(), because the message may already have reached the runtime. The missing acknowledgement does not establish that the turn was never accepted.

Handle that ambiguity with a stable key for each evidence item, a completion check before producing effects, and idempotent effects where possible. For this policy, an idempotent effect is one where processing the same evidence twice leaves the external system in the same intended state as processing it once. If an effect cannot be made idempotent, the policy should stop for reconciliation rather than guess whether omission or duplication is safer.

Choose by the cost of being wrong

Evidence shape Wake mechanism Main failure to design for
A deadline or recurring interval Letta Cloud or local schedule The local process is unavailable, the task is missed, or fallback uses an unsuitable environment
An inbound command, webhook, or delivered record External receiver followed by send() Delivery succeeded but acknowledgement was lost, causing a blind retry
An advancing simulated environment Simulation loop processes an explicit environment tick Excessive cadence creates unnecessary turns, while coarse cadence delays reactions
A source with no event interface External timer and detector followed by send() only on change The detector loses its cursor or treats unchanged evidence as new work

The cost model belongs in the policy. If missing one occurrence is cheap and duplicate side effects are dangerous, require reconciliation before retrying. If delay is expensive and repeated processing is harmless, permit repeated detection while suppressing duplicate effects through the evidence key.

A compact wake-policy record should name the evidence source, trigger mechanism, execution target, conversation strategy, evidence key, retry rule, missed-work rule, effect permissions, and terminal receipt. Those fields turn keep the agent running into inspectable decisions rather than an indefinite model loop.

Sources

  1. Letta schedules documentation
  2. Letta Agent SDK sessions, turns, and durability
  3. Generative Agents: Interactive Simulacra of Human Behavior

Connections

Related

Linked here

Suggest a correction ↗

Appearance