Skip to content

feat(bot-mode): keep multi-gateway rooms running without Desktop - #95967

Closed
dokterdok wants to merge 33 commits into
NousResearch:mainfrom
dokterdok:wip/95163-roomlink-desktop
Closed

dokterdok wants to merge 33 commits into
NousResearch:mainfrom
dokterdok:wip/95163-roomlink-desktop

Conversation

@dokterdok

@dokterdok dokterdok commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Bot group chats should feel the same whether their Bots live on one gateway or
several. Today a cross-gateway room stops when Desktop closes because the
renderer is the relay and coordinator.

This stacked draft makes the green path automatic:

  1. Pick Bots and create a group.
  2. Hermes checks their gateways and chooses the strongest available continuity
    mode.
  3. The room keeps working after Desktop closes when the gateways support it.
  4. Reopening Desktop replays the same ordered room history without duplicate
    turns.

Technical transport choices stay under Advanced. Unsupported or older
gateways keep the current Desktop-driven behavior.

Continuity modes

Hermes chooses between autonomous multi-gateway, one-gateway, and Desktop relay room continuity

User experience

  • Same-gateway Bots continue on that gateway.
  • Cross-gateway Bots use scoped RoomLink when every peer qualifies.
  • Missing setup explains the exact gateway.room_link_url action under
    Advanced; it does not leak routing jargon into the normal flow.
  • Sends progress through Sending, Queued until the gateway reconnects, and
    Working instead of claiming work is active while offline.
  • Keeps the queued state singular: the room header explains the wait and the
    thread does not simultaneously claim that work is running.
  • Reconnect consumes authoritative replay and clears optimistic pending entries
    without duplication.
  • Named Bots route through their target-issued profile path instead of silently
    falling back to the gateway's default Bot.
  • Repeated polls collapse legacy identity-free display rows into the matching
    authoritative event. A polluted local cache repairs itself on refresh.
  • Folded thread counts include visible messages only, not internal driver
    settlement events.
  • Approvals identify the exact Bot and offer Allow once or Deny.
  • Stop remains visible until the target run is terminal; disband stays blocked
    while work is still stopping.
  • Retry warns that uncertain side effects may repeat.
  • Cross-gateway file drop/paste/picker affordances are disabled before the user
    can stage bytes; same-gateway file sharing remains available.

Recovery and compatibility

  • Every create-time rollback operation is persisted before network mutation.
    A renderer crash resumes disband/revocation from the exact checklist.
  • Room removal requires an authenticated tombstone. Absence from a list is not
    deletion.
  • External rename collisions preserve both rooms with a stable local label.
  • Outbox storage failure prevents dispatch rather than losing a command.
  • Old gateways are re-probed periodically and stay Desktop-driven.
  • One malformed stored peer route cannot hide healthy routes.

Validation

Rebased on verified boundary origin/main@f3cbb262c1, exact complete head
a6875fa727:

Check Result
Focused RoomLink Python boundary after the final rebase 331 passed
Complete bundled Bot Mode plugin suite 674 passed
Desktop typecheck and production build passed
Contributor attribution audit and git diff --check passed
Two-host restart/Stop/revoke UAT passed
Exact-head CI on a6875fa727 running after the final rebase
Earlier official per-file full test runner 39,220 passed; 23 host-dependent failures in 14 files

The changed-file Python run has one local-environment failure in
tests/gateway/test_api_server.py: its detailed-health expectation fails
identically on untouched origin/main because this Mac links SQLite 3.50.4 and
Hermes correctly reports degraded WAL safety. No hosted-room, peer-run,
RoomLink, or Bot Mode assertion failed in that run.

The official full runner completed all 3,325 test files. Its remaining failures
are local CUA, SQLite, UNIX-socket/path, Linux/WSL/voice-tool, and checkout-path
preconditions. The only two failing files that intersect this stack are
tests/gateway/test_api_server.py and tests/tools/test_bot_mode_dm.py; both
fail identically on untouched origin/main under the same host conditions.

The isolated canaries covered Desktop-driven compatibility, two Bots on one
gateway, two gateways on one host/network, and two gateways on separate hosts.
The two-host receipt was:

UAT_OK remote_reply=1 restart_recovered=1 stop_acknowledged=1 target_terminal=1 scoped_route_revoked=1

A final real-gateway UAT then created a fresh room with one named Bot on each of
two separately hosted gateways. Both Bots replied. A second turn deliberately
kept both Bots busy while the Desktop process was terminated immediately: the
home gateway still reported running work after the exit, all tasks settled
without Desktop, and a fresh Desktop process replayed both replies plus the
prior ordered threads. The run also found and fixed named-profile routing,
container DNS, actionable setup copy, repeated replay echoes, and inflated
thread counts before this head was published. Production names, URLs, and
conversation content are intentionally omitted here.

Screenshots use the actual built app with synthetic Bot and gateway names. The
full-screen light and dark captures show a normal exchange; a focused offline
capture shows the queued recovery state; Advanced shows the explicit setup
surface. No production names, URLs, credentials, or conversations are shown.

Screenshots

Normal multi-gateway room

A two-gateway Bot room continuing from one ordered conversation

Dark mode

The same multi-gateway Bot room in dark mode

Peer offline: work stays queued

A room preserving work until an unavailable gateway reconnects

Advanced continuity setup

Advanced room continuity setup with the normal green path kept simple

Related work

Type of change

  • Bug fix
  • New feature
  • Security fix
  • Documentation update
  • Tests
  • Refactor

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have needs-decision Awaiting maintainer decision before any implementation comp/desktop Electron desktop app (apps/desktop/*) comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard comp/tui Terminal UI (ui-tui/ + tui_gateway/) area/profiles Multi-profile isolation, HERMES_HOME scoping sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 27, 2026
@dokterdok
dokterdok force-pushed the wip/95163-roomlink-desktop branch 3 times, most recently from 5061197 to c25509e Compare August 27, 2026 07:01
@dokterdok dokterdok changed the title feat(desktop): keep multi-gateway Bot rooms running without Desktop feat(bot-mode): keep multi-gateway rooms running without Desktop Aug 27, 2026
@dokterdok
dokterdok force-pushed the wip/95163-roomlink-desktop branch 5 times, most recently from 9c4bb7e to c50227a Compare August 27, 2026 11:16
@dokterdok
dokterdok force-pushed the wip/95163-roomlink-desktop branch from c50227a to f692068 Compare August 27, 2026 16:33
@Enough1122

Copy link
Copy Markdown
Contributor

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

This diff is too large for an automated line-level review (>30 files or >200KB). Recommend a manual review.

@dokterdok

Copy link
Copy Markdown
Contributor Author

Closing this cumulative prototype now that #97681 captures the user contract, safety boundaries, and phased landing plan against the rebuilt Bot Mode tree. Its useful layer can be re-cut as a narrow current-main contribution after the foundation direction is agreed.

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

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/cli CLI entry point, hermes_cli/, setup wizard comp/desktop Electron desktop app (apps/desktop/*) comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants