Managed Agents Worker on Sprites
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`.Optional: hand this page to your coding agent
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.
| Phase | Activity | Point |
|---|---|---|
| Create | spriteCreate | spawn the per-session sandbox |
| Secure | spriteApplyNetworkPolicy | egress allowlist — Anthropic + registries, deny the rest |
| Hold | spriteTaskCreate | keep-alive task so the Sprite will not pause |
| Stage | spriteWriteFile | the runner env-contract, written to a file |
| Runner | spriteApplyServices | Anthropic’s runner as a supervised service, started |
| Run | spriteExec | the session’s tool calls execute in the sandbox |
| Release / Destroy | spriteTaskRelease / spriteDestroy | free 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.
The session
Section titled “The session”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 }], }),]),The keep-alive hold
Section titled “The keep-alive hold”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.
Prerequisites
Section titled “Prerequisites”- Node.js and
npm. - Docker, for the offline run, where
chant emulator upboots the emulator in a container. Real mode needs no Docker.
Run it offline
Section titled “Run it offline”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.
cd examples/sprites-managed-agent-workernpm install
chant emulator up# ✓ fly: chant-mudflaps up on http://localhost:4280# ✓ fly: chant-spritzer up on http://localhost:4290export SPRITES_BASE_URL=http://localhost:4290
chant run managed-agent-session
chant emulator down # stop both containers when doneThe 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:
unset SPRITES_BASE_URL # the sprite steps fall through to real Sprites
export SPRITES_API_TOKEN=... # a Sprites tokenexport ANTHROPIC_ENVIRONMENT_KEY=... # the scoped environment key, not your org API keyThe 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.