diff --git a/cli.py b/cli.py index a289e3ab2..0de2a53a3 100644 --- a/cli.py +++ b/cli.py @@ -8454,7 +8454,7 @@ class HermesCLI: # in terminal_tool is populated for this thread. The main thread # registration (run() line ~9046) is invisible here because # _callback_tls is threading.local(). Matches the pattern used - # by acp_adapter/server.py for ACP sessions. + # by hermes_agent/acp/server.py for ACP sessions. set_sudo_password_callback(self._sudo_password_callback) set_approval_callback(self._approval_callback) try: diff --git a/hermes_agent/acp/__main__.py b/hermes_agent/acp/__main__.py index a6ccd0997..2ca0c20ad 100644 --- a/hermes_agent/acp/__main__.py +++ b/hermes_agent/acp/__main__.py @@ -1,5 +1,5 @@ -"""Allow running the ACP adapter as ``python -m acp_adapter``.""" +"""Allow running the ACP adapter as ``python -m hermes_agent.acp``.""" -from .entry import main +from hermes_agent.acp.entry import main main() diff --git a/hermes_agent/acp/entry.py b/hermes_agent/acp/entry.py index 3089f78c2..bd1f1db38 100644 --- a/hermes_agent/acp/entry.py +++ b/hermes_agent/acp/entry.py @@ -6,7 +6,7 @@ and starts the ACP agent server. Usage:: - python -m acp_adapter.entry + python -m hermes_agent.acp.entry # or hermes acp # or @@ -16,7 +16,6 @@ Usage:: import asyncio import logging import sys -from pathlib import Path from hermes_constants import get_hermes_home @@ -104,13 +103,8 @@ def main() -> None: logger = logging.getLogger(__name__) logger.info("Starting hermes-agent ACP adapter") - # Ensure the project root is on sys.path so ``from run_agent import AIAgent`` works - project_root = str(Path(__file__).resolve().parent.parent) - if project_root not in sys.path: - sys.path.insert(0, project_root) - import acp - from .server import HermesACPAgent + from hermes_agent.acp.server import HermesACPAgent agent = HermesACPAgent() try: diff --git a/hermes_agent/acp/events.py b/hermes_agent/acp/events.py index 1257f902e..9386c0bc8 100644 --- a/hermes_agent/acp/events.py +++ b/hermes_agent/acp/events.py @@ -15,7 +15,7 @@ from typing import Any, Callable, Deque, Dict import acp -from .tools import ( +from hermes_agent.acp.tools import ( build_tool_complete, build_tool_start, make_tool_call_id, diff --git a/hermes_agent/acp/server.py b/hermes_agent/acp/server.py index d73c71157..0d266b252 100644 --- a/hermes_agent/acp/server.py +++ b/hermes_agent/acp/server.py @@ -52,15 +52,15 @@ try: except ImportError: from acp.schema import AuthMethod as AuthMethodAgent # type: ignore[attr-defined] -from acp_adapter.auth import detect_provider -from acp_adapter.events import ( +from hermes_agent.acp.auth import detect_provider +from hermes_agent.acp.events import ( make_message_cb, make_step_cb, make_thinking_cb, make_tool_progress_cb, ) -from acp_adapter.permissions import make_approval_callback -from acp_adapter.session import SessionManager, SessionState +from hermes_agent.acp.permissions import make_approval_callback +from hermes_agent.acp.session import SessionManager, SessionState logger = logging.getLogger(__name__) diff --git a/hermes_cli/main.py b/hermes_cli/main.py index ec0441f8b..6896f3b15 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -8516,7 +8516,7 @@ Examples: def cmd_acp(args): """Launch Hermes Agent as an ACP server.""" try: - from acp_adapter.entry import main as acp_main + from hermes_agent.acp.entry import main as acp_main acp_main() except ImportError: diff --git a/pyproject.toml b/pyproject.toml index ac4bdcc5f..77bec16a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,7 +117,7 @@ all = [ [project.scripts] hermes = "hermes_cli.main:main" hermes-agent = "run_agent:main" -hermes-acp = "acp_adapter.entry:main" +hermes-acp = "hermes_agent.acp.entry:main" [tool.setuptools] py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajectory_compressor", "toolset_distributions", "cli", "hermes_constants", "hermes_state", "hermes_time", "hermes_logging", "rl_cli", "utils"] @@ -126,7 +126,7 @@ py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajector hermes_cli = ["web_dist/**/*"] [tool.setuptools.packages.find] -include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "acp_adapter", "plugins", "plugins.*"] +include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "hermes_agent", "hermes_agent.*", "plugins", "plugins.*"] [tool.pytest.ini_options] testpaths = ["tests"] diff --git a/tests/acp/test_auth.py b/tests/acp/test_auth.py index ffb07463f..cda11a748 100644 --- a/tests/acp/test_auth.py +++ b/tests/acp/test_auth.py @@ -1,6 +1,6 @@ -"""Tests for acp_adapter.auth — provider detection.""" +"""Tests for hermes_agent.acp.auth — provider detection.""" -from acp_adapter.auth import has_provider, detect_provider +from hermes_agent.acp.auth import has_provider, detect_provider class TestHasProvider: diff --git a/tests/acp/test_entry.py b/tests/acp/test_entry.py index 760522c31..4d76f2db4 100644 --- a/tests/acp/test_entry.py +++ b/tests/acp/test_entry.py @@ -1,8 +1,8 @@ -"""Tests for acp_adapter.entry startup wiring.""" +"""Tests for hermes_agent.acp.entry startup wiring.""" import acp -from acp_adapter import entry +from hermes_agent.acp import entry def test_main_enables_unstable_protocol(monkeypatch): diff --git a/tests/acp/test_events.py b/tests/acp/test_events.py index c9f91a181..eb233fbe0 100644 --- a/tests/acp/test_events.py +++ b/tests/acp/test_events.py @@ -1,4 +1,4 @@ -"""Tests for acp_adapter.events — callback factories for ACP notifications.""" +"""Tests for hermes_agent.acp.events — callback factories for ACP notifications.""" import asyncio from concurrent.futures import Future @@ -9,7 +9,7 @@ import pytest import acp from acp.schema import ToolCallStart, ToolCallProgress, AgentThoughtChunk, AgentMessageChunk -from acp_adapter.events import ( +from hermes_agent.acp.events import ( make_message_cb, make_step_cb, make_thinking_cb, @@ -48,7 +48,7 @@ class TestToolProgressCallback: cb = make_tool_progress_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) # Run callback in the event loop context - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -72,7 +72,7 @@ class TestToolProgressCallback: cb = make_tool_progress_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -89,7 +89,7 @@ class TestToolProgressCallback: cb = make_tool_progress_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -107,7 +107,7 @@ class TestToolProgressCallback: progress_cb = make_tool_progress_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) step_cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -135,7 +135,7 @@ class TestThinkingCallback: cb = make_thinking_cb(mock_conn, "session-1", loop) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -150,7 +150,7 @@ class TestThinkingCallback: cb = make_thinking_cb(mock_conn, "session-1", loop) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: cb("") mock_rcts.assert_not_called() @@ -169,7 +169,7 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, {}) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -187,7 +187,7 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, {}) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: cb(1, [{"name": "unknown_tool", "result": "ok"}]) mock_rcts.assert_not_called() @@ -199,7 +199,7 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, {}) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -218,8 +218,8 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, {}) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ - patch("acp_adapter.events.build_tool_complete") as mock_btc: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ + patch("hermes_agent.acp.events.build_tool_complete") as mock_btc: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -240,8 +240,8 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, {}) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ - patch("acp_adapter.events.build_tool_complete") as mock_btc: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ + patch("hermes_agent.acp.events.build_tool_complete") as mock_btc: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -259,8 +259,8 @@ class TestStepCallback: cb = make_step_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ - patch("acp_adapter.events.build_tool_complete") as mock_btc: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts, \ + patch("hermes_agent.acp.events.build_tool_complete") as mock_btc: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -280,8 +280,8 @@ class TestStepCallback: tool_call_meta = {} loop = event_loop_fixture - with patch("acp_adapter.events.make_tool_call_id", return_value="tc-meta"), \ - patch("acp_adapter.events._send_update") as mock_send, \ + with patch("hermes_agent.acp.events.make_tool_call_id", return_value="tc-meta"), \ + patch("hermes_agent.acp.events._send_update") as mock_send, \ patch("agent.display.capture_local_edit_snapshot", return_value="snapshot"): cb = make_tool_progress_cb(mock_conn, "session-1", loop, tool_call_ids, tool_call_meta) cb("tool.started", "write_file", None, {"path": "diff-test.txt", "content": "hello"}) @@ -306,7 +306,7 @@ class TestMessageCallback: cb = make_message_cb(mock_conn, "session-1", loop) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: future = MagicMock(spec=Future) future.result.return_value = None mock_rcts.return_value = future @@ -321,7 +321,7 @@ class TestMessageCallback: cb = make_message_cb(mock_conn, "session-1", loop) - with patch("acp_adapter.events.asyncio.run_coroutine_threadsafe") as mock_rcts: + with patch("hermes_agent.acp.events.asyncio.run_coroutine_threadsafe") as mock_rcts: cb("") mock_rcts.assert_not_called() diff --git a/tests/acp/test_mcp_e2e.py b/tests/acp/test_mcp_e2e.py index 88e89acf2..8e3b2247e 100644 --- a/tests/acp/test_mcp_e2e.py +++ b/tests/acp/test_mcp_e2e.py @@ -27,9 +27,9 @@ from acp.schema import ( ToolCallStart, ) -from acp_adapter.server import HermesACPAgent -from acp_adapter.session import SessionManager -from acp_adapter.tools import build_tool_start +from hermes_agent.acp.server import HermesACPAgent +from hermes_agent.acp.session import SessionManager +from hermes_agent.acp.tools import build_tool_start # --------------------------------------------------------------------------- diff --git a/tests/acp/test_permissions.py b/tests/acp/test_permissions.py index 57e2bd4e5..a16f57fee 100644 --- a/tests/acp/test_permissions.py +++ b/tests/acp/test_permissions.py @@ -1,4 +1,4 @@ -"""Tests for acp_adapter.permissions — ACP approval bridging.""" +"""Tests for hermes_agent.acp.permissions — ACP approval bridging.""" import asyncio from concurrent.futures import Future @@ -11,7 +11,7 @@ from acp.schema import ( DeniedOutcome, RequestPermissionResponse, ) -from acp_adapter.permissions import make_approval_callback +from hermes_agent.acp.permissions import make_approval_callback def _make_response(outcome): @@ -37,7 +37,7 @@ def _setup_callback(outcome, timeout=60.0): future = MagicMock(spec=Future) future.result.return_value = response - with patch("acp_adapter.permissions.asyncio.run_coroutine_threadsafe", return_value=future): + with patch("hermes_agent.acp.permissions.asyncio.run_coroutine_threadsafe", return_value=future): cb = make_approval_callback(mock_rp, loop, session_id="s1", timeout=timeout) result = cb("rm -rf /", "dangerous command") @@ -68,7 +68,7 @@ class TestApprovalMapping: future = MagicMock(spec=Future) future.result.side_effect = TimeoutError("timed out") - with patch("acp_adapter.permissions.asyncio.run_coroutine_threadsafe", return_value=future): + with patch("hermes_agent.acp.permissions.asyncio.run_coroutine_threadsafe", return_value=future): cb = make_approval_callback(mock_rp, loop, session_id="s1", timeout=0.01) result = cb("rm -rf /", "dangerous") @@ -82,7 +82,7 @@ class TestApprovalMapping: future = MagicMock(spec=Future) future.result.return_value = None - with patch("acp_adapter.permissions.asyncio.run_coroutine_threadsafe", return_value=future): + with patch("hermes_agent.acp.permissions.asyncio.run_coroutine_threadsafe", return_value=future): cb = make_approval_callback(mock_rp, loop, session_id="s1", timeout=1.0) result = cb("echo hi", "demo") diff --git a/tests/acp/test_ping_suppression.py b/tests/acp/test_ping_suppression.py index b072bbd7a..d9d63275a 100644 --- a/tests/acp/test_ping_suppression.py +++ b/tests/acp/test_ping_suppression.py @@ -1,4 +1,4 @@ -"""Tests for acp_adapter.entry._BenignProbeMethodFilter. +"""Tests for hermes_agent.acp.entry._BenignProbeMethodFilter. Covers both the isolated filter logic and the full end-to-end path where a client sends a bare JSON-RPC ``ping`` request over stdio and the acp runtime @@ -18,7 +18,7 @@ import pytest from acp.exceptions import RequestError -from acp_adapter.entry import _BenignProbeMethodFilter +from hermes_agent.acp.entry import _BenignProbeMethodFilter # -- Unit tests on the filter itself ---------------------------------------- diff --git a/tests/acp/test_server.py b/tests/acp/test_server.py index faa4c18a7..257138856 100644 --- a/tests/acp/test_server.py +++ b/tests/acp/test_server.py @@ -1,4 +1,4 @@ -"""Tests for acp_adapter.server — HermesACPAgent ACP server.""" +"""Tests for hermes_agent.acp.server — HermesACPAgent ACP server.""" import asyncio import os @@ -28,8 +28,8 @@ from acp.schema import ( TextContentBlock, Usage, ) -from acp_adapter.server import HermesACPAgent, HERMES_VERSION -from acp_adapter.session import SessionManager +from hermes_agent.acp.server import HermesACPAgent, HERMES_VERSION +from hermes_agent.acp.session import SessionManager from hermes_state import SessionDB @@ -97,7 +97,7 @@ class TestAuthenticate: @pytest.mark.asyncio async def test_authenticate_with_matching_method_id(self, agent, monkeypatch): monkeypatch.setattr( - "acp_adapter.server.detect_provider", + "hermes_agent.acp.server.detect_provider", lambda: "openrouter", ) resp = await agent.authenticate(method_id="openrouter") @@ -106,7 +106,7 @@ class TestAuthenticate: @pytest.mark.asyncio async def test_authenticate_is_case_insensitive(self, agent, monkeypatch): monkeypatch.setattr( - "acp_adapter.server.detect_provider", + "hermes_agent.acp.server.detect_provider", lambda: "openrouter", ) resp = await agent.authenticate(method_id="OpenRouter") @@ -115,7 +115,7 @@ class TestAuthenticate: @pytest.mark.asyncio async def test_authenticate_rejects_mismatched_method_id(self, agent, monkeypatch): monkeypatch.setattr( - "acp_adapter.server.detect_provider", + "hermes_agent.acp.server.detect_provider", lambda: "openrouter", ) resp = await agent.authenticate(method_id="totally-invalid-method") @@ -124,7 +124,7 @@ class TestAuthenticate: @pytest.mark.asyncio async def test_authenticate_without_provider(self, agent, monkeypatch): monkeypatch.setattr( - "acp_adapter.server.detect_provider", + "hermes_agent.acp.server.detect_provider", lambda: None, ) resp = await agent.authenticate(method_id="openrouter") @@ -272,7 +272,7 @@ class TestListAndFork: @pytest.mark.asyncio async def test_list_sessions_pagination_first_page(self, agent): - from acp_adapter import server as acp_server + from hermes_agent.acp import server as acp_server infos = [ {"session_id": f"s{i}", "cwd": "/tmp", "title": None, "updated_at": 0.0} diff --git a/tests/acp/test_session.py b/tests/acp/test_session.py index 50d04b1a9..e3222ffa8 100644 --- a/tests/acp/test_session.py +++ b/tests/acp/test_session.py @@ -1,4 +1,4 @@ -"""Tests for acp_adapter.session — SessionManager and SessionState.""" +"""Tests for hermes_agent.acp.session — SessionManager and SessionState.""" import contextlib import io @@ -8,7 +8,7 @@ from types import SimpleNamespace import pytest from unittest.mock import MagicMock, patch -from acp_adapter.session import SessionManager, SessionState +from hermes_agent.acp.session import SessionManager, SessionState from hermes_state import SessionDB @@ -38,7 +38,7 @@ class TestCreateSession: def test_create_session_registers_task_cwd(self, manager, monkeypatch): calls = [] - monkeypatch.setattr("acp_adapter.session._register_task_cwd", lambda task_id, cwd: calls.append((task_id, cwd))) + monkeypatch.setattr("hermes_agent.acp.session._register_task_cwd", lambda task_id, cwd: calls.append((task_id, cwd))) state = manager.create_session(cwd="/tmp/work") assert calls == [(state.session_id, "/tmp/work")] diff --git a/tests/acp/test_tools.py b/tests/acp/test_tools.py index 603fe7459..488e01ef7 100644 --- a/tests/acp/test_tools.py +++ b/tests/acp/test_tools.py @@ -1,8 +1,8 @@ -"""Tests for acp_adapter.tools — tool kind mapping and ACP content building.""" +"""Tests for hermes_agent.acp.tools — tool kind mapping and ACP content building.""" import pytest -from acp_adapter.tools import ( +from hermes_agent.acp.tools import ( TOOL_KIND_MAP, build_tool_complete, build_tool_start,