Skip to content

feat(gateway): auto-delete Discord tool progress bubbles - #26055

Closed
nazirulhafiy wants to merge 13 commits into
NousResearch:mainfrom
nazirulhafiy:feat/delete-progress-bubble-clean
Closed

nazirulhafiy wants to merge 13 commits into
NousResearch:mainfrom
nazirulhafiy:feat/delete-progress-bubble-clean

Conversation

@nazirulhafiy

@nazirulhafiy nazirulhafiy commented May 15, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR makes Hermes clean up Discord tool progress bubbles after they are no longer useful.

Hermes can show little “I’m working on it” messages while tools run:

  • 💻 terminal command running
  • 🐍 code executing
  • 📖 file being read
  • 🔍 search in progress
  • 🌐 web page loading

Those bubbles are helpful while Hermes is working.

But once the final answer is delivered, they should not hang around forever like abandoned scaffolding.

This PR makes them disappear automatically after successful runs, while still preserving useful breadcrumbs when something fails.


Problem

Hermes already had progress bubbles, and Discord already had the ability to delete messages.

The missing piece was the cleanup path.

In practice, this could happen:

  1. Hermes starts using a tool
  2. Discord shows a progress bubble
  3. Hermes finishes the task
  4. The final answer appears
  5. The old progress bubble sometimes stays behind

For users, this makes Discord channels feel noisy and stale.

For maintainers, the confusing part was that the config setting looked correct:

display.auto_delete_tool_progress: true

…but the gateway was not always tracking enough cleanup state to actually delete the bubbles later.


Solution

This PR wires progress cleanup to the setting users expect:

display.auto_delete_tool_progress: true

When enabled:

  • ✅ progress bubbles appear while tools are running
  • ✅ successful runs clean up their progress bubbles
  • ✅ cleanup can survive a gateway restart
  • ✅ Discord deletion uses the adapter’s delete_message() capability
  • ✅ failed runs can keep breadcrumbs visible for debugging
  • ✅ setting auto_delete_tool_progress: false preserves the old behavior

In plain English:

Hermes can show her work while she’s working, then tidy the desk when she’s done.


Technical details

This PR updates the gateway progress lifecycle so that:

  • display.auto_delete_tool_progress enables cleanup tracking directly
  • pending cleanup state is persisted for restart recovery
  • final cleanup paths delete progress bubbles only when appropriate
  • failed runs can keep visible traces instead of deleting potentially useful debugging context

Key behavior change:

auto_delete_tool_progress = true

now means both:

  1. show progress bubbles while tools run
  2. track them so they can actually be deleted later

Previously, those two parts could drift apart.


User-facing behavior

Successful run

💻 Tool bubble appears
✅ Hermes finishes
🧹 Tool bubble disappears

Gateway restart with pending bubbles

💻 Bubble was still pending
🔁 Gateway restarts
🧹 Startup cleanup drains stale bubbles

Failed run

💻 Bubble appears
❌ Run fails
🧭 Breadcrumb can remain for debugging

Files changed

File Change
gateway/platforms/discord.py Adds Discord message deletion support
gateway/run.py Tracks and cleans up tool progress bubbles
tests/gateway/test_progress_auto_delete.py Adds component coverage for progress auto-delete
tests/gateway/test_run_cleanup_progress.py Adds/updates gateway cleanup path coverage

Testing

Ran targeted gateway tests:

pytest tests/gateway/test_progress_auto_delete.py       tests/gateway/test_run_cleanup_progress.py -q

Result:

16 passed

Also manually verified locally:

  • gateway restarted successfully
  • startup cleanup drained stale progress bubbles
  • successful tool runs no longer leave stale Discord progress bubbles behind

Breaking changes

None.

The feature is controlled by:

display.auto_delete_tool_progress

Default behavior is auto-delete enabled.

Users who prefer the old “leave progress bubbles visible” behavior can set:

display.auto_delete_tool_progress: false

Reviewer note

This PR overlaps with earlier progress cleanup work, but the current branch fixes the practical config-path gap:

display.auto_delete_tool_progress now actually causes progress bubbles to be tracked and cleaned up reliably.

So the goal is not just “Discord can delete messages.”

The goal is:

Hermes should be visibly busy while working, then clean up after herself when the work is done — not leave a raccoon trail of stale terminal bubbles across Discord.

@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery platform/discord Discord bot adapter P3 Low — cosmetic, nice to have labels May 15, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

Duplicate of #18306 (same feature, same approach). Also overlaps with #21890 which adds delete_message support. Note that #21186 (opt-in cleanup of progress bubbles) is already merged — this PR may be partially redundant.

Adds delete_message() to the Discord adapter and wires it into both
__reset__ handlers in the progress message loop, plus the final edit
drain path. When a content bubble lands after a tool batch, the
progress bubble (🔧, 📖, 💻) is now deleted instead of left orphaned
in the channel, reducing chat clutter.

- gateway/platforms/discord.py: new delete_message() method
- gateway/run.py: delete in normal __reset__, CancelledError drain,
  and final-edit path — with capability gate via
  'type(adapter).delete_message is not BasePlatformAdapter.delete_message'
…o-delete

- Final-drain path (3rd location) now logs delete attempts and errors,
  matching the __reset__ handlers — so lingering bubbles are diagnosable.
- Adds config key `display.auto_delete_tool_progress` (default: true).
  Set to `false` in config.yaml to disable progress bubble auto-deletion.
- All three delete locations respect the toggle.
…eanup

Bug: The __reset__ delete handler gated deletion on can_edit,
which flips to False on any edit failure (e.g. Discord 429 rate
limit on rapid tool calls). Once can_edit went False, every
subsequent progress bubble became permanent.

Fix:
- Add can_delete flag alongside can_edit
- Use can_delete in the __reset__ delete gate instead of can_edit
- Track can_delete = False only when delete_message() actually
  fails, not when edit fails
- Apply same failure tracking to CancelledError drain and final
  drain delete paths

This ensures Discord rate-limiting an edit mid-session no longer
disables progress bubble deletion.
…o-delete

Adds 8 tests covering:
- Capability check: overridden vs base adapter delete_message detection
- Adapter behavior: success, failure, and multiple sequential calls
- Config resolution: auto_delete_tool_progress default, explicit off,
  and per-platform overrides via display_config

Pragmatic approach: tests verify the component pieces directly
(capability checks, adapter contract, config resolver) rather than
requiring a full _run_agent integration test, since the delete code
path requires an active Discord adapter + live agent loop that doesn't
map cleanly to the mock-based test harness.

Part of PR #18306.
…nterrupt

Bug: When the agent finishes normally (not interrupted/cancelled),
_run_still_current() returned False and send_progress_messages()
exited via early return at the top of the main loop body. This
bypassed the CancelledError handler where the delete calls live,
so tool progress bubbles (e.g. ⏰ cronjob) lingered permanently
in Discord.

Fix: Added delete logic at the early-return site (normal completion)
matching the existing pattern in the CancelledError drain handler.
All three exit paths now clean up: normal completion, __reset__
drain, and final-drain.

Part of PR #18306.
- Add delete to first _run_still_current() check (race: run completes
  before __reset__ signal arrives). Tagged (run-completed).
- Move __reset__ delete outside can_edit gate (Discord supports
  delete even when edit fails). Fixes nested-gate bug May 2026.
- Add pending_progress_cleanup.json queue at ~/.hermes/gateway/
- Record (platform, chat_id, message_id) on bubble creation
- Clear record on successful delete (4 existing paths + startup drain)
- Retry failed deletes up to 5 attempts
- GatewayRunner.start() drains stale records after adapter connect
- Add TestPersistedProgressCleanup (3 tests: round-trip, startup success,
  startup failure retries)

Extends PR #18306 (auto-delete tool progress bubbles).
…w() with timezone-aware alternative; B2: unify auto_delete_tool_progress config source via resolve_display_setting
austinpickett

This comment was marked as duplicate.

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use .github/PULL_REQUEST_TEMPLATE.md and fix merge conflicts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/discord Discord bot adapter type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants