AgentsOpen SourceFreeActiveMachine-verified· intermediate · ~15 min setup

Flue: define a sandboxed headless agent and deploy it anywhere

Author a Flue agent manifest that runs each agent in a sandbox instead of a dedicated container, keeping infra costs flat as task volume grows, and validate the config before you deploy.

by Shilpa Mitra· verified today· v1.0.0

Run this workflow

CI-verified, 2/2 fixtures passing.

Build this with your agent

One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.

Intended Use

Anyone running headless agents at a volume where per-container cost adds up. CI validates the Flue agent manifest: a name is set, at least one tool is listed, sandbox config exists with a valid mode, and a deploy target is specified. The actual npm install, sandbox execution, and deploy are fenced.

Not for

  • Low-volume one-off agent runs where a container is perfectly affordable and simpler
  • Production load-bearing workloads before pinning a stable version, the API is actively evolving

The Stack

Tested Against

withastro/flue (2026-06)ruby@3.x (YAML stdlib)

Side effects & data flow

Network
none, local only
Writes
./flue-agent.yaml
Credentials
none required

Prerequisites

  • Node.js 18+
  • npm install @flue/runtime @flue/cli (to actually run)

Steps

  1. 1

    Author the agent manifest and validate it

    Write flue-agent.yaml: a name, a list of tools the agent can call, a sandbox block with a mode (virtual, local, or remote), and a deploy target. CI checks the required fields; the npm install and agent run are fenced.

    cat > flue-agent.yaml <<'YAML'
    name: code-reviewer
    tools:
      - read_file
      - run_tests
      - post_comment
    sandbox:
      mode: virtual
    deploy:
      target: cloudflare-workers
    YAML
    ruby -ryaml -e '
    c = YAML.safe_load(File.read("flue-agent.yaml")) || {}
    abort "BAD: name is required" if c["name"].to_s.empty?
    tools = c["tools"]
    abort "BAD: tools must be a non-empty list" unless tools.is_a?(Array) && !tools.empty?
    sandbox = c["sandbox"] || {}
    allowed = ["virtual", "local", "remote"]
    abort "BAD: sandbox.mode must be one of: " + allowed.join(", ") unless allowed.include?(sandbox["mode"].to_s)
    abort "BAD: deploy.target is required" if (c["deploy"] || {})["target"].to_s.empty?
    puts "manifest OK: agent " + c["name"].inspect + ", " + tools.length.to_s + " tool(s), sandbox mode " + sandbox["mode"].inspect + ", deploy -> " + c["deploy"]["target"].inspect
    '
  2. 2

    Install, run, and deploy (fenced)

    Install the Flue packages (npm install @flue/runtime @flue/cli), implement the tools listed in the manifest, then deploy with the Flue CLI. Pin the version in package.json before building anything load-bearing. The install, sandbox execution, and deploy are fenced.

Eval, 2 fixtures

Last passed: verified today
  • manifest-okcontainstimeout 30s · max $0

    Expected: manifest OK: agent

  • clean-exitexit_codetimeout 30s · max $0

    Expected: 0

Results

A full container per agent is the default but expensive pattern at scale. Flue (from the Astro team, ~6.6k stars) lets each agent run in a configurable sandbox (virtual, local, or remote container) on Node.js, Cloudflare Workers, GitHub Actions, GitLab CI, Daytona, or Render. The infra saving is real only when volume justifies it; for a handful of runs, a container is fine. The API is actively developed with no explicit stability guarantee, so pin your version.

Did this work for you?

Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.

Related workflows

Liked this workflow?

Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).