Open-source release of MAESTRO, an agent orchestration platform that runs LLM-driven tasks through sandboxed tools, with a web UI. Apache-2.0. See README.md and docs/ (getting-started, configuration, architecture).
4.0 KiB
Piece YAML Schema
This is the reference for the piece YAML format consumed by
src/engine/piece-runner.ts (loadPiece / validatePieceDef) and the
/api/pieces HTTP layer (src/bridge/pieces-api.ts validatePiece).
Field names are snake_case in the YAML; the engine maps them to
camelCase internally (see Movement in src/engine/agent-loop.ts).
Top-level
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | lowercase [a-z0-9-]+ |
description |
string | yes | shown in the piece classifier |
max_movements |
positive integer | yes | hard cap on movement count per run |
initial_movement |
string | yes | must reference a movements[].name |
triggers.keywords |
string[] | no | classifier hint only |
required_mcp |
string[] | no | [a-z0-9_-]{1,64} server slugs |
model |
string | no | preferred LLM model |
movements |
Movement[] | yes | non-empty array |
Movement
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | unique within the piece |
edit |
boolean | yes | when true, Write/Edit are exposed |
persona |
string | yes | system-prompt persona |
instruction |
string | yes | the movement's task description |
allowed_tools |
string[] | yes | tool names; 'mcp__*' wildcard allowed |
allowed_commands |
string[] | no | Bash command allowlist (overrides default) |
allowed_ssh_connections |
string[] | conditional | see below |
rules |
Rule[] | yes | transition rules; may be empty |
default_next |
string | no | engine-internal fallback (sentinel-friendly) |
max_consecutive_revisits |
number | no | loop-detection threshold override |
allowed_ssh_connections
Per-movement SSH connection allowlist (Phase 4 of the SSH tool integration
| Value | Meaning |
|---|---|
undefined (field omitted) |
SSH tools reject with no_allowed_connections_declared. |
[] (empty array) |
SSH tools reject with no_allowed_connections_declared. The empty form is preferred over omission when the movement intentionally denies all connections (intent is explicit). |
['<connection-id>', ...] |
Only listed connection IDs may be passed to SSH tools. |
['*'] |
Any registered connection may be passed. Still subject to ownership and grant checks (defense in depth). Use sparingly — typically only ssh-ops-style pieces. |
Required: If a movement's allowed_tools contains any of SshExec,
SshUpload, or SshDownload, then allowed_ssh_connections MUST be
present. validatePieceDef and validatePiece both reject pieces that
omit it for SSH-using movements.
Format: each entry must be '*' or a lowercase hex/hyphen id with
8+ characters (loose match against randomUUID() output).
Example:
movements:
- name: ops
edit: false
persona: ops-operator
instruction: Run health checks on production hosts.
allowed_tools: [SshExec, Read]
allowed_ssh_connections:
- 6f9619ff-8b86-d011-b42d-00c04fc964ff
- 7a8b9cde-1234-4567-89ab-cdef12345678
rules:
- condition: all checks pass
next: COMPLETE
Rule
- condition: <human-readable description shown to the LLM>
next: <movement name | WAIT_SUBTASKS>
rules[].next may NOT use the reserved terminal sentinels
COMPLETE / ABORT / ASK — those are reachable only through the
complete tool (status: success / aborted / needs_user_input).
default_next does accept the terminal sentinels because it is an
engine-internal fallback (context overflow, ASK limit, SpawnSubTask
unavailable).
Validation paths
Two validators implement the same rules:
validatePieceDefinsrc/engine/piece-runner.ts— runs on everyloadPiece(file-backed) andCreatePiece(runtime).validatePieceinsrc/bridge/pieces-api.ts— runs onPUT /api/pieces/:name(UI editor).
Both must stay in sync. When changing the schema, update both and add
test coverage in src/engine/piece-runner.test.ts and
src/bridge/pieces-api.test.ts.