Code Mode
Im Code Mode schreibt der Agent ein kurzes JavaScript-Programm, statt die Tools einer App einzeln aufzurufen. Das Programm ruft die Tools auf, arbeitet mit ihren Ergebnissen und gibt nur das zurück, was der Agent braucht. Das spart Tokens, denn große Ergebnisse bleiben im Programm und kommen nicht in den Kontext des Modells. Das Programm kann auch viele Tools auf einmal aufrufen.
Code Mode gibt dem Agent keine neuen Rechte. Jeder Aufruf einer App in einem Programm geht durch dieselbe Prüfung der Fähigkeiten wie ein normaler Aufruf eines App-Tools. Jeder Aufruf ist auch eine normale App operation.
| Wort | Bedeutung |
|---|---|
| Programm | Der JavaScript-Code, den der Agent schreibt. Er ist der Rumpf einer async-Funktion. |
| Binding | Eine Fähigkeit einer App, die ein Programm aufrufen kann, zum Beispiel apps.work_calendar.list_events. |
| Sandbox | Ein geschlossener Ort, an dem das Programm läuft. Er hat kein Netzwerk, keine Dateien, keine Timer und kein Node.js. |
| Code run | Ein Programm und die Liste aller seiner Aufrufe. Lies ihn mit GET /v1/code-runs/:id. |
| Replay | Ein neuer Lauf desselben Programms nach einer Entscheidung. Aufrufe, die schon liefen, geben ihr gespeichertes Ergebnis. |
Code Mode einschalten
Code Mode ist am Anfang aus. Ein Admin der Platform schaltet ihn in den Einstellungen der Platform ein:
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"expectedVersion":3,"codeMode":{"enabled":true,"timeoutMs":30000,"memoryMb":64,"outputBytes":65536}}' \ https://api.example.com/v1/platform/settings| Feld | Was es ist |
|---|---|
enabled |
Bei true bekommen Agents die Tools von Code Mode in jedem Turn, der Connections zu Apps hat. |
timeoutMs |
Wie lange ein Lauf eines Programms dauern darf. Die Zeit, in der es auf Aufrufe von Apps wartet, zählt nicht. |
memoryMb |
Wie viel Speicher ein Programm nutzen darf. |
outputBytes |
Der größte Rückgabewert eines Programms und die größte Menge an Log-Text, die es behält. |
Diese Grenzen schützen den Server. Sie sind keine Grenzen für den Agent. Jede Instanz von OpenBot nutzt dieselben Grenzen. So verhält sich ein Programm gleich, wenn eine andere Instanz es noch einmal ausführt.
So nutzt der Agent ihn
Der Agent bekommt zwei weitere Tools. Sie stehen neben den normalen Tools der Apps und ersetzen sie nicht.
| Tool | Was es tut |
|---|---|
openbot_code_api |
Zeigt die TypeScript-Deklarationen der Bindings. Der Agent kann sie nach Wörtern oder nach Connection suchen. |
openbot_run_code |
Führt ein Programm aus und gibt sein Ergebnis, seine Log-Zeilen und eine Liste seiner Aufrufe zurück. |
Jedes Binding hat zwei Teile: die Connection und die Fähigkeit. Eine Connection mit dem Namen “Work calendar” und dem Tool list-events wird zu apps.work_calendar.list_events. apps.call("work_calendar.list_events", args) tut dasselbe. Auch Ressourcen und Prompts werden zu Bindings zum Lesen. Ein Programm kann so aussehen:
const [today, tomorrow] = await Promise.all([ apps.work_calendar.list_events({ day: "2026-10-23" }), apps.work_calendar.list_events({ day: "2026-10-24" }),])const busy = [today, tomorrow].flatMap( (result) => result.structuredContent.events,)console.log("events", busy.length)return busy.filter((event) => event.attendees > 10).map((event) => event.title)Ein Aufruf eines Tools gibt dem Programm das Ergebnis, das die App geschickt hat. Wenn ein Aufruf nicht klappt, bekommt das Programm einen Error:
| Name des Fehlers | Warum |
|---|---|
AppCallDenied |
Ein Entscheider hat den Aufruf nicht erlaubt. |
AppCallFailed |
Der Aufruf der App ist fehlgeschlagen. details.reason sagt, warum. |
AppInputRequired |
Die App braucht mehr Eingaben. Beantworte die App operation in details.operationId außerhalb des Codes. |
Das Programm kann diese Fehler abfangen und weitermachen.
Wenn ein Aufruf eine Entscheidung braucht
Manche Aufrufe einer App brauchen eine Entscheidung, zum Beispiel ein Tool, das schreibt. Dann hält das Programm bei diesem Aufruf an, und der Turn wartet. Der Request hat den Aufruf der App in app und das Programm in code:
{ "capability": { "action": "apps.call", "target": "conn-7/send_email" }, "toolCallId": "call-9", "app": { "id": "…", "callId": "call-9:1", "arguments": { "to": "team@example.com" } }, "code": { "run": "8f1c…", "index": 1, "code": "const notes = await …" }}Nach der Entscheidung führt OpenBot das Programm noch einmal von oben aus. Jeder Aufruf, der schon lief, gibt sein gespeichertes Ergebnis. OpenBot schickt ihn nicht noch einmal an die App. Dann läuft das Programm nach dem Aufruf weiter, der gewartet hat. Wenn es endet, bekommt der Turn das Ergebnis und macht weiter.
Das klappt nur, wenn das Programm jedes Mal dieselben Aufrufe in derselben Reihenfolge macht. Darum sieht das Programm in Date.now() eine feste Zeit, und Math.random() gibt in jedem Lauf dieselben Zahlen. Wenn ein Programm andere Aufrufe macht als vorher, stoppt OpenBot es mit ReplayMismatch. Das kann passieren, wenn sich eine Connection geändert hat, während das Programm gewartet hat. Nichts wird aus Versehen geschickt.
Code runs lesen
GET /v1/sessions/:sessionId/code-runs listet die Programme einer Session. GET /v1/code-runs/:id liest eines. Beide brauchen apps.use. Die Liste braucht auch sessions.read für die Session. Du siehst nur die Programme deiner eigenen Sessions.
{ "id": "8f1c…", "session": "c81d…", "turn": "t-77", "callId": "call-9", "status": "Completed", "code": "const notes = await …", "reason": "Send the notes to the team.", "calls": [ { "index": 0, "binding": "notes.read_note", "source": { "connectionName": "Notes", "name": "read_note", "…": "…" }, "operationId": "3a9e…", "outcome": { "_tag": "Done", "result": { "_tag": "Completed", "…": "…" } } } ], "result": { "_tag": "Completed", "value": "sent", "logs": [] }, "createdAt": 1792486800000, "updatedAt": 1792486801000}status |
Bedeutung |
|---|---|
Running |
Das Programm läuft gerade. |
Waiting |
Ein Aufruf des Programms wartet auf eine Entscheidung. |
Completed |
Das Programm ist fertig. result.value ist sein Rückgabewert. |
Failed |
Das Programm hat nicht gut geendet. result.reason sagt, warum. |
Cancelled |
Der Turn wurde unterbrochen, während das Programm lief. |
OpenBot speichert Code runs verschlüsselt in der Datenbank, wie App operations.
Gründe für Fehler
reason |
Bedeutung |
|---|---|
Error |
Das Programm hat einen Fehler geworfen und ihn nicht abgefangen. |
Timeout |
Das Programm hat seine ganze Zeit verbraucht. |
Memory |
Das Programm hat seinen ganzen Speicher verbraucht. |
OutputTooLarge |
Das Programm hat mehr Daten zurückgegeben, als outputBytes erlaubt. |
ReplayMismatch |
Das Programm hat andere Aufrufe gemacht als beim letzten Lauf. |
Cancelled |
Das Programm wurde gestoppt. |
Unavailable |
OpenBot konnte das Programm nicht ausführen oder speichern, oder Code Mode ist aus. |