Skip to main content

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 deferred;
71pub mod edge;
72pub mod error;
73pub mod executor;
74pub mod graph;
75pub mod interrupt;
76pub mod node;
77pub mod state;
78pub mod stream;
79pub mod timeout;
80
81#[cfg(feature = "node-cache")]
82pub mod cache;
83
84#[cfg(feature = "delta-checkpoint")]
85pub mod delta;
86
87#[cfg(feature = "time-travel")]
88pub mod time_travel;
89
90#[cfg(feature = "action")]
91pub mod action;
92#[cfg(feature = "action")]
93pub mod workflow;
94
95// Re-exports
96pub use agent::{GraphAgent, GraphAgentBuilder};
97pub use checkpoint::{Checkpointer, MemoryCheckpointer};
98pub use deferred::{DeferredNodeConfig, FanInTracker, MergeStrategy};
99pub use edge::{END, Edge, EdgeTarget, Router, START};
100pub use error::{GraphError, InterruptedExecution, Result};
101pub use executor::PregelExecutor;
102pub use graph::{CompiledGraph, StateGraph};
103pub use interrupt::{Interrupt, interrupt, interrupt_with_data};
104pub use node::{AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput};
105pub use state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
106pub use stream::{StreamEvent, StreamMode};
107pub use timeout::{OnTimeout, ProgressHandle, TimeoutPolicy, execute_with_timeout};
108
109#[cfg(feature = "sqlite")]
110pub use checkpoint::SqliteCheckpointer;
111
112#[cfg(feature = "node-cache")]
113pub use cache::{CacheBackend, NodeCache, NodeCachePolicy, compute_cache_key};
114
115#[cfg(feature = "delta-checkpoint")]
116pub use delta::{
117    CheckpointType, DeltaCheckpointer, DeltaConfig, Diff, MapDelta, StringDelta, StringOp, VecDelta,
118};
119
120#[cfg(feature = "time-travel")]
121pub use time_travel::{StepInfo, TimeTravelHandle};
122
123/// Prelude module for convenient imports
124pub mod prelude {
125    pub use crate::agent::{GraphAgent, GraphAgentBuilder};
126    pub use crate::checkpoint::{Checkpointer, MemoryCheckpointer};
127    pub use crate::deferred::{DeferredNodeConfig, FanInTracker, MergeStrategy};
128    pub use crate::edge::{END, Edge, EdgeTarget, Router, START};
129    pub use crate::error::{GraphError, InterruptedExecution, Result};
130    pub use crate::graph::{CompiledGraph, StateGraph};
131    pub use crate::interrupt::{Interrupt, interrupt, interrupt_with_data};
132    pub use crate::node::{
133        AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput,
134    };
135    pub use crate::state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
136    pub use crate::stream::{StreamEvent, StreamMode};
137
138    #[cfg(feature = "sqlite")]
139    pub use crate::checkpoint::SqliteCheckpointer;
140
141    #[cfg(feature = "action")]
142    pub use crate::action::ActionNodeExecutor;
143
144    // Re-export commonly used serde_json
145    pub use serde_json::{Value, json};
146}