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