mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(delegate): default inherit_mcp_toolsets=true, drop version bump
Follow-up on helix4u's PR #14211: - Flip default to true: narrowing toolsets=['web','browser'] expresses 'I want these extras', not 'silently strip MCP'. Parent MCP tools (registered at runtime) should survive narrowing by default. - Drop _config_version bump (22->23); additive nested key under delegation.* is handled by _deep_merge, no migration needed. - Update tests to reflect new default behavior.
This commit is contained in:
parent
3e96c87f37
commit
7d8b2eee63
4 changed files with 37 additions and 35 deletions
|
|
@ -776,7 +776,7 @@ delegation:
|
|||
# max_concurrent_children: 3 # Max parallel child agents (default: 3)
|
||||
# max_spawn_depth: 1 # Tree depth cap (1-3, default: 1 = flat). Raise to 2 or 3 to allow orchestrator children to spawn their own workers.
|
||||
# orchestrator_enabled: true # Kill switch for role="orchestrator" children (default: true).
|
||||
# inherit_mcp_toolsets: true # When explicit child toolsets are narrowed, also keep the parent's MCP toolsets (default: false).
|
||||
# inherit_mcp_toolsets: true # When explicit child toolsets are narrowed, also keep the parent's MCP toolsets (default: true). Set false for strict intersection.
|
||||
# model: "google/gemini-3-flash-preview" # Override model for subagents (empty = inherit parent)
|
||||
# provider: "openrouter" # Override provider for subagents (empty = inherit parent)
|
||||
# # Resolves full credentials (base_url, api_key) automatically.
|
||||
|
|
|
|||
|
|
@ -713,9 +713,11 @@ DEFAULT_CONFIG = {
|
|||
"base_url": "", # direct OpenAI-compatible endpoint for subagents
|
||||
"api_key": "", # API key for delegation.base_url (falls back to OPENAI_API_KEY)
|
||||
# When delegate_task narrows child toolsets explicitly, preserve any
|
||||
# MCP toolsets the parent already has enabled. Off by default so
|
||||
# narrowed child toolsets stay strict unless the operator opts in.
|
||||
"inherit_mcp_toolsets": False,
|
||||
# MCP toolsets the parent already has enabled. On by default so
|
||||
# narrowing (e.g. toolsets=["web","browser"]) expresses "I want these
|
||||
# extras" without silently stripping MCP tools the parent already has.
|
||||
# Set to false for strict intersection.
|
||||
"inherit_mcp_toolsets": True,
|
||||
"max_iterations": 50, # per-subagent iteration cap (each subagent gets its own budget,
|
||||
# independent of the parent's max_iterations)
|
||||
"reasoning_effort": "", # reasoning effort for subagents: "xhigh", "high", "medium",
|
||||
|
|
@ -927,7 +929,7 @@ DEFAULT_CONFIG = {
|
|||
},
|
||||
|
||||
# Config schema version - bump this when adding new required fields
|
||||
"_config_version": 23,
|
||||
"_config_version": 22,
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
|
|
|
|||
|
|
@ -1059,35 +1059,7 @@ class TestChildCredentialPoolResolution(unittest.TestCase):
|
|||
self.assertEqual(mock_child._credential_pool, mock_pool)
|
||||
|
||||
@patch("tools.delegate_tool._load_config", return_value={})
|
||||
def test_build_child_agent_does_not_preserve_mcp_toolsets_by_default(self, mock_cfg):
|
||||
parent = _make_mock_parent()
|
||||
parent.enabled_toolsets = ["web", "browser", "mcp-MiniMax"]
|
||||
|
||||
with patch("run_agent.AIAgent") as MockAgent:
|
||||
mock_child = MagicMock()
|
||||
MockAgent.return_value = mock_child
|
||||
|
||||
_build_child_agent(
|
||||
task_index=0,
|
||||
goal="Test narrowed toolsets",
|
||||
context=None,
|
||||
toolsets=["web", "browser"],
|
||||
model=None,
|
||||
max_iterations=10,
|
||||
parent_agent=parent,
|
||||
task_count=1,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
MockAgent.call_args[1]["enabled_toolsets"],
|
||||
["web", "browser"],
|
||||
)
|
||||
|
||||
@patch(
|
||||
"tools.delegate_tool._load_config",
|
||||
return_value={"inherit_mcp_toolsets": True},
|
||||
)
|
||||
def test_build_child_agent_can_preserve_parent_mcp_toolsets(self, mock_cfg):
|
||||
def test_build_child_agent_preserves_mcp_toolsets_by_default(self, mock_cfg):
|
||||
parent = _make_mock_parent()
|
||||
parent.enabled_toolsets = ["web", "browser", "mcp-MiniMax"]
|
||||
|
||||
|
|
@ -1111,6 +1083,34 @@ class TestChildCredentialPoolResolution(unittest.TestCase):
|
|||
["web", "browser", "mcp-MiniMax"],
|
||||
)
|
||||
|
||||
@patch(
|
||||
"tools.delegate_tool._load_config",
|
||||
return_value={"inherit_mcp_toolsets": False},
|
||||
)
|
||||
def test_build_child_agent_strict_intersection_when_opted_out(self, mock_cfg):
|
||||
parent = _make_mock_parent()
|
||||
parent.enabled_toolsets = ["web", "browser", "mcp-MiniMax"]
|
||||
|
||||
with patch("run_agent.AIAgent") as MockAgent:
|
||||
mock_child = MagicMock()
|
||||
MockAgent.return_value = mock_child
|
||||
|
||||
_build_child_agent(
|
||||
task_index=0,
|
||||
goal="Test narrowed toolsets",
|
||||
context=None,
|
||||
toolsets=["web", "browser"],
|
||||
model=None,
|
||||
max_iterations=10,
|
||||
parent_agent=parent,
|
||||
task_count=1,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
MockAgent.call_args[1]["enabled_toolsets"],
|
||||
["web", "browser"],
|
||||
)
|
||||
|
||||
|
||||
class TestChildCredentialLeasing(unittest.TestCase):
|
||||
def test_run_single_child_acquires_and_releases_lease(self):
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ def _get_orchestrator_enabled() -> bool:
|
|||
def _get_inherit_mcp_toolsets() -> bool:
|
||||
"""Whether narrowed child toolsets should keep the parent's MCP toolsets."""
|
||||
cfg = _load_config()
|
||||
return is_truthy_value(cfg.get("inherit_mcp_toolsets"), default=False)
|
||||
return is_truthy_value(cfg.get("inherit_mcp_toolsets"), default=True)
|
||||
|
||||
|
||||
def _is_mcp_toolset_name(name: str) -> bool:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue