Disabled tools still active or advertised in agent
NousResearch/hermes-agent · cluster 566 · agent
Data as of
Nothing open on GitHub. Fix merged in #18197. Check it covers your case.
The short answer
- Known?
- Yes. 6 related items grouped here, 3 issues already closed.
- Fix event
- A fix was merged to main in PR #18197. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PR #18197. That is separate from the fix event. - Still open
- Nothing open on GitHub.
A cluster of bugs and fixes around tool/toolset disabling logic not being enforced: disabled toolsets were re-enabling themselves, being advertised in descriptions, or still dispatched at runtime across CLI, gateway, and web backends.
Open issues0
Open PRs0
Fixes on record
-
#18197 fix(tools): strictly subtract agent.disabled_toolsets in CLI + gateway
files:
cli.py,gateway/run.py,hermes_cli/config.py,model_tools.py,scripts/release.pyShow the diff
-
cli.py@@ -15,7 +15,6 @@ import logging import os -import re import shutil import sys import json @@ -600,6 +599,7 @@ def load_cli_config() -> Dict[str, Any]: # Load configuration at module startup CLI_CONFIG = load_cli_config() + # Initialize centralized logging early — agent.log + errors.log in ~/.hermes/logs/. # This ensures CLI sessions produce a log trail even before AIAgent is instantiated. try: @@ -2118,6 +2118,8 @@ def __init__( # Parse and validate toolsets self.enabled_toolsets = toolsets + self.disabled_toolsets = CLI_CONFIG["agent"].get("disabled_toolsets") or [] + if toolsets and "all" not in toolsets and "*" not in toolsets: # Validate each toolset — MCP server names are resolved via # live registry aliases (registered during discover_mcp_tools), @@ -3568,6 +3570,7 @@ def _init_agent(self, *, model_override: str = None, runtime_override: dict = No credential_pool=[redacted:secret-assignment]"credential_pool"), max_iterations=self.max_turns, enabled_toolsets=self.enabled_toolsets, + disabled_toolsets=self.disabled_toolsets, verbose_logging=self.verbose, quiet_mode=not self.verbose, ephemeral_system_prompt=self.system_prompt if self.system_prompt else None, -
gateway/run.py@@ -7978,6 +7978,8 @@ async def _run_background_task( from hermes_cli.tools_config import _get_platform_tools enabled_toolsets = sorted(_get_platform_tools(user_config, platform_key)) + agent_cfg = user_config.get("agent") or {} + disabled_toolsets = agent_cfg.get("disabled_toolsets") or None pr = self._provider_routing max_iterations = int(os.getenv("HERMES_MAX_ITERATIONS", "90")) @@ -7994,6 +7996,7 @@ def run_sync(): quiet_mode=True, verbose_logging=False, enabled_toolsets=enabled_toolsets, + disabled_toolsets=disabled_toolsets, reasoning_config=reasoning_config, service_tier=self._service_tier, request_overrides=turn_route.get("request_overrides"), @@ -10352,6 +10355,7 @@ async def _run_process_watcher(self, watcher: dict) -> None: ("compression", "threshold"), ("compression", "target_ratio"), ("compression", "protect_last_n"), + ("agent", "disabled_toolsets"), ) @classmethod @@ -11135,6 +11139,8 @@ def _run_still_current() -> bool: from hermes_cli.tools_config import _get_platform_tools enabled_toolsets = sorted(_get_platform_tools(user_config, platform_key)) + agent_cfg_local = user_config.get("agent") or {} + disabled_toolsets = agent_cfg_local.get("disabled_toolsets") or None display_config = user_config.get("display", {}) if not isinstance(display_config, dict): @@ -11763,6 +11769,7 @@ def _interim_assistant_cb(text: str, *, already_streamed: bool = False) -> None: quiet_mode=True, verbose_logging=False, enabled_toolsets=enabled_toolsets, + disabled_toolsets=disabled_toolsets, ephemeral_system_prompt=combined_ephemeral or None, prefill_messages=self._prefill_messages or None, reasoning_config=reasoning_config, -
hermes_cli/config.py@@ -457,6 +457,7 @@ def _ensure_hermes_home_managed(home: Path): # remains available as a tool regardless of this setting — the routing # only controls how inbound user images are presented. "image_input_mode": "auto", + "disabled_toolsets": [], }, "terminal": { -
model_tools.py@@ -356,12 +356,17 @@ def _compute_tool_definitions( else: if not quiet_mode: print(f"⚠️ Unknown toolset: {toolset_name}") - - elif disabled_toolsets: + else: + # Default: start with everything from toolsets import get_all_toolsets for ts_name in get_all_toolsets(): tools_to_include.update(resolve_toolset(ts_name)) + # Always apply disabled toolsets as a subtraction step at the end. + # This ensures that even if a composite toolset (like hermes-cli) + # is enabled, any tools belonging to a disabled toolset are strictly + # stripped out. See issue #17309. + if disabled_toolsets: for toolset_name in disabled_toolsets: if validate_toolset(toolset_name): resolved = resolve_toolset(toolset_name) @@ -376,10 +381,6 @@ def _compute_tool_definitions( else: if not quiet_mode: print(f"⚠️ Unknown toolset: {toolset_name}") - else: - from toolsets import get_all_toolsets - for ts_name in get_all_toolsets(): - tools_to_include.update(resolve_toolset(ts_name)) # Plugin-registered tools are now resolved through the normal toolset # path — validate_toolset() / resolve_toolset() / get_all_toolsets() -
scripts/release.py@@ -48,6 +48,7 @@ "[redacted:email]": "adamludwin", "[redacted:email]": "exiao", "[redacted:email]": "rylena", + "[redacted:email]": "jatingodnani", "[redacted:email]": "tmimmanuel", "[redacted:email]": "revaraver", # Matrix parity salvage batch (April 2026)
-
2 PRs closed without merging
From the close comments: done elsewhere 1 · merged via another change 1
Closed issues · 3
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.25: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- agent
- Merged PRs
- #18197
- Closed issues
- 3
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 1 May 2026