fix(toolsets): preserve core tools when a posture toolset is in disabled_toolsets (#57315)

The disabled_toolsets subtraction loop in _compute_tool_definitions
preserved shared core tools only for hermes-* platform bundles (#33924),
subtracting bundle_non_core_tools(); every other name took the else
branch and got a full resolve_toolset() subtraction. The `coding`
toolset is a posture toolset (posture: True) that re-lists the shared
_HERMES_CORE_TOOLS it does not own, so disabled_toolsets=["coding"]
stripped those core tools from the whole schema (34 tools collapsed to a
handful; terminal/read_file/write_file/web_search/execute_code gone).

Extend the core-preserving branch to also match posture toolsets, so
they subtract only the non-core delta. Only `coding` carries
posture: True, so atomic toolsets stay fully removable. The
bundle-misconfiguration info log is gated to hermes-* names, since its
wording is bundle-specific and disabled_toolsets=["coding"] is a
legitimate config written by older `hermes setup` runs.

Adds a regression test (TestDisabledToolsetsPostureToolset) alongside
the existing #33924 bundle tests.
This commit is contained in:
Brett Bonner 2026-07-03 01:24:43 -04:00 committed by Teknium
parent b57fe5ca01
commit e5636da5d8
2 changed files with 61 additions and 7 deletions

View file

@ -399,16 +399,19 @@ def _compute_tool_definitions(
if disabled_toolsets:
for toolset_name in disabled_toolsets:
if validate_toolset(toolset_name):
if toolset_name.startswith("hermes-"):
# Platform bundles (hermes-*) include _HERMES_CORE_TOOLS, so
# subtracting the whole bundle would strip core tools shared
# by other enabled toolsets and empty the tool list (#33924).
# Subtract only the bundle's non-core delta; keep core.
from toolsets import bundle_non_core_tools
from toolsets import bundle_non_core_tools, get_toolset
if toolset_name.startswith("hermes-") or (get_toolset(toolset_name) or {}).get("posture"):
# Platform bundles (hermes-*) include _HERMES_CORE_TOOLS, and
# posture toolsets (`posture: True`, e.g. `coding`) re-list
# those same core tools without owning them, so subtracting
# the whole toolset would strip core tools shared by other
# enabled toolsets and empty the tool list (#33924, #57315).
# Subtract only the non-core delta; keep core.
to_remove = bundle_non_core_tools(toolset_name)
tools_to_include.difference_update(to_remove)
resolved = sorted(to_remove)
if not quiet_mode and toolset_name not in _WARNED_DISABLED_BUNDLES:
if (not quiet_mode and toolset_name.startswith("hermes-")
and toolset_name not in _WARNED_DISABLED_BUNDLES):
_WARNED_DISABLED_BUNDLES.add(toolset_name)
logger.info(
"agent.disabled_toolsets contains platform-bundle "