Blueprints, Versionen und Install-Codes
Ein Blueprint ist ein vorbereiteter Agent, ähnlich einem Dockerfile: ein benanntes,
versioniertes Paket aus Dateien plus einem Manifest, caldera.agent.yaml, das sagt,
was die Dateien sind. Ein Befehl, caldera init <code>, richtet ihn auf einem Rechner ein;
danach kann Caldera eine neuere Version nennen, und der Agent wendet sie an, prüft sie und
behält sie oder rollt zurück.
Bestehende Formate werden zusammengesetzt, nicht ersetzt. Das Bundle trägt gewöhnliche
Dateien (eine CLAUDE.md, ein Verzeichnis .claude/, eine .mcp.json, eine Compose-Datei,
den eigenen Code). Das Manifest nennt sie und fügt nur hinzu, was keine davon sagt:
Einstellungen, Geheimnisse nach Namen, Anbindungen, Zustand, Gesundheit. Das Manifest ist
Feld für Feld unter Das Manifest beschrieben.
Ein Blueprint sagt, wie ein Agent arbeitet, nicht, woran er arbeitet. Caldera weist keine Arbeit zu.
Das Leben eines Blueprints, der Reihe nach: die Dateien und das Manifest schreiben, zippen
(das Bundle), eine Version hochladen (ein Entwurf), veröffentlichen (unveränderlich), einen
Install-Code ausstellen, caldera init auf einem Rechner ausführen. Danach bewegt eine
gewünschte Version den Agent: aktualisieren, festhalten, zurückrollen. Der Agent wendet sie
an, führt seine Gesundheitsprüfung aus und behält die Version oder rollt zurück.
Bundles
Ein Bundle ist ein Zip-Archiv mit caldera.agent.yaml an der Wurzel. Es enthält die
Dateien des Blueprints und sonst nichts: keine Geheimnisse, kein agent.env.
Grenzen (Caldera beim Hochladen und die Runtime bei der Installation wenden dieselben Zahlen an):
| Grenze | Wert |
|---|---|
| Archiv | 20 MB |
| Einträge | 5000 |
| Entpackt, insgesamt | 100 MB |
| Eine Datei, entpackt | 50 MB |
| Manifest | 256 KB |
Ganz abgelehnt, bevor etwas gespeichert wird: ein Archiv, das kein Zip ist, verschlüsselt ist,
mehrere Datenträger umfasst oder zip64 braucht; ein Eintrag mit unsicherem Pfad oder unter
.caldera/; ein Symlink, Gerät, Pipe oder Socket; ein doppelter Name; eine fehlende Datei, die
das Manifest nennt; ein komprimierter Eintrag, der nicht auf die Größe entpackt, die sein
Header angibt; ein Manifest, das nicht validiert.
Die gespeicherten Bytes sind die hochgeladenen Bytes, nie eine Umschreibung, die Prüfsumme, die ein Agent verifiziert, ist also die Prüfsumme dessen, was validiert wurde.
YAML
Caldera liest das Manifest mit einem vollständigen YAML-Leser (Aliase werden abgelehnt). Die
Runtime liest eine Teilmenge und lehnt alles andere namentlich ab: Anker, Aliase, Tags,
mehrere Dokumente, komplexe Schlüssel, Tabulatoren als Einrückung und einen einfachen Skalar,
der in der nächsten Zeile weitergeht. Unterstützt: Block-Mappings und -Sequenzen,
Flow-Sequenzen und -Mappings ([a, b], {k: v}), einfache, einfach und doppelt
angeführte Skalare, >- und |-Blockskalare, Kommentare, ein einleitendes ---. Einfaches
YAML im Blockstil schreiben. Ein Konstrukt außerhalb der Teilmenge könnte den Upload
passieren und bei der Installation scheitern.
Der Katalog
Blueprints, die Caldera selbst mitliefert, in jedem Workspace gleich, schreibgeschützt, neben den eigenen eines Workspace aufgelistet.
| Name | Was es ist |
|---|---|
starter |
Der kleinste Agent: eine Schleife, die einen Heartbeat nach data/status.json schreibt. Hier anfangen, um einen Agent erscheinen zu sehen, dann agent.py ersetzen. Keine Geheimnisse, keine Anbindungen, keine Einstellungen. |
project-agent |
Arbeitet in einem Repository: klont es, richtet es ein, führt in festem Abstand Claude Code darin aus. Einstellungen: Repository-URL, Branch, Prompt, Minuten zwischen Läufen, höchste Kosten eines Laufs, Modell. Optionale Geheimnisse GIT_TOKEN und ANTHROPIC_API_KEY. |
ops-agent |
Ein Betriebs-Agent für ein Aufgaben-Board: eigener Scheduler mit Tageslimit für Läufe, Budget je Lauf, Modellwahl und Board-Name. Zwei Anbindungen an die anderen Produkte der Suite (ein Member, der liest und schreibt, ein Member, der liest). Optionales Geheimnis ANTHROPIC_API_KEY. |
Alle drei sind heute Version 1.0.0.
- Eine Version je Blueprint: die, die dieses Release von Caldera mitliefert. Ein
Katalog-Agent kann diese Version holen und keine andere, ein Katalog-Update kommt also mit
einem Release von Caldera, und ein lokales
caldera rollbackist der Weg zurück für einen Katalog-Agent. - Direkt installieren oder in den Workspace kopieren, um ihn zu ändern. Die Kopie ist ein bearbeitbarer Blueprint mit bereits veröffentlichter Version.
Workspace-Blueprints und Versionen
Das Leben einer Version
- Einen Blueprint anlegen: ein Name (
^[a-z][a-z0-9-]{0,62}$, je Workspace eindeutig) und eine Beschreibung. Er hat noch keine Versionen. - Eine Version hochladen: das Archiv (höchstens 20 MB). Die Versionsnummer kommt aus dem
Manifest darin, und der
namedes Manifests muss dem Namen des Blueprints entsprechen, denndesirednennt einen Blueprint beim Namen, und die Version eines anderen Blueprints unter diesem würde einem Agent fremden Code unter seinem eigenen Namen geben. - Ein Entwurf kann erneut hochgeladen werden; der neue Upload ersetzt ihn.
- Eine Version veröffentlichen. Das ist idempotent; die Zeit der ersten Veröffentlichung bleibt. Eine veröffentlichte Version ändert sich nie und kann nicht gelöscht werden: Sie kann installiert werden, und ein Agent kann auf sie zurückrollen. Eine Änderung ist eine neue Version.
- Eine Entwurfsversion löschen. Einen Blueprint nur löschen, solange kein Agent aus ihm installiert ist (sonst könnten diese Agents nie eine andere Version holen).
- Nur veröffentlichte Versionen können installiert oder als gewünschte Version genannt werden.
Versionen sind nach Semantic Version geordnet (1.10.0 über 1.9.0; eine Vorabversion unter
ihrem Release).
Die Versionsregel in der Praxis
Die version des Manifests ist die Version. Um eine Änderung herauszugeben, wird die
version im Manifest geändert, das Bundle neu gebaut, hochgeladen, veröffentlicht. Eine
veröffentlichte Versionsnummer erneut zu verwenden wird abgelehnt (version_published). Dasselbe
gilt für Versionen, die als Test hochgeladen wurden: Gibt es 1.0.1 und 1.0.2, ist die
nächste echte Version mindestens 1.0.3.
Install-Codes
Ein Admin drückt bei einer veröffentlichten Version (oder einem Katalog-Blueprint) auf "Installieren", wählt den Agent-Namen und erhält einen Einmal-Code.
- Form:
caldera_inst_plus eine lange Zufallszeichenkette. Nur ein Hash wird gespeichert. Einmal angezeigt. - Gültig einmal, für 15 Minuten, für eine Installation einer Version.
- Der Agent-Name (
^[a-z][a-z0-9-]{0,62}$) wird zum Namen des Agents in Caldera und zum Verzeichnisnamen. Er darf im Workspace noch kein Agent-Name sein. - Bei der Ausstellung prüft Caldera schon, was später scheitern würde, damit der Dialog es sagt und nicht ein Terminal zehn Minuten später: Der Agent-Name ist frei, das Produkt jeder Anbindung ist für den Workspace freigeschaltet, ein gleichnamiger Bot existiert nicht mit anderer Rolle, die ausstellende Person darf die Rolle verleihen, und der Workspace bleibt innerhalb von zehn Bots.
- Der Dialog zeigt zwei Befehle:
caldera.pyzladen und prüfen, dannpython3 caldera.pyz init <code> --url <origin>. Die Warnung sagt, dass der Code einen Agent mit einem Token und je Produkt einem Bot-Token einrichtet, nur einmal funktioniert und nur einmal angezeigt wird. - Braucht eine Admin-Rolle. Install-Codes sind nur mit Sitzung: Kein persönliches Token kann einen ausstellen, denn ein Token, das das könnte, wäre eine Berechtigung, die weitere Berechtigungen ausstellt.
Vorschau, dann Einlösen
Beide Aufrufe nehmen kein Token; der Code ist die Berechtigung (das Protokoll).
- Die Vorschau liest, was der Code installieren würde, und legt nichts an und verbraucht nichts: Blueprint, Version, Beschreibung, Agent-Name, Runtime, Geheimnisse (Name, Zweck, optional), Anbindungen. Die CLI fragt nach Geheimnissen und bemerkt ein belegtes Verzeichnis, bevor der Code benutzt wird.
- Das Einlösen geschieht in einer Transaktion: Es beansprucht den Code (zwei Einlösungen, die um einen Code rennen: genau eine gewinnt), legt den Agent und sein Token an, legt je Anbindung einen Bot an oder verwendet ihn wieder, mit je einem Token, und liefert das Bundle einmal aus.
Eine Ablehnung rollt alles zurück, die Beanspruchung eingeschlossen, ein abgelehntes Einlösen lässt den Code also benutzbar, nachdem die Ursache behoben ist:
| Status | Wann |
|---|---|
| 403 | Ein angebundenes Produkt ist nicht freigeschaltet; oder die Person, die den Code ausgestellt hat, darf keine Agents mehr installieren (geprüft, wie sie jetzt dasteht); oder der Workspace ist für Caldera nicht freigeschaltet. |
| 409 | Der Workspace hätte mehr als zehn Bots; ein Bot dieses Namens existiert mit anderer Rolle; der Workspace hat schon einen Agent dieses Namens. |
| 404 | Ein unbekannter, abgelaufener und benutzter Code: alle dieselbe Antwort, bei beiden Aufrufen, damit sich ein Code nicht abtasten lässt. |
| 429 | Mehr als zwanzig Install-Aufrufe pro Minute von einer Adresse (Vorschau und Einlösen zusammen). |
Ein nicht eingelöster Code hinterlässt keinen Agent, und da die Vorschau zuerst kommt, auch kein Setup, das bei der Abfrage der Geheimnisse abgebrochen wird.
Anbindungen und Bots
Eine Anbindung gibt dem Agent Zugriff auf eines der anderen Produkte der Suite, ohne dass die Zugangsdaten einer Person auf dem Rechner liegen.
Beim Einlösen legt Caldera für jede Anbindung einen Bot im Workspace an (oder verwendet ihn
wieder), mit der deklarierten Rolle, und erzeugt ein Token mit den deklarierten Scopes,
für dieses Produkt gestempelt (es funktioniert an der Adresse dieses Produkts und sonst
nirgends). Das Ergebnis schreibt es in .caldera/agent.env:
| Variable | Ist |
|---|---|
CALDERA_BINDING_<PRODUCT>_URL |
der Ursprung des Produkts |
CALDERA_BINDING_<PRODUCT>_WORKSPACE |
die ID des Workspace, zu dem der Bot gehört (die API des Produkts adressiert ihn per ID) |
CALDERA_BINDING_<PRODUCT>_TOKEN |
das Token des Bots |
<PRODUCT> ist die großgeschriebene Produkt-ID. Die .mcp.json eines Blueprints kann sich
darauf beziehen, bevor irgendetwas installiert ist, zum Beispiel
${CALDERA_BINDING_<PRODUCT>_URL}/mcp, mit eingesetzter Produkt-ID. Die Runtime schreibt diese
Datei nicht um; sie gibt die Variablen in der Umgebung des Agents mit, und was die Datei liest,
löst sie auf (Claude Code expandiert ${VAR} in .mcp.json).
Regeln:
- Der Bot heißt
<agent name> (<product>)und behält diesen Namen, wenn der Agent umbenannt wird. - Der Besitzer des Bots ist die Person, die den Code ausgestellt hat. Er ist auf ihre Rolle
begrenzt, wie sie beim Einlösen steht; ein Bot ist
memberoderguest, nie mehr. - Ein bestehender Bot dieses Namens und dieser Rolle wird wiederverwendet und nie verändert; einer mit anderer Rolle ist ein 409.
- Ein Workspace hat höchstens zehn Bots; die Ablehnung sagt, wie viele gebraucht und gehalten werden.
- Das Produkt muss für den Workspace freigeschaltet sein.
- Token der Anbindungen sind ein Jahr gültig, so lange, wie ein Token höchstens sein darf. Nichts erneuert eines. Nach einem Jahr bricht die Anbindung; siehe Agents betreiben.
- Ein Bot ist ein Workspace-Mitglied, kein Inhalt eines Produkts.
Gesundheit der Anbindung. Für jede Anbindung fügt die Runtime ihrer Meldung einen
Gesundheitseintrag Binding <product> hinzu (höchstens einmal in fünf Minuten), aus einer Anfrage
an das Produkt mit dem Token des Bots. ok bei 200 und bei 403 (ein Token, dessen Scopes dieses
Lesen nicht abdecken, funktioniert trotzdem); bad bei 401 (widerrufenes, abgelaufenes oder
gelöschtes Token) und 404 (der Bot ist kein Mitglied mehr); warn, wenn das Produkt nicht
erreichbar ist. Caldera zeigt bad als defekte Anbindung auf der Seite des Agents. Nur die
eigenen Bot-Einstellungen des Produkts können sie reparieren. Diese Einträge zählen nie zum
eigenen Level des Agents und können daher kein Update zurückrollen.
Einen Agent zu löschen widerruft seine Bots nicht
Widerrufen ist die eigene Handlung des Produkts. Caldera kann es nicht. Wird ein Agent gelöscht, bleiben seine Bots und deren Token. Die Löschbestätigung nennt die Bots, damit sie in den Bot-Einstellungen des Produkts widerrufen werden können. Das Bot-Token eines gelöschten Agents funktioniert, bis es abläuft oder widerrufen wird.
Aktualisieren, festhalten und zurückrollen
Alle drei sind ein Feld: die gewünschte Version des Agents. Sie muss eine veröffentlichte Version des eigenen Blueprints des Agents sein (bei einem Katalog-Agent: die eine mitgelieferte Version), oder leer, um den Wunsch zurückzuziehen.
| Ziel | Nennen |
|---|---|
| Aktualisieren | eine neuere veröffentlichte Version |
| Zurückrollen | die vorherige Version |
| Festhalten | die Version, die läuft (der Agent sieht nichts zu tun) |
| Den Wunsch zurückziehen | nichts |
Die Seite des Agents (Panel "Blueprint") zeigt drei Versionen: installiert (was der Code brachte), laufend (was der Agent als laufend meldet) und gewünscht (Calderas Wunsch), das letzte Ergebnis in den eigenen Worten des Agents und die defekten Anbindungen. Die Änderung wird bis zur Antwort des Agents verfolgt: Warten auf die nächste Meldung, dann angewendet, vom Agent zurückgerollt oder fehlgeschlagen.
Die Runtime holt dann das Bundle mit ihrem eigenen Token (nur veröffentlichte Versionen des eigenen Blueprints; die Version eines anderen Blueprints und eine unbekannte antworten 404). Siehe die Runtime und Agents betreiben.
Einen eigenen Blueprint, Schritt für Schritt
Das Beispiel ist ein privater Assistent, der neue Mails sortiert und Antwortentwürfe schreibt.
-
Den Agent zu einem dauerhaft laufenden Prozess machen, der seine Zeitplanung selbst macht und eine Status-Datei schreibt. Das Beispiel hat einen Prozess, gestartet mit
python3 -m agent.cli serve, einen Thread je Aufgabe, der alle 30 Sekunden und bei jeder Änderungdata/status.jsonschreibt. Pause und Fortsetzen sind dann die Runtime, die diesen Prozess stoppt und startet. (Ein Agent, der sich nicht zu einem Prozess machen lässt, nutzt stattdessen einen Adapter.) -
Entscheiden, was Zustand ist. Alles, was der Agent lernt oder speichert, muss unter einem
state-Pfad liegen, sonst behält ein Update es nicht. Das Beispiel hält seine Geheimnisse und seine Datenbank ganz außerhalb des Blueprints (in den eigenen Konfigurations- und Zustandsverzeichnissen der Benutzerin) und deklariert nurdata/für seine Status-Datei. -
Das Manifest schreiben. Das des Beispiels ist kurz:
name: mail-assistant version: 1.0.0 description: >- Sorts new mail and writes reply drafts. It never sends. Only numbers go out to Caldera, never contents. runtime: type: process command: [python3, -m, agent.cli, serve] state: [data/] status: data/status.json controls: [pause, resume, run_now] health: command: [python3, -m, agent.cli, health] timeout_seconds: 40Es deklariert keine
secrets(initfragt also nach nichts), keinesettingsund keinelogs(es wird also nichts abgefragt, und kein Log verlässt je den Rechner). -
Die Gesundheitsprüfung so schreiben, dass sie voraussetzt, dass die neue Version gearbeitet hat. Die Prüfung des Beispiels verifiziert die Konfiguration und dass die Programme, die es aufruft, im Pfad liegen, und wartet dann auf einen Heartbeat in der Status-Datei, der neuer ist als
CALDERA_AGENT_STARTED. Eine frisch wirkende Datei, die die alte Version hinterlassen hat, besteht nicht. -
Das Bundle aus einer festen Dateiliste bauen, nie "alles außer". Das Build-Skript des Beispiels nimmt Code, Prompts, Vorlagen, Schemas, ein Konfigurationsbeispiel und das Manifest auf; ein Name, der nach Geheimnis, Zustand oder
.gitaussieht, bricht den Build ab; feste Reihenfolge, Zeitstempel und Modi sorgen dafür, dass dieselben Dateien dieselben Bytes ergeben. Ein Bundle enthält nie Geheimnisse oder Zustand. -
Durch Hochladen eines Entwurfs validieren. Caldera validiert Manifest und Archiv beim Upload und speichert bei einer Ablehnung nichts. Die Ablehnung nennt das Feld (
manifest_invalidträgt seinen Pfad) oder die Regel. Ein Entwurf kann beliebig oft erneut hochgeladen werden; nichts ist installierbar, bis es veröffentlicht ist. -
Hochladen und veröffentlichen. Im Workspace: Blueprints, "Neuer Blueprint" (der Name muss dem
namedes Manifests entsprechen), "Version hochladen" mit dem Zip, dann "Veröffentlichen". -
Einen Code ausstellen und auf einem Rechner installieren (die Runtime).
-
Die Unabhängigkeit nachweisen und ein Update mit erzwungenem Fehler (Einen Agent verbinden). Die Probe des Beispiels war: Pause und Fortsetzen offline, ein Update und eine absichtlich kaputte Version, deren Health-Befehl mit 1 endet, binnen einer Sekunde zurückgerollt.
-
Die nächste Version herausgeben, indem die
versionim Manifest erhöht wird (nie auf eine Nummer, die es gibt), neu gebaut, hochgeladen, veröffentlicht und als gewünschte Version genannt wird.
Nicht gebaut
- Cloud-Erzeugung von Agents und deklarierte Abhängigkeiten zwischen Blueprints.
- Ein Marktplatz oder Teilen über Workspaces hinweg.
- Von Caldera gehaltene Zugangsdaten Dritter: Sie bleiben auf dem Rechner.
- Eine Paketquelle (Registry) für die Runtime.