adk_graph/lib.rs
1//! # adk-graph
2//!
3//! Graph-based workflow orchestration for ADK-Rust agents, inspired by LangGraph.
4//!
5//! ## Overview
6//!
7//! `adk-graph` provides a powerful way to build complex, stateful agent workflows
8//! using a graph-based approach. It brings LangGraph-style capabilities to the Rust
9//! ADK ecosystem while maintaining full compatibility with ADK's agent system,
10//! callbacks, and streaming infrastructure.
11//!
12//! ## Features
13//!
14//! - **Graph-Based Workflows**: Define agent workflows as directed graphs
15//! - **Cyclic Support**: Native support for loops and iterative reasoning
16//! - **Conditional Routing**: Dynamic edge routing based on state
17//! - **State Management**: Typed state with reducers (overwrite, append, sum, custom)
18//! - **Checkpointing**: Persistent state after each step
19//! - **Human-in-the-Loop**: Interrupt before/after nodes, dynamic interrupts
20//! - **Streaming**: Multiple stream modes (values, updates, messages, debug)
21//! - **ADK Integration**: Full callback support, works with existing runners
22//!
23//! ## Quick Start
24//!
25//! ```rust,ignore
26//! use adk_graph::prelude::*;
27//!
28//! let agent = GraphAgent::builder("processor")
29//! .description("Process data through multiple steps")
30//! .node_fn("fetch", |ctx| async move {
31//! Ok(NodeOutput::new().with_update("data", json!({"items": [1, 2, 3]})))
32//! })
33//! .node_fn("transform", |ctx| async move {
34//! let data = ctx.state.get("data").unwrap();
35//! Ok(NodeOutput::new().with_update("result", data.clone()))
36//! })
37//! .edge(START, "fetch")
38//! .edge("fetch", "transform")
39//! .edge("transform", END)
40//! .build()?;
41//!
42//! // Execute
43//! let result = agent.invoke(State::new(), ExecutionConfig::new("thread_1")).await?;
44//! ```
45//!
46//! ## ReAct Pattern
47//!
48//! ```rust,ignore
49//! use adk_graph::prelude::*;
50//!
51//! let react_agent = GraphAgent::builder("react")
52//! .node(llm_agent_node)
53//! .node_fn("tools", execute_tools)
54//! .edge(START, "llm")
55//! .conditional_edge(
56//! "llm",
57//! |state| {
58//! if has_tool_calls(state) { "tools" } else { END }
59//! },
60//! [("tools", "tools"), (END, END)],
61//! )
62//! .edge("tools", "llm") // Cycle back
63//! .recursion_limit(25)
64//! .build()?;
65//! ```
66
67pub mod agent;
68pub mod checkpoint;
69pub mod edge;
70pub mod error;
71pub mod executor;
72pub mod graph;
73pub mod interrupt;
74pub mod node;
75pub mod state;
76pub mod stream;
77
78// Re-exports
79pub use agent::{GraphAgent, GraphAgentBuilder};
80pub use checkpoint::{Checkpointer, MemoryCheckpointer};
81pub use edge::{Edge, EdgeTarget, Router, END, START};
82pub use error::{GraphError, InterruptedExecution, Result};
83pub use executor::PregelExecutor;
84pub use graph::{CompiledGraph, StateGraph};
85pub use interrupt::{interrupt, interrupt_with_data, Interrupt};
86pub use node::{AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput};
87pub use state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
88pub use stream::{StreamEvent, StreamMode};
89
90#[cfg(feature = "sqlite")]
91pub use checkpoint::SqliteCheckpointer;
92
93/// Prelude module for convenient imports
94pub mod prelude {
95 pub use crate::agent::{GraphAgent, GraphAgentBuilder};
96 pub use crate::checkpoint::{Checkpointer, MemoryCheckpointer};
97 pub use crate::edge::{Edge, EdgeTarget, Router, END, START};
98 pub use crate::error::{GraphError, InterruptedExecution, Result};
99 pub use crate::graph::{CompiledGraph, StateGraph};
100 pub use crate::interrupt::{interrupt, interrupt_with_data, Interrupt};
101 pub use crate::node::{
102 AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput,
103 };
104 pub use crate::state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
105 pub use crate::stream::{StreamEvent, StreamMode};
106
107 #[cfg(feature = "sqlite")]
108 pub use crate::checkpoint::SqliteCheckpointer;
109
110 // Re-export commonly used serde_json
111 pub use serde_json::{json, Value};
112}