use std::sync::Arc;
use lellm_graph::{Graph, GraphBuilder, NodeKind, TaskNode};
use super::super::typed_state::{AgentState, AgentStateMerge};
use super::guards::{BudgetCondition, CompactorNode, PostLLMGuard, StopConfig};
use super::llm_node::LLMNode;
use super::tool_node::ToolNode;
pub fn build_react_graph(
llm_node: LLMNode,
tool_node: ToolNode,
compactor_node: CompactorNode,
) -> Graph<AgentState, AgentStateMerge> {
let llm_name = llm_node.name.clone();
let budget = llm_node.config.context_budget.clone();
let stop_config = StopConfig::from_tool_use_config(&llm_node.config);
let mut builder =
GraphBuilder::<AgentState, AgentStateMerge>::new(format!("react_{}", llm_name));
builder.start("budget_check");
builder.end("end");
builder.node("llm", NodeKind::ExternalLeaf(Arc::new(llm_node)));
builder.node("tool", NodeKind::ExternalLeaf(Arc::new(tool_node)));
builder.node(
"post_llm_check",
NodeKind::ExternalLeaf(Arc::new(PostLLMGuard::new(
format!("{}_post_llm", llm_name),
stop_config,
))),
);
builder.node(
"budget_check",
NodeKind::ExternalLeaf(Arc::new(BudgetCondition::new(
format!("{}_budget", llm_name),
budget,
))),
);
builder.node(
"compactor",
NodeKind::ExternalLeaf(Arc::new(compactor_node)),
);
builder.node(
"end",
NodeKind::Task(TaskNode::<AgentState>::new("end", |_| Ok(()))),
);
builder.edge("budget_check", "llm");
builder.edge_fallback("budget_check", "compactor");
builder.edge("compactor", "llm");
builder.edge("llm", "post_llm_check");
builder.edge("post_llm_check", "tool");
builder.edge_fallback("post_llm_check", "end");
builder.edge("tool", "budget_check");
builder.build().expect("ReAct graph should be valid")
}