Skip to content

feat(discord): show subagent progress#95604

Merged
steipete merged 9 commits into
openclaw:mainfrom
kklouzal:feature/discord-subagent-progress
Jul 17, 2026
Merged

feat(discord): show subagent progress#95604
steipete merged 9 commits into
openclaw:mainfrom
kklouzal:feature/discord-subagent-progress

Conversation

@kklouzal

@kklouzal kklouzal commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Discord users can see a parent turn as idle while tracked subagents are still running. The source message provides no compact indication of concurrent child work or terminal failure.

Why This Change Was Made

Core now emits one generic typed subagent_progress presentation event with source-message provenance. The Discord plugin maps that portable event to typing plus one count reaction, and retains a red reaction after a non-OK child outcome. One opt-in switch, channels.discord.subagentProgress, controls the behavior; emoji, cadence, and the one-hour typing bound remain internal defaults.

The maintainer rewrite deliberately keeps transport policy in Discord, routes native and tracked ACP spawns through the same core lifecycle, and persists only Discord reaction ownership and terminal outcome in plugin SQLite. Durable rows make count cleanup and failure presentation retry-safe across response loss and gateway restart without blocking subagent lifecycle delivery. Progress runtime code remains behind its own lazy import so the public Discord API and unrelated subagent hooks do not increase lightweight CLI startup memory.

User Impact

When enabled, the Discord source message shows 1️⃣ through 🔟 as tracked child concurrency changes, removes the count after the final child ends, keeps typing active for up to one hour, and leaves 🔴 for error, timeout, or killed outcomes. Other channels ignore the generic event and keep current behavior.

Evidence

  • node scripts/run-vitest.mjs extensions/discord/src/subagent-hooks.test.ts extensions/discord/src/subagent-progress.test.ts src/agents/subagent-registry.persistence.test.ts src/plugins/wired-hooks-subagent.test.ts — 90 passed across three shards.
  • node --max-old-space-size=8192 --import tsx scripts/generate-plugin-sdk-api-baseline.ts --check — baseline current.
  • git diff --check — clean.
  • Fresh whole-branch and final-patch autoreviews — no accepted/actionable findings.
  • Blacksmith changed-surface gate — green: format, SDK baseline, plugin boundaries, extension production and test typechecks, extension lint, database-first, runtime sidecar, import-cycle, and related guards.
  • Contributor live Discord proof already recorded on this PR covered count add/replace/remove, concurrent children, channel/thread sources, typing drain, and a retained failure reaction. The rewrite preserves that user-visible shape while replacing the original configurable/internal hook design with the approved generic event and one-toggle contract.

No linked issue. No changelog edit per maintainer instruction.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord gateway Gateway runtime agents Agent runtime and tooling size: L labels Jun 21, 2026
@clawsweeper

clawsweeper Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed July 17, 2026, 6:46 AM ET / 10:46 UTC.

Summary
Adds opt-in Discord source-message typing, concurrent subagent count reactions, retained failure reactions, a generic typed progress hook, durable progress state, configuration, documentation, and regression coverage.

PR surface: Source +1256, Tests +1151, Docs +19, Generated 0. Total +2426 across 32 files.

Reproducibility: not applicable. this is a new opt-in Discord capability rather than a report of broken established behavior. The relevant review path is the supplied live Discord demonstration plus source-level lifecycle inspection.

Review metrics: 3 noteworthy metrics.

  • Configuration surfaces: 1 added, default false. The Discord toggle is additive but becomes a user-facing setup and upgrade contract, including account-level override behavior.
  • Plugin API surfaces: 1 hook added. subagent_progress becomes a public extension contract whose ordering and failure semantics must remain stable after release.
  • Persisted progress surfaces: 1 core locator + 1 plugin keyed store. Restart-safe source provenance and reaction ownership increase the importance of upgrade, cleanup, and stale-state proof.

Stored data model
Persistent data-model change detected: serialized state: extensions/discord/src/subagent-progress-state.ts, serialized state: src/agents/sessions-spawn-hooks.test.ts, serialized state: src/agents/tools/sessions-spawn-tool.test.ts, serialized state: src/agents/tools/sessions-spawn-tool.ts, unknown-data-model-change: src/agents/sessions-spawn-hooks.test.ts, unknown-data-model-change: src/agents/tools/sessions-spawn-tool.test.ts, and 2 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: canonical
Canonical: #95604
Summary: This PR is the canonical Discord-specific subagent progress implementation; the supplied related items concern distinct Telegram visibility, yielded-parent projection, or descendant delivery accounting.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Move progress hook execution off the accepted-spawn and terminal lifecycle critical paths.
  • [P2] Add a regression where runSubagentProgress never resolves and prove spawn acceptance and terminal completion still finish.

Risk before merge

  • [P1] The awaited progress hook can make accepted subagent completion and cleanup wait on Discord API, plugin state, or third-party hook latency; an indefinitely pending hook can stall lifecycle availability.
  • [P2] The new subagent_progress hook becomes an additive public Plugin SDK contract, so its ordering, best-effort semantics, requester provenance, and non-blocking behavior need to be explicit before release.
  • [P1] The feature persists source-message provenance in core run state and reaction/terminal ownership in plugin SQLite; restart and upgrade behavior must avoid stale or mis-associated reactions even when Discord operations fail.

Maintainer options:

  1. Detach presentation before merge (recommended)
    Move both progress phases off the core lifecycle wait path while preserving one canonical event, plugin-side serialization, durable recovery, and existing visible behavior.
  2. Explicitly own the blocking contract
    Keep the awaited ordering only if maintainers intentionally make progress hooks lifecycle-critical, add a strict upper bound, and prove timeout behavior for Discord and third-party hooks.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Remove awaited subagent progress presentation from accepted-spawn and terminal-completion critical paths; preserve canonical once-only emission, Discord queue serialization, persistence, recovery, lazy loading, and the default-off config, and add tests proving a never-resolving progress hook cannot delay spawn or completion.

Next step before merge

  • [P2] A narrow mechanical repair can remove the lifecycle wait while preserving the maintainer-approved architecture, proof, and user-visible behavior.

Security
Cleared: No concrete security or supply-chain regression was found; the patch adds no dependency, workflow, permission, secret-handling, download, or package-resolution changes.

Review findings

  • [P1] Keep progress presentation off the terminal lifecycle path — src/agents/subagent-registry-lifecycle.ts:2187
Review details

Best possible solution:

Keep the generic event and plugin-owned Discord implementation, but dispatch started and ended presentation outside the accepted-spawn and canonical terminal critical paths through a bounded, serialized best-effort queue, with regression tests proving a never-resolving hook cannot delay lifecycle completion.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this is a new opt-in Discord capability rather than a report of broken established behavior. The relevant review path is the supplied live Discord demonstration plus source-level lifecycle inspection.

Is this the best way to solve the issue?

No, not yet: the generic event and Discord-owned presentation are the right architecture, but awaiting best-effort presentation inside core spawn and terminal lifecycle paths is not the safest implementation boundary.

Full review comments:

  • [P1] Keep progress presentation off the terminal lifecycle path — src/agents/subagent-registry-lifecycle.ts:2187
    This terminal transition still awaits emitSubagentProgressEndedForRun, which transitively awaits every subagent_progress plugin hook. A slow or never-resolving Discord reaction/state call—or another plugin hook—therefore delays canonical completion and cleanup despite presentation being best-effort. Dispatch it through a bounded non-blocking path, and cover both ended and started phases with a never-resolving-hook regression test. This re-raises the prior blocker; the final baseline-only commit did not change this path.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against d7056abbc81e.

Label changes

Label changes:

  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (recording): The accepted live Discord recording demonstrates the visible count lifecycle, concurrent children, channel and thread sources, typing drain, and retained failure reaction; tests and CI supplement that real behavior proof.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: ⏳ waiting on author.

Label justifications:

  • P2: This is a valuable opt-in channel feature with a concrete merge blocker, but it is not a shipped regression or emergency.
  • merge-risk: 🚨 compatibility: The PR adds a user-facing configuration field and a public Plugin SDK hook whose behavior becomes an upgrade-sensitive contract.
  • merge-risk: 🚨 session-state: The PR persists source-message provenance and terminal presentation ownership across gateway restarts, where stale association could affect the wrong Discord message.
  • merge-risk: 🚨 availability: The current awaited hook can delay subagent terminal completion and cleanup on slow or indefinitely pending presentation work.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (recording): The accepted live Discord recording demonstrates the visible count lifecycle, concurrent children, channel and thread sources, typing drain, and retained failure reaction; tests and CI supplement that real behavior proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The accepted live Discord recording demonstrates the visible count lifecycle, concurrent children, channel and thread sources, typing drain, and retained failure reaction; tests and CI supplement that real behavior proof.
  • proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The accepted live Discord recording demonstrates the visible count lifecycle, concurrent children, channel and thread sources, typing drain, and retained failure reaction; tests and CI supplement that real behavior proof.
Evidence reviewed

PR surface:

Source +1256, Tests +1151, Docs +19, Generated 0. Total +2426 across 32 files.

View PR surface stats
Area Files Added Removed Net
Source 18 1265 9 +1256
Tests 10 1157 6 +1151
Docs 1 19 0 +19
Config 0 0 0 0
Generated 3 24 24 0
Other 0 0 0 0
Total 32 2465 39 +2426

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs src/agents/subagent-registry-lifecycle.test.ts src/agents/sessions-spawn-hooks.test.ts src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.test.ts src/agents/tools/sessions-spawn-tool.test.ts.
  • [P1] node scripts/run-vitest.mjs extensions/discord/src/subagent-hooks.test.ts extensions/discord/src/subagent-progress.test.ts src/agents/subagent-registry.persistence.test.ts src/plugins/wired-hooks-subagent.test.ts.
  • [P1] node --max-old-space-size=8192 --import tsx scripts/generate-plugin-sdk-api-baseline.ts --check.
  • [P1] git diff --check.

What I checked:

  • Blocking lifecycle wait remains: The terminal transition awaits emitSubagentProgressEndedForRun before continuing completion; that call awaits the generic plugin hook even though progress presentation is documented as transient and best-effort. (src/agents/subagent-registry-lifecycle.ts:2187, a89f0bfd5cc2)
  • Hook transitively performs presentation work: emitSubagentProgressEndedHook awaits runSubagentProgress, while the Discord handler owns reaction, typing, keyed-store, cleanup, and retry behavior; plugin or Discord latency therefore remains on the core lifecycle path. (src/agents/subagent-registry-completion.ts:166, a89f0bfd5cc2)
  • Re-review continuity: The previous review raised the same lifecycle-boundary blocker at a686f2e; the only subsequent listed commit refreshes the Plugin SDK baseline, and the final supplied patch still contains the awaited lifecycle call. (src/agents/subagent-registry-lifecycle.ts:2187, a89f0bfd5cc2)
  • Maintainer-backed direction: A maintainer was assigned and authored the nine-commit rewrite, moving the feature to one generic typed event, one opt-in Discord setting, plugin-owned transport policy, durable keyed state, and lazy loading. (extensions/discord/src/subagent-progress.ts:1, a2807c8d612d)
  • Live behavior proof: The PR body and prior completed ClawSweeper cycles record live Discord video proof for count add/replace/remove, concurrent children, channel and thread sources, typing drain, and retained failure feedback. (a89f0bfd5cc2)
  • Additive public surfaces: The patch adds one default-off Discord configuration field and one generic Plugin SDK hook, with schema, generated baseline, documentation, and focused hook-wiring coverage. (src/plugins/hook-types.ts:843, a89f0bfd5cc2)

Likely related people:

  • steipete: Authored the current nine-commit rewrite across Discord progress, core subagent lifecycle, configuration, Plugin SDK hooks, persistence, tests, and generated baselines after being assigned the PR. (role: feature owner and recent rewrite author; confidence: high; commits: a2807c8d612d, e0bab4ea2a09, b3529ca82191; files: extensions/discord/src/subagent-progress.ts, extensions/discord/src/subagent-progress-state.ts, src/agents/subagent-registry-lifecycle.ts)
  • kklouzal: Originated this Discord progress proposal and also contributed the merged yielded-parent lifecycle work, giving relevant history beyond merely opening this PR. (role: original feature contributor and adjacent lifecycle contributor; confidence: medium; commits: 2333bd59dbeb; files: src/agents/agent-lifecycle-parent-state.ts, src/gateway/session-lifecycle-state.ts, ui/src/pages/chat/run-lifecycle.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (40 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-14T02:11:03.464Z sha 1adbf57 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-15T10:12:02.563Z sha 4915ba6 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-16T20:04:43.169Z sha 1f17f21 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T00:06:57.377Z sha 9461f9b :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T09:39:09.603Z sha 697a67d :: needs changes before merge. :: [P1] Bound presentation work outside the subagent lifecycle
  • reviewed 2026-07-17T09:58:32.060Z sha 1da4473 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T10:21:35.033Z sha 5508ba4 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T10:34:22.150Z sha a686f2e :: needs changes before merge. :: [P1] Bound the progress hook outside subagent lifecycle

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 21, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch from abf892f to f48f9f1 Compare June 21, 2026 19:25
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 21, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch 2 times, most recently from f73f56c to 6013499 Compare June 21, 2026 20:24
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. label Jun 21, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch 3 times, most recently from 2038b32 to b608094 Compare June 21, 2026 21:41
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 21, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch 3 times, most recently from 0af41a8 to 6a286e0 Compare June 21, 2026 22:13
@clawsweeper

clawsweeper Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 24, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch from 024fd0a to a1bdc8f Compare June 25, 2026 01:15
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 25, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch 2 times, most recently from d17f593 to 20a11bf Compare June 25, 2026 20:59
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 25, 2026
@kklouzal
kklouzal force-pushed the feature/discord-subagent-progress branch from 20a11bf to 0f0ea76 Compare June 25, 2026 23:04
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: discord Channel integration: discord docs Improvements or additions to documentation feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants