Projekt-Bundles
Ein Projekt-Bundle (spec.type: project) ist die zusammengesetzte Form eines
Bundles: Es packt nicht eine einzelne Ressource, sondern
ein ganzes Projekt mit allem, was es zum Laufen braucht, in ein
einziges Dokument.
project meint hier dasselbe Projekt, das Sie sonst in der Oberfläche öffnen — kein
zweites, bundle-spezifisches Konzept mit zufällig gleichem Namen. Ein Projekt-Bundle
zu installieren heißt: ein BasePeak.AI-Projekt anzulegen.
Was ein Projekt-Bundle enthält
Der eigentliche Nutzlastteil (spec.payload) ist das Projekt selbst — der
führende Thread mit Spec.Project = true — zusammen mit seinen Aufgaben. Alles,
was das Projekt zum Betrieb braucht, reist als verschachteltes Bundle unter
spec.includes mit:
| Kind-Typ | Kardinalität |
|---|---|
| Agent | genau 1 |
| App | höchstens 1 |
Wissenssammlung (knowledge) | 0 bis beliebig viele |
MCP-Connector (connector) | 0 bis beliebig viele |
Projekt (project) | nicht erlaubt — ein Projekt-Bundle kann kein weiteres Projekt verschachteln |
Installations- und Deinstallationsreihenfolge
Beim Installieren werden die Kinder in dieser Reihenfolge angelegt:
Connector → Wissen → Agent → App → Projekt → Aufgaben.
Beim Deinstallieren wird zuerst der eigene Thread des Projekts entfernt, danach kommen die Kinder in der Reihenfolge App → Agent → Wissen → Connector herunter. Das ist nicht willkürlich — eine Wissenssammlung, die noch an einem Agenten hängt, lässt sich nicht entfernen. Wird zuerst der Agent entfernt, wird die Wissenssammlung dadurch frei und kann anschließend sauber entfernt werden, gefolgt vom Connector, von dem sonst nichts im Baum abhängt.
Die installierten Wissenssammlungen werden dabei an den installierten Agenten angehängt, genau wie beim manuellen Anhängen einer eigenständigen Wissenssammlung an einen bestehenden Agenten — nur automatisch als Teil der Installation.
Ein fehlgeschlagener Install räumt nichts weg
Schlägt die Installation eines Kindes fehl, wird nichts rückgängig gemacht. Die übergeordnete Installation wird als fehlgeschlagen markiert, der Fehler nennt das betroffene Kind, und jedes bereits erfolgreich angelegte Kind bleibt verzeichnet. Um aufzuräumen, genügt ein einziger Aufruf:
DELETE /api/bundles/installations/{id}
Das entfernt die übergeordnete Installation und alle bereits gelandeten Kinder in einem Schritt.
Aktualisieren ist idempotent und fortsetzbar
Ein Update eines zusammengesetzten Bundles lässt sich einfach erneut ausführen, wenn es unterwegs abgebrochen ist: Ein Kind, das bereits auf der Zielversion steht, wird übersprungen statt erneut angefasst. Ein halb durchgelaufenes Update ist also kein Sackgassenzustand — der gleiche Request, noch einmal gestellt, bringt den Rest nach.
Eine Ausnahme: Würde die Aktualisierung eines Kindes dessen eigenes Auswertungs-Gate (Eval-Gate) auslösen, wird das gesamte Update abgelehnt, bevor irgendetwas geschrieben wird — nicht nur für dieses eine Kind, sondern für das ganze Composite. Die Fehlermeldung benennt das betroffene Kind. Der Weg daraus: die Installation dieses Kindes direkt aktualisieren, dort läuft das Gate normal ab, und anschließend das Composite-Update erneut anstoßen — bereits aktualisierte Geschwister werden dabei übersprungen.
Verwaiste Aufgaben und Kinder
Ein Update kann eine Aufgabe oder ein Kind-Bundle fallen lassen, das eine frühere Version angelegt hat. Keines von beiden wird dabei gelöscht:
- Eine Aufgabe, die die neue Nutzlast nicht mehr deklariert, läuft als gewöhnliche Aufgabe des Projekts weiter — sie verliert nur die Markierung, die sie als Eigentum dieses Bundles auswies. Sonst ändert sich nichts an ihr.
- Ein Kind-Bundle (ein Agent, eine Wissenssammlung, ein Connector), das
spec.includesnicht mehr nennt, wird vollständig unangetastet gelassen — Ressource und Installationsdatensatz beide — und in der übergeordneten Installation als verwaist verzeichnet. Einen Agenten oder eine Wissenssammlung unter einem laufenden Projekt wegzuziehen, ist einem Update nicht erlaubt.
In beiden Fällen gilt: Die Deinstallation des Projekts verweigert sich, solange noch eine verwaiste Aufgabe auf seinem Thread liegt. Die eigene Ressource des Projekts ist der Thread, und ihn zu löschen würde jede Aufgabe darauf mitlöschen — auch eine, die diesem Bundle nicht mehr gehört. Die Verweigerung nennt die Aufgabe bei ihrem Objektnamen.
Der Ausweg ist eine von zwei Entscheidungen:
- Die Aufgabe löschen — eine verwaiste Aufgabe ist jetzt eine gewöhnliche
Aufgabe,
DELETE /api/tasks/{id}entfernt sie wie jede andere. Sobald keine verwaiste Aufgabe mehr existiert, läuft die Deinstallation des Projekts normal durch. - Das Projekt behalten — die Installation einfach stehen lassen. Es gibt keine Frist; der Datensatz übersteht eine verweigerte Deinstallation und lässt sich später erneut versuchen, sobald entschieden ist, was mit der Aufgabe geschehen soll.
Ein verwaistes Kind-Bundle blockiert eine Deinstallation nicht auf dieselbe Weise — es ist keine Ressource auf dem eigenen Thread des Projekts. Die Deinstallations-Kaskade rührt es aber auch nicht an: Seine Ressource und sein eigener Installationsdatensatz bleiben genau so stehen, wie das Update, das es verwaist hat, sie hinterlassen hat. Es zu entfernen bedeutet, die Installation dieses Kindes direkt zu deinstallieren.
Export
GET /api/assistants/{assistant_id}/projects/{project_id}/bundle
exportiert den Agenten, jede eigenständige an ihn angehängte Wissenssammlung und
jeden MCP-Connector, den Projekt oder Agent tatsächlich referenzieren. Ein
App-Kind wird nur eingeschlossen, wenn der Aufrufer es explizit benennt, über
?app=<publicID>. Das ist kein Versehen: Ein Projekt hat im Datenmodell keine
Zuordnung zu einer App — es gibt kein Feld, aus dem der Export eine App ableiten
könnte, also muss der Aufrufer sagen, welche gemeint ist.
Was bewusst nicht mitreist
Ein Projekt-Bundle ist für den Transport zwischen Instanzen gedacht, nicht als Kopie eines laufenden Betriebs. Folgendes wird beim Export entfernt (und, falls es dennoch in einem handgeschriebenen Dokument auftaucht, beim Install ein zweites Mal, mit einer Warnung):
| Was fehlt | Warum |
|---|---|
Genehmiger-Adressen (step.approval.approvers) | die Adresse einer realen Sachbearbeiterin gehört nicht auf eine fremde Instanz |
| Werte von Umgebungsvariablen (Namen reisen mit) | Zugangsdaten; der Name ist der Vertrag, den die Zielinstanz erfüllen muss |
Projekt-Capabilities, Aufgaben-Trigger webhook und email | das Webhook-Secret liegt im Klartext in der Spec, und zwei Projekte könnten sich sonst denselben eingehenden Trigger teilen |
Aufgaben-Trigger poll, onSlackMessage, onDiscordMessage | instanzlokale Trigger-Konfiguration |
onTaskComplete | verweist auf eine lokale Workflow-ID; eine Zuordnung über Instanzgrenzen hinweg ist (noch) nicht vorgesehen |
SharedTasks | eine Liste lokaler Workflow-Namen; dieses Bundle installiert seine eigenen Aufgaben |
Mitglieder, Rollenvergaben, Dateien, Zugangsdaten, sowie alles unter Status | lokale Personen, lokaler Zustand |
Übrig bleiben als Aufgaben-Trigger nur geplant (schedule) und auf Abruf
(onDemand) — siehe Aufgaben.
Grenzen dieser Phase
- Nur über die API. Es gibt noch keinen Export- oder Install-Dialog für Projekt-Bundles in der Oberfläche.
- Ein zusammengesetztes Update als Einheit zu gaten (statt nur pro Kind) ist noch nicht umgesetzt.
onTaskCompletewird beim Export entfernt, nicht über Instanzen hinweg neu zugeordnet.