{"repo":"NousResearch/hermes-agent","public_id":"41445","display_label":"Accurate tool counting with platform toolsets","summary":"These changes correct prompt-size diagnostics that over-counted tools by ignoring enabled/disabled state and platform-specific toolset resolution. A related change ensures string-typed toolset lists are coerced to proper lists rather than iterated as individual characters.","subsystem":"agent","counts":{"members":6,"open_issues":0,"open_issues_distinct":0,"open_prs":1,"closed_issues":1,"merged_prs":1,"attempt_prs":4},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":59210,"merged_at":"2026-07-06T02:13:21+00:00"},"resolution":{"state":"resolved","by":"pr-59210"},"freshness":{"state":"verified","last_verified_at":"2026-07-06T02:13:21+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.3333333333333333},"fix_edges":[{"issue_number":41445,"pr_number":59210,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-07-06T02:13:21+00:00"}],"members":[{"kind":"issue","number":41445,"title":"hermes prompt-size over-counts tools by not respecting enabled/disabled toolsets","url":null,"state":"closed"},{"kind":"pr","number":41461,"title":"fix(cli): pass platform toolsets to prompt-size inspection agent","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"fe8d02cec722dbd43de39eaa46e6996e1015185a","number":0}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":52032,"title":"fix(cli): honor agent.disabled_toolsets in prompt-size diagnostic","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#59210","number":59210},{"kind":"pr","value":"#41445","number":41445},{"kind":"pr","value":"#41575","number":41575},{"kind":"pr","value":"#51586","number":51586}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":57167,"title":"fix(prompt-size): honor effective Hermes toolsets","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#41461","number":41461},{"kind":"pr","value":"#41445","number":41445},{"kind":"pr","value":"#41575","number":41575},{"kind":"pr","value":"#52032","number":52032},{"kind":"pr","value":"#48532","number":48532}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":59210,"title":"fix(prompt-size): pass platform-resolved toolsets into the inspection agent","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["hermes_cli/prompt_size.py","scripts/release.py","tests/hermes_cli/test_prompt_size.py"],"fix_hunks":[{"file":"hermes_cli/prompt_size.py","hunks":["@@ -34,11 +34,17 @@ def _build_inspection_agent(platform: str) -> Any:\n     \"\"\"\n     from run_agent import AIAgent\n     from hermes_cli.config import load_config\n+    from hermes_cli.tools_config import _get_platform_tools\n \n     cfg = load_config()\n     model_cfg = cfg.get(\"model\", {}) if isinstance(cfg.get(\"model\"), dict) else {}\n     model = model_cfg.get(\"default\") or model_cfg.get(\"model\") or \"\"\n \n+    # Resolve platform-specific toolsets the same way the gateway does.\n+    enabled_toolsets = sorted(_get_platform_tools(cfg, platform))\n+    agent_cfg = cfg.get(\"agent\") or {}\n+    disabled_toolsets = agent_cfg.get(\"disabled_toolsets\") or None\n+\n     return AIAgent(\n         model=model,\n         api_key=\"[redacted:secret-assignment]\",","@@ -46,6 +52,8 @@ def _build_inspection_agent(platform: str) -> Any:\n         quiet_mode=True,\n         save_trajectories=False,\n         platform=platform,\n+        enabled_toolsets=enabled_toolsets,\n+        disabled_toolsets=disabled_toolsets,\n     )\n \n "]},{"file":"scripts/release.py","hunks":["@@ -896,6 +896,7 @@\n     \"[redacted:email]\": \"JezzaHehn\",\n     \"[redacted:email]\": \"JezzaHehn\",\n     \"254021826+dodo-reach@users.noreply.github.com\": \"dodo-reach\",\n+    \"[redacted:email]\": \"EdderTalmor\",  # PR #41575 salvage (prompt-size: pass platform-resolved enabled_toolsets + agent.disabled_toolsets into the inspection agent; #41445)\n     \"259807879+Bartok9@users.noreply.github.com\": \"Bartok9\",\n     \"123342691+banditburai@users.noreply.github.com\": \"banditburai\",\n     \"9063726+Kyzcreig@users.noreply.github.com\": \"Kyzcreig\","]},{"file":"tests/hermes_cli/test_prompt_size.py","hunks":["@@ -1,11 +1,14 @@\n \"\"\"Tests for the ``hermes prompt-size`` diagnostic (issue #34667).\"\"\"\n \n import json\n+import sys\n+from types import SimpleNamespace\n \n import pytest\n \n from hermes_cli.prompt_size import (\n     _SKILLS_BLOCK_RE,\n+    _build_inspection_agent,\n     compute_prompt_breakdown,\n     render_breakdown,\n )","@@ -70,6 +73,56 @@ def test_runs_offline_without_credentials(isolated_home, monkeypatch):\n     assert data[\"system_prompt\"][\"bytes\"] > 0\n \n \n+def test_inspection_agent_uses_resolved_platform_toolsets(monkeypatch):\n+    \"\"\"Inspection must match real CLI tool resolution, including disables.\"\"\"\n+    captured = {}\n+\n+    class FakeAIAgent:\n+        def __init__(self, **kwargs):\n+            captured.update(kwargs)\n+\n+    cfg = {\n+        \"model\": {\"default\": \"test/model\"},\n+        \"agent\": {\"disabled_toolsets\": [\"memory\"]},\n+    }\n+\n+    monkeypatch.setitem(\n+        sys.modules,\n+        \"run_agent\",\n+        SimpleNamespace(AIAgent=FakeAIAgent),\n+    )\n+    monkeypatch.setattr(\"hermes_cli.config.load_config\", lambda: cfg)\n+    monkeypatch.setattr(\n+        \"hermes_cli.tools_config._get_platform_tools\",\n+        lambda passed_cfg, platform: {\"terminal\", \"file\"},\n+    )\n+\n+    _build_inspection_agent(\"cli\")\n+\n+    assert captured[\"model\"] == \"test/model\"\n+    assert captured[\"platform\"] == \"cli\"\n+    assert captured[\"enabled_toolsets\"] == [\"file\", \"terminal\"]\n+    assert captured[\"disabled_toolsets\"] == [\"memory\"]\n+\n+\n+def test_blank_slate_prompt_size_counts_only_minimal_tools(isolated_home):\n+    \"\"\"Blank Slate prompt-size should report file + terminal schemas only.\"\"\"\n+    from hermes_cli.config import save_config\n+    from hermes_cli.setup import (\n+        _blank_slate_minimal_toolsets,\n+        _blank_slate_minimize_config,\n+    )\n+\n+    cfg = {\"model\": {\"default\": \"MiniMax-M2.7\"}}\n+    _blank_slate_minimal_toolsets(cfg)\n+    _blank_slate_minimize_config(cfg)\n+    save_config(cfg)\n+\n+    data = compute_prompt_breakdown(\"cli\")\n+\n+    assert data[\"tools\"][\"count\"] == 6\n+\n+\n def test_skills_index_reflects_installed_skills(isolated_home):\n     \"\"\"Installing a skill makes the skills-index block non-empty.\n \n"]}]},{"kind":"pr","number":65452,"title":"fix(toolsets): coerce string-typed toolset lists instead of iterating characters","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"309cf2c5e2b","number":0}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false}],"trust":{"default_tier":"verified","includes_suggested":false}}