diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index 9c3c7c1dcd3..7cdbeabe8e9 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -3054,6 +3054,12 @@ def _blank_slate_minimal_toolsets(config: dict): continue # platform composites — not user-facing toolsets if isinstance(tdef, dict) and tdef.get("includes"): continue # composite groupings, not leaf toolsets + if isinstance(tdef, dict) and tdef.get("posture"): + continue # posture toolsets (e.g. coding) are session-level + # selections made by agent/coding_context.py — not permanent + # user-facing disables. Adding them here causes model_tools + # to subtract their tools (terminal, read_file, …) from the + # minimal Blank Slate surface (#57315). all_keys.add(k) disabled = sorted(all_keys - keep) diff --git a/tests/hermes_cli/test_setup_blank_slate.py b/tests/hermes_cli/test_setup_blank_slate.py index a62cf9a2250..b4afd3e138e 100644 --- a/tests/hermes_cli/test_setup_blank_slate.py +++ b/tests/hermes_cli/test_setup_blank_slate.py @@ -34,6 +34,17 @@ class TestBlankSlateMinimalToolsets: # The recovered non-configurable toolset that used to leak is suppressed. assert "kanban" in disabled + def test_disabled_toolsets_excludes_posture_toolsets(self): + """Posture toolsets (e.g. coding) are session-level selections made by + agent/coding_context.py — not permanent user-facing disables. Including + them in disabled_toolsets causes model_tools to subtract their tools + (terminal, read_file, …) from the minimal Blank Slate surface (#57315). + """ + cfg = {} + _blank_slate_minimal_toolsets(cfg) + disabled = set(cfg["agent"]["disabled_toolsets"]) + assert "coding" not in disabled + def test_resolver_yields_exactly_file_and_terminal(self): from hermes_cli.tools_config import _get_platform_tools cfg = {} @@ -59,6 +70,30 @@ class TestBlankSlateMinimalToolsets: assert names == ["patch", "process", "read_file", "search_files", "terminal", "write_file"] + def test_tool_schema_survives_disabled_toolsets_from_config(self): + """Regression: disabled_toolsets must not erase the minimal Blank Slate + surface when passed to model_tools. Before the fix, posture toolsets + like ``coding`` in disabled_toolsets caused model_tools to subtract + terminal, read_file, write_file, etc. (#57315). + """ + import model_tools + from hermes_cli.tools_config import _get_platform_tools + cfg = {} + _blank_slate_minimal_toolsets(cfg) + _blank_slate_minimize_config(cfg) + enabled = sorted(_get_platform_tools(cfg, "cli")) + disabled = cfg.get("agent", {}).get("disabled_toolsets") or [] + defs = model_tools.get_tool_definitions( + enabled_toolsets=enabled, + disabled_toolsets=disabled, + quiet_mode=True, + ) + names = sorted( + {(d.get("function") or {}).get("name") or d.get("name") for d in defs} + ) + assert names == ["patch", "process", "read_file", "search_files", + "terminal", "write_file"] + class TestBlankSlateMinimizeConfig: def test_optional_features_turned_off(self):