Repository navigation
Add opt-in "Extended rounds" for Bot Mode group-chat rooms - #1
Merged
RFingAdam merged 2 commits intoAug 23, 2026
Conversation
…ake live-tunable
Upstream's Bot Mode group-chat room loop hard-caps at GROUP_CHAT_MAX_ROUNDS=3
and GROUP_CHAT_MAX_MESSAGES=10 per user send. That's tuned for a quick
multi-bot exchange, not letting a room of specialist bots (Ironhaven Exec,
Engineering Ops, Bounty Ops, etc.) actually work a problem turn-over-turn
until it settles -- our real usage keeps hitting the ceiling mid-task with
work still in flight, forcing a manual re-send to get another 3 rounds.
Changes:
- GROUP_CHAT_MAX_ROUNDS 3 -> 24, GROUP_CHAT_MAX_MESSAGES 10 -> 120 (both
now `let`, not `const`).
- New applyGroupChatSettings(value) + getGroupChatCeilings(): both
ceilings are live-tunable via ctx.storage('group-chat-settings') =
{ maxRounds, maxMessages }, clamped to sane bounds (1-500 rounds,
1-2000 messages) and silently ignoring malformed/out-of-range input --
a bad stored value can never brick the room loop. Hydrated at plugin
registration alongside the existing bot-meta/activity-toasts/
group-chats storage reads.
- No settings-panel UI wired yet (this plugin SDK version has no generic
settings-panel registration area to hook into) -- tuning today means
writing directly to ctx.storage, not a toggle in the Bots pane. A
proper settings UI is a natural follow-up, not required for the
ceiling raise itself to take effect.
Deliberately did NOT touch the anti-cascade design: the "everyone passed
this round" settle exit is unchanged and remains the real safety valve
against a runaway/looping room -- a genuinely stuck room still stops
within one round regardless of how high these ceilings go. This raises
how long a room is ALLOWED to keep working, not how long it's forced to.
Tests: 5 new regression tests (raised-defaults sanity, settings-override
accept/clamp/malformed-input, and an end-to-end enforcement check that a
tuned-down cap actually stops the loop) plus the existing hard-caps test
updated to read the live ceiling via getGroupChatCeilings() instead of
the now-mutable constant. Full hermes-bots plugin suite: 241/241 passing.
Not changed: the gateway-side per-platform require_mention gate (Discord/
Telegram/etc adapters) that Adam's actual production group chats run on --
that's a different, per-message mention-gate mechanism, not a round-count
ceiling, and is out of scope for this change. Tracked as a likely
follow-up once this round-cap raise is proven out in the desktop rooms.
…lt change
Redesigned the previous commit's approach per Adam's direction: upstream's
stock behavior (3 rounds / 10 messages, no wall-clock cap) stays the
untouched DEFAULT for every install -- a fresh clone of this fork behaves
byte-identically to NousResearch's hermes-agent until a user explicitly
opts in. Longer-running multi-bot rooms (what our Ironhaven Exec /
Engineering Ops / Bounty Ops / General Workbots setups actually need) are
now a deliberate, protected opt-in, not the blanket global raise the prior
commit shipped.
Design:
- GROUP_CHAT_STOCK_MAX_ROUNDS=3 / GROUP_CHAT_STOCK_MAX_MESSAGES=10: exact
upstream constants, always available regardless of the toggle.
- GROUP_CHAT_EXTENDED_MAX_ROUNDS=24 / _MAX_MESSAGES=120 /
_WALL_CLOCK_MS=30min: only take effect once a user flips "Extended
rounds" on (persisted via ctx.storage('group-chat-extended-mode'),
default false). Flipping it back off always restores exact stock
behavior -- no override can leak through.
- New protection extended mode has that stock never had: an independent
wall-clock deadline on the whole room-turn drive. The existing "everyone
passed this round" settle exit is conversation-shaped (only fires when
literally every member passes/times out) -- running many more rounds
widens the exposure window if a member ever gets stuck producing
real-looking, non-settling text every turn. The wall-clock cap bounds
worst-case cost/duration independent of whether that heuristic ever
fires.
- Optional fine-tuning via ctx.storage('group-chat-extended-override') =
{ maxRounds, maxMessages, wallClockMinutes | wallClockMs }, hard-clamped
(rounds 1-100, messages 1-500, wall-clock 1s-2h) with per-field
rejection (not silent clamping to a boundary) of anything out of range
or malformed -- a bad stored value can never brick the loop or escape
the safe ranges. An override only has any effect while extended mode is
actually on.
- New UI toggle in the Bots pane header (stopwatch icon, next to the
activity-toast bell) makes this a real discoverable setting, not
storage-only.
$groupChatExtendedMode's atom() call is deliberately declared up near
$activityToasts rather than down in the group-chat section, because
soul-protocol-backfill.test.mjs vm-evals a fixed line-range slice of this
file (botHandle .. the human-readable-row-helpers marker) with no `atom`
in scope -- keeping every top-level atom() call above that slice avoids
breaking it. Documented inline at both the declaration and the removed
site.
This is a forward-only fix commit on top of the previous one (never
force-pushed/rewrote it) -- see hard rule 3 in github-rfingadam-pr: no
history rewrite even on our own fork's own feature branch.
Tests: rewrote the fork-specific regression tests to match the new
stock-default/opt-in design (default-is-stock, toggle-raises-and-restores,
override-clamps-per-field-both-directions, a real end-to-end enforcement
test that a tuned-down extended cap stops the loop, a real end-to-end test
that the wall-clock deadline ends a non-settling drive early via genuine
setTimeout-based turn latency, and a test proving stock mode ignores a
staged extended-mode override entirely). Fixed the test harness's
prompt.submit mock to await turnScript (previously synchronous-only,
which silently no-op'd on an async turnScript). Full hermes-bots plugin
suite: 244/244 passing (`node --test src/plugins/hermes-bots/tests/*.test.mjs`).
Secret scan clean.
Owner
Author
|
Post-merge verification — workstation (swamp) desktop rollout Repointed this workstation's checkout (
One UX/docs note worth surfacing: in rooms with 5 bots the message cap (10), not the round cap (3), is the effective wall — it bites after 2 rounds. A user reads "3 max" in the tooltip but sees the drive stop at 2 rounds / 10 messages. Might be worth wording the stock tooltip around messages, or scaling the message cap with roster size. Extended's 120 makes this a non-issue there. Rollout follow-ups (not this PR):
|
This was referenced Aug 23, 2026
RFingAdam
added a commit
that referenced
this pull request
Aug 26, 2026
Bot Mode's group-chat room loop (`apps/desktop/src/plugins/hermes-bots/plugin.js`) gets an opt-in **"Extended rounds"** setting:
- **Default (OFF): exact upstream stock behavior** — 3 rounds / 10 messages / no wall-clock cap. A fresh install of this fork is byte-identical to `NousResearch/hermes-agent` until a user explicitly opts in.
- **ON: raised ceilings + a new protection** — 24 rounds / 120 messages, plus a 30-minute wall-clock cap that stock never had.
- New UI toggle in the Bots pane header (stopwatch icon, next to the activity-toast bell).
- Both the toggle and an optional fine-tune override (`{ maxRounds, maxMessages, wallClockMinutes }`, hard-clamped, malformed/out-of-range input rejected per-field) persist via plugin storage.
The first commit on this branch just raised the shipped defaults globally. Adam's direction was better: keep Nous's own behavior as the untouched default, and make "run longer" an explicit, protected opt-in — so this fork never silently diverges from upstream for anyone who doesn't ask for it, and the extended path gets its own independent safety net rather than just bigger numbers.
- Flipping extended mode off always restores exact stock constants — no override can leak through.
- The wall-clock cap is new and independent of the existing "everyone passed this round" settle exit, which is conversation-shaped (only fires when literally every member passes/times out). Extended mode's much higher round ceiling widens the exposure window if a member ever got stuck producing real-looking, non-settling text every turn — the wall-clock deadline bounds worst-case cost/duration regardless of whether that heuristic ever fires.
- Override values are clamped to hard ranges (rounds 1-100, messages 1-500, wall-clock 1s-2h) and rejected (not silently clamped to a boundary) when out of range or malformed.
- Rewrote the fork's regression tests for the new design: default-is-stock, toggle raises/restores correctly, override clamps per-field in both directions, an end-to-end test that a tuned-down extended cap actually stops the loop, an end-to-end test that the wall-clock deadline ends a non-settling drive early via real `setTimeout`-based turn latency, and a test proving stock mode ignores a staged extended-mode override entirely.
- Fixed the test harness's `prompt.submit` mock to `await turnScript` (previously sync-only, silently no-op'd on an async turnScript — needed for the real-latency wall-clock test).
- Full `hermes-bots` plugin suite: **244/244 passing** (`node --test src/plugins/hermes-bots/tests/*.test.mjs`).
- Secret scan clean on both changed files.
Targets our fork's own working branch (`feat/kanban-completion-guards-and-oauth-sanitize`, which carries pre-existing local kanban/OAuth patches), not `NousResearch/hermes-agent` upstream `main` — this is a fork-local feature we're managing ourselves, not (yet) proposed upstream.
The gateway-side per-platform `require_mention` mention-gate (Discord/Telegram/etc adapters) that production group chats actually run on is a different mechanism (per-message gating, not a round-count ceiling) and isn't touched by this PR.
(cherry picked from commit 791fc66)
RFingAdam
added a commit
that referenced
this pull request
Aug 26, 2026
…esets Replace the install-wide stock/extended ceiling toggle as the only governor with optional per-room modes that override it when set. Unset rooms keep exact prior global-toggle behavior (zero regression). - rooms[name].mode: 'build' | 'decide' | 'standing' | unset - Message budget scales as messagesPerMemberPerRound * members * rounds (fixes the PR #1 5-bot stock bug where a flat 10-msg cap died at round 2) - decide: chat-only prompt rule + deterministic system summary on hard cap - build: long ceilings, tool-capable (prompt does not restrict tools) - standing: moderate multi-trigger coordination ceilings - Room-header dropdown to set/clear mode (persists on the room record) Kanban: t_ee2e6fe4 (cherry picked from commit e212071)
RFingAdam
added a commit
that referenced
this pull request
Aug 26, 2026
…esets (#2) * feat(desktop/hermes-bots): per-room build/decide/standing Bot Mode presets Replace the install-wide stock/extended ceiling toggle as the only governor with optional per-room modes that override it when set. Unset rooms keep exact prior global-toggle behavior (zero regression). - rooms[name].mode: 'build' | 'decide' | 'standing' | unset - Message budget scales as messagesPerMemberPerRound * members * rounds (fixes the PR #1 5-bot stock bug where a flat 10-msg cap died at round 2) - decide: chat-only prompt rule + deterministic system summary on hard cap - build: long ceilings, tool-capable (prompt does not restrict tools) - standing: moderate multi-trigger coordination ceilings - Room-header dropdown to set/clear mode (persists on the room record) Kanban: t_ee2e6fe4 * ci: retrigger checks (never ran on this PR)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Bot Mode's group-chat room loop (
apps/desktop/src/plugins/hermes-bots/plugin.js) gets an opt-in "Extended rounds" setting:NousResearch/hermes-agentuntil a user explicitly opts in.{ maxRounds, maxMessages, wallClockMinutes }, hard-clamped, malformed/out-of-range input rejected per-field) persist via plugin storage.Why the redesign (this supersedes the first commit on this branch)
The first commit on this branch just raised the shipped defaults globally. Adam's direction was better: keep Nous's own behavior as the untouched default, and make "run longer" an explicit, protected opt-in — so this fork never silently diverges from upstream for anyone who doesn't ask for it, and the extended path gets its own independent safety net rather than just bigger numbers.
Safety
Testing
setTimeout-based turn latency, and a test proving stock mode ignores a staged extended-mode override entirely.prompt.submitmock toawait turnScript(previously sync-only, silently no-op'd on an async turnScript — needed for the real-latency wall-clock test).hermes-botsplugin suite: 244/244 passing (node --test src/plugins/hermes-bots/tests/*.test.mjs).Scope note
Targets our fork's own working branch (
feat/kanban-completion-guards-and-oauth-sanitize, which carries pre-existing local kanban/OAuth patches), notNousResearch/hermes-agentupstreammain— this is a fork-local feature we're managing ourselves, not (yet) proposed upstream.Not in scope here
The gateway-side per-platform
require_mentionmention-gate (Discord/Telegram/etc adapters) that production group chats actually run on is a different mechanism (per-message gating, not a round-count ceiling) and isn't touched by this PR.