refactor discord thread bindings to idle and max-age lifecycle

This commit is contained in:
Onur Solmaz
2026-02-26 19:14:28 +01:00
parent c92c3ad224
commit 41eacccc42
32 changed files with 965 additions and 365 deletions

View File

@@ -635,7 +635,8 @@ Default slash command settings:
- `/focus <target>` bind current/new thread to a subagent/session target
- `/unfocus` remove current thread binding
- `/agents` show active runs and binding state
- `/session ttl <duration|off>` inspect/update auto-unfocus TTL for focused bindings
- `/session idle <duration|off>` inspect/update inactivity auto-unfocus for focused bindings
- `/session max-age <duration|off>` inspect/update hard max age for focused bindings
Config:
@@ -644,14 +645,16 @@ Default slash command settings:
session: {
threadBindings: {
enabled: true,
ttlHours: 24,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
ttlHours: 24,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in
},
},

View File

@@ -244,7 +244,8 @@ WhatsApp runs through the gateway's web channel (Baileys Web). It starts automat
},
threadBindings: {
enabled: true,
ttlHours: 24,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in for sessions_spawn({ thread: true })
},
voice: {
@@ -277,8 +278,9 @@ WhatsApp runs through the gateway's web channel (Baileys Web). It starts automat
- Bot-authored messages are ignored by default. `allowBots: true` enables them (own messages still filtered).
- `maxLinesPerMessage` (default 17) splits tall messages even when under 2000 chars.
- `channels.discord.threadBindings` controls Discord thread-bound routing:
- `enabled`: Discord override for thread-bound session features (`/focus`, `/unfocus`, `/agents`, `/session ttl`, and bound delivery/routing)
- `ttlHours`: Discord override for auto-unfocus TTL (`0` disables)
- `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
- `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 + TTS overrides.
@@ -1246,7 +1248,8 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden
},
threadBindings: {
enabled: true,
ttlHours: 24, // default auto-unfocus TTL for thread-bound sessions (0 disables)
idleHours: 24, // default inactivity auto-unfocus in hours (`0` disables)
maxAgeHours: 0, // default hard max age in hours (`0` disables)
},
mainKey: "main", // legacy (runtime always uses "main")
agentToAgent: { maxPingPongTurns: 5 },
@@ -1273,7 +1276,8 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden
- **`maintenance`**: `warn` warns the active session on eviction; `enforce` applies pruning and rotation.
- **`threadBindings`**: global defaults for thread-bound session features.
- `enabled`: master default switch (providers can override; Discord uses `channels.discord.threadBindings.enabled`)
- `ttlHours`: default auto-unfocus TTL in hours (`0` disables; providers can override)
- `idleHours`: default inactivity auto-unfocus in hours (`0` disables; providers can override)
- `maxAgeHours`: default hard max age in hours (`0` disables; providers can override)
</Accordion>

View File

@@ -184,7 +184,8 @@ When validation fails:
dmScope: "per-channel-peer", // recommended for multi-user
threadBindings: {
enabled: true,
ttlHours: 24,
idleHours: 24,
maxAgeHours: 0,
},
reset: {
mode: "daily",
@@ -196,7 +197,7 @@ When validation fails:
```
- `dmScope`: `main` (shared) | `per-peer` | `per-channel-peer` | `per-account-channel-peer`
- `threadBindings`: global defaults for thread-bound session routing (Discord supports `/focus`, `/unfocus`, `/agents`, and `/session ttl`).
- `threadBindings`: global defaults for thread-bound session routing (Discord supports `/focus`, `/unfocus`, `/agents`, `/session idle`, and `/session max-age`).
- See [Session Management](/concepts/session) for scoping, identity links, and send policy.
- See [full reference](/gateway/configuration-reference#session) for all fields.

View File

@@ -1050,13 +1050,13 @@ Basic flow:
- Spawn with `sessions_spawn` using `thread: true` (and optionally `mode: "session"` for persistent follow-up).
- Or manually bind with `/focus <target>`.
- Use `/agents` to inspect binding state.
- Use `/session ttl <duration|off>` to control auto-unfocus.
- Use `/session idle <duration|off>` and `/session max-age <duration|off>` to control auto-unfocus.
- Use `/unfocus` to detach the thread.
Required config:
- Global defaults: `session.threadBindings.enabled`, `session.threadBindings.ttlHours`.
- Discord overrides: `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.ttlHours`.
- 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`.
Docs: [Sub-agents](/tools/subagents), [Discord](/channels/discord), [Configuration Reference](/gateway/configuration-reference), [Slash commands](/tools/slash-commands).

View File

@@ -78,7 +78,8 @@ Text + native (when enabled):
- `/context [list|detail|json]` (explain “context”; `detail` shows per-file + per-tool + per-skill + system prompt size)
- `/export-session [path]` (alias: `/export`) (export current session to HTML with full system prompt)
- `/whoami` (show your sender id; alias: `/id`)
- `/session ttl <duration|off>` (manage session-level settings, such as TTL)
- `/session idle <duration|off>` (manage inactivity auto-unfocus for focused thread bindings)
- `/session max-age <duration|off>` (manage hard max-age auto-unfocus for focused thread bindings)
- `/subagents list|kill|log|info|send|steer|spawn` (inspect, control, or spawn sub-agent runs for the current session)
- `/agents` (list thread-bound agents for this session)
- `/focus <target>` (Discord: bind this thread, or a new thread, to a session/subagent target)
@@ -124,7 +125,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`).
- Discord thread-binding commands (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`) 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.
- Tool failure summaries are still shown when relevant, but detailed failure text is only included when `/verbose` is `on` or `full`.
- `/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.

View File

@@ -30,7 +30,8 @@ These commands work on channels that support persistent thread bindings. See **T
- `/focus <subagent-label|session-key|session-id|session-label>`
- `/unfocus`
- `/agents`
- `/session ttl <duration|off>`
- `/session idle <duration|off>`
- `/session max-age <duration|off>`
`/subagents info` shows run metadata (status, timestamps, session id, transcript path, cleanup).
@@ -93,14 +94,14 @@ When thread bindings are enabled for a channel, a sub-agent can stay bound to a
### Thread supporting channels
- Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (`sessions_spawn` with `thread: true`), manual thread controls (`/focus`, `/unfocus`, `/agents`, `/session ttl`), and adapter keys `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.ttlHours`, and `channels.discord.threadBindings.spawnSubagentSessions`.
- Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (`sessions_spawn` with `thread: true`), manual thread controls (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`), and adapter keys `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`, and `channels.discord.threadBindings.spawnSubagentSessions`.
Quick flow:
1. Spawn with `sessions_spawn` using `thread: true` (and optionally `mode: "session"`).
2. OpenClaw creates or binds a thread to that session target in the active channel.
3. Replies and follow-up messages in that thread route to the bound session.
4. Use `/session ttl` to inspect/update auto-unfocus TTL.
4. Use `/session idle` to inspect/update inactivity auto-unfocus and `/session max-age` to control the hard cap.
5. Use `/unfocus` to detach manually.
Manual controls:
@@ -108,11 +109,11 @@ Manual controls:
- `/focus <target>` binds the current thread (or creates one) to a sub-agent/session target.
- `/unfocus` removes the binding for the current bound thread.
- `/agents` lists active runs and binding state (`thread:<id>` or `unbound`).
- `/session ttl` only works for focused bound threads.
- `/session idle` and `/session max-age` only work for focused bound threads.
Config switches:
- Global default: `session.threadBindings.enabled`, `session.threadBindings.ttlHours`
- 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.
See [Configuration Reference](/gateway/configuration-reference) and [Slash commands](/tools/slash-commands) for current adapter details.