Files
nextcraft/apps/ai-service/tests/agents/test_registry.py
T
CIAgent 88a1dab810 docs(milestone): complete v0.2-ai-tutor-architecture
---ci---
phase: 7
milestone: v0.2
status: complete
requirements:
  covered: [REQ-2-001, REQ-2-002, REQ-2-003, REQ-2-004, REQ-2-005, REQ-2-006, REQ-2-007, REQ-2-008, REQ-2-009, REQ-2-010, REQ-2-011, REQ-2-012]
  partial: []
---/ci---

Milestone v0.2 (ai-tutor-architecture) merged to main.

Escalation record (audit remediation, durable): P1 executor
delegation failed twice (empty subagent results, zero files
created); auto-resolved at full autonomy to inline execution with
identical plan fidelity (commit 3271373, reflog-only after phase
branch squash-delete).
2026-09-11 17:34:50 +00:00

133 lines
4.4 KiB
Python

"""Agent registry tests — register/get round-trip, error paths (G-4), builtins."""
import pytest
from ai_service.agents.base import BaseAgent
from ai_service.agents.coach import CoachAgent
from ai_service.agents.registry import (
AgentRegistry,
DuplicateAgentError,
UnknownAgentError,
register_builtin_agents,
)
from ai_service.agents.tutor import TutorAgent
from ai_service.config import Settings
from ai_service.llm.mock import MockProvider
class DummyAgent(BaseAgent):
name = "dummy"
def system_prompt(self, learner_context=None) -> str:
return "dummy"
def make_factory():
def factory(provider, settings):
return DummyAgent(provider, settings)
return factory
def test_register_and_get():
registry = AgentRegistry()
registry.register("dummy", make_factory())
agent = registry.get(MockProvider(), Settings(provider="mock"), "dummy")
assert isinstance(agent, DummyAgent)
assert agent.name == "dummy"
def test_unknown_agent_raises():
registry = AgentRegistry()
with pytest.raises(UnknownAgentError):
registry.get(MockProvider(), Settings(provider="mock"), "ghost")
def test_duplicate_registration_raises():
registry = AgentRegistry()
registry.register("dummy", make_factory())
with pytest.raises(DuplicateAgentError):
registry.register("dummy", make_factory())
def test_names_sorted():
registry = AgentRegistry()
registry.register("zeta", make_factory())
registry.register("alpha", make_factory())
assert registry.names() == ["alpha", "zeta"]
def test_builtin_agents_register_and_resolve():
registry = AgentRegistry()
register_builtin_agents(registry)
assert set(registry.names()) >= {"coach", "tutor"}
settings = Settings(provider="mock")
coach = registry.get(MockProvider(), settings, "coach")
tutor = registry.get(MockProvider(), settings, "tutor")
assert isinstance(coach, CoachAgent)
assert isinstance(tutor, TutorAgent)
def test_lab_and_assessor_resolve_via_registry():
"""Phase 4: lab + assessor registered centrally (Task 4-3-01)."""
from ai_service.agents.assessor import AssessorAgent
from ai_service.agents.lab import LabAgent
registry = AgentRegistry()
register_builtin_agents(registry)
assert {"lab", "assessor"} <= set(registry.names())
settings = Settings(provider="mock")
lab = registry.get(MockProvider(), settings, "lab")
assessor = registry.get(MockProvider(), settings, "assessor")
assert isinstance(lab, LabAgent)
assert isinstance(assessor, AssessorAgent)
def test_proctor_and_mentor_resolve_via_registry():
"""Phase 5: proctor + mentor registered centrally (Tasks 5-1-02/5-2-01)."""
from ai_service.agents.mentor import MentorAgent
from ai_service.agents.proctor import ProctorAgent
registry = AgentRegistry()
register_builtin_agents(registry)
settings = Settings(provider="mock")
proctor = registry.get(MockProvider(), settings, "proctor")
mentor = registry.get(MockProvider(), settings, "mentor")
assert isinstance(proctor, ProctorAgent)
assert isinstance(mentor, MentorAgent)
def test_registry_resolves_all_six_agents():
"""Must-Have (Phase 5): the full roster — coach/tutor/lab/assessor/proctor/mentor."""
from ai_service.agents.assessor import AssessorAgent
from ai_service.agents.coach import CoachAgent
from ai_service.agents.lab import LabAgent
from ai_service.agents.mentor import MentorAgent
from ai_service.agents.proctor import ProctorAgent
from ai_service.agents.tutor import TutorAgent
registry = AgentRegistry()
register_builtin_agents(registry)
assert registry.names() == ["assessor", "coach", "lab", "mentor", "proctor", "tutor"]
settings = Settings(provider="mock")
expected = {
"coach": CoachAgent,
"tutor": TutorAgent,
"lab": LabAgent,
"assessor": AssessorAgent,
"proctor": ProctorAgent,
"mentor": MentorAgent,
}
for name, cls in expected.items():
agent = registry.get(MockProvider(), settings, name)
assert isinstance(agent, cls), f"{name} resolved to {type(agent).__name__}"
assert agent.name == name
def test_builtin_registration_is_idempotent_safe():
"""Duplicate registration raises — builtin bootstrap must be called once."""
registry = AgentRegistry()
register_builtin_agents(registry)
with pytest.raises(DuplicateAgentError):
register_builtin_agents(registry)