docs: document thread-bound subagent sessions and remove plan

This commit is contained in:
Peter Steinberger
2026-02-21 19:59:50 +01:00
parent 51c0893673
commit 817905f3a0
9 changed files with 135 additions and 339 deletions

View File

@@ -464,7 +464,7 @@ Core parameters:
- `sessions_list`: `kinds?`, `limit?`, `activeMinutes?`, `messageLimit?` (0 = none)
- `sessions_history`: `sessionKey` (or `sessionId`), `limit?`, `includeTools?`
- `sessions_send`: `sessionKey` (or `sessionId`), `message`, `timeoutSeconds?` (0 = fire-and-forget)
- `sessions_spawn`: `task`, `label?`, `agentId?`, `model?`, `runTimeoutSeconds?`, `cleanup?`
- `sessions_spawn`: `task`, `label?`, `agentId?`, `model?`, `thinking?`, `runTimeoutSeconds?`, `thread?`, `mode?`, `cleanup?`
- `session_status`: `sessionKey?` (default current; accepts `sessionId`), `model?` (`default` clears override)
Notes:
@@ -475,6 +475,10 @@ Notes:
- `sessions_send` waits for final completion when `timeoutSeconds > 0`.
- Delivery/announce happens after completion and is best-effort; `status: "ok"` confirms the agent run finished, not that the announce was delivered.
- `sessions_spawn` starts a sub-agent run and posts an announce reply back to the requester chat.
- Supports one-shot mode (`mode: "run"`) and persistent thread-bound mode (`mode: "session"` with `thread: true`).
- If `thread: true` and `mode` is omitted, mode defaults to `session`.
- `mode: "session"` requires `thread: true`.
- Discord thread-bound flows depend on `session.threadBindings.*` and `channels.discord.threadBindings.*`.
- Reply format includes `Status`, `Result`, and compact stats.
- `Result` is the assistant completion text; if missing, the latest `toolResult` is used as fallback.
- Manual completion-mode spawns send directly first, with queue fallback and retry on transient failures (`status: "ok"` means run finished, not that announce delivered).

View File

@@ -124,6 +124,7 @@ Notes:
- `/usage` controls the per-response usage footer; `/usage cost` prints a local cost summary from OpenClaw session logs.
- `/restart` is enabled by default; set `commands.restart: false` to disable it.
- Discord-only native command: `/vc join|leave|status` controls voice channels (requires `channels.discord.voice` and native commands; not available as text).
- Discord thread-binding commands (`/focus`, `/unfocus`, `/agents`, `/session ttl`) require effective thread bindings to be enabled (`session.threadBindings.enabled` and/or `channels.discord.threadBindings.enabled`).
- `/verbose` is meant for debugging and extra visibility; keep it **off** in normal use.
- `/reasoning` (and `/verbose`) are risky in group settings: they may reveal internal reasoning or tool output you did not intend to expose. Prefer leaving them off, especially in group chats.
- **Fast path:** command-only messages from allowlisted senders are handled immediately (bypass queue + model).

View File

@@ -3,6 +3,7 @@ summary: "Sub-agents: spawning isolated agent runs that announce results back to
read_when:
- You want background/parallel work via the agent
- You are changing sessions_spawn or sub-agent tool policy
- You are implementing or troubleshooting thread-bound subagent sessions
title: "Sub-Agents"
---
@@ -22,6 +23,13 @@ Use `/subagents` to inspect or control sub-agent runs for the **current session*
- `/subagents steer <id|#> <message>`
- `/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]`
Discord thread binding controls:
- `/focus <subagent-label|session-key|session-id|session-label>`
- `/unfocus`
- `/agents`
- `/session ttl <duration|off>`
`/subagents info` shows run metadata (status, timestamps, session id, transcript path, cleanup).
### Spawn behavior
@@ -40,6 +48,7 @@ Use `/subagents` to inspect or control sub-agent runs for the **current session*
- compact runtime/token stats
- `--model` and `--thinking` override defaults for that specific run.
- Use `info`/`log` to inspect details and output after completion.
- `/subagents spawn` is one-shot mode (`mode: "run"`). For persistent thread-bound sessions, use `sessions_spawn` with `thread: true` and `mode: "session"`.
Primary goals:
@@ -69,8 +78,40 @@ Tool params:
- `model?` (optional; overrides the sub-agent model; invalid values are skipped and the sub-agent runs on the default model with a warning in the tool result)
- `thinking?` (optional; overrides thinking level for the sub-agent run)
- `runTimeoutSeconds?` (default `0`; when set, the sub-agent run is aborted after N seconds)
- `thread?` (default `false`; when `true`, requests channel thread binding for this sub-agent session)
- `mode?` (`run|session`)
- default is `run`
- if `thread: true` and `mode` omitted, default becomes `session`
- `mode: "session"` requires `thread: true`
- `cleanup?` (`delete|keep`, default `keep`)
## Discord thread-bound sessions
When thread bindings are enabled, a sub-agent can stay bound to a Discord thread so follow-up user messages in that thread keep routing to the same sub-agent session.
Quick flow:
1. Spawn with `sessions_spawn` using `thread: true` (and optionally `mode: "session"`).
2. OpenClaw creates or binds a Discord thread to that session target.
3. Replies and follow-up messages in that thread route to the bound session.
4. Use `/session ttl` to inspect/update auto-unfocus TTL.
5. Use `/unfocus` to detach manually.
Manual controls:
- `/focus <target>` binds the current thread (or creates one) to a sub-agent/session target.
- `/unfocus` removes the binding for the current Discord thread.
- `/agents` lists active runs and binding state (`thread:<id>` or `unbound`).
- `/session ttl` only works for focused Discord threads.
Config switches:
- Global default: `session.threadBindings.enabled`, `session.threadBindings.ttlHours`
- Discord override: `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.ttlHours`
- Spawn auto-bind opt-in: `channels.discord.threadBindings.spawnSubagentSessions`
See [Discord](/channels/discord), [Configuration Reference](/gateway/configuration-reference), and [Slash commands](/tools/slash-commands).
Allowlist:
- `agents.list[].subagents.allowAgents`: list of agent ids that can be targeted via `agentId` (`["*"]` to allow any). Default: only the requester agent.