# factlens_crew/orchestrator.py
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableParallel
from factlens_crew.schemas import VerificationState
def build_factlens_graph():
workflow = StateGraph(VerificationState)
# Register the 12 Stage Nodes
workflow.add_node("intake", intake_agent)
workflow.add_node("router", domain_router_agent)
workflow.add_node("retrieval_trio", RunnableParallel({
"web": web_scout_agent,
"archive": archive_hunter_agent,
"extractor": data_extractor_agent
}))
workflow.add_node("tri_consistency", tri_consistency_agent)
workflow.add_node("aggregator", evidence_aggregator_agent)
workflow.add_node("skeptic", skeptic_agent)
workflow.add_node("auditor", evidence_auditor_agent)
workflow.add_node("stat_comparator", stat_comparator_agent)
workflow.add_node("moderator", consensus_moderator_agent)
workflow.add_node("rebuttal_loop", rebuttal_agent)
workflow.add_node("memory_tail", memory_tail_node)
# Edge Sequence
workflow.set_entry_point("intake")
workflow.add_edge("intake", "router")
workflow.add_edge("router", "retrieval_trio")
workflow.add_edge("retrieval_trio", "tri_consistency")
workflow.add_edge("tri_consistency", "aggregator")
workflow.add_edge("aggregator", "skeptic")
workflow.add_edge("skeptic", "auditor")
workflow.add_edge("auditor", "stat_comparator")
workflow.add_edge("stat_comparator", "moderator")
# Conditional Rebuttal Edge: If Skeptic flags contradiction & confidence < 80%
workflow.add_conditional_edges(
"moderator",
should_rebut,
{
"rebuttal": "rebuttal_loop",
"finalize": "memory_tail"
}
)
workflow.add_edge("rebuttal_loop", "auditor")
workflow.add_edge("memory_tail", END)
return workflow.compile()