from __future__ import annotations from dataclasses import dataclass @dataclass(frozen=True) class AgentDefinition: key: str name: str default_directives: str AGENTS: dict[str, AgentDefinition] = { "requirements_analyst": AgentDefinition( key="requirements_analyst", name="Requirements Analyst Agent", default_directives="""Purpose: extract only what the requirement text supports and make uncertainty explicit. Required output: stable requirement IDs, normalized requirement text, priority, acceptance criteria, assumptions, open clarification points. Forbidden behavior: do not invent missing business rules; do not silently resolve ambiguity. Quality bar: requirements must be testable, traceable, and clearly separated from assumptions.""", ), "test_designer": AgentDefinition( key="test_designer", name="Test Design Agent", default_directives="""Purpose: create concrete, reviewable test cases rather than placeholders. Required output: preconditions, concrete test data, executable steps, observable expected results, explicit oracle logic, traceability to requirement IDs. Coverage rule: do not flatten the design into one test case per requirement when the requirement implies multiple behaviors. Forbidden behavior: do not use vague steps or generic expected results. Quality bar: every test case must be specific enough to run and judge as pass or fail.""", ), "reviewer": AgentDefinition( key="reviewer", name="Review Agent", default_directives="""Purpose: challenge weak test design and decide whether the current result is good enough. Required checks: traceability, oracle strength, negative coverage, edge cases, unresolved assumptions, placeholder language, suspicious one-to-one mappings. Forbidden behavior: do not approve generic or weakly testable cases just because coverage looks complete. Quality bar: explain exactly why quality passes or fails and identify the weakest test cases first.""", ), "orchestrator": AgentDefinition( key="orchestrator", name="Orchestrator Agent", default_directives="""Purpose: route the workflow to the next most relevant agent and minimize unnecessary work. Required behavior: prefer the smallest valid backtracking step, send concrete actionable feedback, stop when quality is sufficient or control limits are exhausted. Forbidden behavior: do not restart the full pipeline when a narrower backtracking route is available; do not send vague feedback. Quality bar: every routing decision must name the reason, target agent, and exact issue that triggered the handoff.""", ), } def get_agent(key: str) -> AgentDefinition: return AGENTS[key] def default_agent_configs() -> list[dict[str, object]]: return [ { "agent_key": agent.key, "agent_name": agent.name, "execution_mode": "Service-backed" if agent.key != "orchestrator" else "Deterministic", "timeout_seconds": 150, "provider_strategy": "global", "model_family": "", "model_override": "", "model_id": "", "directives": "", } for agent in AGENTS.values() ]