Thread-bound sessions
When thread bindings are enabled for a channel, a sub-agent can stay bound to a thread so follow-up user messages in that thread keep routing to the same sub-agent session.Thread supporting channels
A channel supports persistent thread-bound subagent sessions (sessions_spawn with thread: true) when it registers a conversation
binding adapter. Bundled channels with that support: Discord,
iMessage, Matrix, and Telegram. Discord and Matrix default to
creating a child thread; Telegram and iMessage default to binding the
current conversation. Use the per-channel threadBindings config keys for
enablement, timeouts, and spawnSessions.
Quick flow
1
Spawn
sessions_spawn with thread: true (and optionally mode: "session").2
Bind
OpenClaw creates or binds a thread to that session target in the active channel.
3
Route follow-ups
Replies and follow-up messages in that thread route to the bound session.
4
Inspect timeouts
Use
/session idle to inspect/update inactivity expiry and
/session max-age to control the hard cap.5
Detach
Use
/session unbind to detach without closing the agent session.Manual controls
Config switches
- Global default:
session.threadBindings.enabled,session.threadBindings.idleHours,session.threadBindings.maxAgeHours. - Channel override and spawn auto-bind keys are adapter-specific. See Thread supporting channels above.
Allowlist
string[]
List of configured agent ids that can be targeted via explicit
agentId (["*"] allows any configured target). Default: only the requester agent. If you set a list and still want the requester to spawn itself with agentId, include the requester id in the list.string[]
Default configured target-agent allowlist used when the requester agent does not set its own
subagents.allowAgents.boolean
default:"false"
Block
sessions_spawn calls that omit agentId (forces explicit profile selection). Per-agent override: agents.entries.*.subagents.requireAgentId.number
default:"120000"
Timeout for gateway
agent announcement handoff attempts. Once a handoff is accepted, waiting for the parent session’s turn does not consume this budget. After execution starts, the requester’s normal runtime timeout and cancellation controls apply; the announcement timer does not restart. Values are positive integer milliseconds and are clamped to the platform-safe timer maximum. Queue waits, requester execution, and transient retries can make total delivery time longer than one configured timeout.sessions_spawn rejects targets
that would run unsandboxed.
Discovery
Useagents_list to see which agent ids are currently allowed for
sessions_spawn. The response includes each listed agent’s effective
model and embedded runtime metadata so callers can distinguish OpenClaw, Codex
app-server, and other configured native runtimes.
allowAgents entries must point at configured agent ids in agents.entries.*.
["*"] means any configured target agent plus the requester. If an agent config
is deleted but its id remains in allowAgents, sessions_spawn rejects that id
and agents_list omits it. Run openclaw doctor --fix to clean stale
allowlist entries, or add a minimal agents.entries.* entry when the target should
remain spawnable while inheriting defaults.
Auto-archive
- Sub-agent sessions are automatically archived after
agents.defaults.subagents.archiveAfterMinutes(default60). - Archive uses
sessions.deleteand renames the transcript to*.deleted.<timestamp>(same folder). cleanup: "delete"archives immediately after announce (still keeps the transcript via rename).- Auto-archive is best-effort; pending timers are lost if the gateway restarts.
- Configured run timeouts do not auto-archive; they only stop the run. The session remains until auto-archive.
- Auto-archive applies equally at every sub-agent depth.
- Browser cleanup is separate from archive cleanup: tracked browser tabs/processes are best-effort closed when the run finishes, even if the transcript/session record is kept.
subagent_ended plugin hook is best-effort. Hook execution or plugin runtime
loading failures are logged and do not abort sub-agent cleanup.