Skip to content

Managed Agents Worker on Sprites

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 — 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 — no build phase, no 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 — never process args, so the scoped key never shows up in a process listing — and 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 — it boots the spritzer emulator in a container). Real mode needs no Docker.

Boot the spritzer emulator, point the sprite endpoint at it, and run the Op:

Terminal window
docker run -d --rm -p 4290:4290 --name spritzer ghcr.io/intentius/spritzer:0.4.1
cd examples/sprites-managed-agent-worker
npm install
export SPRITES_BASE_URL=http://localhost:4290
chant run managed-agent-session
docker rm -f spritzer # stop the emulator when done

The phases run end to end 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.