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

ToolWhat it does
sessionsModify, clear, remove, or reassign visible sessions and handle session group management
sessions_listEnumerate sessions, applying optional filters for kind, label, agent, archive, or preview
sessions_searchLook through visible session transcripts and pull matching text fragments
sessions_historyRetrieve the full transcript belonging to one particular session
sessions_sendExecute another session on the same Gateway, with an optional wait
conversations_listEnumerate stable external conversation identifiers
conversations_sendDeliver a message to a single specific external conversation, bypassing local session execution
conversations_turnDeliver a message to one specific external conversation and block for its correlated response
sessions_spawnLaunch a detached sub-agent session for background processing
sessions_yieldConclude the active turn and await results from follow-up sub-agents
subagentsEnumerate or terminate background jobs inside this session tree
session_statusRender 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 through sessionKey. It can adjust the label, persistent sidebar icon, sidebar category, pin/archive state, model, and thinking level. To clear category, pass null or 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 icons braces, book, monitor, bot, kanban, and coins; 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 its sessions_list sessionId as expectedSessionId.
  • action: "reset" resets another visible session chosen via sessionKey.
  • action: "delete" first archives, then deletes the identical generation of another visible session selected by sessionKey. By default, its transcript stays as a deleted archive; pass deleteTranscript: false to 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. Provide ownerType ("human" or "agent") and ownerId; the target defaults to the current session, or another visible one through sessionKey. 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, and group_delete handle the global ordered session-group catalog. group_set swaps the ordered name list rather than assigning a session; use action: "patch" with category for 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: 0 to 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:

  • origin marks where the session originated, or the provider deduced from a deliverable session-key prefix when older state lacks stored origin metadata.
  • active identifies the current live-run route. It appears only for the live or current session being handled at this moment.
  • deliveryContext holds 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.
  • model and thinking serve as overrides for the child session.
  • runTimeoutSeconds overrides the configured child-run timeout; setting 0 turns it off.
  • thread: true ties 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 use context: "isolated" to start a fresh child. context: "fork" works only alongside runtime: "subagent". Native sub-agents bound to a thread default to context: "fork" unless threadBindings.defaultSpawnContext specifies otherwise.
  • visible: true creates a persistent dashboard session rather than a hidden sub-agent one. Visible spawns allow an explicit sidebar category, 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 UI sessionUrl (excluded when the Control UI is off), and an owner entry that names the requesting agent. When acknowledging the spawn in a channel, place the session URL on the first line and Owner: <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:

LevelScope
selfOnly the current session
treeCurrent plus spawned; from main, all same-agent sessions
agentEvery session for this agent
allAll 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

2,739 words · updated Aug 24, 2026