mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:30:57 +00:00
feat: simplify thread-bound session spawning
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
94f7879b0771e81973c0749c719c19283fdc26e0e42fe6536f8ee563be6a44e5 config-baseline.json
|
||||
a38ea77d2f0f0188f14ce0e3a8a564ff80e51415849359042f51921eb01ec2d9 config-baseline.core.json
|
||||
eab8a85eefa2792fb8b98a07698e5ec31ff0b6f8af6222767e8049dcc5c4f529 config-baseline.channel.json
|
||||
6bd6c72b17801072b2d3285c82f4c21adcc95f0edffc1e6f64e767d0a07b678f config-baseline.plugin.json
|
||||
d0b1fc318d2f737c91c21ffffae2fe12197b4ba6d49859c4786ecbc586cf5a82 config-baseline.json
|
||||
3f9c52903905d82d4b4ca9dbda530cac2e059870b08c69965099ebcd09a270a3 config-baseline.core.json
|
||||
f42329d45c095881bd226bdb192c235980658fd250606d0c0badc2b12f12f5d3 config-baseline.channel.json
|
||||
af71b84b2411d8ccabcc6e09de0ee41f8212ff9869a6677698b6e7e3afdfaa47 config-baseline.plugin.json
|
||||
|
||||
@@ -738,7 +738,8 @@ Default slash command settings:
|
||||
enabled: true,
|
||||
idleHours: 24,
|
||||
maxAgeHours: 0,
|
||||
spawnSubagentSessions: false, // opt-in
|
||||
spawnSessions: true,
|
||||
defaultSpawnContext: "fork",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -749,8 +750,9 @@ Default slash command settings:
|
||||
|
||||
- `session.threadBindings.*` sets global defaults.
|
||||
- `channels.discord.threadBindings.*` overrides Discord behavior.
|
||||
- `spawnSubagentSessions` must be true to auto-create/bind threads for `sessions_spawn({ thread: true })`.
|
||||
- `spawnAcpSessions` must be true to auto-create/bind threads for ACP (`/acp spawn ... --thread ...` or `sessions_spawn({ runtime: "acp", thread: true })`).
|
||||
- `spawnSessions` controls auto-create/bind threads for `sessions_spawn({ thread: true })` and ACP thread spawns. Default: `true`.
|
||||
- `defaultSpawnContext` controls native subagent context for thread-bound spawns. Default: `"fork"`.
|
||||
- Deprecated `spawnSubagentSessions`/`spawnAcpSessions` keys are migrated by `openclaw doctor --fix`.
|
||||
- If thread bindings are disabled for an account, `/focus` and related thread binding operations are unavailable.
|
||||
|
||||
See [Sub-agents](/tools/subagents), [ACP Agents](/tools/acp-agents), and [Configuration Reference](/gateway/configuration-reference).
|
||||
@@ -816,7 +818,7 @@ Default slash command settings:
|
||||
|
||||
- `/acp spawn codex --bind here` binds the current channel or thread in place and keeps future messages on the same ACP session. Thread messages inherit the parent channel binding.
|
||||
- In a bound channel or thread, `/new` and `/reset` reset the same ACP session in place. Temporary thread bindings can override target resolution while active.
|
||||
- `spawnAcpSessions` is only required when OpenClaw needs to create/bind a child thread via `--thread auto|here`.
|
||||
- `spawnSessions` gates child thread creation/binding via `--thread auto|here`.
|
||||
|
||||
See [ACP Agents](/tools/acp-agents) for binding behavior details.
|
||||
|
||||
|
||||
@@ -530,7 +530,7 @@ Explicit conversation bindings always win over `sessionScope`, so bound rooms an
|
||||
- Message-tool sends auto-inherit the current Matrix thread when targeting the same room (or the same DM user target), unless an explicit `threadId` is provided.
|
||||
- DM user-target reuse only kicks in when the current session metadata proves the same DM peer on the same Matrix account; otherwise OpenClaw falls back to normal user-scoped routing.
|
||||
- `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, and thread-bound `/acp spawn` all work in Matrix rooms and DMs.
|
||||
- Top-level `/focus` creates a new Matrix thread and binds it to the target session when `threadBindings.spawnSubagentSessions: true`.
|
||||
- Top-level `/focus` creates a new Matrix thread and binds it to the target session when `threadBindings.spawnSessions` is enabled.
|
||||
- Running `/focus` or `/acp spawn --thread here` inside an existing Matrix thread binds that thread in place.
|
||||
|
||||
When OpenClaw detects a Matrix DM room colliding with another DM room on the same shared session, it posts a one-time `m.notice` in that room pointing to the `/focus` escape hatch and suggesting a `dm.sessionScope` change. The notice only appears when thread bindings are enabled.
|
||||
@@ -550,7 +550,7 @@ Fast operator flow:
|
||||
Notes:
|
||||
|
||||
- `--bind here` does not create a child Matrix thread.
|
||||
- `threadBindings.spawnAcpSessions` is only required for `/acp spawn --thread auto|here`, where OpenClaw needs to create or bind a child Matrix thread.
|
||||
- `threadBindings.spawnSessions` gates `/acp spawn --thread auto|here`, where OpenClaw needs to create or bind a child Matrix thread.
|
||||
|
||||
### Thread binding config
|
||||
|
||||
@@ -559,13 +559,13 @@ Matrix inherits global defaults from `session.threadBindings`, and also supports
|
||||
- `threadBindings.enabled`
|
||||
- `threadBindings.idleHours`
|
||||
- `threadBindings.maxAgeHours`
|
||||
- `threadBindings.spawnSubagentSessions`
|
||||
- `threadBindings.spawnAcpSessions`
|
||||
- `threadBindings.spawnSessions`
|
||||
- `threadBindings.defaultSpawnContext`
|
||||
|
||||
Matrix thread-bound spawn flags are opt-in:
|
||||
Matrix thread-bound session spawns default on:
|
||||
|
||||
- Set `threadBindings.spawnSubagentSessions: true` to allow top-level `/focus` to create and bind new Matrix threads.
|
||||
- Set `threadBindings.spawnAcpSessions: true` to allow `/acp spawn --thread auto|here` to bind ACP sessions to Matrix threads.
|
||||
- Set `threadBindings.spawnSessions: false` to block top-level `/focus` and `/acp spawn --thread auto|here` from creating/binding Matrix threads.
|
||||
- Set `threadBindings.defaultSpawnContext: "isolated"` when native subagent thread spawns should not fork the parent transcript.
|
||||
|
||||
## Reactions
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
**Persistent ACP topic binding**: Forum topics can pin ACP harness sessions through top-level typed ACP bindings (`bindings[]` with `type: "acp"` and `match.channel: "telegram"`, `peer.kind: "group"`, and a topic-qualified id like `-1001234567890:topic:42`). Currently scoped to forum topics in groups/supergroups. See [ACP Agents](/tools/acp-agents).
|
||||
|
||||
**Thread-bound ACP spawn from chat**: `/acp spawn <agent> --thread here|auto` binds the current topic to a new ACP session; follow-ups route there directly. OpenClaw pins the spawn confirmation in-topic. Requires `channels.telegram.threadBindings.spawnAcpSessions=true`.
|
||||
**Thread-bound ACP spawn from chat**: `/acp spawn <agent> --thread here|auto` binds the current topic to a new ACP session; follow-ups route there directly. OpenClaw pins the spawn confirmation in-topic. Requires `channels.telegram.threadBindings.spawnSessions` to remain enabled (default: `true`).
|
||||
|
||||
Template context exposes `MessageThreadId` and `IsForum`. DM chats with `message_thread_id` keep DM routing but use thread-aware session keys.
|
||||
|
||||
|
||||
@@ -143,6 +143,8 @@ Key options:
|
||||
- `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.
|
||||
Thread-bound native sub-agents default to `context: "fork"` unless
|
||||
`threadBindings.defaultSpawnContext` says otherwise.
|
||||
|
||||
Default leaf sub-agents do not get session tools. When
|
||||
`maxSpawnDepth >= 2`, depth-1 orchestrator sub-agents additionally receive
|
||||
|
||||
@@ -1229,6 +1229,8 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden
|
||||
- `enabled`: master default switch (providers can override; Discord uses `channels.discord.threadBindings.enabled`)
|
||||
- `idleHours`: default inactivity auto-unfocus in hours (`0` disables; providers can override)
|
||||
- `maxAgeHours`: default hard max age in hours (`0` disables; providers can override)
|
||||
- `spawnSessions`: default gate for creating thread-bound work sessions from `sessions_spawn` and ACP thread spawns. Defaults to `true` when thread bindings are enabled; providers/accounts can override.
|
||||
- `defaultSpawnContext`: default native subagent context for thread-bound spawns (`"fork"` or `"isolated"`). Defaults to `"fork"`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
|
||||
@@ -285,7 +285,8 @@ WhatsApp runs through the gateway's web channel (Baileys Web). It starts automat
|
||||
enabled: true,
|
||||
idleHours: 24,
|
||||
maxAgeHours: 0,
|
||||
spawnSubagentSessions: false, // opt-in for sessions_spawn({ thread: true })
|
||||
spawnSessions: true,
|
||||
defaultSpawnContext: "fork",
|
||||
},
|
||||
voice: {
|
||||
enabled: true,
|
||||
@@ -336,7 +337,8 @@ WhatsApp runs through the gateway's web channel (Baileys Web). It starts automat
|
||||
- `enabled`: Discord override for thread-bound session features (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, and bound delivery/routing)
|
||||
- `idleHours`: Discord override for inactivity auto-unfocus in hours (`0` disables)
|
||||
- `maxAgeHours`: Discord override for hard max age in hours (`0` disables)
|
||||
- `spawnSubagentSessions`: opt-in switch for `sessions_spawn({ thread: true })` auto thread creation/binding
|
||||
- `spawnSessions`: switch for `sessions_spawn({ thread: true })` and ACP thread-spawn auto thread creation/binding (default: `true`)
|
||||
- `defaultSpawnContext`: native subagent context for thread-bound spawns (`"fork"` by default)
|
||||
- Top-level `bindings[]` entries with `type: "acp"` configure persistent ACP bindings for channels and threads (use channel/thread id in `match.peer.id`). Field semantics are shared in [ACP Agents](/tools/acp-agents#channel-specific-settings).
|
||||
- `channels.discord.ui.components.accentColor` sets the accent color for Discord components v2 containers.
|
||||
- `channels.discord.voice` enables Discord voice channel conversations and optional auto-join + LLM + TTS overrides. Text-only Discord configs leave voice off by default; set `channels.discord.voice.enabled=true` to opt in.
|
||||
|
||||
@@ -215,7 +215,7 @@ lives on the [First-run FAQ](/help/faq-first-run).
|
||||
|
||||
- Global defaults: `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`.
|
||||
- Discord overrides: `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`.
|
||||
- Auto-bind on spawn: set `channels.discord.threadBindings.spawnSubagentSessions: true`.
|
||||
- Auto-bind on spawn: `channels.discord.threadBindings.spawnSessions` defaults to `true`; set it to `false` to disable thread-bound session spawns.
|
||||
|
||||
Docs: [Sub-agents](/tools/subagents), [Discord](/channels/discord), [Configuration Reference](/gateway/configuration-reference), [Slash commands](/tools/slash-commands).
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ Thread binding config is channel-adapter specific. Example for Discord:
|
||||
discord: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
spawnAcpSessions: true,
|
||||
spawnSessions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -118,7 +118,7 @@ Thread binding config is channel-adapter specific. Example for Discord:
|
||||
|
||||
If thread-bound ACP spawn does not work, verify the adapter feature flag first:
|
||||
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Discord: `channels.discord.threadBindings.spawnSessions=true`
|
||||
|
||||
Current-conversation binds do not require child-thread creation. They require an active conversation context and a channel adapter that exposes ACP conversation bindings.
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ Examples:
|
||||
<Accordion title="Binding rules and exclusivity">
|
||||
- `--bind here` and `--thread ...` are mutually exclusive.
|
||||
- `--bind here` only works on channels that advertise current-conversation binding; OpenClaw returns a clear unsupported message otherwise. Bindings persist across gateway restarts.
|
||||
- On Discord, `spawnAcpSessions` is only required when OpenClaw needs to create a child thread for `--thread auto|here` — not for `--bind here`.
|
||||
- On Discord, `spawnSessions` gates child thread creation for `--thread auto|here` — not `--bind here`.
|
||||
- If you spawn to a different ACP agent without `--cwd`, OpenClaw inherits the **target agent's** workspace by default. Missing inherited paths (`ENOENT`/`ENOTDIR`) fall back to the backend default; other access errors (e.g. `EACCES`) surface as spawn errors.
|
||||
- Gateway management commands stay local in bound conversations — `/acp ...` commands are handled by OpenClaw even when normal follow-up text routes to the bound ACP session; `/status` and `/unfocus` also stay local whenever command handling is enabled for that surface.
|
||||
|
||||
@@ -297,9 +297,9 @@ Examples:
|
||||
|
||||
- `acp.enabled=true`
|
||||
- `acp.dispatch.enabled` is on by default (set `false` to pause automatic ACP thread dispatch; explicit `sessions_spawn({ runtime: "acp" })` calls still work).
|
||||
- Channel-adapter ACP thread-spawn flag enabled (adapter-specific):
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Telegram: `channels.telegram.threadBindings.spawnAcpSessions=true`
|
||||
- Channel-adapter thread session spawns enabled (default: `true`):
|
||||
- Discord: `channels.discord.threadBindings.spawnSessions=true`
|
||||
- Telegram: `channels.telegram.threadBindings.spawnSessions=true`
|
||||
|
||||
Thread binding support is adapter-specific. If the active channel
|
||||
adapter does not support thread bindings, OpenClaw returns a clear
|
||||
@@ -592,8 +592,8 @@ Two ways to start an ACP session:
|
||||
|
||||
- On non-thread binding surfaces, default behavior is effectively `off`.
|
||||
- Thread-bound spawn requires channel policy support:
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Telegram: `channels.telegram.threadBindings.spawnAcpSessions=true`
|
||||
- Discord: `channels.discord.threadBindings.spawnSessions=true`
|
||||
- Telegram: `channels.telegram.threadBindings.spawnSessions=true`
|
||||
- Use `--bind here` when you want to pin the current conversation without creating a child thread.
|
||||
|
||||
</Tab>
|
||||
|
||||
@@ -26,8 +26,10 @@ Primary goals:
|
||||
default. For heavy or repetitive tasks, set a cheaper model for sub-agents
|
||||
and keep your main agent on a higher-quality model. Configure via
|
||||
`agents.defaults.subagents.model` or per-agent overrides. When a child
|
||||
genuinely needs the requester's current transcript, the agent can request
|
||||
`context: "fork"` on that one spawn.
|
||||
genuinely needs the requester's current transcript, the agent can request
|
||||
`context: "fork"` on that one spawn. Thread-bound subagent sessions default
|
||||
to `context: "fork"` because they branch the current conversation into a
|
||||
follow-up thread.
|
||||
</Note>
|
||||
|
||||
## Slash command
|
||||
@@ -179,7 +181,7 @@ session to confirm the effective tool list.
|
||||
`require` rejects spawn unless the target child runtime is sandboxed.
|
||||
</ParamField>
|
||||
<ParamField path="context" type='"isolated" | "fork"' default="isolated">
|
||||
`fork` branches the requester's current transcript into the child session. Native sub-agents only. Use `fork` only when the child needs the current transcript.
|
||||
`fork` branches the requester's current transcript into the child session. Native sub-agents only. Thread-bound spawns default to `fork`; non-thread spawns default to `isolated`.
|
||||
</ParamField>
|
||||
|
||||
<Warning>
|
||||
@@ -203,7 +205,7 @@ persistent thread-bound subagent sessions (`sessions_spawn` with
|
||||
`channels.discord.threadBindings.enabled`,
|
||||
`channels.discord.threadBindings.idleHours`,
|
||||
`channels.discord.threadBindings.maxAgeHours`, and
|
||||
`channels.discord.threadBindings.spawnSubagentSessions`.
|
||||
`channels.discord.threadBindings.spawnSessions`.
|
||||
|
||||
### Quick flow
|
||||
|
||||
|
||||
Reference in New Issue
Block a user