Zum Artikel springen
HB CodeDocsApp herunterladen

HandbuchArchitektur

Zwei Agenten, eine Chat-Schicht

Wie Codex und Claude in eine Chat-Schicht passen: was der gemeinsamen Schicht gehört, was jedem Adapter gehört, was die Dispatch-Schicht entscheidet und wo sich die beiden Agenten bei Konten, Zugriffsstufen und Fähigkeiten unterscheiden.

Gegen den Quellcode geprüft am 30. September 2026

Auf dieser Seite

Codex und Claude nebeneinander

HB Code betreibt zwei Coding-Agenten. Codex läuft über den Codex app-server, einen Kindprozess, der JSON-RPC spricht. Claude läuft über den Agent-Host, einen Node-Prozess, der das Claude Agent SDK ausführt. Beide Agenten speisen eine Chat-Schicht: eine Outbox, eine Run-Registry, einen Satz Timeline-Zeilen, eine Freigabekarte, einen Tool-Katalog und einen RPC-Vertrag für die Telefone. Eine Session nutzt ihr ganzes Leben lang einen Agenten.

Der größte Unterschied ist, wie lange die Dinge leben. Die Abbildung zeigt zwei Runs einer Session und eine Änderung der Einstellungen dazwischen.

Der Codex-Kindprozess und seine Tool-Liste überleben einen Run. Ein Claude-Host und seine Tool-Liste leben einen Run lang.
Der Codex-Kindprozess und seine Tool-Liste überleben einen Run. Ein Claude-Host und seine Tool-Liste leben einen Run lang.Eine nicht maßstäbliche Zeitachse zeigt zwei Runs einer Session mit einer Pause dazwischen. In der Pause speichert der Benutzer einen Gemini-API-Schlüssel, der dem HB-Code-Tool-Katalog zwei Tools hinzufügt. Die oberste Spur ist der gemeinsame Chat-Run. In einer Codex-Session läuft der app-server-Kindprozess durch beide Runs und die Pause weiter, und der Thread behält die Tool-Liste, die thread/start ihm gegeben hat, sodass Run 2 noch die alte Liste hat. In einer Claude-Session startet jeder Run einen neuen Agent-Host, der mit dem Run endet, und in der Pause existiert kein Claude-Prozess. Jedes open sendet die aktuelle Tool-Liste, sodass Run 2 die zwei neuen Tools hat.
Chat-Rungemeinsame Chat-Schicht
Codex app-serverKindprozess
Codex-Threadseine Tool-Liste
Claude-Agent-HostNode-Prozess
Claude-Tool-Listemit open gesendet
Gemini-API-Schlüssel gespeichert: 2 weitere Tools im Katalog
Run 1
Run 2
ein Kindprozess, bleibt zwischen den Runs
eine Liste, festgelegt bei thread/start
Run 2 hat noch die alte Liste
Host 1
Host 2
kein Claude-Prozess
Liste ohne die Gemini-Tools
Liste mit den Gemini-Tools
Run 1 startet
Run 1 endet
Run 2 startet
Run 2 endet
  • Chat-Runchat/runs

    Von beiden Agenten geteilt. Eine Session hat jeweils einen aktiven Run, und die Outbox startet den nächsten Run, nachdem der erste abgeschlossen ist.

  • Codex app-serverMAX_LIVE_APP_SERVERS = 3

    Ein Kindprozess pro Profilpaar bedient viele Sessions und viele Runs. Höchstens 3 untätige Kindprozesse bleiben bestehen, und die Registry wächst, wenn alle beschäftigt sind.

  • Codex-Threadthread/start · dynamicTools

    Bekommt die Tool-Liste einmal. thread/resume hat kein Feld für Tools, sodass eine neue Einstellung nur einen Thread erreicht, der später startet.

  • Claude-Agent-Hostopen · appCapabilities

    Ein Node-Prozess pro Run. Die open-Anfrage trägt die Tool-Liste dieses Moments, das Modell, den Aufwand und den Berechtigungsmodus.

ThemaCodexClaude
Prozess und LebensdauerDer Kindprozess codex-app-server. Ein Kindprozess pro Profilpaar bedient viele Sessions. Höchstens 3 untätige Kindprozesse bleiben bestehen, und die Registry wächst, wenn alle beschäftigt sind.Der Agent-Host, ein Node-Prozess, der die ausführbare Datei claude startet. Jeder Run bekommt einen neuen Host, und der Host endet mit seinem Run. Lesevorgänge wie der Modellkatalog, ein Titel oder eine Verlaufsseite laufen in einem einmaligen Host.
ProtokollJSON-RPC-Zeilen über stdin und stdout: Anfragen, Benachrichtigungen und Anfragen des app-server an den Desktop.Ein JSON-Objekt pro Zeile über stdin und stdout. Eine Anfrage trägt eine id, und eine Zeile ohne id ist ein Event. Der Desktop gibt jeder Anfrage 35 Sekunden.
Woher der Verlauf kommtthread/items/list über die Pipe. Der Desktop liest die Codex-Dateien nie.Der Host liest das gespeicherte Transkript mit dem SDK-Aufruf getSessionMessages, in Seiten von höchstens 100 Nachrichten. Der Desktop liest die Claude-Dateien nie.
Wann eine Nachricht als gesendet giltDer Thread-Verlauf enthält eine userMessage, deren clientId der operationId der Outbox entspricht.Das gespeicherte Transkript enthält die Nachrichten-UUID, die der Desktop für die Operation in claude_operations gespeichert hat.
Lebensdauer der Tool-ListeWird als dynamicTools mit thread/start gesendet. Der Thread behält diese Liste sein ganzes Leben lang.Wird als appCapabilities mit jedem open gesendet. Jeder Run bekommt die Liste, die die Einstellungen in diesem Moment ergeben.
FreigabenDer app-server sendet eine Anfrage an den Desktop. Die Zugriffsstufe legt die Sandbox und die Freigaberichtlinie fest.Das SDK ruft canUseTool im Host auf. Der Host hält den Aufruf offen und sendet ein permission-Event.
KontenCodex-Auth-Profile. Das aktive Profil bezahlt den nächsten Turn.Das Standardkonto in Claudes eigenem Ordner und hinzugefügte Kontoordner. Das aktive Konto bezahlt den nächsten Run.
Subagents oder Kind-ThreadsKind-Threads des Wurzel-Threads. Der Desktop verfolgt einen geöffneten Kind-Thread live über eine Beobachtung.Subagents des Runs, die ein Workflow in Gruppen starten kann. Ihre Turns kommen über den Host des Elternteils an, und ein Subagent nimmt keine direkte Eingabe an.
Was HB Code speichertcodex_session_links: die Thread-ID, das Profil und der Rollout-Pfad als undurchsichtiger Wert.claude_sessions: die Claude-Session-ID der Session. claude_operations: eine Nachrichten-UUID pro Outbox-Operation.

Die Schichtregel: chat, dispatch, Adapter

Der Rust-Code hat eine Regel für die beiden Agenten. Die gemeinsame Chat-Schicht in desktop/src-tauri/src/chat nennt nie einen Adapter. Wenn ein Schritt den Agenten braucht, ruft chat agents/dispatch auf. dispatch liest den Agenten der Session und ruft agents/codex oder agents/claude auf. Die beiden Adapter importieren einander nie.

Die Chat-Schicht erreicht einen Adapter nur über agents/dispatch, und die Adapter erreichen einander nie
Die Chat-Schicht erreicht einen Adapter nur über agents/dispatch, und die Adapter erreichen einander nieEine Karte von vier Code-Bereichen in desktop/src-tauri/src. Oben nimmt die gemeinsame Chat-Schicht in chat/ Aufrufe der Tauri-Befehle und des Telefon-RPC entgegen. Ein Pfeil führt von chat/ hinunter in agents/dispatch/, das sechs Entscheidungsdateien enthält: send.rs, selection.rs, runs.rs, approvals.rs, conversations.rs und timeline.rs. Jede Datei zeigt ihre Regel: nach dem Agenten der Erlaubnis, nach dem Agenten der Session oder zuerst Claude und dann Codex. Von dispatch führt ein Pfeil zu agents/codex/ und einer zu agents/claude/. Zwei durchkreuzte Stummel unter chat/ zeigen, dass chat nie direkt einen Adapter aufruft. Eine gestrichelte Wand mit einem Kreuz zwischen den beiden Adaptern zeigt, dass sie einander nie importieren. Zwei blasse Pfeile führen von den Adaptern hinauf zu chat/, weil beide dessen gemeinsame Typen nutzen. Rechts liest usage_history/ beide Adapter direkt.
chat/agentenneutral: Outbox, Run-Registry, Timeline-Zeilen, Freigaben, Session-Nachrichten
AufruferTauri-Befehle · Telefon-RPC
jeder Agent-Schritt
kein direkter Aufruf
kein direkter Aufruf
agents/dispatch/liest den Agenten der Session, wählt den Adapter
send.rsnach Agent der Erlaubnis
selection.rsnach Agent der Session
runs.rserst Claude, dann Codex
approvals.rserst Claude, dann Codex
conversations.rsnach Agent der Session
timeline.rsnach Agent der Session
agents/codex/app-server-Kindprozess, Turns, Verlauf, Auth-Profile
agents/claude/Agent-Host, Run-Schleife, Projektion, Konten
nutzt die gemeinsamen Typen
nutzt die gemeinsamen Typen
kein Import in beide Richtungen
usage_history/speichert Limit-Messwerte beider Kontoarten
liest beide Adapter
  • chat/desktop/src-tauri/src/chat

    Die agentenneutrale Schicht. Keine Datei darin nennt agents::codex oder agents::claude. Sie ruft agents/dispatch auf, wenn ein Schritt den Agenten braucht.

  • agents/dispatch/7 Dateien · mod.rs: session()

    Liest die Session-Zeile und wählt den Adapter. Beide Adapter rufen außerdem seine Session-Suche auf, und sonst nichts darin.

  • agents/codex/ und agents/claude/zwei Adapter

    Jeder Adapter betreibt seine eigene Engine und bildet sie auf den Chat-Vertrag ab. Keiner nennt den anderen.

  • usage_history/mod.rs · recording.rs

    Die zweite Stelle, die beide Adapter nennt. Sie liest das aktive Codex-Profil und das aktive Claude-Konto, weil sie Limit-Messwerte von beiden speichert.

Beide Adapter nutzen die gemeinsamen Typen und Dienste von chat, zum Beispiel die Sendeanfrage, die Timeline-Zeilen und die Run-Registry. Beide rufen außerdem eine Funktion von dispatch auf, die Session-Suche. usage_history ist das zweite Modul, das beide Adapter nennt, weil es die Limit-Messwerte beider Kontoarten speichert. Code, der einem Agenten dient, nennt diesen Adapter direkt. Der Worker für HTML-Dokumente in services/agent_tools ist ein Beispiel: Er least einen Codex app-server.

Was die Dispatch-Schicht entscheidet

agents/dispatch hat sieben Dateien. Die meisten Funktionen lesen die Session-Zeile und verzweigen nach ihrem Agenten. Einige Funktionen haben eine andere Regel, weil ihr Aufrufer keinen Session-Agenten zur Hand hat oder weil nur ein Adapter den Zustand hält.

DateiWas sie entscheidetWer antwortet
mod.rsDie Session-Suche über die Basis-Session-ID. Jede andere Datei beginnt hier.Eine fehlende Zeile schlägt mit „The chat session does not exist.“ fehl.
selection.rsDer Modellkatalog für die Auswahl, das erste Modell und der erste Aufwand einer Session und die Prüfung von Modell und Aufwand vor einem Versand.Der Agent der Session. Die Prüfung gibt eine Erlaubnis für diesen Agenten zurück. Eine Claude-Erlaubnis kann nach einer fehlenden Thread-Verknüpfung nicht auf einen frischen Thread wechseln.
send.rsDie drei Fähigkeits-Flags, der Versand selbst, die Verlaufsprüfung einer unsicheren Operation, der aktive Turn, die Freigabe einer angenommenen Steuerung für eine Wiederholung, das Zurückrollen des letzten Turns und das Entfernen einer toten Thread-Verknüpfung.Der Versand folgt der Erlaubnis: Eine Claude-Erlaubnis geht an den Claude-Adapter, und ohne Erlaubnis läuft nur eine Codex-Steuerung weiter. Die Verlaufsprüfung folgt dem Agenten der Session. Die anderen vier gibt es nur für Codex.
runs.rsFragen der Run-Registry: Gehört dieser Run noch einem Agent-Turn, darf ein veralteter Run zurückgefordert werden, einen Run abbrechen und einen Kind-Thread beobachten.Die Turn-Zuständigkeit beantwortet immer der Codex-Adapter, der für eine Claude-Session keine Einträge führt. Ein registrierter Codex-Turn oder ein lebender Claude-Host blockiert eine Rückforderung. Bei einem Abbruch antwortet zuerst Claude, dann Codex. Eine Claude-Session bekommt keine Kind-Thread-Beobachtung.
approvals.rsDie Antwort auf eine Freigabekarte. Der Auflösungsaufruf nennt eine Anfrage, einen Thread, einen Turn und ein Item, aber keine Session.Claude antwortet zuerst, wenn es eine Anfrage mit dieser id hält. Sonst erledigt sie der Codex app-server, dem die Anfrage gehört.
conversations.rsDie eigene Unterhaltungs-ID des Agenten, die Liste und die Vorschau gespeicherter Unterhaltungen, der Session-Titel, die Session, der eine Unterhaltung bereits gehört, und die Verknüpfung einer neuen oder duplizierten Session.Der Agent der Session oder der Agent in der Anfrage. Eine Claude-Liste braucht ein Projektverzeichnis. Codex schreibt Titel mit gpt-5.6-luna, Claude mit haiku.
timeline.rsDas neueste Fenster, eine ältere Seite, ein Kind-Thread und seine Seiten, die Liste der Agent-Threads mit den Workflows, die sie gestartet haben, und die Befehlsausgabe.Der Agent der Session. Bei Claude ist ein Kind-Thread ein Subagent, und nur Claude füllt die Liste workflows. Codex gibt eine leere Liste zurück. Ausgabe, die der Desktop als Artefakt gespeichert hat, gibt es nur für Codex-Runs. Claude-Ausgabe kommt vom Host-Aufruf toolOutput und läuft durch den gemeinsamen Bereichsleser.

Eine Session wählt ihren Agenten bei der Erstellung

session.create trägt agent und eine optionale conversationId. agent ist codex oder claude, und der Anfragetyp hat dafür keinen Standardwert, sodass eine Anfrage ohne agent beim Dekodieren fehlschlägt. conversationId nennt eine gespeicherte Unterhaltung dieses Agenten: eine Codex-Thread-ID oder eine Claude-Session-ID.

  1. Wenn eine Session diese Unterhaltung bereits fortsetzt, gibt create diese Session zurück. Eine Unterhaltung hat einen Besitzer.
  2. Sonst speichert der Desktop die Session-Zeile mit chat_agent und mit ausstehenden Chat-Einstellungen.
  3. Der Adapter verknüpft die Session. Codex verknüpft den gewählten Thread. Claude schreibt eine Zeile in claude_sessions mit der gewählten Session-ID oder mit einer neuen UUID für eine neue Unterhaltung.
  4. Wenn die Verknüpfung fehlschlägt, löscht der Desktop die neue Session und gibt den Fehler zurück.

Die Spalte chat_agent akzeptiert nur codex und claude, und kein Code ändert sie nach dem Einfügen. Eine Session wechselt ihren Agenten daher nie. Eine duplizierte Session behält den Agenten und beginnt eine eigene Unterhaltung: Claude bekommt sofort eine neue Session-ID, und Codex startet beim ersten Versand einen neuen Thread.

Der Desktop merkt sich die letzte Wahl im lokalen Speicher der WebView unter plantocode:new-session-agent:v1 und wählt sie im nächsten Dialog vor. Ohne gespeicherten Wert wählt er Codex vor. Der Wert ist eine Vorauswahl, und die Erstellungsanfrage nennt den Agenten immer.

Eine Zugriffsstufe, zwei Mechanismen

Eine Nachricht trägt eine von vier HB-Code-Zugriffsstufen. Jeder Adapter bildet die Stufe auf den eigenen Mechanismus des Agenten ab. Codex bekommt ein Berechtigungsprofil und eine Freigaberichtlinie. Claude bekommt einen seiner Berechtigungsmodi. Die Oberfläche zeigt für die Stufe den eigenen Namen des jeweiligen Agenten.

ZugriffsstufeCodex: Name, permissions, approvalPolicyClaude: Name, permissionMode
read-onlyRead only. :read-only, on-requestPlan mode. plan
full-autoFull auto. :workspace, on-requestAccept edits. acceptEdits
full-accessFull access. :danger-full-access, on-requestAuto mode. auto
unrestrictedNever ask. :danger-full-access, neverBypass permissions. bypassPermissions

Codex erhält das Paar mit thread/start und erneut mit jedem turn/start, sodass eine neue Stufe für den nächsten Turn gilt. Eine kurzlebige Codex-Anfrage läuft immer mit :read-only und never. Claude erhält den Modus mit der open-Anfrage jedes Runs, sodass eine neue Stufe für den nächsten Run gilt. Bei auto fragt der Host das SDK, ob das gewählte Modell den Auto mode unterstützt. Wenn nicht, schlägt open fehl und der Run startet nicht.

Was jeder Agent kann

Der Submit-Dienst fragt agents/dispatch nach drei Flags, bevor er eine Nachricht speichert: steer, replace_latest und speed_modes. Codex hat alle drei, Claude hat keines. Eine Anfrage, die eine fehlende Fähigkeit braucht, schlägt beim Übermitteln mit einem Validierungsfehler fehl und gelangt daher nie in die Outbox. Die anderen Unterschiede liegen in den Adaptern.

FähigkeitCodexClaude
Einen laufenden Turn steuernJa. Die Nachricht geht in den aktiven Turn ein.Nein. Die Übermittlung lehnt die Steuerung ab. Die Nachricht wartet in der Warteschlange oder geht hinaus, nachdem Sie den Run gestoppt haben.
Die letzte gesendete Nachricht ersetzenJa. Der Desktop rollt den letzten Turn zurück und sendet die bearbeitete Nachricht.Nein. Die Übermittlung lehnt die Ersetzung ab.
GeschwindigkeitsmodusJa. Fast sendet serviceTier priority.Nein. Die Übermittlung lehnt jeden Modus außer standard ab.
Stop and send nowJa. Es nimmt eine angenommene Steuerung zurück und sendet sie als neuen Turn.Nein. Eine Claude-Session hat keine angenommene Steuerung, die sich zurücknehmen ließe.
ZieleJa. Ein Run kann viele Turns enthalten.Nein. Der Aufruf schlägt mit „Goals are available in Codex sessions.“ fehl.
HB-Code-ToolsDerselbe Katalog. Codex führt diese Tools aus, ohne zu fragen.Derselbe Katalog. maintain_sessions läuft, ohne zu fragen, send_session_message folgt der eigenen Regel des Desktops, und jedes andere Tool folgt der Zugriffsstufe.
Worker für HTML-DokumenteEin Codex-Turn auf dem app-server der Session, mit den Einstellungen des aufrufenden Turns.Derselbe Codex-Worker. Der Tool-Aufruf least einen Codex app-server, sodass Codex das Dokument auch in einer Claude-Session schreibt.
Kind-ThreadsEin Kind-Thread kann direkte Eingabe annehmen, wenn Codex canAcceptDirectInput meldet.Ein Subagent nimmt nie direkte Eingabe an.
BefehlsausgabeDer Desktop speichert Live-Ausgabe als Artefakt und liest gespeicherte Ausgabe vom app-server.Der Host liest gespeicherte Ausgabe bei Bedarf mit toolOutput.
Eine gespeicherte Unterhaltung fortsetzenJa. Das Projektverzeichnis ist in der Listenanfrage optional.Ja. Die Listenanfrage braucht ein Projektverzeichnis.

Konten, Limits und Nutzungsverlauf

Jeder Agent hat eigene Konten und eigene Plan-Limits. Codex hat Auth-Profile, und Claude hat das Standardkonto und hinzugefügte Kontoordner. Ein Wechsel ändert, wer den nächsten Turn bezahlt. Er verschiebt nie eine Unterhaltung. Der Desktop behält einen Codex-Limit-Messwert 60 Sekunden lang und einen Messwert pro Claude-Konto 60 Sekunden lang.

Jeder frische Limit-Messwert geht außerdem in die Tabelle agent_usage_samples in der Desktop-Datenbank. Das Speichern läuft in einem eigenen Task, sodass ein Limit-Lesevorgang nie darauf wartet und nie deswegen fehlschlägt.

RegelWert
Zeileagent, account_key, window_kind, used_percent, resets_at, sampled_at. account_key ist die Codex-Profil-ID oder die Claude-Konto-ID.
Gespeicherte FensterNur die Fenster für alle Modelle: session (die rollierenden fünf Stunden) und weekly. Codex-Fenster werden an ihrer Länge erkannt, 300 und 10.080 Minuten. Ein Claude-Fenster für ein einzelnes Modell wird nicht gespeichert.
WiederholungsfilterEin Messwert wird übersprungen, wenn der neueste gespeicherte desselben Fensters jünger als 10 Minuten ist, dieselbe Rücksetzzeit hat und um weniger als 0,5 Prozentpunkte abweicht.
AufbewahrungMesswerte bleiben 35 Tage. Der Desktop löscht ältere höchstens einmal pro Stunde.
Was ein Lesevorgang liefertDie Wochen-Messwerte des aktiven Kontos aus den letzten 14 Tagen und den Zeitpunkt des ältesten gespeicherten Messwerts dieses Agenten.
Codex-TokensFür Codex ergänzt der Lesevorgang bis zu 30 Tage täglicher Tokens und eine Zusammenfassung aus dem app-server-Aufruf account/usage/read. Die Antwort wird 5 Minuten aufbewahrt. Claude hat keinen Token-Teil.

Settings > Agents auf dem Desktop zeigt beide Agenten nebeneinander und danach die Nutzung, die Verlaufsdiagramme und die Konten des gewählten Agenten. Es liest den Verlauf über den Befehl agent_usage_history_command. Die Telefone lesen dieselben Daten über system.agentUsageHistory.