tomas.helmfridsson
Add HF-backed LangGraph app and deploy workflow
b85de73
Raw History Blame Contribute Delete
3.26 kB
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()
]