Skip to content

Managed Agents Worker on Sprites

llms.txt lists every page for an agent
Optional: hand this page to your coding agentThe steps work by hand too.
Show the whole prompt
Read https://intentius.io/chant/tutorials/sprites-managed-agent-worker/.
Run `npm install` and `npx chant emulator up` in `examples/sprites-managed-agent-worker`, then run `npx chant run managed-agent-session --no-record` with `SPRITES_BASE_URL=http://localhost:4290` exported.
Show me the output of each phase, then run `npx chant emulator down`.
Do not set an Anthropic key or a Sprites token, and do not put a key in a process argument or a file you commit.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.

The sprites-managed-agent-worker example runs a Claude Managed Agents session inside a per-session Sprite, Fly.io’s stateful, checkpointable sandbox.

Anthropic runs the agent loop and the model and queues work items. A worker on your infrastructure claims each item and spawns a Sprite that executes the tools, so the agent’s filesystem and network egress never leave your account. The org API key stays with the worker, and only a scoped environment key reaches the Sprite.

This tutorial is the per-session unit the worker runs once per claimed work item. One Op composes every Sprite runtime primitive in turn:

  • Secure: an egress allowlist so the sandbox reaches only Anthropic and the package registries (spriteApplyNetworkPolicy);
  • Hold: a keep-alive task so the Sprite will not pause mid-session (spriteTaskCreate, released on exit);
  • Stage: the runner env-contract written to a file, never process args (spriteWriteFile);
  • Runner: Anthropic’s runner as a supervised service (spriteApplyServices);
  • Run, then Release and Destroy: the session works, then tears down.

The whole flow runs offline against the emulator (no Anthropic key, no Fly account), and points at real Sprites + real Managed Agents by changing two environment variables.

PhaseActivityPoint
CreatespriteCreatespawn the per-session sandbox
SecurespriteApplyNetworkPolicyegress allowlist — Anthropic + registries, deny the rest
HoldspriteTaskCreatekeep-alive task so the Sprite will not pause
StagespriteWriteFilethe runner env-contract, written to a file
RunnerspriteApplyServicesAnthropic’s runner as a supervised service, started
RunspriteExecthe session’s tool calls execute in the sandbox
Release / DestroyspriteTaskRelease / spriteDestroyfree the hold and tear down

onFailure releases the hold and destroys the Sprite, so a stuck session never leaves a paused-but-billed sandbox behind.

ops/managed-agent-session.op.ts is a pure activity sequence, with no build phase or serialized plan. The Secure phase locks egress before anything runs:

phase("Secure", [
spriteApplyNetworkPolicy({
id: SESSION,
rules: [
{ domain: "api.anthropic.com", action: "allow" },
{ domain: "*.pypi.org", action: "allow" },
{ domain: "*", action: "deny" },
],
}),
]),

The Stage phase writes the runner’s environment to a file instead of process args, so the scoped key never shows up in a process listing. The Runner phase starts Anthropic’s runner as a service that sources it:

phase("Stage", [
spriteWriteFile({ id: SESSION, path: "/run/agent.env", mkdir: true, mode: "0600", content: envContract }),
]),
phase("Runner", [
spriteApplyServices({
id: SESSION,
start: true,
services: [{ name: "agent-runner", cmd: "sh", args: ["-c", "set -a; . /run/agent.env; exec agent-runner"], dir: "/run", http_port: 8080 }],
}),
]),

A task holds the Sprite active while the session runs; without it the Sprite pauses after a short idle window. A task’s expire is capped at one hour, so a session that can run longer refreshes its hold on a shorter interval (the docs recommend a 5-minute expiry refreshed every 60 seconds with spriteTaskRefresh). That refresh loop lives in the long-running worker around this Op; this bounded session takes a single 5-minute hold and releases it at the end.

  • Node.js and npm.
  • Docker, for the offline run, where chant emulator up boots the emulator in a container. Real mode needs no Docker.

chant emulator up starts the local Sprites emulator (spritzer) in a container and prints its endpoint, http://localhost:4290. Export that as SPRITES_BASE_URL and the sprite activities talk to the emulator instead of the real Sprites API, so this needs no Sprites account and no key. The image tag is pinned in lexicons/fly/src/op/activities/emulator-images.ts. The fly lexicon ships two emulators, so up also starts mudflaps (the Machines API fake), which this Op does not use.

Terminal window
cd examples/sprites-managed-agent-worker
npm install
chant emulator up
# ✓ fly: chant-mudflaps up on http://localhost:4280
# ✓ fly: chant-spritzer up on http://localhost:4290
export SPRITES_BASE_URL=http://localhost:4290
chant run managed-agent-session
chant emulator down # stop both containers when done

The phases run against the emulator with no key: create the sandbox, apply the egress policy, take the keep-alive hold, stage the env-contract file, start the runner service, run the session, then release and destroy.

Run it against real Sprites + real Managed Agents

Section titled “Run it against real Sprites + real Managed Agents”

Drop the emulator override and provide the tokens. No code change:

Terminal window
unset SPRITES_BASE_URL # the sprite steps fall through to real Sprites
export SPRITES_API_TOKEN=... # a Sprites token
export ANTHROPIC_ENVIRONMENT_KEY=... # the scoped environment key, not your org API key

The scoped environment key is the one that reaches the Sprite; the org API key stays with the worker. See the example README for the worker loop and the Managed Agents setup.

chant