zico-agent / src /graphs /factory.py
github-actions[bot]
Deploy from GitHub Actions: 25f0efbf9a8fcc4d5894a569297e8aeecffe8b08
156dd84
"""
StateGraph construction and compilation.
Wires together all nodes and conditional edges into a single compiled graph.
"""
from __future__ import annotations
import logging
from langgraph.graph import END, StateGraph
from src.graphs.state import AgentState
from src.graphs.nodes import (
entry_node,
semantic_router_node,
llm_router_node,
error_node,
swap_agent_node,
lending_agent_node,
staking_agent_node,
liquidity_agent_node,
dca_agent_node,
strategy_agent_node,
crypto_agent_node,
search_agent_node,
default_agent_node,
database_agent_node,
portfolio_advisor_node,
)
from src.graphs.edges import decide_route, after_llm_router
from src.agents.formatter.node import formatter_node
logger = logging.getLogger(__name__)
# All agent nodes that feed into the formatter
_AGENT_NODES = [
"swap_agent_node",
"lending_agent_node",
"staking_agent_node",
"liquidity_agent_node",
"dca_agent_node",
"strategy_agent_node",
"crypto_agent_node",
"search_agent_node",
"default_agent_node",
"database_agent_node",
"portfolio_advisor_node",
]
def build_graph() -> StateGraph:
"""
Construct and compile the Zico agent StateGraph.
Flow:
entry β†’ semantic_router β†’ {decide_route} β†’ agent / llm_router / error
llm_router β†’ {after_llm_router} β†’ agent
agent β†’ formatter β†’ END
error β†’ END
"""
graph = StateGraph(AgentState)
# --- Register nodes ---
graph.add_node("entry_node", entry_node)
graph.add_node("semantic_router_node", semantic_router_node)
graph.add_node("llm_router_node", llm_router_node)
graph.add_node("error_node", error_node)
graph.add_node("formatter_node", formatter_node)
graph.add_node("swap_agent_node", swap_agent_node)
graph.add_node("lending_agent_node", lending_agent_node)
graph.add_node("staking_agent_node", staking_agent_node)
graph.add_node("liquidity_agent_node", liquidity_agent_node)
graph.add_node("dca_agent_node", dca_agent_node)
graph.add_node("strategy_agent_node", strategy_agent_node)
graph.add_node("crypto_agent_node", crypto_agent_node)
graph.add_node("search_agent_node", search_agent_node)
graph.add_node("default_agent_node", default_agent_node)
graph.add_node("database_agent_node", database_agent_node)
graph.add_node("portfolio_advisor_node", portfolio_advisor_node)
# --- Entry point ---
graph.set_entry_point("entry_node")
# --- Linear edges ---
graph.add_edge("entry_node", "semantic_router_node")
# --- Conditional: after semantic router ---
graph.add_conditional_edges(
"semantic_router_node",
decide_route,
{
"error_node": "error_node",
"llm_router_node": "llm_router_node",
"swap_agent_node": "swap_agent_node",
"lending_agent_node": "lending_agent_node",
"staking_agent_node": "staking_agent_node",
"liquidity_agent_node": "liquidity_agent_node",
"dca_agent_node": "dca_agent_node",
"strategy_agent_node": "strategy_agent_node",
"crypto_agent_node": "crypto_agent_node",
"search_agent_node": "search_agent_node",
"default_agent_node": "default_agent_node",
"database_agent_node": "database_agent_node",
"portfolio_advisor_node": "portfolio_advisor_node",
},
)
# --- Conditional: after LLM router ---
graph.add_conditional_edges(
"llm_router_node",
after_llm_router,
{
"swap_agent_node": "swap_agent_node",
"lending_agent_node": "lending_agent_node",
"staking_agent_node": "staking_agent_node",
"liquidity_agent_node": "liquidity_agent_node",
"dca_agent_node": "dca_agent_node",
"strategy_agent_node": "strategy_agent_node",
"crypto_agent_node": "crypto_agent_node",
"search_agent_node": "search_agent_node",
"default_agent_node": "default_agent_node",
"database_agent_node": "database_agent_node",
"portfolio_advisor_node": "portfolio_advisor_node",
},
)
# --- All agent nodes β†’ formatter β†’ END ---
for node_name in _AGENT_NODES:
graph.add_edge(node_name, "formatter_node")
graph.add_edge("formatter_node", END)
# --- Error β†’ END ---
graph.add_edge("error_node", END)
compiled = graph.compile()
logger.info("StateGraph compiled: %d nodes", len(_AGENT_NODES) + 5)
return compiled