|
| 1 | +"""Wire-up tests for ``AC_run_agent`` + ``ac_run_agent``. |
| 2 | +
|
| 3 | +The closed-loop AgentLoop already has direct-API tests in |
| 4 | +``test_agent_loop.py``. These tests cover the new executor + MCP |
| 5 | +adapters: they verify both surfaces register, dispatch to AgentLoop, |
| 6 | +and faithfully return the structured result. A ``FakeAgentBackend`` |
| 7 | +is patched in so the tests never hit a real LLM. |
| 8 | +""" |
| 9 | +from __future__ import annotations |
| 10 | + |
| 11 | +from typing import Any, Dict, List |
| 12 | + |
| 13 | +from je_auto_control.utils.agent import FakeAgentBackend |
| 14 | + |
| 15 | + |
| 16 | +def _stub_backend_factory(decisions: List[Dict[str, Any]]): |
| 17 | + """Return an Anthropic-/OpenAI-backend stub that ignores tools kwargs.""" |
| 18 | + def factory(*_args, **_kwargs): |
| 19 | + return FakeAgentBackend(decisions) |
| 20 | + return factory |
| 21 | + |
| 22 | + |
| 23 | +def _patch_backends(monkeypatch, decisions): |
| 24 | + """Replace both production backends with the FakeAgentBackend stub.""" |
| 25 | + factory = _stub_backend_factory(decisions) |
| 26 | + import je_auto_control.utils.agent.backends as backends_pkg |
| 27 | + monkeypatch.setattr(backends_pkg, "AnthropicAgentBackend", factory) |
| 28 | + monkeypatch.setattr(backends_pkg, "OpenAIAgentBackend", factory) |
| 29 | + # Disable the screenshot helper so the loop doesn't try to grab a |
| 30 | + # real frame on the CI runner. |
| 31 | + from je_auto_control.utils.agent import agent_loop as loop_mod |
| 32 | + monkeypatch.setattr(loop_mod, "_default_screenshot", lambda: None) |
| 33 | + |
| 34 | + |
| 35 | +def test_executor_registers_ac_run_agent(): |
| 36 | + from je_auto_control.utils.executor.action_executor import executor |
| 37 | + assert "AC_run_agent" in executor.known_commands() |
| 38 | + |
| 39 | + |
| 40 | +def test_mcp_registry_exposes_ac_run_agent(): |
| 41 | + from je_auto_control.utils.mcp_server.tools import ( |
| 42 | + build_default_tool_registry, |
| 43 | + ) |
| 44 | + names = {tool.name for tool in build_default_tool_registry()} |
| 45 | + assert "ac_run_agent" in names |
| 46 | + |
| 47 | + |
| 48 | +def test_executor_path_runs_agent_loop(monkeypatch): |
| 49 | + _patch_backends(monkeypatch, [ |
| 50 | + {"stop": True, "message": "done by stub"}, |
| 51 | + ]) |
| 52 | + # Stop AgentLoop from trying to dispatch a real AC_* tool. |
| 53 | + from je_auto_control.utils.executor.action_executor import _run_agent |
| 54 | + result = _run_agent( |
| 55 | + goal="probe", backend="anthropic", |
| 56 | + max_steps=2, wall_seconds=5.0, |
| 57 | + ) |
| 58 | + assert result["succeeded"] is True |
| 59 | + assert result["final_message"] == "done by stub" |
| 60 | + assert len(result["steps"]) == 1 |
| 61 | + |
| 62 | + |
| 63 | +def test_mcp_handler_round_trips(monkeypatch): |
| 64 | + _patch_backends(monkeypatch, [ |
| 65 | + {"stop": True, "message": "mcp-ok"}, |
| 66 | + ]) |
| 67 | + from je_auto_control.utils.mcp_server.tools._handlers import run_agent |
| 68 | + record = run_agent( |
| 69 | + goal="probe-mcp", backend="openai", |
| 70 | + max_steps=2, wall_seconds=5.0, |
| 71 | + ) |
| 72 | + assert record["succeeded"] is True |
| 73 | + assert record["final_message"] == "mcp-ok" |
| 74 | + |
| 75 | + |
| 76 | +def test_unknown_backend_raises(): |
| 77 | + from je_auto_control.utils.executor.action_executor import _run_agent |
| 78 | + import pytest |
| 79 | + with pytest.raises(ValueError, match="unknown agent backend"): |
| 80 | + _run_agent(goal="x", backend="bogus") |
0 commit comments