Repository navigation
fix(discord, toolsets): clarify body text, thread auto-archive, plugin toolset warning - #114561
chrisluersen wants to merge 2 commits into
Conversation
|
Re-submits #97374 ( The two Discord fixes in this PR have no upstream PR of their own. |
Related: open #111322 also uses persisted plugin-toolset keys to avoid validation before discovery. This PR additionally repairs the CLI/config call sites and two Discord UX issues, so it is related rather than a duplicate; please consolidate the overlapping validation approach. |
|
Independent verification on the PR head (b5338a5): cli-init plus toolset-validation suites 58/58 green (1 skipped) on Linux. Widening the unknown-toolset predicate with last-launch-recorded plugin keys (instead of paying discovery cost at validation time) is the right trade, and best-effort-empty beats raising on an unavailable layer. No findings. |
SummaryThree independent fixes, one commit each: Discord clarify buttons become bare numbers with the full numbered option list in the message body; gateway-opened threads inherit the parent channel's auto-archive window instead of hardcoded 1440; config-declared plugin toolsets ( What changed
Strengths
Findings
VerdictLooks good to merge. Reviewed using Hermes-Agent |
b5338a5 to
0b47880
Compare
0b47880 to
ff85518
Compare
… default _auto_create_thread and create_handoff_thread both hardcoded auto_archive_duration=1440, contradicting the channel's own default: on a channel set to 10080 (7d) an agent-opened thread dropped out of the sidebar 24h after its last message while a human-opened one in the same channel survived a week. Measured live 2026-09-15: every gateway-opened thread carried dur=1440 while its channel default was 10080. One rule now, derived from the channel, shared by every thread-opening path; an absent or non-conforming channel default still falls back to 1440 so the value is always one Discord accepts. The /thread command's documented 1440 default is left alone — that one is an explicit caller-supplied argument. Invariant test proven red on current main (7 failed / 6 passed), 13 pass with the fix.
… carry numbers Discord draws every button at the same width, so a long clarify choice was cut mid-word on mobile while nothing else in the message carried the option text — the label was the only copy. send_clarify now prints the numbered, full-length choice list above the buttons (embed fields chunked to Discord's 1024-char field cap, budgeted against the ~6000-char embed cap; mirrored into plain content, which never drops the question) and ClarifyChoiceView labels buttons 1..N. Resolution is unchanged: a click round-trips the canonical choice text from the gateway entry, not the label. Matches Telegram and WhatsApp, which already do this. Tests updated: bare-number labels + full text in embed and content.
ff85518 to
c6e098b
Compare
|
Correction to my comment above after one more direct probe: I read
and that very process still printed The stronger live finding still stands: That points instead to the startup validation path reading the wrong profile scope/cache/manager (or otherwise not consulting the same profile-scoped key set), rather than simply failing to persist discovery. I am isolating that separately. |
Three independent fixes, one commit each. A closed PR is re-opened here with a corrected shape —
see fix 3.
1. Discord: clarify choices rendered in the message body, buttons carry numbers
send_clarifyput the whole option text in the button label. Discord draws every button at thesame width, so a long choice is cut mid-word on mobile — and nothing else in the message carried
the option text: the (truncated) label was the only copy. Telegram and WhatsApp already print the
numbered list above the buttons.
Now the buttons are bare numbers
1..Nand the full numbered list prints in the embed (fieldschunked at Discord's 1024-char field cap, budgeted against the ~6000-char embed cap) and in
plain content — embeds are invisible/detached on some clients, and the question is never the part
that gets dropped. Resolution is unchanged: a click round-trips the canonical choice text from the
gateway entry, not the label.
tests/gateway/test_discord_clarify_buttons.py— proven red onmain(3 failed / 4 passed;the exact failure is
assert ['1. real choice'] == ['1']), 7/7 green with the fix.2. Discord: threads Hermes opens inherit the channel's auto-archive default
_auto_create_threadandcreate_handoff_threadboth hardcodedauto_archive_duration=1440,contradicting the parent channel's own default. On a channel set to
10080(7 d), a thread theagent opened dropped out of the sidebar 24 h after its last message while a thread a human opened
in the same channel survived a week — two lifetimes for identical content. Measured live
2026-09-15: every gateway-opened thread carried
dur=1440while its channel default was10080.One rule now, derived from the channel, shared by both thread-opening paths. An absent or
non-conforming channel default still falls back to 1440, so the value passed to
create_threadisalways one Discord accepts. The
/threadcommand's documented 1440 default is untouched — that isan explicit caller-supplied argument.
tests/gateway/test_discord_auto_thread_archive.py(new) — proven red onmain(7 failed / 6 passed), 13/13 green with the fix. The assertions are relationships between the
channel default and the duration passed to
create_thread, not snapshots.3. Toolsets: config-declared plugin toolsets no longer reported as "unknown"
Plugin toolsets (
a2a,eikon,buzz, …) enter the tool registry only when plugins arediscovered — later than both config-migration validation (
hermes_cli/config.py) and CLIconstruction (
cli.py::_init_toolsets). Both call sites validated against the registry alone, soevery startup warned
Unknown toolsets: a2a, buzz, eikonabout a toolset the user was explicitlyoffered by
hermes tools.This re-submits #97374, which was closed on 2026-09-09 without merging. The bug still reproduces
on current
main(0a8d4caef4), and it is notimplemented_on_mainorcannot_reproduce:The previous shape called
discover_plugins()from the config path. Measured cold, that costs~870 ms of startup for a warning — exactly the cost the CLI's deliberate "argparse setup skips
discovery (~500 ms)" rule exists to avoid — so this version never discovers plugins at all:
hermes_cli/plugins.py::get_plugin_toolset_keys_cached()— the live registry when it is alreadypopulated, otherwise the keys the previous launch recorded (
cache/plugin_toolset_keys.json,already written on every discovery). Never blocks, never discovers.
hermes_cli/toolset_validation.py::known_plugin_toolset_keys()/with_plugin_toolsets()—the latter widens the injected validity predicate, so
validate_platform_toolsetskeeps itspure-predicate contract.
Both are probed only after a name has actually been rejected, so a config that validates clean
pays nothing:
The set is advisory and self-healing by construction: it is only ever used to EXCLUDE names from a
warning, so a stale-too-small set can make a later run warn, never the reverse.
Tests (each proven red on
main):tests/hermes_cli/test_toolset_validation.py(
test_declared_plugin_toolset_is_not_reported_unknown— asserts the premisenot validate_toolset("a2a")before asserting no warning) andtests/hermes_cli/test_cli_init.py(test_plugin_toolset_not_warned, which fails onmainwithWarning: Unknown toolsets: a2a, buzz, eikon), plus the guard that a genuinely unknown name stillwarns.
Test receipts
All runs via
scripts/run_tests.shagainst a clone oforigin/main0a8d4caef4:tests/gateway/test_discord_clarify_buttons.pytests/gateway/test_discord_auto_thread_archive.pytests/hermes_cli/test_toolset_validation.pytests/hermes_cli/test_cli_init.py(new class)test_tools_config,test_commands,test_cli_tools_command,test_config_validation,test_setup_blank_slate,test_plugin_config_state_bridge,test_completer_config_reads,gateway/test_api_server_toolset)Could not verify
tests/hermes_cli/test_cli_init.py::TestPromptToolkitTerminalCompatibilityhas 2 pre-existingfailures on this Windows host (
test_cpr_gating_posix_suppresses_without_ssh,test_lf_enter_binding_respects_multiline_shortcuts— the POSIX arm asserts on a Windowsconsole). They fail identically with and without these commits and are untouched here.
the thread auto-archive default was measured live on 2026-09-15 (recorded in the commit message)
rather than re-measured for this PR.
cache/plugin_toolset_keys.jsonand a hand-written plugin toolsetin
platform_toolsetscan still warn once; it self-heals on the next launch. Closing that holeneeds discovery, which is the ~870 ms this change deliberately avoids.