OpenClaw Session Binding: Kanalunabhängiges Routing
Kennst du das Problem, wenn dein Code für das Session-Management immer komplexer wird, weil du versuchst, jeden Messenger-Kanal einzeln zu bändigen? Oft landen Nachrichten dann doppelt im Thread oder die Zustellung schlägt fehl, weil die Logik zu tief mit der API des jeweiligen Dienstes verwoben ist.
Wir brauchen eine saubere Lösung, die unabhängig vom Kanal funktioniert, damit du dich auf das Wesentliche konzentrieren kannst. In diesem Guide erfährst du, wie wir das Session-Routing auf eine neue Ebene heben.
Überblick
Abschnitt betitelt „Überblick“Dieses Dokument beschreibt das langfristige Modell für kanalunabhängiges Session Binding und den konkreten Umfang für die nächste Iteration.
Unsere Ziele:
- Subagent bound session routing als Core-Fähigkeit etablieren.
- Kanalspezifisches Verhalten strikt in Adaptern halten.
- Regressionen im normalen Discord-Verhalten verhindern.
- Die Code-Basis für zukünftige Kanäle vorbereiten.
Warum wir das brauchen
Abschnitt betitelt „Warum wir das brauchen“Das aktuelle Verhalten vermischt verschiedene Verantwortlichkeiten:
- Completion Content Policy
- Destination Routing Policy
- Discord-spezifische Details
Das führte zu Fehlern wie doppelten Zustellungen im Hauptkanal und Thread bei parallelen Runs oder veralteten Tokens bei wiederverwendeten Binding-Managern. Auch die fehlende Aktivitätsaufzeichnung bei Webhook-Sendeoperationen und unvorhersehbares Verhalten bei der Wiederverwendung von Sessions waren problematische Edge Cases.
Umfang von Iteration 1
Abschnitt betitelt „Umfang von Iteration 1“Diese Iteration ist bewusst begrenzt gehalten.
1. Kanalunabhängige Core-Interfaces hinzufügen
Abschnitt betitelt „1. Kanalunabhängige Core-Interfaces hinzufügen“Wir führen Core-Typen und Service-Interfaces für Bindings und Routing ein.
Vorgeschlagene Core-Typen:
export type BindingTargetKind = "subagent" | "session";export type BindingStatus = "active" | "ending" | "ended";
export type ConversationRef = { channel: string; accountId: string; conversationId: string; parentConversationId?: string;};
export type SessionBindingRecord = { bindingId: string; targetSessionKey: string; targetKind: BindingTargetKind; conversation: ConversationRef; status: BindingStatus; boundAt: number; expiresAt?: number; metadata?: Record<string, unknown>;};Core Service Contract:
export interface SessionBindingService { bind(input: { targetSessionKey: string; targetKind: BindingTargetKind; conversation: ConversationRef; metadata?: Record<string, unknown>; ttlMs?: number; }): Promise<SessionBindingRecord>;
listBySession(targetSessionKey: string): SessionBindingRecord[]; resolveByConversation(ref: ConversationRef): SessionBindingRecord | null; touch(bindingId: string, at?: number): void; unbind(input: { bindingId?: string; targetSessionKey?: string; reason: string; }): Promise<SessionBindingRecord[]>;}2. Einen Core Delivery Router für Subagent Completions hinzufügen
Abschnitt betitelt „2. Einen Core Delivery Router für Subagent Completions hinzufügen“Wir implementieren einen zentralen Pfad zur Zielauflösung für Completion-Events.
Router Contract:
export interface BoundDeliveryRouter { resolveDestination(input: { eventKind: "task_completion"; targetSessionKey: string; requester?: ConversationRef; failClosed: boolean; }): { binding: SessionBindingRecord | null; mode: "bound" | "fallback"; reason: string; };}Für diese Iteration gilt:
- Nur
task_completionwird über diesen neuen Pfad geleitet. - Bestehende Pfade für andere Event-Typen bleiben unverändert.
- Keine Auswirkungen auf andere Event-Typen.
- Monitoring der neuen Routing-Entscheidungen ist möglich.
3. Discord bleibt ein Adapter
Abschnitt betitelt „3. Discord bleibt ein Adapter“Discord fungiert weiterhin als erste Adapter-Implementierung.
Aufgaben des Adapters:
- Thread-Konversationen erstellen oder wiederverwenden.
- Gebundene Nachrichten via Webhook oder Channel-Send verschicken.
- Thread-Status validieren (archiviert/gelöscht).
- Adapter-Metadaten mappen (Webhook-Identität, Thread-IDs).
4. Bekannte Korrektheitsfehler beheben
Abschnitt betitelt „4. Bekannte Korrektheitsfehler beheben“In dieser Iteration müssen folgende Punkte erledigt werden:
- Token-Nutzung beim Wiederverwenden von Thread-Binding-Managern aktualisieren.
- Outbound-Aktivität für Webhook-basierte Discord-Nachrichten aufzeichnen.
- Den impliziten Fallback auf den Hauptkanal stoppen, wenn ein Thread-Ziel gewählt wurde.
- Validierung der Thread-Metadaten sicherstellen.
5. Aktuelle Runtime-Sicherheitsstandards beibehalten
Abschnitt betitelt „5. Aktuelle Runtime-Sicherheitsstandards beibehalten“Für Nutzer, bei denen Thread Bound Spawning deaktiviert ist, ändert sich nichts.
Die Defaults bleiben:
channels.discord.threadBindings.spawnSubagentSessions = false
Das bedeutet, dass normale Discord-Nutzer das gewohnte Verhalten behalten. Der neue Core-Pfad betrifft nur das Routing gebundener Sessions, wo dies explizit aktiviert wurde.
Nicht in Iteration 1 enthalten
Abschnitt betitelt „Nicht in Iteration 1 enthalten“Folgende Punkte sind auf später verschoben:
- ACP Binding Targets (
targetKind: "acp") - Neue Channel-Adapter außer Discord
- Globaler Austausch aller Delivery-Pfade (
spawn_ack, zukünftigesubagent_message) - Änderungen auf Protokollebene
- Redesign der Store-Migration/Versionierung für die Persistenz
Hinweise zu ACP: Das Interface-Design lässt bereits Raum für ACP, aber die Implementierung startet in dieser Iteration noch nicht.
Routing-Invarianten
Abschnitt betitelt „Routing-Invarianten“Diese Regeln sind für Iteration 1 zwingend erforderlich:
- Die Auswahl des Ziels und die Generierung des Inhalts sind getrennte Schritte.
- Wenn eine Session-Mode Completion ein aktives gebundenes Ziel findet, muss die Zustellung genau dort erfolgen.
- Es gibt kein verstecktes Rerouting vom gebundenen Ziel zum Hauptkanal.
- Fallback-Verhalten muss explizit und nachvollziehbar sein.
Kompatibilität und Rollout
Abschnitt betitelt „Kompatibilität und Rollout“Unser Ziel für die Kompatibilität:
- Keine Regressionen für Nutzer, bei denen Thread Bound Spawning deaktiviert ist.
- Keine Änderungen an Nicht-Discord-Kanälen in dieser Iteration.
Rollout-Plan:
- Interfaces und Router hinter aktuellen Feature Gates implementieren.
- Discord Completion-Zustellungen über den Router leiten.
- Legacy-Pfad für nicht-gebundene Flows beibehalten.
- Mit gezielten Tests und Canary-Logs verifizieren.
Erforderliche Tests in Iteration 1
Abschnitt betitelt „Erforderliche Tests in Iteration 1“Wir benötigen Unit- und Integration-Tests für folgende Szenarien:
- Der Manager nutzt nach einer Wiederverwendung den aktuellsten Token.
- Webhook-Sends aktualisieren die Zeitstempel der Channel-Aktivität.
- Zwei aktive gebundene Sessions im selben Requester-Channel führen nicht zu Duplikaten im Hauptkanal.
- Completions für gebundene Sessions werden nur an das Thread-Ziel gesendet.
- Ein deaktiviertes Spawn-Flag lässt das Legacy-Verhalten unverändert.
Vorgeschlagene Implementierungsdateien
Abschnitt betitelt „Vorgeschlagene Implementierungsdateien“Core:
src/infra/outbound/session-binding-service.ts, src/infra/outbound/bound-delivery-router.ts, src/agents/subagent-announce.ts.
Discord Adapter und Runtime:
src/discord/monitor/thread-bindings.manager.ts, src/discord/monitor/reply-delivery.ts, src/discord/send.outbound.ts.
Tests:
src/discord/monitor/provider*.test.ts, src/discord/monitor/reply-delivery.test.ts, src/agents/subagent-announce.format.test.ts.
Abschlusskriterien für Iteration 1
Abschnitt betitelt „Abschlusskriterien für Iteration 1“- Core-Interfaces existieren und sind für das Completion-Routing bereit.
- Die oben genannten Fixes sind inklusive Tests gemerged.
- Keine doppelten Zustellungen mehr in Session-Mode Runs.
- Kein verändertes Verhalten für Deployments ohne Bound Spawning.
- ACP bleibt explizit auf später verschoben.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Schau dir die Dokumentation zum Session-Management an.
- Erfahre mehr über Discord-Adapter-Konfigurationen.
OpenClaw Expert
Noch festgefahren?
Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.