Repository navigation
fix(cli): don't warn on plugin toolsets at startup; accept them in subagent lifecycle - #89345
adamkrawczyk wants to merge 1 commit into
Conversation
…bagent lifecycle HermesCLI.__init__ validates configured platform toolsets before background plugin discovery has landed plugin-registered toolsets in the live tool registry, so every plugin toolset saved via 'hermes tools' false-flags as 'Unknown toolsets' on startup. MCP server names already had an exclusion at the same call site for the same reason. - cli.py: also exclude names returned by get_plugin_toolset_keys_nowait() (live registry keys, or the persisted key set from the previous launch's discovery sweep while background discovery is in flight). Genuinely unknown names still warn. - agent/subagent_lifecycle.py: _validate_request compared allowed_toolsets against the static TOOLSETS table only, hard-failing delegate_task requests naming a plugin-registered toolset even when the parent legitimately runs with it enabled. Use validate_toolset() instead, which includes plugin-registered toolsets and registry aliases. Fixes NousResearch#71650 Fixes NousResearch#86231
Full-suite verification: zero regressions (A/B against pristine main)Ran Result: 23/24 byte-identical, 0 regressed, 1 improved.
The 6 "collection error" files were pure parallel-run resource contention (load avg 31 on a 12-core box) — all pass cleanly when run individually on both trees: Pre-existing failures on pristine main, reproduced identically here (env-dependent — Daytona/Modal/fal/media gateways need credentials or network): Notably Phase-1 xdist run on this branch: 4974 passed, 149 skipped, 2 failed ( Targeted suites covering the changed code paths, all green on this branch: |
|
Live confirmation from a Hermes v0.21.1 deployment: A2A was configured and runtime-healthy, but startup still emitted the false |
|
Cross-linking, in case it helps move this along: the I re-landed the startup fix against current One data point on impact, since the issue is about warnings: they are written to the console, so they reach the stdout of |
|
Thanks @adamkrawczyk — credited as the earliest fix; the landed change is #116425, which you co-authored. Superseded by #118841 (merge 74f726c), which credits this PR. Closing. |
What does this PR do?
Fixes the false-positive
Warning: Unknown toolsets: ...spam on everyhermes/hermes chatstart for users who enabled plugin toolsets viahermes tools.Root cause (two sites, one bug class):
HermesCLI.__init__validates configured platform toolsets before background plugin discovery has landed plugin-registered toolsets in the live tool registry (startup launches discovery in a daemon thread; validation doesn't wait). MCP server names already had an exclusion at this exact call site for the same reason — plugin toolsets were missed. Live repro on current main:hermes chat -Q --max-turns 1 -q …warnsUnknown toolsets: a2a, evey_autonomy, …while the plugin toolsets are real and load moments later.agent/subagent_lifecycle.py: _validate_requestcomparesallowed_toolsetsagainst the staticTOOLSETStable only — so adelegate_taskrequest naming a plugin-registered toolset (even one the parent legitimately runs with enabled) hard-fails withUnknown toolsets: ….Fix:
cli.py: extend the existing MCP-name exclusion withget_plugin_toolset_keys_nowait()— live registry keys when discovery finished, the persisted key set from the previous launch (cache file already written by_persist_plugin_toolset_keys()) while background discovery is in flight. Non-blocking (no startup latency), race-free on steady state, self-healing on first launch after a plugin is added (worst case one transitional warning).subagent_lifecycle.py: usevalidate_toolset()(static table + plugin toolsets + registry aliases) instead of static-table membership.Genuinely unknown names still warn / still raise — the guard stays real.
Related Issue
Fixes #71650
Fixes #86231
Related: #78102 (same false-positive class for MCP names in platform lists), #52382 (stale toolset names never pruned — orthogonal, config migration), #29532.
Related PRs: #84499 (awaits discovery before warning — correct but adds startup blocking and large concurrency surface), #88003 (excludes only names listed in
known_plugin_toolsetsconfig — misses plugin toolsets a user hasn't saved viahermes toolsyet, and names from plugins disabled in config), #25714 (superseded). This PR is the minimal, non-blocking variant using infrastructure that already exists on main.Type of Change
Changes Made
cli.py: exclude plugin-declared toolset names from the startup "Unknown toolsets" warning (parallel to the existing MCP-name exclusion).agent/subagent_licide.py:_validate_requestnow validates viavalidate_toolset()so plugin-registered toolsets are accepted inallowed_toolsets.tests/cli/test_plugin_toolset_startup_validation.py: 6 regression tests — cold-registry + persisted-cache race, live-registry plugin toolset, typo still warns, cache-fallback helper contract, lifecycle accepts plugin toolset, lifecycle still rejects typos.contributors/emails/adam-krawczyk@outlook.com: attribution mapping.How to Test
hermes tools.hermes chat -Q --max-turns 1 -q 'Reply exactly OK without calling tools.'— before: false warning; after: clean.delegate_taskwithallowed_toolsetsnaming a plugin toolset — no longer raises Unknown toolsets.Real-binary canary on the affected install (15 plugin toolsets configured):
Checklist
Code
pytest tests/ -qand all tests pass (targeted suites: 233 passed — full-suite run in CI)Documentation & Housekeeping
cli-config.yaml.examplechanges are N/A — no config keys changedCONTRIBUTING.md/AGENTS.mdchanges are N/AScreenshots / Logs
Startup output diff on the affected machine: