Session Tools: Cross-Session Agent Orchestration

Learn how OpenClaw agents use session tools for cross-session status, recall, messaging, and sub-agent coordination. This page details available tools for developers building multi-session workflows.

Read this when

  • You want to understand what session tools the agent has
  • You want to configure cross-session access or sub-agent spawning
  • You want to inspect spawned sub-agent status

OpenClaw equips agents with tools that operate across sessions, check status, and coordinate sub-agents.

Available tools

ToolWhat it does
sessionsModify visible session settings and administer the global session-group catalog
sessions_listEnumerate sessions using optional criteria (kind, label, agent, archive, preview)
sessions_searchQuery visible session transcripts and retrieve matching text snippets
sessions_historyObtain the transcript for a given session
sessions_sendExecute a different session on the same Gateway, with an optional wait
conversations_listEnumerate stable external conversation identifiers
conversations_sendDeliver a message to a specific external conversation without initiating a local session
conversations_turnDeliver a message to a specific external conversation and await its correlated response
sessions_spawnCreate an isolated sub-agent session for background processing
sessions_yieldConclude the current turn and await follow-up results from sub-agents
subagentsEnumerate or cancel background tasks in this session tree
session_statusDisplay a /status-style card and optionally apply a per-session model override

These tools remain governed by the active tool profile and its allow/deny policy. tools.profile: "coding" provides the complete session orchestration toolset. tools.profile: "messaging" encompasses session self-service, discovery, recall, cross-session messaging, external-conversation tools, and the full spawn lifecycle (sessions_spawn, sessions_yield, and subagents). The UI-only task-suggestion tools spawn_task and dismiss_task stay within the coding profile.

Group, provider, sandbox, and per-agent policies can still revoke those tools after the profile stage. Use /tools from the relevant session to check the effective tool list.

Listing and reading sessions

sessions_list returns focused discovery rows containing: session key, agent, kind, channel, label/title/preview fields, parent and child relationships, last update, archive/pin state, state version, model, context/total token counts, run status, and whether the last run aborted. Filter by kinds (array; accepted values: main, group, cron, hook, node, other), exact label, exact agentId, search text, or recency (activeMinutes). Active sessions appear by default; supply archived: true to inspect archived sessions. Set includeDerivedTitles, includeLastMessage, or messageLimit (maximum 20) when mailbox-style triage is needed: a visibility-scoped derived title, a last-message preview snippet, or a bounded number of recent messages per row. Delivery routing, internal session IDs, per-run timings/settings, cost estimates, and transcript paths are intentionally omitted; use session_status, conversation tools, and sessions_history for those owner-specific details. Derived titles and previews are generated only for sessions the caller can already see under the configured session tool visibility policy, so unrelated sessions remain hidden. When visibility is restricted, sessions_list returns optional visibility metadata indicating the effective mode and a warning that results may be scope-limited.

sessions_history retrieves the conversation transcript for a particular session. Tool results are excluded by default; pass includeTools: true to include them. Use limit for the most recent bounded tail. Supply offset: 0 when pagination metadata is required, then use the returned nextOffset values to page backward through older OpenClaw transcript windows without reading raw transcript files. Explicit offset pages do not incorporate external CLI fallback imports; use the default newest-tail view (without offset) when that merged display history is needed.

The returned view is deliberately bounded and safety-filtered:

  • Before recall, assistant text undergoes normalization:
    • Thinking tags get removed.
    • <relevant-memories> and <relevant_memories> scaffolding blocks are taken out.
    • Plain-text XML tool-call payload blocks like <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, and <function_calls>...</function_calls> are removed, including truncated payloads that never properly close.
    • Downgraded tool-call or result scaffolding such as [Tool Call: ...], [Tool Result ...], and [Historical context ...] is stripped.
    • Leaked model control tokens like <|assistant|>, other ASCII <|...|> tokens, and full-width <|...|> variants are eliminated.
    • Malformed MiniMax tool-call XML, for instance <invoke ...> or </minimax:tool_call>, is removed.
  • Credential or token-like text gets redacted before being returned.
  • Long text blocks are cut short.
  • Very large histories may drop older rows or replace an oversized row with [sessions_history omitted: message too large].
  • The tool reports summary flags such as truncated, droppedMessages, contentTruncated, contentRedacted, bytes, along with pagination metadata.

Work with the returned session key (for example "main") alongside sessions_history, sessions_send, and session_status. Those target tools can also look up a known session ID, but sessions_list does not expose internal IDs.

If you need the raw, exact transcript, examine the scoped SQLite transcript rows rather than treating sessions_history as an unfiltered dump.

Use sessions_search for precise full-text recall across visible user and assistant transcript text. Its results include a sessionKey for a follow-up sessions_history call; visibility filtering, snippet redaction, and output bounds match the history boundary.

Managing session settings and groups

The owner-gated sessions tool provides two bounded self-service surfaces:

  • action: "patch" modifies the current session by default, or another visible session selected via sessionKey. It can adjust the label, sidebar icon, pin or archive state, model, and thinking level. It does not expose reset, delete, or compact actions.
  • group_list, group_set, group_rename, and group_delete handle the global ordered session-group catalog. group_set replaces the ordered name list rather than patching a single entry.

An agent-selected model patch stays reversible until that selection finishes a successful run. If the selected model is definitively unusable due to authentication, billing, or model-not-found failure, OpenClaw restores the previous model and writes a visible system note. Transient rate-limit, overload, timeout, network, and server failures do not undo the selection.

Sessions versus conversations

A session represents local model context. A conversation is a precise external address, such as one peer, channel, or thread. The two are linked but not interchangeable: direct messages can share a single main session while keeping separate conversation addresses.

conversations_list returns opaque conversationRef values for the active agent. With an explicit channel, the Gateway also refreshes addresses from that channel's local directory, such as approved Reef peers; use query to locate a specific peer beyond the current result page. Discovery catalogs the address without creating a model-context session; the backing session is created only when delivery or inbound context requires it. Conversation discovery and delivery are owner-only because they use the Gateway's channel credentials. Use conversations_send for fire-and-forget delivery. Use conversations_turn when the remote reply belongs to the current model turn: the Gateway reserves one transport message ID, persists a delivery operation and queue intent before transport I/O, and returns the correlated reply from the tool instead of starting a second local agent turn. Delivery operations exist outside model transcripts; a captured reply is retained only as a side artifact while the tool result owns model context. If the Gateway restarts after queueing, delivery can recover but a later reply follows ordinary inbound dispatch because the process-local waiter is gone. Unsolicited inbound messages always continue through the normal channel dispatch path.

Use the shared message tool when you already have an explicit raw channel target or need a channel-specific action. Conversation references are scoped to the active agent and should be obtained through conversations_list, not constructed from session keys.

In Code Mode, the conversation tools reuse their exact Gateway output contracts. A single exec cell can list addresses, select a returned conversationRef, and call conversations_send or conversations_turn; normal tool policy and approvals still apply to the nested calls.

Sending cross-session messages

sessions_send runs another session on the same Gateway and optionally waits for the response. Its sessionKey, label, or agentId selects local model context, not an external destination. The resulting reply can still be announced through the established requester or target delivery context; that existing behavior is unchanged. For exact external delivery, use a conversation tool or message with an explicit channel and target.

  • Fire-and-forget: set timeoutSeconds: 0 to enqueue and return immediately.
  • Wait for reply: set a timeout and get the response inline.

Thread-scoped chat sessions (for example, keys ending in :thread:<id>) cannot serve as valid sessions_send targets. Instead, use the parent channel session key when coordinating between agents, so tool-routed messages stay out of an active human-facing conversation.

Messages and A2A follow-up replies are recorded as inter-session data within the receiving prompt ([Inter-session message ... isUser=false]) and in transcript provenance. The receiving agent should handle them as tool-routed information rather than as a direct instruction authored by an end user.

After the target responds, OpenClaw can initiate a reply-back loop where the agents exchange messages until the built-in limit is reached. The target agent can reply with REPLY_SKIP to exit early.

Pass watch: true to also register the sender as a state-change watcher for the target: when another actor later sends the target a direct human message or modifies its goal, the sender gets a system notice pointing to session_status changesSince. Registration occurs after successful dispatch, targets the session that actually received the message, and begins at its current state version, so only subsequent changes generate notices. The result reports watched: true when registration is successful. See Session state awareness.

Status and orchestration helpers

session_status is the lightweight equivalent of /status for the current or another visible session. It reports usage, time, model/runtime state, and linked background-task context when present. Like /status, it can backfill sparse token and cache counters from the latest transcript usage entry, and model=default clears a per-session override. Use sessionKey="current" for the caller's own session; visible client labels such as openclaw-tui are not session keys.

When route metadata is available, session_status also includes a visible Route context JSON block and matching structured details fields. These fields distinguish the session key from the route currently handling the live run:

  • origin indicates where the session was created, or the provider inferred it from a deliverable session-key prefix when older state lacks stored origin metadata.
  • active is the current live-run route. It is reported only for the live or current session being handled right now.
  • deliveryContext is the persisted delivery route stored on the session, which OpenClaw can reuse for later delivery even when the active surface differs.

Session state changes

OpenClaw maintains a durable signal log of material session state changes (direct human messages to watched sessions, child-run outcomes, goal changes, compaction). sessions_list rows and session_status expose the session's stateVersion, and session_status accepts changesSince: <version> to return the typed events after that version, with exact historyGap signaling when the requested version predates retained history. Watchers (spawn parents automatically, sessions_send watch: true explicitly) receive one coalesced stale-state notice when another actor changes a watched session.

State-change events omit repeated session and agent IDs and expose only model-useful payload fields (outcome, channel, or turns). The event summary and actor or run identifiers remain available for reconciliation.

See Session state awareness for the complete model: event kinds, watcher registration, the anti-spam notice protocol, reconciliation flow, and current limits.

sessions_yield deliberately ends the current turn so the next message can be the follow-up event you are waiting for. Use it after spawning sub-agents when you want completion results to arrive as the next message instead of building poll loops.

subagents is the session-tree view over native sub-agent runs and the shared background-task ledger. action: "list" reports active and recent sub-agents plus scoped ACP, CLI/media, and cron tasks. action: "cancel" accepts a returned taskId and can stop only work inside the caller's controlled session tree; leaf sub-agents cannot cancel another session's task.

Spawning sub-agents

sessions_spawn creates an isolated session for a background task by default. It is always non-blocking and returns immediately with a runId and childSessionKey. Native sub-agent runs receive the delegated task in the child session's first visible [Subagent Task] message, while the system prompt carries only sub-agent runtime rules and routing context.

Key options:

  • runtime: "subagent" (default) or "acp" for external harness agents.
  • model and thinking overrides for the child session.
  • thread: true to bind the spawn to a chat thread (Discord, Slack, etc.).
  • sandbox: "require" to enforce sandboxing on the child.
  • context: "fork" for native sub-agents when the child needs the current requester transcript; omit it or use context: "isolated" for a clean child. context: "fork" is only valid with runtime: "subagent". Thread-bound native sub-agents default to context: "fork" unless threadBindings.defaultSpawnContext says otherwise.
  • visible: true to create a persistent dashboard session instead of a hidden sub-agent session. Visible spawns support an explicit model, working directory, same-agent transcript fork, and an optional managed worktree; see Sub-agents for the exact compatibility limits.

Default leaf sub-agents are not given session tools. With maxSpawnDepth >= 2, depth-1 orchestrator sub-agents also get sessions_spawn, subagents, sessions_list, and sessions_history to handle their own children. Leaf runs still lack recursive orchestration tools.

Once a task finishes, an announce step sends the result to the requester's channel. Completion delivery respects existing bound thread or topic routing when present. If the completion source only specifies a channel, OpenClaw can still apply the requester session's stored route (lastChannel / lastTo) for direct delivery.

ACP-specific behavior is covered in ACP Agents.

Visibility

Session tools are constrained to control what an agent can observe:

LevelScope
selfOnly the current session
treeCurrent plus spawned; reads include watched same-agent groups
agentAll sessions for this agent
allAll sessions (cross-agent if configured)

The default is tree. Sandboxed sessions are limited to tree regardless of configuration. With the default session.dmScope: "main", group activity makes watched same-agent group sessions readable from the main session.

Further reading