mohammedafeef's picture
Upload 16 files
9b9a6d7 verified
"""
graph.py – LangGraph Workflow Builder
Assembles the four agent nodes into a cyclic state machine:
[START] → orchestrator → router → knowledge_agent ─┐
↑ memory_agent ─────┤
└─────────action_agent ─────┘
└──── (final_response) → [END]
"""
import logging
from langgraph.graph import StateGraph, END
from chronic_chatbot.state import AgentState
from chronic_chatbot.agents import (
orchestrator_node,
knowledge_node,
memory_node,
action_node,
)
logger = logging.getLogger(__name__)
def router(state: AgentState) -> str:
"""
Conditional edge function.
Reads state.next_step set by the Orchestrator and routes to
the appropriate agent node or END.
"""
step = state.get("next_step", "final_response")
logger.debug(f"Router → {step}")
routing_map = {
"knowledge": "knowledge_agent",
"memory": "memory_agent",
"action": "action_agent",
"final_response": END,
}
return routing_map.get(step, END)
def build_graph() -> "CompiledGraph":
"""
Construct and compile the LangGraph workflow.
Returns the compiled app ready for `app.invoke(state)` calls.
"""
workflow = StateGraph(AgentState)
# ── Register Nodes ─────────────────────────────────────────
workflow.add_node("orchestrator", orchestrator_node)
workflow.add_node("knowledge_agent", knowledge_node)
workflow.add_node("memory_agent", memory_node)
workflow.add_node("action_agent", action_node)
# ── Entry Point ────────────────────────────────────────────
workflow.set_entry_point("orchestrator")
# ── Conditional Routing from Orchestrator ──────────────────
workflow.add_conditional_edges(
"orchestrator",
router,
{
"knowledge_agent": "knowledge_agent",
"memory_agent": "memory_agent",
"action_agent": "action_agent",
END: END,
},
)
# ── Return Edges – Sub-agents always report back ───────────
workflow.add_edge("knowledge_agent", "orchestrator")
workflow.add_edge("memory_agent", "orchestrator")
workflow.add_edge("action_agent", "orchestrator")
app = workflow.compile()
logger.info("✅ LangGraph workflow compiled successfully")
return app
# Module-level singleton – import this in main.py
graph_app = build_graph()