Skip to content

Blueprint schema

A blueprint is the durable artifact at the heart of Spacecraft: a YAML or JSON file describing a multi-agent pipeline as a directed graph. Given the same blueprint, the same bindings, and the same model, a launch is reproducible.

The canonical, machine-checked contract lives at packages/spacecraft/blueprints/SCHEMA.md. This page is the readable summary.

id: my-blueprint # required, kebab-case
name: My Blueprint # required, human-readable
startNodeId: <node id> # optional — defaults to first node
# Declared inputs the launcher / bindings file can fill in
spec:
inputs:
- key: primary_model
type: string
required: false
default: phi3
description: Base model for all agents.
# Optional: pick an inference adapter + endpoint
inference:
adapter: vercel-ai
baseURL: "${OLLAMA_BASE_URL:-http://localhost:11434/v1}"
apiKey: "${OLLAMA_API_KEY:-ollama}"
# Optional: how long-running conversations are compressed
memory:
adapter: default # or `rag`
strategy: sliding_window # sliding_window | summarize | hybrid | rag
max_messages: 20
window_size: 8
# Required: the agent roster
agents:
- id: agent-mechanic
name: System Mechanic
action: LLM_INFERENCE # or USER_PROMPT
model: "{{ inputs.primary_model }}"
systemPrompt: |
You are a specialized system maintenance agent...
tools: # optional — for tool-agents
- name: disk_usage
description: Check disk space
type: bash
executable: df -h
parameters: { type: object, properties: {} }
# Required: the graph
nodes:
- id: get-input
agentId: agent-user
nextNodes: [ think-and-reply ]
- id: think-and-reply
agentId: agent-mechanic
nextNodes: [ get-input ] # cyclic — loops back
condition: "!ctx.sharedState['exitRequested']" # guard, JS expression

condition is a JavaScript expression evaluated against the runtime context:

  • ctx.messages — OpenAI-shape chat history.
  • ctx.sharedState — free-form agent-to-agent KV. Use this for cross-agent signals (review verdicts, loop counters, exit flags).
  • ctx.currentNodeId — the node currently executing.

The expression must return a boolean. A node is traversed when its incoming edge’s condition is true (or absent).

  • exitRequested — set by USER_PROMPT agents when the user types exit or quit. Use it to break loops cleanly:

    condition: "!ctx.sharedState['exitRequested']"

Give one agent a different host_url (or inference.baseURL) to run a larger reviewer model on a separate port while a smaller implementor runs on the default port. Same blueprint, two engines.

A separate file with shape spacecraft.bindings/v1 fills in spec.inputs.values. Pass it at launch with --bindings:

Terminal window
sc launch ./blueprint.yaml --bindings ./bindings.dev.yaml

Bindings can reference vault entries or env vars. They are the right place for secrets — never inline them in the blueprint itself.

Tools live on agents. Three types are supported today (see sc capabilities for the live list):

  • bash — shell command. executable is the command line; parameters is a JSON-schema describing the structured args the agent must produce.
  • http — HTTP request to an endpoint.
  • js — inline JavaScript evaluated against the runtime context.

inference.adapter defaults to vercel-ai — works against any OpenAI-compatible endpoint (Anthropic, OpenAI, Ollama, vLLM, llama.cpp, SGLang). Run sc adapters for the full list, or Adapter guide for how to write your own.

Spacecraft tracks the full conversation in ctx.messages by default. For long runs, configure memory::

StrategyBehavior
sliding_windowKeep the most recent N messages. Cheapest.
summarizeCompress earlier turns into a summary message; keep recent turns verbatim.
hybridSummarize + sliding window combined.
ragIndex past messages in a vector DB; retrieve the K nearest on each turn. Requires adapter: rag.
  • packages/spacecraft/blueprints/system-mechanic/blueprint.yaml — bash-tool agent doing system maintenance.
  • .starsystem/harnesses/decider-domain-sweep/blueprint.yaml — cyclic multi-agent (research → template creator loop calling the Decider MCP bridge).
Terminal window
sc harness validate <dir> # full package against v0 contract
sc bindings validate <bp> <bindings> # bindings resolve + satisfy inputs
sc launch ./blueprint.yaml --dry-run # resolve graph + adapters, no LLM calls