fix: enforce strictly subtractive toolset filtration
Refactor tool resolution logic in model_tools.py to ensure that disabled_toolsets are always subtracted at the end, preventing composite toolsets (e.g. 'browser') from implicitly enabling tools that should be hidden. - Added 'disabled_toolsets' to DEFAULT_CONFIG in hermes_cli/config.py - Updated HermesCLI in cli.py to load and propagate disabled toolsets to AIAgent - Implemented robust two-phase resolution (additive then subtractive) in model_tools.py
This commit is contained in:
parent
8e58265b60
commit
e3624e00db
7
cli.py
7
cli.py
@ -15,9 +15,8 @@ Usage:
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import platform
|
||||
import shutil
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import concurrent.futures
|
||||
@ -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 @@ class HermesCLI:
|
||||
|
||||
# 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 @@ class HermesCLI:
|
||||
credential_pool=runtime.get("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,
|
||||
|
||||
@ -457,6 +457,7 @@ DEFAULT_CONFIG = {
|
||||
# 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": {
|
||||
|
||||
@ -23,6 +23,8 @@ Public API (signatures preserved from the original 2,400-line version):
|
||||
import json
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from typing import Dict, Any, List, Optional, Tuple
|
||||
@ -356,12 +358,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 #15291.
|
||||
if disabled_toolsets:
|
||||
for toolset_name in disabled_toolsets:
|
||||
if validate_toolset(toolset_name):
|
||||
resolved = resolve_toolset(toolset_name)
|
||||
@ -376,10 +383,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()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user