Das Manifest
caldera.agent.yaml liegt an der Wurzel eines Bundles. Diese Seite beschreibt es Feld für Feld.
Das Manifest ist streng: Ein unbekanntes Feld ist ein Fehler, der seinen Namen trägt (ein
Tippfehler wie secret: statt secrets: würde sonst einen Agent ohne die Zugangsdaten installieren,
die er braucht).
Das JSON-Schema caldera.agent.schema.json ist die Frühwarnung
für einen Editor. Calderas eigene Validierung, einschließlich der Regeln, die Felder miteinander
vergleichen, ist maßgeblich.
Was ein Blueprint ist und wie er veröffentlicht und installiert wird, steht unter Blueprints.
Felder
| Feld | Pflicht | Was | Regeln |
|---|---|---|---|
name |
ja | Der Name des Blueprints. | ^[a-z][a-z0-9-]{0,62}$. Muss dem Namen des Blueprints im Workspace entsprechen. |
version |
ja | Diese Version. | Semantic Version ohne Build-Metadaten: 1.2.3 oder 1.2.3-rc.1. |
description |
ja | Ein Absatz für Menschen. | 1 bis 500 Zeichen. |
runtime |
ja | Wie der Agent läuft. | type: process mit command (Argumentliste, 1 bis 50 Einträge) und optional workdir; oder type: compose mit file und optional workdir; oder type: adapter mit command, optional workdir (ein Bundle-Pfad oder ein absoluter Pfad) und timeout_seconds (1 bis 120). Nie eine Shell-Zeichenkette. |
instructions |
nein | Die Dateien, die den Agent zu dem machen, was er ist (CLAUDE.md, .claude/, Prompts). |
Bis zu 50 Pfade; jeder muss im Bundle existieren. |
mcp |
nein | Eine gewöhnliche .mcp.json. |
Ein Pfad; muss existieren. Zugangsdaten darin sind ${NAME}-Platzhalter. |
settings |
nein | schema (bis zu 50 Felder) und defaults. |
Siehe settings. |
secrets |
nein | Zugangsdaten Dritter, die der Agent braucht, nur nach Name und Zweck. | Bis zu 50. Siehe secrets. |
bindings |
nein | Zugriff auf die anderen Produkte der Suite, über Bots. | Bis zu 10, eines je Produkt. Siehe bindings. |
state |
nein | Pfade, die den Zustand des Agents halten und jedes Update überleben. | Bis zu 50; nicht ineinander. Angelegt, nicht ausgeliefert. |
health |
nein | Der Befehl, der sagt, ob der Agent funktioniert. | command (Argumentliste) und timeout_seconds (1 bis 600, in der Runtime standardmäßig 60). |
status |
nein | Die Datei, in die der Agent seine Meldung schreibt. | Ein Pfad. Siehe die Runtime. |
controls |
nein | Die Knöpfe, die Caldera zeigen darf. | Beliebige von pause, resume, run_now; standardmäßig pause und resume. |
logs |
nein | Die einzigen Logs, die Caldera anfordern darf. | Bis zu 50 aus {name, path}; Namen eindeutig; path relativ zum Arbeitsverzeichnis. |
account |
nein | false schaltet den Hinweis auf das Claude-Konto ab. |
Ein Boolean; standardmäßig an. Siehe der Hinweis auf das Claude-Konto. |
Pfade
Jeder Pfad in einem Manifest wird später an ein Verzeichnis auf dem Rechner von jemandem angehängt, Pfade sind also die Sicherheitsfläche. Ein Pfad ist gültig, wenn er
- relativ ist, mit Schrägstrichen, höchstens 200 Zeichen;
- frei von
..,.und leeren Segmenten, Backslashes, NUL-Bytes, einem führenden/und einem Laufwerksbuchstaben ist; - nicht unter
.caldera/liegt (dem eigenen Verzeichnis der Runtime).
Ein abschließender Schrägstrich meint das Verzeichnis (data/, .claude/). Die Runtime prüft nach
dem Auflösen erneut gegen das echte Dateisystem.
runtime
runtime:
type: process
command: [python3, agent.py] # argv: keine Shell, kein Quoting, nichts zum Einschleusen
workdir: . # optional, relativ zum Versionsverzeichnis
compose nennt eine Compose-Datei im Bundle. Sie ist unerprobt; siehe
die Runtime.
adapter ist für einen Agent, der eigene Prozesse behält (ein Timer, ein Bot, eine Pause-Datei, die
auch andere setzen):
runtime:
type: adapter
command: [.venv/bin/python, caldera/adapter.py] # argv, als Benutzer der Runtime ausgeführt
workdir: /home/agent/my-agent # der eigene Checkout des Agents; oder ein Pfad im Bundle
timeout_seconds: 25 # optional: ersetzt die Timeouts je Verb
Die Runtime startet dann nichts, stoppt nichts und liest keine Datei des Agents: Sie meldet, was
adapter status ausgibt, und reicht Befehle an den Adapter weiter, der das letzte Wort hat. Ein
Manifest mit dieser Runtime darf status, logs, state, secrets, bindings, instructions oder
mcp nicht nennen. Die ganze Schnittstelle steht unter
Adapter-Modus und sein Vertrag.
settings
Das Formular, das Caldera zeigt. Die Felder haben genau die Form, die das Protokoll meldet, was der Blueprint deklariert, ist also, was Caldera zeigt.
settings:
schema:
- key: max_budget_usd # ^[a-z][a-z0-9_]{0,63}$
label: Highest cost of one run # 1 bis 80 Zeichen
type: number
min: 1
max: 30
step: 1
unit: USD
group: Work
help: Stops a run that would cost more than this.
defaults:
max_budget_usd: 5
type |
Wert | Grenzen |
|---|---|---|
percent |
eine Zahl von 0 bis 1 | min/max verengen sie; Standardbereich 0 bis 1 |
number |
eine Zahl | min und max sind Pflicht |
bool |
true oder false | keine |
datetime |
ganze Unix-Sekunden | min/max optional |
text |
eine Zeichenkette von höchstens 300 Zeichen, kein NUL | keine |
select |
eines aus options (value, label) |
options Pflicht, bis zu 50 |
stepwird abmingezählt.- Ein Standardwert muss zu seinem Feld passen; ein Standardwert für einen nicht deklarierten Schlüssel ist ein Fehler.
- Ein Schlüssel ohne Standardwert ist optional: Er darf ungesetzt sein, und ein
set-Befehl darf ihn löschen. Ein Schlüssel mit Standardwert lässt sich nicht löschen. - Schlüssel sind eindeutig.
mindarfmaxnicht überschreiten. - Caldera zeigt
unitauf 20,helpauf 300 undgroupauf 60 Zeichen gekürzt. - Jedes
setwird in der Runtime gegen diese Grenzen geprüft, ganz oder gar nicht. Caldera prüft vorab nur, um es einer Person sofort zu sagen; die Runtime entscheidet.
secrets
secrets:
- name: ANTHROPIC_API_KEY # ^[A-Z][A-Z0-9_]{0,63}$, darf nicht mit CALDERA_ beginnen
purpose: Runs Claude Code, if the machine is not already signed in to Claude
optional: true
Ein Manifest trägt nie einen Wert. caldera init fragt auf dem Rechner nach jedem Geheimnis (oder
liest CALDERA_SECRET_<NAME>) und schreibt es nach .caldera/secrets.env (Modus 600). Geheimnisse
laufen nie durch Caldera; sie stehen unter diesem Namen in der Umgebung des Agents. Dass Caldera
Zugangsdaten Dritter hält, ist nicht gebaut.
bindings
bindings:
- product: "<product id>" # ein Produkt der Suite, siehe unten
role: member # member | guest, nie mehr
scopes: [content:read, content:write] # 1 bis 4 aus content:read, content:write, admin:read, admin:write
product ist die ID des Produkts, auf das der Agent zugreifen muss. Die gültigen Werte sind
"basalt", "lithic", "tecto" und "caldera", genau wie die Schema-Datei sie auflistet.
Eine Anbindung je Produkt, weil das Token als ein Satz Umgebungsvariablen je Produkt übergeben wird. Siehe Anbindungen und Bots.
state
state: [data/]
Ein Update ersetzt Anweisungen und Code und berührt nie State-Pfade. Sie liegen in <dir>/state
und sind in jede Version eingelinkt. Eine Datei, die das Bundle an einem State-Pfad mitbringt, ist ein
Seed und wird nur kopiert, wenn dort noch nichts liegt.
health
health:
command: [python3, health.py]
timeout_seconds: 30
Läuft nach einem Update, im Arbeitsverzeichnis der neuen Version, mit der Umgebung des Agents. Exit 0
heißt, es funktioniert. So schreiben, dass es voraussetzt, dass die neue Version gelaufen ist,
indem ein Heartbeat mit CALDERA_AGENT_STARTED verglichen wird.
Ein vollständiges Beispiel
name: report-agent
version: 1.2.0
description: Writes a weekly report from a repository and keeps a status file.
runtime:
type: process
command: [python3, agent.py]
instructions: [CLAUDE.md, .claude/]
settings:
schema:
- key: minutes_between_runs
label: Minutes between runs
type: number
min: 5
max: 1440
unit: min
group: Work
- key: model
label: Model
type: select
options:
- { value: sonnet, label: Sonnet }
- { value: opus, label: Opus }
defaults:
minutes_between_runs: 60
secrets:
- name: GIT_TOKEN
purpose: Reads the repository
optional: true
state: [data/]
status: data/status.json
controls: [pause, resume, run_now]
logs:
- { name: agent, path: data/agent.log }
health:
command: [python3, health.py]
timeout_seconds: 30