Skip to content

feat(desktop): add Stop button to group chat Activity bar - #94570

Closed
ShonnQ wants to merge 2 commits into
NousResearch:mainfrom
ShonnQ:feat/group-activity-stop-button
Closed

ShonnQ wants to merge 2 commits into
NousResearch:mainfrom
ShonnQ:feat/group-activity-stop-button

Conversation

@ShonnQ

@ShonnQ ShonnQ commented Aug 25, 2026

Copy link
Copy Markdown

Closes #94569

What

Adds a Stop button to the group chat Activity bar in Hermes Desktop:

  • Activity header row: shows ⏹ 停止 while the room is running
  • working activity rows: each working event row gets a stop button beside its timestamp
  • Clicking sends session.interrupt to every member session (requestForBot), then marks the room not-running
  • Hidden when idle

Why

Multi-bot group rooms run long turns with no one-click escape from the room view. Single sessions have stop affordances in the composer; group rooms were the gap. Users reported needing to type '/stop' or wait — a button on the room's own Activity bar is the natural affordance.

Implementation

apps/desktop/src/plugins/hermes-bots/plugin.js only:

  • stopAllBots() helper in GroupChatWorkspace — iterates room.sessions per member, sends session.interrupt, resets running
  • Reuses existing requestForBot, groupMemberKey, updateGroupChat plumbing
  • UI mirrors existing activity-row styling (theme vars, Codicon debug-stop)

Tests

All 556 hermes-bots tests pass.

ShonnQ added 2 commits August 25, 2026 15:58
Interrupt all member sessions of a running group room from the room view:
- Stop button on the Activity header row when the room is running
- Stop button beside each 'working' activity event row
- Sends session.interrupt per member via requestForBot, then marks
  the room not-running; hidden when idle.

Closes NousResearch#94569
Keep the bundled plugin free of hardcoded CJK strings — the rest of
hermes-bots uses English literals (no i18n table in this plugin).

Closes NousResearch#94569
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) labels Aug 25, 2026
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference, author can ignore or act on any point.

This PR adds a Stop button to the group chat Activity bar, allowing users to interrupt all bot sessions in a room with one click. The UI integration is clean — the button appears conditionally on room.running, sits alongside the existing activity toggle, and a second instance is embedded in individual "working" activity events. The use of Promise.allSettled to fire interrupts in parallel without one failure blocking others is a good pattern for fire-and-forget multi-bot operations.

Three concerns:

  1. Always-success notification is misleading (apps/desktop/src/plugins/hermes-bots/plugin.js:12760): stopAllBots uses Promise.allSettled with per-bot catch { } blocks, then unconditionally calls host.notify({ kind: 'success', ... }). If every interrupt failed (network down, sessions expired, etc.), the user sees "Stopped all bot tasks" while nothing was actually stopped. Consider counting settled results: if all rejected, show an error; if some failed, show a partial-success message with the count.

  2. No double-click guard: The Stop button's onClick is () => void stopAllBots() with no disabled state. During the async gap before room.running flips to false, rapid clicks fire duplicate session.interrupt requests to every bot. A simple stopping boolean state flag — set true at the start of stopAllBots and used to disable the button — would prevent redundant interrupt storms.

  3. Per-event Stop button stops ALL bots (plugin.js:12827): The Stop button rendered on individual "working" activity events also calls stopAllBots(), which interrupts every bot in the room. The tooltip says "Stop all bots working on this room" which is technically accurate, but placing it next to a specific bot's activity event creates the expectation that it stops only that bot. Either rename the tooltip to "Stop this bot" and route to a single-bot interrupt, or make it visually clearer that the action is room-wide (e.g., move it to a separate row rather than inline with the event).

teknium1 pushed a commit that referenced this pull request Aug 27, 2026
Salvaged from #94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
teknium1 added a commit that referenced this pull request Aug 27, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the #94570 per-member interrupt spray), and carries no hardcoded
CJK label.
teknium1 pushed a commit that referenced this pull request Aug 27, 2026
Salvaged from #94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
teknium1 added a commit that referenced this pull request Aug 27, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the #94570 per-member interrupt spray), and carries no hardcoded
CJK label.
teknium1 pushed a commit that referenced this pull request Aug 27, 2026
Salvaged from #94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
teknium1 added a commit that referenced this pull request Aug 27, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the #94570 per-member interrupt spray), and carries no hardcoded
CJK label.
@teknium1

Copy link
Copy Markdown
Collaborator

Merged via #96241 (rebase-merge) — your Stop button is on main with your authorship preserved: b00e71d. Thanks @ShonnQ! The salvage rewired the button from per-member interrupts onto a new stopGroupThread primitive (epoch bump + holds + interrupt to the member actually on turn + poll staleness check) so the round loop genuinely halts, and the label now rides the plugin's standard activity-label pattern. Your UI shell and visibility condition are what shipped — the button appears exactly while a round runs. Live-verified: mid-essay Stop interrupted the in-flight member, no further turns ran.

@teknium1 teknium1 closed this Aug 27, 2026
and7777 pushed a commit to and7777/hermes-agent that referenced this pull request Aug 27, 2026
…ch#94570)

Salvaged from NousResearch#94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
and7777 pushed a commit to and7777/hermes-agent that referenced this pull request Aug 27, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the NousResearch#94570 per-member interrupt spray), and carries no hardcoded
CJK label.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…ch#94570)

Salvaged from NousResearch#94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the NousResearch#94570 per-member interrupt spray), and carries no hardcoded
CJK label.
zapabob pushed a commit to zapabob/hermes-agent-windows that referenced this pull request Sep 5, 2026
…ch#94570)

Salvaged from NousResearch#94570 (@ShonnQ): the Activity bar gains a Stop button
while a round is running (room.running), plus an inline Stop on the
expanded 'working' activity row. Rewired from the original per-member
session.interrupt spray onto the stopGroupThread primitive so the round
loop actually stops (epoch bump + holds + on-turn interrupt) instead of
marching to the next member; labels are plain English like the rest of
the plugin's UI strings.

Co-authored-by: Hermes Agent <agent@nousresearch.com>
zapabob pushed a commit to zapabob/hermes-agent-windows that referenced this pull request Sep 5, 2026
…itive

Source-contract tests (the group-room-ux pattern): the workspace renders
the Stop button only while room.running, wires it to stopGroupThread
(not the NousResearch#94570 per-member interrupt spray), and carries no hardcoded
CJK label.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop: group chat Activity bar — add a Stop button to interrupt all bot turns

4 participants