fix(plugins): nested category plugin discovery + alias-normalized enable/disable (#41066)#41999
Closed
kshitijk4poor wants to merge 1 commit into
Closed
Conversation
2 tasks
b14805d to
4b1acb5
Compare
…ble/disable (NousResearch#41066) Salvage consolidating three complementary community PRs into one coherent fix: - NousResearch#41076 (islam666): made `hermes plugins list` discover nested category plugins (e.g. `observability/nemo_relay`, `image_gen/openai`). - NousResearch#41613 (mnajafian-nv): the superset — nested discovery aligned with the runtime loader (reuses `PluginManager._scan_directory`/`_scan_entry_points` so list state can't drift from what actually loads), PLUS the enable/disable mutation side NousResearch#41076 left flat. - NousResearch#41081 (annguyenNous): identified the `web_server.py` dashboard plugins-hub caller of `_discover_all_plugins()`, which must also be updated for the new tuple shape + key-aware status. This combines the best of all three and fixes the mutation-side gap that made nested bundled plugins untoggleable: $ hermes plugins enable nemo_relay Plugin 'nemo_relay' is not installed or bundled. # exit 1 (before) Now `enable`/`disable`/`toggle`, the `hermes plugins list` views, the dashboard plugins-hub endpoint, and the dashboard enable/disable helpers all resolve a bare manifest name OR a full path-derived key to the canonical key the loader gates on, via a single `_resolve_plugin_reference()` normalization point, and persist that key while clearing any stale legacy bare-name alias so the two can't drift. `_plugin_status` is key+legacy-name aware. `_discover_all_plugins` now returns 6-tuples `(key, legacy_name, version, description, source, dir_path)`; ALL call sites (`cmd_list` table/plain/JSON, `_filter_plugin_entries`, `cmd_toggle`, `dashboard_remove_user_plugin`, and `web_server._merged_plugins_hub`) and the `test_plugins_cmd_list.py` fixtures are updated to match. Updating the `web_server.py` caller prevents a `ValueError: too many values to unpack` crash in the dashboard plugins-hub endpoint. Verified e2e on the real CLI + runtime loader (isolated HERMES_HOME): `hermes plugins enable nemo_relay` writes `observability/nemo_relay` to config.yaml and the loader then loads it (`enabled=True, error=None`); a stale bare-name alias is cleared on disable (no contradictory state); the dashboard `_merged_plugins_hub()` runs and lists nested plugins by canonical key. Full `tests/hermes_cli/test_plugins_cmd*` + web_server plugin tests green. Closes NousResearch#41066. Supersedes NousResearch#41076, NousResearch#41081, and NousResearch#41613. Co-authored-by: islam666 <islam666@users.noreply.github.com> Co-authored-by: mnajafian-nv <mnajafian@nvidia.com> Co-authored-by: annguyenNous <annguyenNous@users.noreply.github.com> Co-authored-by: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com>
4b1acb5 to
3904df5
Compare
Collaborator
Author
|
Closing — this overreached. #41076 (@islam666) is the right main PR for nested discovery, and @mnajafian-nv intentionally closed #41613 in favor of it. This PR resurrected that approach and superseded #41076, which wasn't the right call. The alias-normalized enable/disable gap is better as a narrow follow-up (which @mnajafian-nv offered to own). Reopening the focused piece separately; #41076 stays the discovery base. |
teknium1
added a commit
that referenced
this pull request
Jun 9, 2026
AGENTS.md was almost entirely how-to/mechanics with the want/don't-want
guidance implicit and scattered. Adds a single authoritative intent layer
near the top, calibrated against what actually merges and what actually
gets rejected.
- 'What Hermes Is': framing + the two properties that drive design
(prompt-cache integrity, narrow-waist core).
- 'Contribution Rubric': dual-purpose intent doc — (1) for humans/own work:
what gets merged vs rejected; (2) for the triage sweeper: when a PR is safe
to close on the three allowed reasons AND when NOT to close one. Taste-based
'won't implement / out of scope' closes stay human-only by design.
- 'What we want' calibrated against the last ~55 merges: fix real bugs well,
expand reach at the edges (platforms/channels/providers/models/desktop —
large features land routinely), refactor god-files into clean modules,
keep the CORE narrow. 'Expansive at the edges, conservative at the waist.'
- 'What we don't want': speculative hooks, .env-for-non-secrets, needless
core tools, lazy-read escape hatches, feature-destroying fixes, ungated
telemetry, change-detector tests, core-touching plugins.
- 'Before you call it a bug — verify the premise (and when NOT to close)':
distilled from real closes (#41741 intentional-design-not-a-gap, #41610
wrong-premise, #42327 fix-never-executes, #42393 deliberate-omission,
#41999 overreach). Doubles as sweeper guidance to avoid wrongly closing
legitimate PRs.
- 'The Footprint Ladder' (core-tool decision): extend > CLI+skill > gated tool
> plugin > MCP server in the catalog > new core tool (last resort).
Trim: 'Adding New Tools' intro points at the ladder. Detailed mechanics stay
where readers need them.
teknium1
added a commit
that referenced
this pull request
Jun 10, 2026
#42641) AGENTS.md was almost entirely how-to/mechanics with the want/don't-want guidance implicit and scattered. Adds a single authoritative intent layer near the top, calibrated against what actually merges and what actually gets rejected. - 'What Hermes Is': framing + the two properties that drive design (prompt-cache integrity, narrow-waist core). - 'Contribution Rubric': dual-purpose intent doc — (1) for humans/own work: what gets merged vs rejected; (2) for the triage sweeper: when a PR is safe to close on the three allowed reasons AND when NOT to close one. Taste-based 'won't implement / out of scope' closes stay human-only by design. - 'What we want' calibrated against the last ~55 merges: fix real bugs well, expand reach at the edges (platforms/channels/providers/models/desktop — large features land routinely), refactor god-files into clean modules, keep the CORE narrow. 'Expansive at the edges, conservative at the waist.' - 'What we don't want': speculative hooks, .env-for-non-secrets, needless core tools, lazy-read escape hatches, feature-destroying fixes, ungated telemetry, change-detector tests, core-touching plugins. - 'Before you call it a bug — verify the premise (and when NOT to close)': distilled from real closes (#41741 intentional-design-not-a-gap, #41610 wrong-premise, #42327 fix-never-executes, #42393 deliberate-omission, #41999 overreach). Doubles as sweeper guidance to avoid wrongly closing legitimate PRs. - 'The Footprint Ladder' (core-tool decision): extend > CLI+skill > gated tool > plugin > MCP server in the catalog > new core tool (last resort). Trim: 'Adding New Tools' intro points at the ladder. Detailed mechanics stay where readers need them.
changman
pushed a commit
to changman/hermes-agent
that referenced
this pull request
Jun 10, 2026
NousResearch#42641) AGENTS.md was almost entirely how-to/mechanics with the want/don't-want guidance implicit and scattered. Adds a single authoritative intent layer near the top, calibrated against what actually merges and what actually gets rejected. - 'What Hermes Is': framing + the two properties that drive design (prompt-cache integrity, narrow-waist core). - 'Contribution Rubric': dual-purpose intent doc — (1) for humans/own work: what gets merged vs rejected; (2) for the triage sweeper: when a PR is safe to close on the three allowed reasons AND when NOT to close one. Taste-based 'won't implement / out of scope' closes stay human-only by design. - 'What we want' calibrated against the last ~55 merges: fix real bugs well, expand reach at the edges (platforms/channels/providers/models/desktop — large features land routinely), refactor god-files into clean modules, keep the CORE narrow. 'Expansive at the edges, conservative at the waist.' - 'What we don't want': speculative hooks, .env-for-non-secrets, needless core tools, lazy-read escape hatches, feature-destroying fixes, ungated telemetry, change-detector tests, core-touching plugins. - 'Before you call it a bug — verify the premise (and when NOT to close)': distilled from real closes (NousResearch#41741 intentional-design-not-a-gap, NousResearch#41610 wrong-premise, NousResearch#42327 fix-never-executes, NousResearch#42393 deliberate-omission, NousResearch#41999 overreach). Doubles as sweeper guidance to avoid wrongly closing legitimate PRs. - 'The Footprint Ladder' (core-tool decision): extend > CLI+skill > gated tool > plugin > MCP server in the catalog > new core tool (last resort). Trim: 'Adding New Tools' intro points at the ladder. Detailed mechanics stay where readers need them.
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 does this PR do?
Salvage that merges two complementary community PRs into one coherent fix for nested category plugin handling, superseding both:
hermes plugins listdiscover nested category plugins (observability/nemo_relay,image_gen/openai, …).The gap this closes
#41076 fixed discovery/listing but the mutation path stayed flat, so nested bundled plugins were untoggleable:
How
_discover_all_plugins()now reuses the runtimePluginManager._scan_directory/_scan_entry_points, so the list view can't drift from what actually loads (covers bundled categories, platforms, user, project, entry points). Returns 6-tuples(key, legacy_name, version, description, source, dir_path)._resolve_plugin_reference(), resolves a bare manifest/leaf name or a fullcategory/namekey to the canonical key the loader gates on, with the full alias set.cmd_enable/cmd_disable/cmd_toggle, the dashboard helpers, and_plugin_statusare all key+legacy-name aware; enable/disable persist the canonical key and clear stale bare-name aliases so the two can't drift.cmd_list/_filter_plugin_entriescall sites and thetest_plugins_cmd_list.pyfixtures updated to the 6-tuple shape (this also fixes the 5-tuple→6-tupleValueErrorthose tests would otherwise hit).Verification
_resolve_plugin_reference("nemo_relay")resolves toobservability/nemo_relay(with both aliases) — the original bug is fixed.tests/hermes_cli/test_plugins_cmd_list.py+test_plugins_cmd.py: 83 passed, ruff clean.test_plugins.py::...test_discover_project_plugins_skipped_by_default) reproduces on cleanorigin/main— environmental (dev-box project plugins), not introduced here.Type of Change
Related
Closes #41066. Supersedes #41076 (@islam666) and #41613 (@mnajafian-nv) — both credited as co-authors. Surfaced while reviewing #41551 (the nested
observability/nemo_relayplugin is what exposed the mutation gap).