Session Tools

Ziel: Ein kleines, einfach zu nutzendes Tool-Set, mit dem Agents Sessions auflisten, den Verlauf abrufen und Nachrichten an andere Sessions senden können.

Tool-Namen

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

Key-Modell

  • Der Haupt-Direktchat-Bucket ist immer der Schlüssel "main" (wird zum Main-Key des aktuellen Agents aufgelöst).
  • Gruppenchats nutzen agent:<agentId>:<channel>:group:<id> oder agent:<agentId>:<channel>:channel:<id> (den vollständigen Key übergeben).
  • Cron-Jobs nutzen cron:<job.id>.
  • Hooks nutzen hook:<uuid>, sofern nicht explizit anders gesetzt.
  • Node-Sessions nutzen node-<nodeId>, sofern nicht explizit anders gesetzt.

global und unknown sind reservierte Werte und werden nie aufgelistet. Wenn session.scope = "global", wird es für alle Tools zu main aliasiert, sodass Aufrufer nie global sehen.

sessions_list

Listet Sessions als Array von Zeilen auf.

Parameter:

  • kinds?: string[] Filter: beliebige Kombination aus "main" | "group" | "cron" | "hook" | "node" | "other"
  • limit?: number maximale Zeilen (Standard: Server-Default, z.B. max. 200)
  • activeMinutes?: number nur Sessions, die innerhalb der letzten N Minuten aktualisiert wurden
  • messageLimit?: number 0 = keine Nachrichten (Standard 0); >0 = die letzten N Nachrichten einschließen

Verhalten:

  • messageLimit > 0 ruft chat.history pro Session ab und schließt die letzten N Nachrichten ein.
  • Tool-Ergebnisse werden in der Listenausgabe herausgefiltert; nutze sessions_history für Tool-Nachrichten.
  • In einer Sandbox-Agent-Session haben Session Tools standardmäßig nur Sichtbarkeit auf gespawnte Sessions (siehe unten).

Zeilenformat (JSON):

  • key: Session-Key (String)
  • kind: main | group | cron | hook | node | other
  • channel: whatsapp | telegram | discord | signal | imessage | webchat | internal | unknown
  • displayName (Gruppen-Anzeigename, falls verfügbar)
  • updatedAt (ms)
  • sessionId
  • model, contextTokens, totalTokens
  • thinkingLevel, verboseLevel, systemSent, abortedLastRun
  • sendPolicy (Session-Override, falls gesetzt)
  • lastChannel, lastTo
  • deliveryContext (normalisiert { channel, to, accountId }, wenn verfügbar)
  • transcriptPath (Best-Effort-Pfad aus Store-Verzeichnis + sessionId)
  • messages? (nur wenn messageLimit > 0)

sessions_history

Ruft das Transkript einer Session ab.

Parameter:

  • sessionKey (erforderlich; akzeptiert Session-Key oder sessionId aus sessions_list)
  • limit?: number maximale Nachrichten (Server begrenzt)
  • includeTools?: boolean (Standard false)

Verhalten:

  • includeTools=false filtert role: "toolResult" Nachrichten heraus.
  • Gibt das Nachrichten-Array im Roh-Transkript-Format zurück.
  • Bei Angabe einer sessionId löst OpenClaw diese zum entsprechenden Session-Key auf (fehlende IDs führen zu Fehlern).

sessions_send

Sendet eine Nachricht an eine andere Session.

Parameter:

  • sessionKey (erforderlich; akzeptiert Session-Key oder sessionId aus sessions_list)
  • message (erforderlich)
  • timeoutSeconds?: number (Standard >0; 0 = Fire-and-Forget)

Verhalten:

  • timeoutSeconds = 0: In Warteschlange einreihen und { runId, status: "accepted" } zurückgeben.
  • timeoutSeconds > 0: Bis zu N Sekunden auf Abschluss warten, dann { runId, status: "ok", reply } zurückgeben.
  • Bei Timeout: { runId, status: "timeout", error }. Der Run läuft weiter; rufe später sessions_history auf.
  • Bei Fehler: { runId, status: "error", error }.
  • Announce-Delivery läuft nach Abschluss des primären Runs und ist Best-Effort; status: "ok" garantiert nicht, dass das Announce zugestellt wurde.
  • Wartet über Gateway agent.wait (serverseitig), sodass Reconnects das Warten nicht abbrechen.
  • Agent-zu-Agent-Nachrichtenkontext wird für den primären Run injiziert.
  • Nach Abschluss des primären Runs führt OpenClaw eine Reply-Back-Schleife aus:
    • Runde 2+ wechselt zwischen Anfrage- und Ziel-Agent ab.
    • Antworte genau mit REPLY_SKIP, um das Ping-Pong zu stoppen.
    • Maximale Runden: session.agentToAgent.maxPingPongTurns (0–5, Standard 5).
  • Nach Ende der Schleife führt OpenClaw den Agent-zu-Agent Announce-Schritt aus (nur Ziel-Agent):
    • Antworte genau mit ANNOUNCE_SKIP, um still zu bleiben.
    • Jede andere Antwort wird an den Ziel-Channel gesendet.
    • Der Announce-Schritt enthält die ursprüngliche Anfrage + Runde-1-Antwort + letzte Ping-Pong-Antwort.

Channel-Feld

  • Bei Gruppen ist channel der auf dem Session-Eintrag gespeicherte Channel.
  • Bei Direktchats wird channel aus lastChannel gemappt.
  • Bei Cron/Hook/Node ist channel internal.
  • Falls nicht vorhanden, ist channel unknown.

Sicherheit / Send Policy

Richtlinienbasierte Blockierung nach Channel/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 über sessions.patch oder Owner-only /send on|off|inherit (als eigenständige Nachricht).

Durchsetzungspunkte:

  • chat.send / agent (Gateway)
  • Auto-Reply-Delivery-Logik

sessions_spawn

Startet einen Sub-Agent-Run in einer isolierten Session und meldet das Ergebnis zurück an den Chat-Channel des Anfragers.

Parameter:

  • task (erforderlich)
  • label? (optional; für Logs/UI)
  • agentId? (optional; unter einer anderen Agent-ID spawnen, falls erlaubt)
  • model? (optional; überschreibt das Sub-Agent-Modell; ungültige Werte führen zu Fehlern)
  • runTimeoutSeconds? (Standard 0; wenn gesetzt, bricht den Sub-Agent-Run nach N Sekunden ab)
  • cleanup? (delete|keep, Standard keep)

Allowlist:

  • agents.list[].subagents.allowAgents: Liste der Agent-IDs, die über agentId erlaubt sind (["*"] für alle). Standard: nur der anfragende Agent.

Discovery:

  • Nutze agents_list, um herauszufinden, welche Agent-IDs für sessions_spawn erlaubt sind.

Verhalten:

  • Startet eine neue agent:<agentId>:subagent:<uuid> Session mit deliver: false.
  • Sub-Agents haben standardmäßig das vollständige Tool-Set ohne Session Tools (konfigurierbar über tools.subagents.tools).
  • Sub-Agents dürfen sessions_spawn nicht aufrufen (kein Sub-Agent zu Sub-Agent Spawning).
  • Immer non-blocking: Gibt sofort { status: "accepted", runId, childSessionKey } zurück.
  • Nach Abschluss führt OpenClaw einen Sub-Agent Announce-Schritt aus und postet das Ergebnis in den Chat-Channel des Anfragers.
  • Antworte genau mit ANNOUNCE_SKIP während des Announce-Schritts, um still zu bleiben.
  • Announce-Antworten werden zu Status/Result/Notes normalisiert; Status kommt vom Runtime-Ergebnis (nicht vom Model-Text).
  • Sub-Agent-Sessions werden nach agents.defaults.subagents.archiveAfterMinutes automatisch archiviert (Standard: 60).
  • Announce-Antworten enthalten eine Stats-Zeile (Laufzeit, Tokens, sessionKey/sessionId, Transkript-Pfad und optionale Kosten).

Sandbox Session-Sichtbarkeit

Sandbox-Sessions können Session Tools nutzen, sehen aber standardmäßig nur Sessions, die sie über sessions_spawn gestartet haben.

Config:

{
  agents: {
    defaults: {
      sandbox: {
        // Standard: "spawned"
        sessionToolsVisibility: "spawned", // oder "all"
      },
    },
  },
}