pub struct StateGraph<S: State, I: IntoState<S> = S, O: FromState<S> = S> { /* private fields */ }Expand description
Builder for constructing executable Juncture graphs
§Examples
use juncture_core::{StateGraph, State, IntoNode};
struct MyState;
impl State for MyState { type Update = MyStateUpdate; }
struct MyStateUpdate;
// Build a simple graph
let mut graph = StateGraph::<MyState>::new();
graph.add_node_simple("process", |state: MyState| async move {
Ok(MyStateUpdate)
});
graph.set_entry_point("process");
graph.set_finish_point("process");
// Compile and validate
let compiled = graph.compile()?;Implementations§
Source§impl<S: State, I: IntoState<S>, O: FromState<S>> StateGraph<S, I, O>
impl<S: State, I: IntoState<S>, O: FromState<S>> StateGraph<S, I, O>
Sourcepub fn add_node(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
defer: bool,
metadata: Option<HashMap<String, Value>>,
destinations: Option<Vec<String>>,
retry_policies: Vec<RetryPolicy>,
timeout_policies: Vec<TimeoutPolicy>,
) -> Result<&mut Self, TopologyError>
pub fn add_node( &mut self, name: impl Into<String>, node: impl IntoNode<S>, defer: bool, metadata: Option<HashMap<String, Value>>, destinations: Option<Vec<String>>, retry_policies: Vec<RetryPolicy>, timeout_policies: Vec<TimeoutPolicy>, ) -> Result<&mut Self, TopologyError>
Sourcepub fn add_node_simple(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
) -> Result<&mut Self, TopologyError>
pub fn add_node_simple( &mut self, name: impl Into<String>, node: impl IntoNode<S>, ) -> Result<&mut Self, TopologyError>
Add a node with default configuration options
This convenience method uses these defaults:
defer:falsemetadata:Nonedestinations:Noneretry_policies: emptytimeout_policies: empty
Returns &mut Self on success for fluent builder chaining.
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_node_with_error_handler(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
handler: Arc<dyn Fn(NodeError<S>) -> Command<S> + Send + Sync>,
) -> Result<&mut Self, TopologyError>where
S: Clone,
pub fn add_node_with_error_handler(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
handler: Arc<dyn Fn(NodeError<S>) -> Command<S> + Send + Sync>,
) -> Result<&mut Self, TopologyError>where
S: Clone,
Add a node with an error recovery handler
When the wrapped node returns an error, the handler is invoked to produce a fallback command instead of propagating the error.
The handler receives NodeError with detailed information (node name,
error, state snapshot, attempt count) and returns a recovery command.
Returns &mut Self on success for fluent builder chaining.
§Arguments
name- Node namenode- The node to wraphandler- Error recovery function receivingNodeError
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_node_with_retry(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
policy: RetryPolicy,
) -> Result<&mut Self, TopologyError>where
S: Clone,
pub fn add_node_with_retry(
&mut self,
name: impl Into<String>,
node: impl IntoNode<S>,
policy: RetryPolicy,
) -> Result<&mut Self, TopologyError>where
S: Clone,
Add a node with automatic retry behavior
When the wrapped node fails, it is retried according to the provided retry policy with exponential backoff.
Returns &mut Self on success for fluent builder chaining.
§Arguments
name- Node namenode- The node to wrappolicy- Retry policy governing retry behavior
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_subgraph(
&mut self,
mount: SubgraphMount<S>,
) -> Result<&mut Self, TopologyError>
pub fn add_subgraph( &mut self, mount: SubgraphMount<S>, ) -> Result<&mut Self, TopologyError>
Add a compiled subgraph as a node in this graph
The subgraph is mounted with input/output mapping functions that transform state between the parent and child graph.
Returns &mut Self on success for fluent builder chaining.
§Arguments
mount- Subgraph mount containing the compiled graph and mapping functions
§Errors
Returns an error if a node with the same name as the subgraph already exists.
Sourcepub fn add_subgraph_node<Sub>(
&mut self,
name: &str,
subgraph: Arc<CompiledGraph<Sub>>,
) -> Result<&mut Self, TopologyError>where
Sub: StateSubset<S> + State + Clone + Serialize + for<'de> Deserialize<'de>,
Sub::Update: Serialize,
S: Clone,
pub fn add_subgraph_node<Sub>(
&mut self,
name: &str,
subgraph: Arc<CompiledGraph<Sub>>,
) -> Result<&mut Self, TopologyError>where
Sub: StateSubset<S> + State + Clone + Serialize + for<'de> Deserialize<'de>,
Sub::Update: Serialize,
S: Clone,
Add a subgraph with shared state using StateSubset
This method adds a subgraph that shares state with its parent graph
using the StateSubset trait for type-safe state transformation.
§Type Parameters
Sub- The subgraph’s state type, which must implementStateSubset<S>
§Arguments
name- The node name for the subgraph mount pointsubgraph- The compiled subgraph to add
§Returns
A mutable reference to self for chaining
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_subgraph_with_config<Sub>(
&mut self,
name: &str,
subgraph: Arc<CompiledGraph<Sub>>,
input_map: impl Fn(&S) -> Sub + Send + Sync + 'static,
output_map: impl Fn(&Sub) -> S::Update + Send + Sync + 'static,
config: SubgraphConfig,
) -> Result<&mut Self, TopologyError>
pub fn add_subgraph_with_config<Sub>( &mut self, name: &str, subgraph: Arc<CompiledGraph<Sub>>, input_map: impl Fn(&S) -> Sub + Send + Sync + 'static, output_map: impl Fn(&Sub) -> S::Update + Send + Sync + 'static, config: SubgraphConfig, ) -> Result<&mut Self, TopologyError>
Add a subgraph with explicit state mapping and custom config
This method adds a subgraph with different state types than the parent, using explicit mapping functions to transform between state types.
§Type Parameters
Sub- The subgraph’s state type
§Arguments
name- The node name for the subgraph mount pointsubgraph- The compiled subgraph to addinput_map- Function to transform parent state to subgraph inputoutput_map- Function to transform subgraph output to parent state updateconfig- Subgraph configuration options
§Returns
A mutable reference to self for chaining
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_subgraph_explicit<Sub>(
&mut self,
name: &str,
subgraph: Arc<CompiledGraph<Sub>>,
input_map: impl Fn(&S) -> Sub + Send + Sync + 'static,
output_map: impl Fn(&Sub) -> S::Update + Send + Sync + 'static,
) -> Result<&mut Self, TopologyError>
pub fn add_subgraph_explicit<Sub>( &mut self, name: &str, subgraph: Arc<CompiledGraph<Sub>>, input_map: impl Fn(&S) -> Sub + Send + Sync + 'static, output_map: impl Fn(&Sub) -> S::Update + Send + Sync + 'static, ) -> Result<&mut Self, TopologyError>
Add a subgraph with explicit state mapping using default config
Convenience overload for add_subgraph_with_config() that uses
SubgraphConfig::default(). See that method for full documentation.
§Type Parameters
Sub- The subgraph’s state type
§Arguments
name- The node name for the subgraph mount pointsubgraph- The compiled subgraph to addinput_map- Function to transform parent state to subgraph inputoutput_map- Function to transform subgraph output to parent state update
§Errors
Returns an error if a node with the same name already exists.
Sourcepub fn add_conditional_edges(
&mut self,
from: impl Into<String>,
router: Arc<dyn Router<S>>,
path_map: PathMap,
)
pub fn add_conditional_edges( &mut self, from: impl Into<String>, router: Arc<dyn Router<S>>, path_map: PathMap, )
Add a conditional edge with dynamic routing
§Examples
use juncture_core::edge::{PathMap, Router};
use std::sync::Arc;
let router = |state: &MyState| -> &str {
if state.should_continue { "continue" } else { "stop" }
};
let path_map = PathMap::from(&[
("continue", "process_more"),
("stop", "finish"),
]);
graph.add_conditional_edges("decide", Arc::new(router), path_map)?;§Errors
This method doesn’t validate node existence or path map targets.
Validation happens during compile.
Sourcepub fn set_entry_point(&mut self, node: impl Into<String>)
pub fn set_entry_point(&mut self, node: impl Into<String>)
Sourcepub fn set_finish_point(&mut self, node: impl Into<String>)
pub fn set_finish_point(&mut self, node: impl Into<String>)
Sourcepub fn add_sequence(
&mut self,
nodes: &[impl AsRef<str>],
) -> Result<&mut Self, TopologyError>
pub fn add_sequence( &mut self, nodes: &[impl AsRef<str>], ) -> Result<&mut Self, TopologyError>
Add a sequence of nodes as a chain
Automatically adds edges between consecutive nodes and sets the first node as the entry point.
Returns &mut Self on success for fluent builder chaining.
§Examples
graph.add_sequence(&["step1", "step2", "step3"])?;§Errors
Returns an error if any of the nodes don’t exist.
Sourcepub fn validate_keys(&self) -> Result<(), TopologyError>
pub fn validate_keys(&self) -> Result<(), TopologyError>
Validate that all state keys are present
Key validation ensures that all nodes can access their required state fields. This validates:
- Node names are non-empty and contain no reserved characters
- Entry point references an existing node
- Finish points reference existing nodes
- Reducer field indices are within bounds of the State type’s field count
§Errors
Returns TopologyError if:
- A node name is empty or contains reserved characters (
:,/,\) - Entry point references a non-existent node
- A finish point references a non-existent node
- A reducer field index exceeds the number of fields in the State type
Sourcepub fn compile(&self) -> Result<CompiledGraph<S, I, O>, TopologyError>
pub fn compile(&self) -> Result<CompiledGraph<S, I, O>, TopologyError>
Compile the graph into an executable form
Runs topology validation and builds the optimized execution structure using default compile configuration (no compile-time interrupts).
§Errors
Returns TopologyError if validation fails.
§Examples
let compiled = graph.compile()?;Sourcepub fn compile_with_config(
&self,
config: CompileConfig,
) -> Result<CompiledGraph<S, I, O>, TopologyError>
pub fn compile_with_config( &self, config: CompileConfig, ) -> Result<CompiledGraph<S, I, O>, TopologyError>
Compile the graph with explicit compile-time configuration
Like compile but accepts a CompileConfig that
sets compile-time defaults for interrupt behavior. Runtime
[RunnableConfig] values override these when present.
§Errors
Returns TopologyError if validation fails.
§Examples
use juncture_core::graph::CompileConfig;
let compiled = graph.compile_with_config(CompileConfig {
interrupt_before: vec!["human_review".into()],
interrupt_after: vec!["llm_call".into()],
..Default::default()
})?;Sourcepub fn compile_ephemeral(&self) -> Result<CompiledGraph<S, I, O>, TopologyError>
pub fn compile_ephemeral(&self) -> Result<CompiledGraph<S, I, O>, TopologyError>
Compile the graph without persistence (dev/test)
Creates a compiled graph with no checkpointer attached. Useful for development and testing where persistence is not needed.
§Errors
Returns TopologyError if validation fails.
Sourcepub fn compile_with_checkpointer(
&self,
checkpointer: Option<Arc<dyn CheckpointSaver>>,
) -> Result<CompiledGraph<S, I, O>, TopologyError>
pub fn compile_with_checkpointer( &self, checkpointer: Option<Arc<dyn CheckpointSaver>>, ) -> Result<CompiledGraph<S, I, O>, TopologyError>
Compile the graph with optional checkpointer
This is a forward-compatible method that accepts an optional checkpointer. Uses default compile configuration (no compile-time interrupts).
§Errors
Returns TopologyError if validation fails.