from __future__ import annotations from beaver.coordinator.models import AgentDescriptor, ExecutionGraph, ExecutionNode from beaver.coordinator.registry import AgentRegistry, RegisteredAgent, TargetResolver from beaver.tasks import TaskRecord def _task() -> TaskRecord: return TaskRecord( task_id="task-1", session_id="session-1", description="implement tests", goal="implement tests", constraints=[], priority=0, status="open", creator="test", created_at="now", updated_at="now", ) def test_registry_seeds_builtin_agents_and_filters_disabled(tmp_path) -> None: registry = AgentRegistry(tmp_path) assert {agent.agent_id for agent in registry.list_active_agents()} >= { "researcher", "implementer", "reviewer", "tester", "documenter", } registry.disable_agent("tester") assert "tester" not in {agent.agent_id for agent in registry.list_active_agents()} def test_resolver_selects_registered_agent_by_role_and_capabilities(tmp_path) -> None: registry = AgentRegistry(tmp_path) registry.upsert_agent( RegisteredAgent( agent_id="security-reviewer", name="security-reviewer", display_name="Security Reviewer", role="security review", description="Reviews auth, permissions, and data exposure risk.", system_prompt="review security", capabilities=["security", "review", "auth"], priority=90, ) ) resolver = TargetResolver(registry) graph = ExecutionGraph( strategy="sequence", nodes=[ ExecutionNode( node_id="review", task="review auth handling", agent=AgentDescriptor( name="reviewer", role="security review", metadata={"requested_capabilities": ["security"]}, ), ) ], ) resolved, reports = resolver.resolve_graph(graph, task=_task(), user_message="review auth", attempt_index=1) assert resolved.nodes[0].agent.metadata["agent_id"] == "security-reviewer" assert reports[0].fallback_used is False assert reports[0].selected_agent_id == "security-reviewer" def test_resolver_falls_back_to_ephemeral_agent_when_no_match(tmp_path) -> None: registry = AgentRegistry(tmp_path) for agent in registry.list_agents(): registry.disable_agent(agent.agent_id) resolver = TargetResolver(registry) graph = ExecutionGraph( strategy="sequence", nodes=[ExecutionNode("rare", "rare work", AgentDescriptor(name="rare", role="rare"))], ) resolved, reports = resolver.resolve_graph(graph, task=_task(), user_message="rare work", attempt_index=1) assert resolved.nodes[0].agent.name == "rare" assert resolved.nodes[0].agent.metadata["resolution"] == "fallback_ephemeral" assert reports[0].fallback_used is True