Blueprints

A blueprint stitches agent, tool, script, and human-approval steps into a typed graph: hybrid deterministic/agentic workflows with fan-out, retry, and verify loops. This is how Boitata automates multi-step workflows instead of a single free-form agent run.

Blueprints are YAML files you provide. Point --blueprint at a path, either one of the ready-to-copy examples under examples/blueprints/ or your own file:

# a shipped example
boitata run "fix the failing test" --blueprint examples/blueprints/fix_test_failure.yaml

# your own file
boitata run "prepare the repo" --blueprint ./my-blueprint.yaml

Agent nodes in a blueprint inherit the same provider, tools, policy, and agent settings the single-agent path uses.

Schema

A blueprint is a YAML document with a name, an entry node, a map of nodes, and a list of edges:

name: default
entry: main
nodes:
  main:
    type: agent
    prompt: "{task}"
  fmt:
    type: tool
    tool: cargo_fmt
  verify:
    type: script
    run: "cargo check"
edges:
  - {from: main, to: fmt}
  - {from: fmt, to: verify}
  - {from: verify, when: failure, to: main}
  - {from: verify, when: success, to: END}

Unknown fields are rejected (deny_unknown_fields), so a typo fails loudly at load time rather than silently misbehaving.

Node types

Every node is tagged by type (snake_case):

TypeFieldsWhat it does
agentprompt, tools?Run the LLM agent loop on prompt, optionally scoped to a subset of tools
tooltool, args?Invoke a registered tool with arguments (defaults to {})
scriptrunRun a shell script deterministically, routing on its exit code
humanprompt, mode?Pause for human input (human-in-the-loop); mode defaults to input
provisionimage, env?Create an ephemeral sandbox from image; its output is the sandbox id, referenced downstream as {name}. env is a list of variable names to forward into the sandbox (see below)
checkoutcontainer, repo, ref?, path?git clone a repo into a sandbox (path defaults to /workspace)
execcontainer, run, workdir?Run a shell command inside a sandbox, routing on its exit code
agent_sandboxcontainer, prompt, port?, command?Run the agent inside the sandbox over ACP, streaming its events into the run

The last four move a run off the host into an isolated sandbox. See Sandboxed Execution. A sandbox a run provisions is destroyed automatically when the run ends.

Forwarding secrets into a sandbox: a provision node's env lists environment variable names (for example env: [ANTHROPIC_API_KEY]). Their values are read from the orchestrator's environment at run time and injected into the container's environment only. A value is never written in the blueprint, shown in the graph view (which displays the names), or logged. Set the named variables where you run boitata, and keep secrets out of the YAML.

Prompts

{task} in an agent or human prompt is substituted with the run's task description. This is how a generic blueprint adapts to the task you pass on the command line.

Edges

Edges out of a node are either:

  • a single unconditional to, or
  • a set of conditional edges each tagged when: success | failure.

The loader folds the conditional set into one status router. to: END (any case) routes to the terminal sentinel; that path ends the run.

edges:
  - {from: verify, when: failure, to: fix}   # loop back on failure
  - {from: verify, when: success, to: END}   # finish on success

Several edges sharing a when fan out (parallel super-steps); a status with no edge yields an empty set and that path ends.

Execution model

  • Parallel super-steps. Edges that fan out from one node run concurrently (fan-out / fan-in).
  • Checkpoint and retry. A failing super-step can be retried, each attempt restoring the pre-step state from an in-memory checkpoint. Bounded by blueprint_max_retries.
  • Step limit. Cyclic graphs are bounded by blueprint_max_steps.
  • Human-in-the-loop. A human node with mode: approval prompts for a yes/no; an affirmative reply routes onward, anything else ends the run. Requires an interactive stdin; on a non-interactive run the approval node errors rather than proceeding unattended.

Human-in-the-loop nodes are not yet supported over the web UI.

Example blueprints

Boitata ships ready-to-copy example blueprints in examples/blueprints/. They are plain YAML files, not compiled into the binary, so copy one as a starting point and point --blueprint at your copy (or run it in place):

BlueprintShape
defaultagent -> cargo_fmt -> cargo check, looping back on a failed check
fix_lint_errorsagent -> cargo_fmt -> clippy (-D warnings), looping until clean
fix_test_failureagent -> cargo test, looping until the suite passes
setup_devboxscript (devbox init && install) -> agent
human_approvalhuman (approval) -> agent, ending on a negative reply
containerized_taskprovision -> checkout -> agent (in-container) -> cargo test, the agent fixing failures until they pass

Writing your own

Drop a .yaml file and point --blueprint at its path. A common pattern is the verify loop: an agent node does the work, a deterministic script node checks it, and a failure edge routes back to the agent:

name: fmt_then_verify
entry: work
nodes:
  work:
    type: agent
    prompt: |
      Refactor the logging module for clarity. Task context: {task}
  fmt:
    type: tool
    tool: cargo_fmt
  verify:
    type: script
    run: "cargo test && cargo clippy -- -D warnings"
edges:
  - {from: work, to: fmt}
  - {from: fmt, to: verify}
  - {from: verify, when: failure, to: work}
  - {from: verify, when: success, to: END}

On the server

The web UI / server runs blueprints too, but by name rather than by path: start it with --blueprints-dir <dir> and it offers every .yaml in that directory (by file stem) in the run form and at GET /api/blueprints. Only those vetted names are accepted; the server never reads an arbitrary path from a network request. Point it at examples/blueprints, or your own directory:

boitata-server --blueprints-dir examples/blueprints