Create build_graph
Browse files- agents/build_graph +47 -0
agents/build_graph
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langgraph.graph import StateGraph, END
|
| 2 |
+
|
| 3 |
+
def build_graph(llm_model_name: str = "gpt-4o-mini"):
|
| 4 |
+
|
| 5 |
+
# --- Base LLM for agents & synthesizer (swap to your provider as needed) ---
|
| 6 |
+
openai_api_key="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"
|
| 7 |
+
llm = ChatOpenAI(api_key=openai_api_key,model=llm_model_name, temperature=0)
|
| 8 |
+
|
| 9 |
+
# --- Create specialized agents ---
|
| 10 |
+
news_agent = make_news_agent(llm)
|
| 11 |
+
earnings_agent = make_earnings_agent(llm)
|
| 12 |
+
market_agent = make_market_agent(llm)
|
| 13 |
+
|
| 14 |
+
# --- Create synthesizer chain ---
|
| 15 |
+
synthesizer = make_synthesizer(llm)
|
| 16 |
+
|
| 17 |
+
# --- LangGraph: wire nodes ---
|
| 18 |
+
g = StateGraph(GraphState)
|
| 19 |
+
|
| 20 |
+
# Bind node callables with their dependencies via closures
|
| 21 |
+
g.add_node("news", lambda s: news_node(s, news_agent))
|
| 22 |
+
g.add_node("earnings", lambda s: earnings_node(s, earnings_agent))
|
| 23 |
+
g.add_node("market", lambda s: market_node(s, market_agent))
|
| 24 |
+
g.add_node("synth", lambda s: synth_node(s, synthesizer))
|
| 25 |
+
|
| 26 |
+
# Supervisor node
|
| 27 |
+
g.add_node("supervisor", supervisor_node)
|
| 28 |
+
# Edges: start -> supervisor -> (news|earnings|market|synth) -> supervisor ... -> synth -> END
|
| 29 |
+
g.set_entry_point("supervisor")
|
| 30 |
+
|
| 31 |
+
for a in AGENTS:
|
| 32 |
+
g.add_edge(a, "supervisor")
|
| 33 |
+
g.add_edge("synth", END)
|
| 34 |
+
|
| 35 |
+
# Route decisions come from the router function (returns a string)
|
| 36 |
+
g.add_conditional_edges(
|
| 37 |
+
"supervisor",
|
| 38 |
+
supervisor_router, # returns: "news" | "earnings" | "market" | "synth"
|
| 39 |
+
{
|
| 40 |
+
"news": "news",
|
| 41 |
+
"earnings": "earnings",
|
| 42 |
+
"market": "market",
|
| 43 |
+
"synth": "synth",
|
| 44 |
+
},
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
return g.compile()
|