myrmidon / python /tests /integration /services /test_agent_awakening.py
tek Atrust
chore(deploy): build monolithic server for Hugging Face
d5ef46f
Raw
History Blame Contribute Delete
3.95 kB
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
import src.server.services.agents.dispatcher
from src.server.services.agent_registry import get_agent_config
from src.server.services.agent_service import AgentService
from src.server.services.projects.task_service import task_service as real_task_service
@pytest.mark.asyncio
class TestAgentAwakening:
async def test_agent_registry_load(self):
"""Verify Registry loads correct config for known agents."""
# 1. MarketBot
market_config = get_agent_config("market-bot")
assert market_config is not None
assert market_config["name"] == "Archon MarketBot"
assert "search_job_market" in market_config["tools"]
assert "Marketing Content Writer" in market_config["system_prompt"] or "Blog" in market_config["system_prompt"]
# 2. Librarian
lib_config = get_agent_config("librarian")
assert lib_config is not None
assert lib_config["name"] == "Archon Librarian"
assert "rag_search_knowledge_base" in lib_config["tools"]
@patch.object(src.server.services.agents.dispatcher, "get_llm_client")
@patch.object(src.server.services.agents.dispatcher, "credential_service")
async def test_marketbot_awakening_loop(self, mock_cred_service, mock_get_client):
"""
Verify MarketBot wakes up, loads its prompt, and executes a task loop.
"""
# Physical Alignment: Setup Mock MCP Client with new OpenAI-style tool schema (Phase 4.6.19)
mock_mcp = AsyncMock()
mock_mcp.list_tools.return_value = [
{
"type": "function",
"function": {"name": "search_job_market", "description": "Search 104", "parameters": {}},
},
{
"type": "function",
"function": {"name": "perform_rag_query", "description": "Search RAG", "parameters": {}},
},
]
service = AgentService(mcp_client=mock_mcp)
# Mock LLM Client
mock_client_instance = AsyncMock()
mock_get_client.return_value.__aenter__.return_value = mock_client_instance
# Simulate LLM Response
mock_response = MagicMock()
mock_response.choices[0].message.content = "Blog Draft Content"
mock_response.choices[0].message.tool_calls = None
mock_client_instance.chat.completions.create.return_value = mock_response
with patch.object(real_task_service, 'get_task', new_callable=AsyncMock, return_value=(True, {"task": {"title": "Write a blog", "description": "About AI"}})) as mock_get_task, \
patch.object(real_task_service, 'update_task', new_callable=AsyncMock, return_value=(True, {})):
mock_cred_service.get_credential = AsyncMock(return_value="fake_key")
# Execute Run (MarketBot) - Phase 5.1.0: Use immediate=True to run synchronously in test
await service.run_agent_task(task_id="task_123", agent_id="market-bot", immediate=True)
# Verify:
# 1. Task was fetched
mock_get_task.assert_called_with("task_123")
# 2. LLM was called with MarketBot's System Prompt
call_args = mock_client_instance.chat.completions.create.call_args
assert call_args is not None
messages = call_args.kwargs["messages"]
system_msg = messages[0]
assert system_msg["role"] == "system"
# Check if system prompt matches registry
config = get_agent_config("market-bot")
assert system_msg["content"] == config["system_prompt"]
# 3. Tools were passed
tools = call_args.kwargs["tools"]
assert tools is not None
# We expected filtered tools for MarketBot
tool_names = [t["function"]["name"] for t in tools]
assert "search_job_market" in tool_names
assert "search_code_examples" not in tool_names # DevBot tool should NOT be here