Skip to main content

rust_langgraph/
runtime.rs

1//! Runtime context for node execution.
2//!
3//! The Runtime provides nodes with access to execution context like
4//! the current step, checkpoint ID, and configuration.
5
6use crate::config::Config;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9
10/// Execution context available to nodes during execution.
11///
12/// Runtime provides nodes with information about the current execution
13/// state and allows them to interact with the execution environment.
14///
15/// # Example
16///
17/// ```rust
18/// use rust_langgraph::runtime::Runtime;
19/// use rust_langgraph::Config;
20///
21/// let config = Config::new().with_thread_id("test-123");
22/// let runtime = Runtime::new(config);
23///
24/// assert_eq!(runtime.step(), 0);
25/// ```
26#[derive(Debug, Clone)]
27pub struct Runtime {
28    config: Config,
29    checkpoint_id: Option<String>,
30    step: usize,
31}
32
33impl Runtime {
34    /// Create a new runtime context
35    pub fn new(config: Config) -> Self {
36        Self {
37            config,
38            checkpoint_id: None,
39            step: 0,
40        }
41    }
42
43    /// Get the configuration
44    pub fn config(&self) -> &Config {
45        &self.config
46    }
47
48    /// Get the current checkpoint ID
49    pub fn checkpoint_id(&self) -> Option<&str> {
50        self.checkpoint_id.as_deref()
51    }
52
53    /// Get the current step number
54    pub fn step(&self) -> usize {
55        self.step
56    }
57
58    /// Set the checkpoint ID
59    pub fn set_checkpoint_id(&mut self, id: impl Into<String>) {
60        self.checkpoint_id = Some(id.into());
61    }
62
63    /// Increment the step counter
64    pub fn increment_step(&mut self) {
65        self.step += 1;
66    }
67
68    /// Get the thread ID from config
69    pub fn thread_id(&self) -> Option<&str> {
70        self.config.thread_id.as_deref()
71    }
72}
73
74/// Shared runtime context that can be passed between tasks
75pub type SharedRuntime = Arc<RwLock<Runtime>>;
76
77/// Create a shared runtime
78pub fn shared_runtime(config: Config) -> SharedRuntime {
79    Arc::new(RwLock::new(Runtime::new(config)))
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_runtime_creation() {
88        let config = Config::new().with_thread_id("test");
89        let runtime = Runtime::new(config);
90
91        assert_eq!(runtime.thread_id(), Some("test"));
92        assert_eq!(runtime.step(), 0);
93        assert!(runtime.checkpoint_id().is_none());
94    }
95
96    #[test]
97    fn test_runtime_mutations() {
98        let config = Config::new();
99        let mut runtime = Runtime::new(config);
100
101        runtime.set_checkpoint_id("checkpoint-1");
102        assert_eq!(runtime.checkpoint_id(), Some("checkpoint-1"));
103
104        runtime.increment_step();
105        assert_eq!(runtime.step(), 1);
106
107        runtime.increment_step();
108        assert_eq!(runtime.step(), 2);
109    }
110
111    #[tokio::test]
112    async fn test_shared_runtime() {
113        let config = Config::new();
114        let runtime = shared_runtime(config);
115
116        {
117            let mut rt = runtime.write().await;
118            rt.increment_step();
119        }
120
121        {
122            let rt = runtime.read().await;
123            assert_eq!(rt.step(), 1);
124        }
125    }
126}