Skip to main content

ri_agent_graph/
interrupt.rs

1use crate::state::AgentState;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5/// Configuration for interrupt points in graph execution.
6#[derive(Debug, Clone, Default)]
7pub struct InterruptConfig {
8    /// Nodes to interrupt BEFORE execution
9    pub interrupt_before: Vec<String>,
10    /// Nodes to interrupt AFTER execution
11    pub interrupt_after: Vec<String>,
12}
13
14impl InterruptConfig {
15    pub fn new() -> Self {
16        Self::default()
17    }
18
19    pub fn before(mut self, node: impl Into<String>) -> Self {
20        self.interrupt_before.push(node.into());
21        self
22    }
23
24    pub fn after(mut self, node: impl Into<String>) -> Self {
25        self.interrupt_after.push(node.into());
26        self
27    }
28
29    pub fn should_interrupt_before(&self, node: &str) -> bool {
30        self.interrupt_before.iter().any(|n| n == node)
31    }
32
33    pub fn should_interrupt_after(&self, node: &str) -> bool {
34        self.interrupt_after.iter().any(|n| n == node)
35    }
36
37    pub fn is_empty(&self) -> bool {
38        self.interrupt_before.is_empty() && self.interrupt_after.is_empty()
39    }
40}
41
42/// Result of a graph execution that may be interrupted.
43#[derive(Debug)]
44pub enum ExecutionResult {
45    /// Execution completed normally
46    Complete(AgentState),
47    /// Execution was interrupted
48    Interrupted {
49        /// Current state at interrupt point
50        state: AgentState,
51        /// Node where interruption occurred
52        node: String,
53        /// Value passed to the interrupt function
54        interrupt_value: Option<Value>,
55        /// Data needed to resume execution
56        checkpoint_data: Option<InterruptCheckpoint>,
57    },
58    /// Execution failed with a typed error.
59    ///
60    /// AG-001: Ordinary (non-interrupt) errors are preserved as `Failed`
61    /// instead of being silently mapped to `Complete`. The original error
62    /// is carried so callers can inspect and handle it.
63    Failed {
64        /// The error that caused execution to fail.
65        error: crate::error::AgentGraphError,
66        /// State at the point of failure (may be partially mutated).
67        state: AgentState,
68    },
69}
70
71/// Data needed to resume from an interrupt.
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct InterruptCheckpoint {
74    /// The node to resume from
75    pub resume_node: String,
76    /// Whether to re-execute the node or continue to next
77    pub resume_before: bool,
78    /// The iteration count at interrupt
79    pub iteration: usize,
80    /// Active nodes in current superstep
81    pub active_nodes: Vec<String>,
82    /// Hash of the graph topology at checkpoint time.
83    /// Used to detect graph-definition drift on resume.
84    #[serde(default)]
85    pub graph_hash: Option<String>,
86}