diff --git a/.openclaw-sync/source.json b/.openclaw-sync/source.json index 2ed9860ff..d343bc74a 100644 --- a/.openclaw-sync/source.json +++ b/.openclaw-sync/source.json @@ -1,5 +1,5 @@ { "repository": "openclaw/openclaw", - "sha": "ad85e5c64ca0d93302c920d3cfedc1c9b05a67a3", - "syncedAt": "2026-05-02T05:57:38.575Z" + "sha": "267f5e081ab0ea877eac748ac219e9df49416b8b", + "syncedAt": "2026-05-02T05:59:17.827Z" } diff --git a/docs/.generated/config-baseline.sha256 b/docs/.generated/config-baseline.sha256 index 3e953061d..23c54309d 100644 --- a/docs/.generated/config-baseline.sha256 +++ b/docs/.generated/config-baseline.sha256 @@ -1,4 +1,4 @@ -94f7879b0771e81973c0749c719c19283fdc26e0e42fe6536f8ee563be6a44e5 config-baseline.json -a38ea77d2f0f0188f14ce0e3a8a564ff80e51415849359042f51921eb01ec2d9 config-baseline.core.json -eab8a85eefa2792fb8b98a07698e5ec31ff0b6f8af6222767e8049dcc5c4f529 config-baseline.channel.json -6bd6c72b17801072b2d3285c82f4c21adcc95f0edffc1e6f64e767d0a07b678f config-baseline.plugin.json +0020a49cdf07b79fddfed9584f10323ef77e3ca5c7f907d441c1f2e3f45932c9 config-baseline.json +8193fd771c9fa50e77c71ff69d41015e6dc02d140182ceea3baaa17713f04b18 config-baseline.core.json +f42329d45c095881bd226bdb192c235980658fd250606d0c0badc2b12f12f5d3 config-baseline.channel.json +af71b84b2411d8ccabcc6e09de0ee41f8212ff9869a6677698b6e7e3afdfaa47 config-baseline.plugin.json diff --git a/docs/channels/discord.md b/docs/channels/discord.md index e1d7cd38b..ac324dcd4 100644 --- a/docs/channels/discord.md +++ b/docs/channels/discord.md @@ -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. diff --git a/docs/channels/matrix.md b/docs/channels/matrix.md index 361eaa6b5..65698fd61 100644 --- a/docs/channels/matrix.md +++ b/docs/channels/matrix.md @@ -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 diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 599aa25ec..9f969df23 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -540,7 +540,7 @@ curl "https://api.telegram.org/bot/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 --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 --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. diff --git a/docs/concepts/session-tool.md b/docs/concepts/session-tool.md index e0500ee00..21d5fe198 100644 --- a/docs/concepts/session-tool.md +++ b/docs/concepts/session-tool.md @@ -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 diff --git a/docs/gateway/config-agents.md b/docs/gateway/config-agents.md index 8f9aa8610..6bebcc117 100644 --- a/docs/gateway/config-agents.md +++ b/docs/gateway/config-agents.md @@ -1174,7 +1174,6 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/{agentId}/sessions/sessions.json", - parentForkMaxTokens: 100000, // skip parent-thread fork above this token count (0 disables) maintenance: { mode: "warn", // warn | enforce pruneAfter: "30d", @@ -1211,9 +1210,6 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden - **`identityLinks`**: map canonical ids to provider-prefixed peers for cross-channel session sharing. Dock commands such as `/dock_discord` use the same map to switch the active session's reply route to another linked channel peer; see [Channel docking](/concepts/channel-docking). - **`reset`**: primary reset policy. `daily` resets at `atHour` local time; `idle` resets after `idleMinutes`. When both configured, whichever expires first wins. Daily reset freshness uses the session row's `sessionStartedAt`; idle reset freshness uses `lastInteractionAt`. Background/system-event writes such as heartbeat, cron wakeups, exec notifications, and gateway bookkeeping can update `updatedAt`, but they do not keep daily/idle sessions fresh. - **`resetByType`**: per-type overrides (`direct`, `group`, `thread`). Legacy `dm` accepted as alias for `direct`. -- **`parentForkMaxTokens`**: max parent-session `totalTokens` allowed when creating a forked thread session (default `100000`). - - If parent `totalTokens` is above this value, OpenClaw starts a fresh thread session instead of inheriting parent transcript history. - - Set `0` to disable this guard and always allow parent forking. - **`mainKey`**: legacy field. Runtime always uses `"main"` for the main direct-chat bucket. - **`agentToAgent.maxPingPongTurns`**: maximum reply-back turns between agents during agent-to-agent exchanges (integer, range: `0`–`5`). `0` disables ping-pong chaining. - **`sendPolicy`**: match by `channel`, `chatType` (`direct|group|channel`, with legacy `dm` alias), `keyPrefix`, or `rawKeyPrefix`. First deny wins. @@ -1229,6 +1225,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"`. diff --git a/docs/gateway/config-channels.md b/docs/gateway/config-channels.md index fe4644495..66af03250 100644 --- a/docs/gateway/config-channels.md +++ b/docs/gateway/config-channels.md @@ -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. diff --git a/docs/help/faq.md b/docs/help/faq.md index c9db380d7..52419b68f 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -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). diff --git a/docs/reference/session-management-compaction.md b/docs/reference/session-management-compaction.md index 32b92e2b3..f6f871239 100644 --- a/docs/reference/session-management-compaction.md +++ b/docs/reference/session-management-compaction.md @@ -148,7 +148,7 @@ Rules of thumb: - **Daily reset** (default 4:00 AM local time on the gateway host) creates a new `sessionId` on the next message after the reset boundary. - **Idle expiry** (`session.reset.idleMinutes` or legacy `session.idleMinutes`) creates a new `sessionId` when a message arrives after the idle window. When daily + idle are both configured, whichever expires first wins. - **System events** (heartbeat, cron wakeups, exec notifications, gateway bookkeeping) may mutate the session row but do not extend daily/idle reset freshness. Reset rollover discards queued system-event notices for the previous session before the fresh prompt is built. -- **Thread parent fork guard** (`session.parentForkMaxTokens`, default `100000`) skips parent transcript forking when the parent session is already too large; the new thread starts fresh. Set `0` to disable. +- **Parent fork policy** uses PI's active branch when creating a thread or subagent fork. If that branch is too large, OpenClaw starts the child with isolated context instead of failing or inheriting unusable history. The sizing policy is automatic; legacy `session.parentForkMaxTokens` config is removed by `openclaw doctor --fix`. Implementation detail: the decision happens in `initSessionState()` in `src/auto-reply/reply/session.ts`. diff --git a/docs/tools/acp-agents-setup.md b/docs/tools/acp-agents-setup.md index 44787262c..317d20b0e 100644 --- a/docs/tools/acp-agents-setup.md +++ b/docs/tools/acp-agents-setup.md @@ -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. diff --git a/docs/tools/acp-agents.md b/docs/tools/acp-agents.md index c1ec71ea7..2076dcc09 100644 --- a/docs/tools/acp-agents.md +++ b/docs/tools/acp-agents.md @@ -279,7 +279,7 @@ Examples: - `--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. diff --git a/docs/tools/subagents.md b/docs/tools/subagents.md index 6c1b45441..d48497b9f 100644 --- a/docs/tools/subagents.md +++ b/docs/tools/subagents.md @@ -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. ## Slash command @@ -179,7 +181,7 @@ session to confirm the effective tool list. `require` rejects spawn unless the target child runtime is sandboxed. - `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`. @@ -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