Session-Tools
Ziel: kleines, schwer missbrauchbares Tool-Set, mit dem Agents Sessions auflisten, Historie abrufen und Nachrichten an andere Sessions senden koennen.
Tool-Namen
sessions_listsessions_historysessions_sendsessions_spawn
Key-Modell
- Der Haupt-Direktchat-Bucket ist immer der literale Key
"main"(wird auf den Main-Key des aktuellen Agents aufgeloest). - Gruppenchats nutzen
agent:<agentId>:<channel>:group:<id>oderagent:<agentId>:<channel>:channel:<id>(den vollstaendigen Key uebergeben). - Cron-Jobs nutzen
cron:<job.id>. - Hooks nutzen
hook:<uuid>, sofern nicht explizit gesetzt. - Node-Sessions nutzen
node-<nodeId>, sofern nicht explizit gesetzt.
global und unknown sind reservierte Werte und werden nie aufgelistet. Wenn session.scope = "global", wird es fuer alle Tools zu main aliased, damit Aufrufer nie global sehen.
sessions_list
Sessions als Array von Zeilen auflisten.
Parameter:
kinds?: string[]Filter: beliebige aus"main" | "group" | "cron" | "hook" | "node" | "other"limit?: numbermax. Zeilen (Standard: Server-Standard, z.B. 200 gedeckelt)activeMinutes?: numbernur Sessions, die innerhalb von N Minuten aktualisiert wurdenmessageLimit?: number0 = keine Nachrichten (Standard 0); >0 = letzte N Nachrichten einschliessen
Verhalten:
messageLimit > 0ruftchat.historypro Session ab und schliesst die letzten N Nachrichten ein.- Tool-Ergebnisse werden in der Listenausgabe herausgefiltert; verwende
sessions_historyfuer Tool-Nachrichten. - In einer sandboxed Agent-Session verwenden Session-Tools standardmaessig Spawned-only-Sichtbarkeit (siehe unten).
Zeilenformat (JSON):
key: Session-Key (String)kind:main | group | cron | hook | node | otherchannel:whatsapp | telegram | discord | signal | imessage | webchat | internal | unknowndisplayName(Gruppen-Anzeigelabel, falls verfuegbar)updatedAt(ms)sessionIdmodel,contextTokens,totalTokensthinkingLevel,verboseLevel,systemSent,abortedLastRunsendPolicy(Session-Override, falls gesetzt)lastChannel,lastTodeliveryContext(normalisiert{ channel, to, accountId }, wenn verfuegbar)transcriptPath(Best-Effort-Pfad, abgeleitet aus Store-Dir + sessionId)messages?(nur wennmessageLimit > 0)
sessions_history
Transkript fuer eine Session abrufen.
Parameter:
sessionKey(erforderlich; akzeptiert Session-Key odersessionIdaussessions_list)limit?: numbermax. Nachrichten (Server-seitig gedeckelt)includeTools?: boolean(Standard false)
Verhalten:
includeTools=falsefiltertrole: "toolResult"-Nachrichten heraus.- Gibt das Nachrichten-Array im Roh-Transkript-Format zurueck.
- Bei Angabe einer
sessionIdloest OpenClaw sie zum entsprechenden Session-Key auf (fehlende IDs fuehren zu einem Fehler).
sessions_send
Nachricht in eine andere Session senden.
Parameter:
sessionKey(erforderlich; akzeptiert Session-Key odersessionIdaussessions_list)message(erforderlich)timeoutSeconds?: number(Standard >0; 0 = Fire-and-Forget)
Verhalten:
timeoutSeconds = 0: einreihen und{ runId, status: "accepted" }zurueckgeben.timeoutSeconds > 0: bis zu N Sekunden auf Abschluss warten, dann{ runId, status: "ok", reply }zurueckgeben.- Bei Timeout:
{ runId, status: "timeout", error }. Der Lauf geht weiter; spaetersessions_historyaufrufen. - Bei Fehler:
{ runId, status: "error", error }. - Announce-Delivery-Laeufe finden nach dem primaeren Lauf statt und sind Best-Effort;
status: "ok"garantiert nicht, dass die Announce-Nachricht zugestellt wurde. - Warten per Gateway
agent.wait(Server-seitig), sodass Reconnects das Warten nicht unterbrechen. - Agent-zu-Agent-Nachrichtenkontext wird fuer den primaeren Lauf injiziert.
- Inter-Session-Nachrichten werden mit
message.provenance.kind = "inter_session"persistiert, damit Transkript-Leser geroutete Agent-Anweisungen von externen Nutzereingaben unterscheiden koennen. - Nach Abschluss des primaeren Laufs fuehrt OpenClaw eine Reply-Back-Schleife aus:
- Ab Runde 2 wechseln Requester- und Ziel-Agent sich ab.
- Antworte mit genau
REPLY_SKIP, um das Ping-Pong zu stoppen. - Maximale Runden:
session.agentToAgent.maxPingPongTurns(0-5, Standard 5).
- Nach Ende der Schleife fuehrt OpenClaw den Agent-zu-Agent-Announce-Schritt aus (nur Ziel-Agent):
- Antworte mit genau
ANNOUNCE_SKIP, um still zu bleiben. - Jede andere Antwort wird an den Zielkanal gesendet.
- Der Announce-Schritt enthaelt den urspruenglichen Request + Runde-1-Antwort + letzte Ping-Pong-Antwort.
- Antworte mit genau
Channel-Feld
- Fuer Gruppen ist
channelder auf dem Session-Eintrag aufgezeichnete Kanal. - Fuer Direktchats wird
channelauslastChannelabgeleitet. - Fuer Cron/Hook/Node ist
channelinternal. - Falls fehlend, ist
channelunknown.
Sicherheit / Send Policy
Richtlinienbasierte Blockierung nach Kanal/Chat-Typ (nicht pro Session-ID).
{
"session": {
"sendPolicy": {
"rules": [
{
"match": { "channel": "discord", "chatType": "group" },
"action": "deny"
}
],
"default": "allow"
}
}
}
Runtime-Override (pro Session-Eintrag):
sendPolicy: "allow" | "deny"(nicht gesetzt = Config erben)- Setzbar per
sessions.patchoder Owner-only/send on|off|inherit(eigenstaendige Nachricht).
Enforcement-Punkte:
chat.send/agent(Gateway)- Auto-Reply-Delivery-Logik
sessions_spawn
Sub-Agent-Lauf in einer isolierten Session starten und das Ergebnis im Requester-Chat-Kanal ankuendigen.
Parameter:
task(erforderlich)label?(optional; fuer Logs/UI)agentId?(optional; unter einer anderen Agent-ID spawnen, falls erlaubt)model?(optional; ueberschreibt das Sub-Agent-Modell; ungueltige Werte fuehren zu einem Fehler)thinking?(optional; ueberschreibt das Thinking-Level fuer den Sub-Agent-Lauf)runTimeoutSeconds?(Standard:agents.defaults.subagents.runTimeoutSecondsfalls gesetzt, sonst0; bricht den Sub-Agent-Lauf nach N Sekunden ab)thread?(Standard false; thread-gebundenes Routing fuer diesen Spawn anfordern, wenn vom Kanal/Plugin unterstuetzt)mode?(run|session; Standardrun, aber Standardsessionwennthread=true;mode="session"erfordertthread=true)cleanup?(delete|keep, Standardkeep)sandbox?(inherit|require, Standardinherit;requirelehnt Spawn ab, wenn die Ziel-Child-Runtime nicht sandboxed ist)attachments?(optionales Array von Inline-Dateien; nur Subagent-Runtime, ACP lehnt ab). Jeder Eintrag:{ name, content, encoding?: "utf8" | "base64", mimeType? }. Dateien werden im Child-Workspace unter.openclaw/attachments/<uuid>/materialisiert. Gibt eine Quittung mit sha256 pro Datei zurueck.attachAs?(optional;{ mountPath? }Hinweis, reserviert fuer zukuenftige Mount-Implementierungen)
Allowlist:
agents.list[].subagents.allowAgents: Liste erlaubter Agent-IDs peragentId(["*"]fuer beliebige). Standard: nur der anfragende Agent.- Sandbox-Inheritance-Guard: Wenn die Requester-Session sandboxed ist, lehnt
sessions_spawnZiele ab, die unsandboxed laufen wuerden.
Discovery:
- Nutze
agents_list, um herauszufinden, welche Agent-IDs fuersessions_spawnerlaubt sind.
Verhalten:
- Startet eine neue
agent:<agentId>:subagent:<uuid>-Session mitdeliver: false. - Sub-Agents nutzen standardmaessig das volle Tool-Set ohne Session-Tools (konfigurierbar ueber
tools.subagents.tools). - Sub-Agents duerfen
sessions_spawnnicht aufrufen (kein Sub-Agent -> Sub-Agent-Spawning). - Immer non-blocking: gibt sofort
{ status: "accepted", runId, childSessionKey }zurueck. - Mit
thread=truekoennen Kanal-Plugins Delivery/Routing an ein Thread-Ziel binden (Discord-Unterstuetzung wird uebersession.threadBindings.*undchannels.discord.threadBindings.*gesteuert). - Nach Abschluss fuehrt OpenClaw einen Sub-Agent-Announce-Schritt aus und postet das Ergebnis im Requester-Chat-Kanal.
- Wenn die finale Assistant-Antwort leer ist, wird das letzte
toolResultaus der Sub-Agent-Historie alsResulteingeschlossen.
- Wenn die finale Assistant-Antwort leer ist, wird das letzte
- Antworte mit genau
ANNOUNCE_SKIPim Announce-Schritt, um still zu bleiben. - Announce-Antworten werden auf
Status/Result/Notesnormalisiert;Statuskommt aus dem Runtime-Ergebnis (nicht aus dem Modelltext). - Sub-Agent-Sessions werden nach
agents.defaults.subagents.archiveAfterMinutesautomatisch archiviert (Standard: 60). - Announce-Antworten enthalten eine Statistik-Zeile (Laufzeit, Tokens, sessionKey/sessionId, Transkript-Pfad und optionale Kosten).
Sandbox-Session-Sichtbarkeit
Session-Tools koennen eingeschraenkt werden, um Cross-Session-Zugriff zu reduzieren.
Standardverhalten:
tools.sessions.visibilitysteht standardmaessig auftree(aktuelle Session + gespawnte Subagent-Sessions).- Fuer sandboxed Sessions kann
agents.defaults.sandbox.sessionToolsVisibilitydie Sichtbarkeit hart begrenzen.
Config:
{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
// Standard: "tree"
visibility: "tree",
},
},
agents: {
defaults: {
sandbox: {
// Standard: "spawned"
sessionToolsVisibility: "spawned", // oder "all"
},
},
},
}
Hinweise:
self: nur der aktuelle Session-Key.tree: aktuelle Session + von der aktuellen Session gespawnte Sessions.agent: jede Session der aktuellen Agent-ID.all: jede Session (Cross-Agent-Zugriff erfordert weiterhintools.agentToAgent).- Wenn eine Session sandboxed ist und
sessionToolsVisibility="spawned", begrenzt OpenClaw die Sichtbarkeit auftree, selbst wenn dutools.sessions.visibility="all"setzt.