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//! - **Functional API** (`functional` feature): Write workflows as async functions
24//!   with `#[entrypoint]`/`#[task]` macros, automatic checkpointing, typed state
25//!   reducers (ReducedValue, UntrackedValue, MessagesValue), state schema
26//!   validation, interrupt/resume, and loop iteration checkpoint keying
27//!
28//! ## Quick Start
29//!
30//! ```rust,ignore
31//! use adk_graph::prelude::*;
32//!
33//! let agent = GraphAgent::builder("processor")
34//!     .description("Process data through multiple steps")
35//!     .node_fn("fetch", |ctx| async move {
36//!         Ok(NodeOutput::new().with_update("data", json!({"items": [1, 2, 3]})))
37//!     })
38//!     .node_fn("transform", |ctx| async move {
39//!         let data = ctx.state.get("data").unwrap();
40//!         Ok(NodeOutput::new().with_update("result", data.clone()))
41//!     })
42//!     .edge(START, "fetch")
43//!     .edge("fetch", "transform")
44//!     .edge("transform", END)
45//!     .build()?;
46//!
47//! // Execute
48//! let result = agent.invoke(State::new(), ExecutionConfig::new("thread_1")).await?;
49//! ```
50//!
51//! ## ReAct Pattern
52//!
53//! ```rust,ignore
54//! use adk_graph::prelude::*;
55//!
56//! let react_agent = GraphAgent::builder("react")
57//!     .node(llm_agent_node)
58//!     .node_fn("tools", execute_tools)
59//!     .edge(START, "llm")
60//!     .conditional_edge(
61//!         "llm",
62//!         |state| {
63//!             if has_tool_calls(state) { "tools" } else { END }
64//!         },
65//!         [("tools", "tools"), (END, END)],
66//!     )
67//!     .edge("tools", "llm")  // Cycle back
68//!     .recursion_limit(25)
69//!     .build()?;
70//! ```
71
72pub mod agent;
73pub mod checkpoint;
74pub mod deferred;
75pub mod edge;
76pub mod error;
77pub mod executor;
78pub mod graph;
79pub mod interrupt;
80pub mod node;
81pub mod state;
82pub mod stream;
83pub mod timeout;
84
85#[cfg(feature = "node-cache")]
86pub mod cache;
87
88#[cfg(feature = "delta-checkpoint")]
89pub mod delta;
90
91#[cfg(feature = "time-travel")]
92pub mod time_travel;
93
94#[cfg(feature = "action")]
95pub mod action;
96#[cfg(feature = "action")]
97pub mod workflow;
98
99#[cfg(feature = "functional")]
100pub mod functional;
101
102// Functional API re-exports for convenient access
103#[cfg(feature = "functional")]
104pub use functional::schema::{ExpectedType, StateSchemaValidator};
105#[cfg(feature = "functional")]
106pub use functional::{
107    AppendReducer, ExecutionLog, FunctionalError, MergeReducer, MessagesValue, ReducedValue,
108    ReplaceReducer, TaskContext, TypedReducer, UntrackedValue,
109};
110
111// Re-exports
112pub use agent::{GraphAgent, GraphAgentBuilder};
113pub use checkpoint::{Checkpointer, MemoryCheckpointer};
114pub use deferred::{DeferredNodeConfig, FanInTracker, MergeStrategy};
115pub use edge::{END, Edge, EdgeTarget, Router, START};
116pub use error::{GraphError, InterruptedExecution, Result};
117pub use executor::PregelExecutor;
118pub use graph::{CompiledGraph, StateGraph};
119pub use interrupt::{Interrupt, interrupt, interrupt_with_data};
120pub use node::{AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput};
121pub use state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
122pub use stream::{StreamEvent, StreamMode};
123pub use timeout::{OnTimeout, ProgressHandle, TimeoutPolicy, execute_with_timeout};
124
125#[cfg(feature = "sqlite")]
126pub use checkpoint::SqliteCheckpointer;
127
128#[cfg(feature = "node-cache")]
129pub use cache::{CacheBackend, NodeCache, NodeCachePolicy, compute_cache_key};
130
131#[cfg(feature = "delta-checkpoint")]
132pub use delta::{
133    CheckpointType, DeltaCheckpointer, DeltaConfig, Diff, MapDelta, StringDelta, StringOp, VecDelta,
134};
135
136#[cfg(feature = "time-travel")]
137pub use time_travel::{StepInfo, TimeTravelHandle};
138
139/// Prelude module for convenient imports
140pub mod prelude {
141    pub use crate::agent::{GraphAgent, GraphAgentBuilder};
142    pub use crate::checkpoint::{Checkpointer, MemoryCheckpointer};
143    pub use crate::deferred::{DeferredNodeConfig, FanInTracker, MergeStrategy};
144    pub use crate::edge::{END, Edge, EdgeTarget, Router, START};
145    pub use crate::error::{GraphError, InterruptedExecution, Result};
146    pub use crate::graph::{CompiledGraph, StateGraph};
147    pub use crate::interrupt::{Interrupt, interrupt, interrupt_with_data};
148    pub use crate::node::{
149        AgentNode, ExecutionConfig, FunctionNode, Node, NodeContext, NodeOutput,
150    };
151    pub use crate::state::{Channel, Checkpoint, Reducer, State, StateSchema, StateSchemaBuilder};
152    pub use crate::stream::{StreamEvent, StreamMode};
153
154    #[cfg(feature = "sqlite")]
155    pub use crate::checkpoint::SqliteCheckpointer;
156
157    #[cfg(feature = "action")]
158    pub use crate::action::ActionNodeExecutor;
159
160    // Re-export commonly used serde_json
161    pub use serde_json::{Value, json};
162}