Session Tools for Cross-Session Operation and Coordination
Learn about OpenClaw's agent tools for cross-session status, recall, messaging, and sub-agent orchestration. This page is 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 capabilities for cross-session operation, status checking, and sub-agent coordination.
Available tools
| Tool | What it does |
|---|---|
sessions | Modify, clear, remove, or reassign visible sessions and handle session group management |
sessions_list | Enumerate sessions, applying optional filters for kind, label, agent, archive, or preview |
sessions_search | Look through visible session transcripts and pull matching text fragments |
sessions_history | Retrieve the full transcript belonging to one particular session |
sessions_send | Execute another session on the same Gateway, with an optional wait |
conversations_list | Enumerate stable external conversation identifiers |
conversations_send | Deliver a message to a single specific external conversation, bypassing local session execution |
conversations_turn | Deliver a message to one specific external conversation and block for its correlated response |
sessions_spawn | Launch a detached sub-agent session for background processing |
sessions_yield | Conclude the active turn and await results from follow-up sub-agents |
subagents | Enumerate or terminate background jobs inside this session tree |
session_status | Render a /status-style card, optionally applying a model override for the session |
The active tool profile and allow/deny policy continue to govern these tools. The full session orchestration suite is part of tools.profile: "coding". Session self-service, discovery, recall, inter-session messaging, external-conversation tools, and the entire spawn lifecycle (sessions_spawn, sessions_yield, and subagents) all fall under tools.profile: "messaging". The UI-only task-suggestion tools, suggest_task and dismiss_task, remain part of the coding profile.
Group, provider, sandbox, and per-agent policies can still strip these tools after the profile stage. To see the effective tool list, run /tools from the session in question.
Listing and reading sessions
sessions_list yields compact discovery rows containing the session key, durable session ID, agent, kind, channel, label/title/preview fields, sidebar category, parent and child links, last update time, archive/pin state, state version, model, context and total token counts, run status, and whether the last run aborted. Filtering works via kinds (an array accepting main, group, cron, hook, node, other), an exact label, an exact agentId, search text, or recency through activeMinutes. Active sessions show up by default; to inspect archived ones, pass archived: true. For mailbox-style triage, set includeDerivedTitles, includeLastMessage, or messageLimit (capped at 20), which yields a visibility-scoped derived title, a last-message preview snippet, or bounded recent messages per row. When the sessions tool archives, restores, or deletes another session, use the returned sessionId as expectedSessionId so a stale key cannot target a replacement. Owner-specific details such as delivery routing, other internal IDs, per-run timings and settings, cost estimates, and transcript paths are not included; rely on session_status, conversation tools, and sessions_history for those. Derived titles and previews are generated only for sessions already visible to the caller under the configured session tool visibility policy, keeping unrelated sessions out of sight. With restricted visibility, sessions_list returns optional visibility metadata that reports the effective mode and warns that results may be scope-limited.
sessions_history retrieves the conversation transcript for a given session. Tool results are omitted by default; pass includeTools: true to include them. The newest bounded tail is available via limit. For pagination metadata, pass offset: 0, then feed returned nextOffset values back to page backward through older OpenClaw transcript windows without touching raw transcript files. Explicit offset pages do not incorporate external CLI fallback imports; for that merged display history, use the default newest-tail view without offset.
The returned view is deliberately bounded and safety-filtered:
- Prior to recall, assistant text gets normalized: thinking tags are removed,
<relevant-memories>/<relevant_memories>scaffolding blocks are taken out, plain-text tool-call XML 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 close cleanly), downgraded tool-call/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, and malformed MiniMax tool-call XML such as<invoke ...>/</minimax:tool_call>is removed. - Before anything is returned, credential/token-like text gets redacted.
- Long text blocks are cut short.
- For very large histories, older rows may be dropped, or an oversized row gets replaced with
[sessions_history omitted: message too large]. - The tool reports summary flags such as
truncated,droppedMessages,contentTruncated,contentRedacted,bytes, along with pagination metadata.
Pair the returned session key (like "main") with sessions_history, sessions_send, and session_status. The durable sessionId should only serve as the lifecycle identity described earlier.
When the exact raw transcript is needed, check the scoped SQLite transcript rows rather than relying on sessions_history as an unfiltered dump.
For exact full-text recall across visible user and assistant transcript text, use sessions_search. Its results carry a sessionKey for a follow-up sessions_history call; visibility filtering, snippet redaction, and output bounds all follow the history boundary.
Managing session settings and groups
The owner-gated sessions tool provides bounded self-service surfaces:
action: "patch"alters the active session by default, or another visible one chosen throughsessionKey. It can adjust the label, persistent sidebaricon, sidebarcategory, pin/archive state, model, and thinking level. To clearcategory, passnullor an empty string; assigning a category registers it in the catalog upon first use. The icon must be a single emoji grapheme or one of the named iconsbraces,book,monitor,bot,kanban, andcoins; an empty string clears it. The Control UI picker also supports a custom emoji and displays the macOS (Control-Command-Space) or Windows (Windows-period) system emoji picker shortcut. Archiving or restoring another session needs itssessions_listsessionIdasexpectedSessionId.action: "reset"resets another visible session chosen viasessionKey.action: "delete"first archives, then deletes the identical generation of another visible session selected bysessionKey. By default, its transcript stays as a deleted archive; passdeleteTranscript: falseto leave the transcript state unchanged. Resetting or deleting the session currently running the tool is refused.action: "assign_owner"transfers session ownership to a person or agent. ProvideownerType("human"or"agent") andownerId; the target defaults to the current session, or another visible one throughsessionKey. Agent owner ids must reference a configured agent. The assignment logs who reassigned it and when, and the Control UI updates the new owner right away. Ownership is about display and responsibility, not access control; refer to Multi-user mode.group_list,group_set,group_rename, andgroup_deletehandle the global ordered session-group catalog.group_setswaps the ordered name list rather than assigning a session; useaction: "patch"withcategoryfor membership.
Employ sessions_spawn with visible: true to establish a persistent dashboard session. Pass category to place it in a sidebar group atomically; omit category or pass an empty string to keep it ungrouped. This ensures session creation follows the controlled spawn path, which enforces the parent's tool policy, sandbox, concurrency limits, and run timeout.
An agent-selected model patch stays reversible until that selection finishes a successful run. If the selected model is clearly unusable due to authentication, billing, or model-not-found failure, OpenClaw reverts to the previous model and posts a visible system note. Transient rate-limit, overload, timeout, network, and server failures do not reverse the selection.
Sessions versus conversations
A session is local model context. A conversation is an exact external address such as one peer, channel, or thread. They are connected but not interchangeable: direct messages can share one 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 rely on 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 launching a second local agent turn. Delivery operations exist outside model transcripts; a captured reply is kept 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 proceed 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 built 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: 0to enqueue and return immediately. - Wait for reply: set a timeout and get the response inline.
A waited send that finishes without visible assistant text returns status: "no_reply". That is a terminal, intentional non-outcome: no announcement remains pending. Continue without waiting, or send a new message if a response is required.
Thread-scoped chat sessions, for instance keys that terminate in :thread:<id>, do not qualify as valid sessions_send targets. For coordination between agents, rely on the parent channel session key so that tool-routed messages stay out of an active human-facing thread.
In the receiving prompt ([Inter-session message ... isUser=false]) and within transcript provenance, messages and A2A follow-up replies get flagged as inter-session data. The receiving agent ought to interpret them as tool-routed information rather than a direct instruction authored by an end user.
Once the target responds, OpenClaw may engage a reply-back loop, letting the agents exchange messages until the built-in limit is reached. To end early, the target agent can send REPLY_SKIP.
Passing watch: true also registers the sender as a state-change watcher for the target: if another actor later delivers a direct human message to the target or modifies its goal, the sender gets a system notice that points to session_status changesSince. Registration occurs only after a successful dispatch, applies to the session that actually received the message, and begins at its current state version, so notices arise solely from subsequent changes. The result indicates watched: true when registration succeeded. Refer to Session state awareness.
Status and orchestration helpers
session_status serves as the lightweight counterpart to /status for either the current session or another visible one. It surfaces usage, timing, model/runtime state, and linked background-task context when such context exists. Much like /status, it can fill in sparse token/cache counters from the most recent transcript usage entry, and model=default removes a per-session override. For the caller's own session, use sessionKey="current"; visible client labels such as openclaw-tui are not session keys.
When route metadata is present, session_status additionally includes a visible Route context JSON block and corresponding structured details fields. These fields clarify the distinction between the session key and the route currently handling the live run:
originmarks where the session originated, or the provider deduced from a deliverable session-key prefix when older state lacks stored origin metadata.activeidentifies the current live-run route. It appears only for the live or current session being handled at this moment.deliveryContextholds 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 substantive session state changes (direct human messages to watched sessions, child-run outcomes, goal alterations, compaction). Rows from sessions_list and session_status reveal the session's stateVersion, and session_status takes changesSince: <version> to return the typed events following that version, with exact historyGap signaling when the requested version predates retained history. Watchers, including spawn parents automatically and sessions_send watch: true explicitly, receive one coalesced stale-state notice whenever another actor modifies a watched session.
State-change events omit repeated session/agent IDs and expose only payload fields useful to the model (outcome, channel, or turns). The event summary and actor/run identifiers stay available for reconciliation.
For the complete model, see Session state awareness: event kinds, watcher registration, the anti-spam notice protocol, reconciliation flow, and current limits.
sessions_yield deliberately terminates the current turn so the next message can be the follow-up event you are awaiting. After spawning sub-agents, use it when you want completion results to arrive as the next message rather than constructing poll loops.
subagents provides the session-tree view over native sub-agent runs and the shared background-task ledger. action: "list" reports active or recent sub-agents plus scoped ACP, CLI/media, and cron tasks. action: "cancel" accepts a returned taskId and can halt only work within the caller's controlled session tree; leaf sub-agents cannot cancel another session's task.
Spawning sub-agents
By default, sessions_spawn creates an isolated session for a background task. It never blocks; it 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"(the default) or"acp"when the harness agent is external.modelandthinkingserve as overrides for the child session.runTimeoutSecondsoverrides the configured child-run timeout; setting0turns it off.thread: trueties the spawn to a chat thread, such as Discord or Slack.sandbox: "require"forces sandboxing on the child.context: "fork"is meant for native sub-agents that need the current requester transcript; leave it out or usecontext: "isolated"to start a fresh child.context: "fork"works only alongsideruntime: "subagent". Native sub-agents bound to a thread default tocontext: "fork"unlessthreadBindings.defaultSpawnContextspecifies otherwise.visible: truecreates a persistent dashboard session rather than a hidden sub-agent one. Visible spawns allow an explicit sidebarcategory, a model, a working directory, a same-agent transcript fork, and an optional managed worktree; refer to Sub-agents for the exact compatibility constraints. The accepted result is a receipt containing the child session key, run id, a Control UIsessionUrl(excluded when the Control UI is off), and anownerentry that names the requesting agent. When acknowledging the spawn in a channel, place the session URL on the first line andOwner: <label>on the second. The sidebar credits the requesting agent with the spawned session; see Multi-user mode.
Default leaf sub-agents lack 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 do not receive recursive orchestration tools.
Once finished, an announce step posts the outcome to the requester's channel. Completion delivery keeps bound thread or topic routing when present, and if the completion origin only points to a channel, OpenClaw can still use the requester session's stored route (lastChannel / lastTo) for direct delivery.
For ACP-specific details, see ACP Agents.
Visibility
Session tools are restricted to control what the agent can observe:
| Level | Scope |
|---|---|
self | Only the current session |
tree | Current plus spawned; from main, all same-agent sessions |
agent | Every session for this agent |
all | All sessions (cross-agent if configured) |
The default is tree. The main-session widening affects list, history, search, send, and status, but never crosses agents. self stays a strict lockdown, even for main. A sandboxed caller under the default spawned-only session tool clamp remains confined to its spawn subtree. Incognito sessions stay hidden from every cross-session tool. Ambient group watches still add activity notices and prompt hints; they do not grant access.
Further reading
- Session Management: routing, lifecycle, maintenance
- Sub-agents: child-session lifecycle and delivery
- ACP Agents: external harness spawning
- Multi-agent: multi-agent architecture
- Gateway Configuration: session tool config knobs