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).
99 lines
4.0 KiB
Markdown
99 lines
4.0 KiB
Markdown
# 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:
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
- 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:
|
|
|
|
- `validatePieceDef` in `src/engine/piece-runner.ts` — runs on every
|
|
`loadPiece` (file-backed) and `CreatePiece` (runtime).
|
|
- `validatePiece` in `src/bridge/pieces-api.ts` — runs on `PUT
|
|
/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`.
|