diff --git a/acp_adapter/session.py b/acp_adapter/session.py index 9cec87a7ec..2e9a179a06 100644 --- a/acp_adapter/session.py +++ b/acp_adapter/session.py @@ -463,6 +463,7 @@ class SessionManager: return self._agent_factory() from run_agent import AIAgent + from agent.skill_utils import parse_config_string_list from hermes_cli.config import load_config from hermes_cli.runtime_provider import resolve_runtime_provider from hermes_constants import resolve_reasoning_config @@ -485,7 +486,9 @@ class SessionManager: "platform": "acp", "quiet_mode": True, "session_id": session_id, "session_db": self._get_db(), "enabled_toolsets": (list(enabled_toolsets) if enabled_toolsets is not None else _expand_acp_enabled_toolsets(["hermes-acp"], mcp_server_names=configured_mcp_servers)), - "disabled_toolsets": list(disabled_toolsets) if disabled_toolsets is not None else None, + # agent.disabled_toolsets is subtracted at tool granularity by the agent, as on the CLI/gateway/cron. + "disabled_toolsets": (list(disabled_toolsets) if disabled_toolsets is not None + else parse_config_string_list((config.get("agent") or {}).get("disabled_toolsets")) or None), "model": model or default_model, "cwd": cwd, # Same chokepoint as the CLI/gateway/TUI/cron: without it ``agent.reasoning_effort: none`` never diff --git a/tests/acp_adapter/test_session.py b/tests/acp_adapter/test_session.py index f4e0c1c129..856c232799 100644 --- a/tests/acp_adapter/test_session.py +++ b/tests/acp_adapter/test_session.py @@ -190,6 +190,59 @@ class TestCreateSession: assert seen[0]["credential_pool"] is sentinel_pool + @staticmethod + def _patch_make_agent_env(monkeypatch, config): + class FakeAgent: + model = "fake-model" + + def __init__(self, **kwargs): + self.kwargs = kwargs + + monkeypatch.setattr("run_agent.AIAgent", FakeAgent) + monkeypatch.setattr("acp_adapter.session.load_config", lambda: config, raising=False) + monkeypatch.setattr("hermes_cli.config.load_config", lambda: config) + monkeypatch.setattr( + "hermes_cli.runtime_provider.resolve_runtime_provider", + lambda requested=None: { + "provider": requested, + "api_mode": "openai_chat", + "base_url": "https://example.invalid", + "api_key": "test-key", + }, + ) + monkeypatch.setattr("acp_adapter.session._register_task_cwd", lambda task_id, cwd: None) + + def test_make_agent_passes_configured_disabled_toolsets(self, monkeypatch): + # The CLI and gateway hand agent.disabled_toolsets to AIAgent, but the + # ACP path dropped it — config-disabled toolsets (e.g. todo) remained + # executable in editor/ACP sessions. + self._patch_make_agent_env( + monkeypatch, + { + "model": {"default": "fake-model", "provider": "fake-provider"}, + "mcp_servers": {}, + "agent": {"disabled_toolsets": ["todo", "browser"]}, + }, + ) + + state = SessionManager(db=None).create_session(cwd="/tmp/project") + + assert state.agent.kwargs.get("disabled_toolsets") == ["todo", "browser"] + + def test_make_agent_omits_disabled_toolsets_when_none_configured(self, monkeypatch): + self._patch_make_agent_env( + monkeypatch, + { + "model": {"default": "fake-model", "provider": "fake-provider"}, + "mcp_servers": {}, + "agent": {}, + }, + ) + + state = SessionManager(db=None).create_session(cwd="/tmp/project") + + assert "disabled_toolsets" not in state.agent.kwargs +