""" Tests for the Plan agent. Tests registration, API endpoints, and tool restrictions. """ import pytest from src.domains.agents.base import get_agent, list_agents from src.domains.agents.plan import plan_agent, PlanAgentImpl class TestPlanAgentRegistration: """Tests for Plan agent registration.""" def test_plan_agent_registered(self): """Test that plan agent is registered in registry.""" agent = get_agent("plan") assert agent is not None assert agent.name == "plan" def test_plan_agent_in_list(self): """Test that plan agent appears in agent list.""" agents = list_agents() names = [a["name"] for a in agents] assert "plan" in names def test_plan_agent_has_description(self): """Test that plan agent has a description.""" agent = get_agent("plan") assert agent is not None assert len(agent.description) > 0 assert "plan" in agent.description.lower() or "architect" in agent.description.lower() def test_plan_agent_singleton(self): """Test that plan_agent is the registered instance.""" registered = get_agent("plan") assert registered is plan_agent def test_plan_agent_is_correct_type(self): """Test that plan agent is correct implementation type.""" assert isinstance(plan_agent, PlanAgentImpl) class TestPlanAgentTools: """Tests for Plan agent tool restrictions.""" def test_plan_agent_has_read_only_tools(self): """Test that plan agent has read-only tools.""" # Access the underlying PydanticAI agent to check tools agent = plan_agent.agent tool_names = list(agent._function_toolset.tools.keys()) # Should have read-only tools assert "read_file" in tool_names assert "glob_files" in tool_names assert "grep_content" in tool_names assert "bash_readonly" in tool_names def test_plan_agent_no_write_tools(self): """Test that plan agent does NOT have write tools.""" agent = plan_agent.agent tool_names = list(agent._function_toolset.tools.keys()) # Should NOT have write tools assert "edit_file" not in tool_names assert "write_file" not in tool_names assert "bash" not in tool_names assert "web_search" not in tool_names def test_plan_agent_tool_count(self): """Test that plan agent has exactly 4 tools.""" agent = plan_agent.agent tool_count = len(agent._function_toolset.tools) assert tool_count == 4 class TestPlanAgentAPI: """Tests for Plan agent REST API.""" @pytest.mark.anyio async def test_list_agents_includes_plan(self, auth_client): """Test that agent list includes plan agent.""" response = await auth_client.get("/agents/") assert response.status_code == 200 data = response.json() names = [a["name"] for a in data["agents"]] assert "plan" in names @pytest.mark.anyio async def test_get_plan_agent_info(self, auth_client): """Test getting plan agent info.""" response = await auth_client.get("/agents/plan") assert response.status_code == 200 data = response.json() assert data["name"] == "plan" assert "description" in data assert len(data["description"]) > 0 @pytest.mark.anyio async def test_run_plan_with_invalid_body(self, auth_client): """Test running plan agent with invalid request.""" response = await auth_client.post( "/agents/run", json={ "agent_type": "plan", # Missing prompt } ) assert response.status_code == 422 @pytest.mark.anyio async def test_stream_plan_with_invalid_body(self, auth_client): """Test streaming plan agent with invalid request.""" response = await auth_client.post( "/agents/stream", json={ "agent_type": "plan", # Missing prompt } ) assert response.status_code == 422 class TestPlanAgentProperties: """Tests for Plan agent properties and configuration.""" def test_plan_agent_name(self): """Test plan agent name property.""" assert plan_agent.name == "plan" def test_plan_agent_description_not_empty(self): """Test plan agent description is not empty.""" assert plan_agent.description assert len(plan_agent.description) > 10 def test_plan_agent_creates_agent_lazily(self): """Test that PydanticAI agent is created lazily.""" # Create a fresh instance fresh_agent = PlanAgentImpl() # _agent should be None before first access assert fresh_agent._agent is None # Access the agent property _ = fresh_agent.agent # Now _agent should be set assert fresh_agent._agent is not None