Caldera docs
calderaapp.io

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
  • step wird ab min gezä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. min darf max nicht überschreiten.
  • Caldera zeigt unit auf 20, help auf 300 und group auf 60 Zeichen gekürzt.
  • Jedes set wird 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