# Thread-bound sub-agent sessions

> Bind a sub-agent to a channel thread, and the allowlist, discovery, and auto-archive rules

- 网址：https://funcoding.ai/agents/openclaw/tools/subagents/thread-bound-sessions/
- 来源：OpenClaw 官方文档原文（英文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/tools/subagents/thread-bound-sessions

---
## Thread-bound sessions

When thread bindings are enabled for a channel, a spawned sub-agent can get
its own new thread. Follow-up user messages in that thread keep routing to the
same sub-agent session, while the conversation you spawned it from stays with
your agent.

### Thread supporting channels

`sessions_spawn` with `thread: true` always opens a new child thread; it never
hands the current conversation to the worker. Bundled channels that can open
one: **Discord** and **Matrix**. On channels that would bind the current
conversation instead (for example Telegram, iMessage, Feishu, and LINE),
`thread: true` is rejected; spawn with `mode: "run"` and the result is
announced back to the conversation. Use the per-channel `threadBindings` config
keys for enablement, timeouts, and `spawnSessions`.

Worker bindings created by older versions on the current conversation are
ignored: messages there route to your agent again, and the stale binding
expires through its normal idle timeout. To hand a conversation to an ACP
session deliberately, use `/acp spawn --bind here`.

### Quick flow

**Spawn**

`sessions_spawn` with `thread: true` (and optionally `mode: "session"`).

**Bind**

OpenClaw opens a new child thread in the active channel and binds it to that session.

**Route follow-ups**

Replies and follow-up messages in that thread route to the bound session.

**Inspect timeouts**

Use `/session idle` to inspect/update inactivity expiry and
`/session max-age` to control the hard cap.

**Detach**

Use `/session unbind` to detach without closing the agent session.

### Manual controls

| Command            | Effect                                                                                    |
| ------------------ | ----------------------------------------------------------------------------------------- |
| `/session unbind`  | Remove the current conversation binding without closing the agent session                 |
| `/agents`          | List active runs and binding state (`binding:<id>`, `unbound`, or `bindings unavailable`) |
| `/session idle`    | Inspect/update inactivity expiry for the current binding                                  |
| `/session max-age` | Inspect/update the maximum age of the current binding                                     |

### 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](#thread-supporting-channels) above.

See [Configuration reference](https://funcoding.ai/agents/openclaw/gateway/configuration-reference/) and
[Slash commands](https://funcoding.ai/agents/openclaw/tools/slash-commands/) for current adapter details.

### Allowlist

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.

Default configured target-agent allowlist used when the requester agent does not set its own `subagents.allowAgents`.

Block `sessions_spawn` calls that omit `agentId` (forces explicit profile selection). Per-agent override: `agents.entries.*.subagents.requireAgentId`.

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](https://funcoding.ai/agents/openclaw/concepts/agent-loop/#timeouts) 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.

If the requester session is sandboxed, `sessions_spawn` rejects targets
that would run unsandboxed.

### Discovery

Use `agents_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` (default `60`).
- Archive uses `sessions.delete` and 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.

If a newer run takes over the same session, the older run stops claiming tabs for
cleanup. Cleanup already admitted for a tab still settles against that tab's
captured ownership; it does not remove a later registration.

The `subagent_ended` plugin hook is best-effort. Hook execution or plugin runtime
loading failures are logged and do not abort sub-agent cleanup.

Periodic context-engine cleanup continues after the request that started it ends.
Best-effort context-engine cleanup failures log the redacted error, cleanup reason,
and masked child session key.
