Code-Aufgaben
Aufgaben für den Coding-Agenten einreihen, ihren Weg von der Warteschlange bis zur Prüfung verfolgen und den code-worker-Sidecar betreiben, der die Pull Requests eröffnet.
Code-Aufgaben sind eine Warteschlange für den KI-Coding-Agenten. Eine Aufgabe trägt eine umgangssprachliche Beschreibung eines Features oder Bugfixes; der code-worker-Sidecar ist dafür ausgelegt, sie aufzunehmen, Ihr Repository zu klonen, die Änderung mit einem Coding-Agenten zu schreiben, die Test-Suite auszuführen und einen Pull Request zu eröffnen, den Sie prüfen können. Das Dashboard unter Postfach -> Code-Aufgaben zeigt jede Aufgabe und ihre aktuelle Stufe. Das ist eine Admin-Oberfläche — nur Owner und Admins können Aufgaben anlegen oder abbrechen.
Die Backend-Warteschlange und das Dashboard funktionieren bereits heute, und der code-worker-Sidecar authentifiziert sich mit dem Admin-Key des Deployments, beansprucht Aufgaben aus der Warteschlange und meldet den Fortschritt zurück. Beide mitgelieferten Compose-Stacks — der Dev-Stack und das VPS-Template — reichen CONVEX_ADMIN_KEY an den code-worker-Service durch, sodass eine Standardinstallation den Worker startet, sobald Sie das Profil aktivieren (siehe Setup).
Was Code-Aufgaben sind
Das Feature besteht aus zwei Hälften: der Warteschlange, die im Owlat-Backend liegt (die Tabelle codeWorkTasks), und dem code-worker, einem separaten Docker-Container, der die eigentliche Programmierarbeit erledigt. Das Dashboard liest Aufgaben lediglich und bricht sie ab; die eigentliche Arbeit passiert außerhalb des Prozesses im Sidecar.
Code-Aufgaben sind durch das Feature-Flag Code-Aufgaben aus dem Postfach extrahieren (inbox.codeTasks) abgesichert, das standardmäßig deaktiviert ist. Weil das Flag sowohl inbox als auch ai.agent voraussetzt (requires), aktiviert das Einschalten auch diese beiden; und wenn Sie ai.agent wieder ausschalten, kaskadiert das die Code-Aufgaben ebenfalls aus. Ist das Flag aktiv, erscheint im Postfach-Abschnitt der Seitenleiste ein Eintrag Code-Aufgaben; ist es aus, verschwindet der Eintrag aus der Seitenleiste, und die Seite selbst ist über die Feature-Voraussetzung inbox.codeTasks abgesichert. Wie Sie es umlegen, lesen Sie unter Feature-Flags.
Ist inbox.codeTasks aktiviert, werden eingehende Nachrichten, die als Feature-Request klassifiziert wurden, über createFromInbound automatisch in Code-Aufgaben in der Warteschlange verwandelt (idempotent je eingehender Nachricht, sodass dieselbe Nachricht nie zwei Aufgaben anlegt). Die manuelle Erstellung über die Mutation codeWorkTasks.create gibt es zusätzlich weiterhin. Siehe Aktuelle Einschränkungen.
Eine Aufgabe anlegen und abbrechen
Eine Aufgabe braucht genau eines: eine Beschreibung dessen, was getan werden soll. Schreiben Sie sie so, wie Sie ein Ticket schreiben würden — „Der Kontakttabelle eine Schaltfläche für den CSV-Export hinzufügen“, „Den Off-by-one-Fehler im Datumsbereich des Digests beheben“. Je klarer die Beschreibung, desto besser das Ergebnis des Coding-Agenten, denn dieser Text wird wortgetreu an den Agenten übergeben und wird zur Zusammenfassung des Pull Requests.
Das Anlegen einer Aufgabe erfordert die Berechtigung organization:manage (Owner und Admins). Die neue Aufgabe startet in der Stufe in Warteschlange und wartet darauf, dass der code-worker sie aufnimmt.
Das Code-Aufgaben-Dashboard hat eine Schaltfläche Neue Code-Aufgabe — in der Kopfzeile und im Leerzustand —, die ein Beschreibungs-Modal öffnet und die Aufgabe über die Mutation codeWorkTasks.create einreicht (dieselbe Mutation, die Sie auch aus dem Convex-Dashboard, einem Skript oder Ihrem eigenen Tooling aufrufen können). Die Beschreibung muss mindestens 10 Zeichen lang sein. Der unten beschriebene Lebenszyklus gilt unabhängig davon, wie die Aufgabe eingereicht wurde.
Zum Abbrechen öffnen Sie das Code-Aufgaben-Dashboard und nutzen die Schaltfläche Abbrechen auf einer Aufgabenkarte. Die Abbrechen-Schaltfläche des Dashboards erscheint nur bei Aufgaben in Warteschlange oder läuft, doch die zugrunde liegende Mutation codeWorkTasks.cancel lehnt nur gemergte Aufgaben ab — Aufgaben in Test und Prüfung lassen sich über das Backend weiterhin abbrechen. Ein Abbruch markiert die Aufgabe als fehlgeschlagen mit der Meldung „Cancelled by user“ — es gibt keine eigene Stufe „abgebrochen“.
Aufgaben-Lebenszyklus und die PR-/Test-/Kostenanzeige
Eine Aufgabe durchläuft einen festen Satz von Stufen. Der code-worker treibt sie im Laufe seiner Arbeit voran, und das Dashboard spiegelt jeden Übergang in Echtzeit wider.
| Stufe | Badge | Was sie bedeutet |
|---|---|---|
queued | In Warteschlange | Eingereicht und wartet darauf, dass der code-worker sie beansprucht. |
running | Läuft (pulsierend) | Der Worker hat die Aufgabe beansprucht, einen Branch eingerichtet und lässt den Coding-Agenten laufen. |
testing | Test | Die Änderung ist committet; der Worker führt die Test-Suite aus. |
review | Prüfung | Ein Pull Request wurde eröffnet. Die Änderung ist bereit dafür, von einem Menschen geprüft und gemerged zu werden. |
merged | Gemerged | Der Pull Request wurde gemerged. |
failed | Fehlgeschlagen | Der Aufgabe sind die Versuche ausgegangen, sie wurde abgebrochen oder sie hat keine Änderungen erzeugt. Der Fehler wird auf der Karte angezeigt. |
Ein fehlgeschlagener Lauf beendet die Aufgabe nicht beim ersten Stolpern: Solange noch Versuche übrig sind, geht sie hinter einer wachsenden Verzögerung zurück in die Warteschlange, und der Worker nimmt sie erneut auf. Siehe Automatische Wiederholungen.
Jede Aufgabenkarte zeigt das Arbeitsergebnis an, sobald es verfügbar ist:
| Feld | Wann es erscheint |
|---|---|
| Branch | Sobald der Worker den Feature-Branch angelegt hat (benannt code-worker/<task-id>). |
| Pull Request | Ein klickbarer Link zum PR, sobald der Worker einen eröffnet hat. |
| Testergebnisse | Ein Auszug der Ausgabe des Test-Runners, aufgezeichnet während der Test-Stufe. |
| Fehler | Nur bei fehlgeschlagenen Aufgaben — der Grund, warum die Aufgabe gestoppt hat. |
| Kosten | Die LLM-Ausgaben für den Lauf, auf vier Nachkommastellen angezeigt (z. B. $0.0123). Das Feld existiert im Schema und in der Oberfläche, doch der code-worker meldet llmCost derzeit nicht (es wird nie an completeWithPR/markFailed gesendet), sodass die Kosten bei vom Worker ausgeführten Aufgaben in der Praxis leer bleiben. |
| Erstellt | Ein relativer Zeitstempel („gerade eben“, „vor 12 Min.“, „vor 3 Tagen“). |
Der Worker eröffnet den Pull Request und setzt die Aufgabe auf Prüfung. Damit sie automatisch auf gemerged weiterrückt, konfigurieren Sie einen GitHub-Webhook, der auf POST /webhooks/github zeigt, mit dem Secret GITHUB_WEBHOOK_SECRET. Wird der PR gemerged, benachrichtigt GitHub Owlat, und die Aufgabe wechselt über markMergedByPrUrl auf gemerged. Die Stufe „gemerged“ ist im Produktivbetrieb erreichbar — die Prüfung ist kein Endzustand.
Setup: der code-worker-Service und seine Umgebung
Der code-worker wird als Docker-Sidecar ausgeliefert. Im mitgelieferten Compose-Stack läuft er unter dem Profil inbox-codetasks, das durch das Feature-Flag inbox.codeTasks aktiviert wird. Er verbindet sich über den Convex-Client mit Ihrem Owlat-Deployment, fragt die nächste Aufgabe im Status queued ab (standardmäßig alle 10 Sekunden) und bearbeitet jeweils eine Aufgabe zur Zeit.
Der Worker authentifiziert sich mit dem Admin-Key des Deployments (CONVEX_ADMIN_KEY), genau wie die Sidecars imap und mail-sync; das erlaubt ihm, die internen Queries und Mutationen aufzurufen, mit denen er die Aufgabe steuert (getNextQueued, claim, updateBranch, markTesting, completeWithPR, markFailed, reclaimStale). Sowohl der Dev-Compose-Stack als auch das VPS-Template reichen die Variable an den Service code-worker durch; die Setup-CLI erzeugt den Key beim ersten Start und schreibt ihn in .env, wo Compose ihn interpoliert. Beendet sich der Worker beim Start mit CONVEX_ADMIN_KEY environment variable is required, fehlt der Key in .env — erzeugen Sie ihn mit docker compose exec convex ./generate_admin_key.sh und starten Sie den Service neu.
Für jede beanspruchte Aufgabe tut der Worker Folgendes:
Die Aufgabe beanspruchen
Er beansprucht atomar die älteste Aufgabe aus der Warteschlange und setzt sie auf läuft, damit kein anderer Abrufvorgang sie aufnimmt.
Einen Workspace und Branch einrichten
Er klont Ihr Repository (flach, auf dem Basis-Branch) in einen aufgabenspezifischen Workspace und checkt einen neuen Branch code-worker/<task-id> aus.
Den Coding-Agenten laufen lassen
Er führt den Coding-Agenten (standardmäßig OpenCode) mit Ihrer Aufgabenbeschreibung als Prompt aus, mit einem Timeout von 10 Minuten. Schlägt der Agent fehl oder erzeugt er keine Dateiänderungen, wird der Lauf als Fehlschlag gemeldet — was die Aufgabe für einen weiteren Versuch zurück in die Warteschlange stellt oder sie endgültig scheitern lässt, sobald die Versuche aufgebraucht sind.
Committen und testen
Er committet die Änderungen, setzt die Aufgabe auf Test und führt die Test-Suite (vitest) mit einem Timeout von 5 Minuten aus, wobei er den Ausgabe-Auszug festhält.
Pushen und einen PR eröffnen
Er pusht den Branch und eröffnet — sofern GitHub-Zugangsdaten konfiguriert sind — einen Pull Request, dessen Beschreibung Ihre Aufgabenbeschreibung und die Testzusammenfassung enthält. Die Aufgabe wechselt auf Prüfung, mit PR-URL, Testergebnissen und Kosten im Gepäck.
Der Container liest seine Konfiguration aus Umgebungsvariablen:
| Variable | Zweck |
|---|---|
CONVEX_URL | Das Owlat-Backend, das der Worker abfragt und an das er meldet. Erforderlich. |
CONVEX_ADMIN_KEY | Admin-Key des Deployments, mit dem sich der Worker authentifiziert, um die internen Queries und Mutationen der Warteschlange aufzurufen. Erforderlich — der Worker wirft beim Start einen Fehler, wenn er nicht gesetzt ist. |
GIT_REPO_URL | Die Klon-URL des Repositorys, in dem der Agent arbeitet. |
GIT_BASE_BRANCH | Branch, der geklont wird und gegen den der PR gerichtet wird (Standard: main). |
GITHUB_TOKEN | GitHub-Token, mit dem der Pull Request eröffnet wird. |
GITHUB_OWNER / GITHUB_REPO | Das Repository, gegen das der PR eröffnet wird. Sind beide nicht gesetzt, pusht der Worker den Branch, überspringt aber das Anlegen des PR. |
LLM_BASE_URL / LLM_API_KEY | LLM-Konfiguration für den Coding-Agenten. Das sind die einzigen beiden LLM-Variablen, die der Kindprozess des Workers tatsächlich liest. |
LLM_PROVIDER / LLM_MODEL | Werden der Bequemlichkeit halber über die Compose-Umgebung durchgereicht, aber vom Worker selbst nicht gelesen. |
OPENCODE_BIN | Pfad zum OpenCode-Binary (Standard: opencode). |
POLL_INTERVAL_MS | Wie oft nach Aufgaben in der Warteschlange gefragt wird (Standard: 10000). |
WORKSPACE_ROOT | Wo die aufgabenspezifischen Klone im Container liegen (Standard: /workspace). |
Der code-worker klont, committet, pusht und eröffnet Pull Requests mit den Zugangsdaten, die Sie ihm geben, und lässt einen autonomen Coding-Agenten auf Ihre Codebasis los. Beschränken Sie GITHUB_TOKEN auf ein einzelnes Repository, richten Sie GIT_BASE_BRANCH auf einen Branch, den Sie mit verpflichtenden Reviews schützen, und behandeln Sie jeden erzeugten Pull Request als nicht vertrauenswürdig, bis Sie ihn gelesen haben.
Wo diese Variablen im Deployment liegen und wie Sie das Profil inbox-codetasks aktivieren, lesen Sie unter Self-Hosting-Konfiguration und Feature-Flags.
Automatische Wiederholungen
Die meisten Arten, auf die eine Code-Aufgabe scheitert, sind vorübergehend — der LLM-Endpunkt schluckt, der Klon läuft in einen Timeout, der Container wird mitten im Lauf neu gestartet —, deshalb wird ein fehlgeschlagener Lauf wiederholt, statt die Aufgabe zu beenden.
Jede Beanspruchung zählt als ein Versuch. Eine Aufgabe erhält insgesamt 3 Versuche; schlägt ein Lauf fehl und sind noch Versuche übrig, stellt das Backend die Aufgabe zurück in die Warteschlange und versieht sie mit dem frühesten Zeitpunkt, zu dem sie erneut beansprucht werden darf. Die Verzögerung wächst mit jedem Fehlschlag — 1 Minute nach dem ersten, 5 Minuten nach dem zweiten —, damit ein komplett ausgefallener LLM-Endpunkt nicht von einer Aufgabe bombardiert wird, die momentan gar nicht erfolgreich sein kann. Der Worker sieht eine Aufgabe erst, wenn dieses Fenster verstrichen ist, und bearbeitet in der Zwischenzeit jede andere bereite Aufgabe. Schlägt der letzte Versuch fehl, gilt die Aufgabe endgültig als fehlgeschlagen, mit dem letzten Fehler auf der Karte.
Zwei Regeln begrenzen das:
- Abbrechen gewinnt immer. Eine Aufgabe, die Sie abbrechen, ist sofort endgültig. War der Worker mitten im Lauf, kann der Fehlschlag, den er anschließend meldet, die Aufgabe nicht zurück in die Warteschlange bringen.
- Ein abgestürzter Worker lässt keine Aufgabe hängen. Beim Start holt der Worker jede Aufgabe zurück, die sein Vorgänger in läuft oder Test hinterlassen hat; jede davon wird hinter demselben Backoff wieder eingereiht (oder als fehlgeschlagen markiert, wenn ihre Versuche aufgebraucht sind), statt für immer in der Schwebe zu hängen.
Die Wiederholungsobergrenze und die Verzögerungen liegen im Backend, sodass ein veraltetes Worker-Image sie nicht ausweiten kann.
Aktuelle Einschränkungen
Code-Aufgaben sind ein frühes Feature. Behalten Sie Folgendes im Hinterkopf:
- Kosten werden nicht gemeldet. Der code-worker sendet nie
llmCost, sodass das Feld Kosten bei vom Worker ausgeführten Aufgaben leer bleibt, obwohl Schema und Oberfläche es unterstützen. - Eine Aufgabe zur Zeit, der Reihe nach. Der Worker bearbeitet pro Abruf die älteste bereite Aufgabe aus der Warteschlange; es gibt keine Parallelität und keine Priorisierung.
- Wiederholungen sind nicht konfigurierbar. Die Versuchsobergrenze und der Backoff-Plan sind im Backend fest verdrahtet; es gibt keine Einstellung pro Aufgabe oder pro Instanz und keine Möglichkeit, eine Aufgabe mit aufgebrauchten Versuchen von Hand erneut zu starten — außer, eine neue einzureichen.
- Eine wiederholte Aufgabe sieht aus wie eine wartende. Während eine Aufgabe ihren Backoff abwartet, zeigt sie das Badge In Warteschlange; das Dashboard zeigt bislang weder die Anzahl der Versuche noch, wann der nächste Versuch ansteht.
Ein umfassenderes Bild davon, wie Owlats Agent eingehende Konversationen und Entwürfe behandelt, finden Sie unter KI-Agent & Autonomie und Team-Postfach.