fix: make /busy command available on gateway platforms#18366
Conversation
|
Hi @AxDSan — solid handler that covers both the busy-mid-run dispatch site and the canonical command path. Two suggestions before merge:
Both nice-to-haves rather than blockers — just helpful for getting it green. |
|
tyvm, will surely do so! |
- gateway/run.py: move save_config_value() call before _busy_input_mode mutation to prevent divergent in-memory/on-disk state when persistence fails. Error messages updated to indicate mode was NOT changed. - tests/gateway/test_busy_command.py: smoke tests covering status, queue, steer, interrupt, invalid arg, and state-not-mutated-on-save-failure. Addresses review feedback from Tranquil-Flow on PR NousResearch#18366.
AxDSan
left a comment
There was a problem hiding this comment.
Tier 3 QA — 2 bugs found, both root-caused and fixed (7/7 passing ✓)
Bug 1 (Critical): MessageEvent has no get_text()
gateway/run.py:8671 calls event.get_text() but MessageEvent is a @dataclass with a text field, not a method. The entire codebase uses event.text directly. get_command() exists on MessageEvent but get_text() does not.
Fix: event.get_text() → event.text
Bug 2 (Test Design): Wrong assertions in queue/steer/interrupt tests
The tests create runner.config = None expecting save_config_value to fail. But save_config_value() in cli.py writes directly to ~/.hermes/config.yaml — it never touches runner.config. The function creates missing dirs, so it always succeeds. The assertions expected "unchanged"/"could not" and frozen in-memory mode, but the save succeeds and mode updates correctly.
Fix: Updated assertions to expect success ("set to" + mode changed)
Test Results
- Before: 7/7 FAILED
- After both fixes: 7/7 PASSED ✓
See inline comments for exact line-level changes.
0336633 to
284cf7c
Compare
|
Updated and rebased clean on latest main. Changes from the original:
Green to merge. |
b77b755 to
8f4f5d2
Compare
|
Reviewed #18366 against current Verdict: APPROVE WITH POLISH — no blocker found. What I verified:
The gateway wiring looks right now: One small polish item, not merge-blocking:
display:
suppress_busy_ack: "false"Local probe result: Suggested fix: parse the config value with Other than that, this looks good to merge from my side. Thanks for the clean rebase and the extra tests, @AxDSan. |
Tranquil-Flow
left a comment
There was a problem hiding this comment.
Approved after review against current upstream/main.
Verified clean mergeability, focused and nearby gateway/CLI tests passing, ruff clean, and green GitHub checks on the PR head. The only note I found is non-blocking polish: parse display.suppress_busy_ack with is_truthy_value(..., default=False) so string values like "false" do not become truthy via bool(...).
Looks good to merge from my side.
|
Hey @Tranquil-Flow — just a heads up that the polish item you flagged (parse Confirmed:
The approval was on the prior commit, so I know the status reset. Would appreciate a quick re-approve if the fix looks good. Otherwise this is merge-ready from my side. @alt-glitch @Teknium — if either of you want to pull the trigger, PR is fully green and reviewed. Also worth noting PR #23660 targets the same issue (#18362) but has failing CI (test, e2e, Windows footguns) and no reviews. Ours has been open since May 1 with a clean approval + the polish addressed. |
a74cf13 to
acacb4e
Compare
|
Rebased on main to resolve conflicts. Reopening to trigger fresh mergeability check. |
acacb4e to
f57d6e4
Compare
|
Rebased against latest main, resolved both conflicts (busy_text_mode vs suppress_busy_ack). Reopening for fresh merge check. |
|
Fixed @staticmethod decorator lost during conflict resolution. All 210 failing tests now passing locally. Reopening for fresh CI run. |
6e1f638 to
91dc271
Compare
- gateway/run.py: move save_config_value() call before _busy_input_mode mutation to prevent divergent in-memory/on-disk state when persistence fails. Error messages updated to indicate mode was NOT changed. - tests/gateway/test_busy_command.py: smoke tests covering status, queue, steer, interrupt, invalid arg, and state-not-mutated-on-save-failure. Addresses review feedback from Tranquil-Flow on PR NousResearch#18366.
91dc271 to
190840d
Compare
Removes cli_only=True from /busy CommandDef and adds gateway handler with subcommand dispatch (status/queue/steer/interrupt). Applied on top of latest upstream/main while preserving original commit intent from PR NousResearch#18366. Also adds smoke tests for the gateway /busy command handler.
a7ee98f to
493751a
Compare
|
Rebased onto latest upstream/main. Conflicts resolved:
The upstream already had the _busy_input_mode read infrastructure (load_busy_input_mode, class attribute, dispatch in busy-message handling). This PR closes the loop by adding the gateway-level /busy write handler so users can change mode from any platform. CI spinning up now. |
… 50-cap Making /busy gateway-available (removing cli_only=True) registered it as a native Slack slash command, pushing the total over Slack's 50-cap. debug was the next command alphabetically bumped off the list.
|
Small follow-up, making /busy gateway-available meant it registered as a native Slack slash, which pushed past Slack's 50-command cap. debug got bumped off. Added it to _SLACK_VIA_HERMES_ONLY so it routes through /hermes debug on Slack instead. Same pattern as credits. |
What does this PR do?
Fixes the
/busycommand being unavailable on gateway platforms (Telegram, Discord, etc.) despite onboarding hints telling users they can use it.The
/busycommand was registered inCOMMAND_REGISTRYwithcli_only=True, making it CLI-only. Meanwhile,agent/onboarding.pytells users they can run/busy interrupt,/busy queue,/busy steer, and/busy status-- creating a confusing UX where gateway users receive onboarding hints for non-functional commands.This PR:
cli_only=Truefrom the/busyCommandDefso it registers on all platforms_handle_busy_commandtogateway/run.pywith full subcommand support (status,queue,steer,interrupt)config.yamlusing the same pattern as other gateway toggle commandsEphemeralReplyso responses are only visible to the usertests/gateway/test_busy_command.pycovering all subcommandsThe approach mirrors existing gateway toggle commands (
/yolo,/verbose) -- minimal handler, config persistence, non-interrupting replies.Related Issue
Fixes #18362
Type of Change
Changes Made
hermes_cli/commands.py: Removedcli_only=Truefrom/busyCommandDefgateway/run.py: Added_handle_busy_commandmethod (+60 lines) with subcommand dispatch, config persistence, andEphemeralReplyresponsesgateway/run.py: Added dispatch entries in active-session and non-running command routing pathstests/gateway/test_busy_command.py: New smoke tests (7 tests) covering all subcommands and invalid argsHow to Test
/busyor/busy status-- should show current mode/busy queue-- should set mode to queue and persist/busy steer-- should set mode to steer and persist/busy interrupt-- should set mode to interrupt and persistpytest tests/gateway/test_busy_command.py -v-- all 7 tests passChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) -- or N/Acli-config.yaml.exampleif I added/changed config keys -- or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows -- or N/AFor New Skills
N/A -- not a skill PR
Screenshots / Logs
N/A -- gateway command handler, no visual UI changes