Skip to main content

ri_agent_graph/
config.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5/// Runtime configuration for graph execution.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct GraphConfig {
8    /// Thread ID for checkpointing and state management
9    pub thread_id: Option<String>,
10    /// Trace ID for cross-crate correlation.
11    /// If None, one is generated automatically at execution start.
12    ///
13    /// ## Phase status: compatibility / migration-only
14    ///
15    /// This field uses `String` for backward compatibility. The canonical
16    /// replacement is [`trace_ctx`](Self::trace_ctx). Use
17    /// [`trace_ctx()`](Self::trace_ctx) to obtain the canonical form.
18    ///
19    /// **Removal condition**: removed when all callers migrate to `trace_ctx`.
20    pub trace_id: Option<String>,
21    /// Canonical trace context for cross-crate correlation.
22    ///
23    /// When set, takes precedence over the legacy `trace_id` field.
24    /// If both are `None`, a new `TraceCtx` is generated at execution start.
25    #[serde(skip_serializing_if = "Option::is_none", default)]
26    pub trace_ctx: Option<stack_ids::TraceCtx>,
27    /// Maximum recursion depth (default: 100)
28    pub recursion_limit: usize,
29    /// Maximum number of parallel nodes in a single superstep.
30    /// Hard-capped at 32. Default: 8.
31    pub max_parallelism: usize,
32    /// Tags for filtering and organization
33    pub tags: Vec<String>,
34    /// Metadata attached to the execution
35    pub metadata: HashMap<String, Value>,
36    /// User-provided configurable values accessible by nodes
37    pub configurable: HashMap<String, Value>,
38}
39
40impl Default for GraphConfig {
41    fn default() -> Self {
42        Self {
43            thread_id: None,
44            trace_id: None,
45            trace_ctx: None,
46            recursion_limit: 100,
47            max_parallelism: 8,
48            tags: Vec::new(),
49            metadata: HashMap::new(),
50            configurable: HashMap::new(),
51        }
52    }
53}
54
55impl GraphConfig {
56    pub fn new() -> Self {
57        Self::default()
58    }
59
60    pub fn with_thread_id(mut self, id: impl Into<String>) -> Self {
61        self.thread_id = Some(id.into());
62        self
63    }
64
65    pub fn with_recursion_limit(mut self, limit: usize) -> Self {
66        self.recursion_limit = limit;
67        self
68    }
69
70    pub fn with_tag(mut self, tag: impl Into<String>) -> Self {
71        self.tags.push(tag.into());
72        self
73    }
74
75    pub fn with_metadata(mut self, key: impl Into<String>, value: Value) -> Self {
76        self.metadata.insert(key.into(), value);
77        self
78    }
79
80    pub fn with_configurable(mut self, key: impl Into<String>, value: Value) -> Self {
81        self.configurable.insert(key.into(), value);
82        self
83    }
84
85    pub fn with_trace_id(mut self, id: impl Into<String>) -> Self {
86        self.trace_id = Some(id.into());
87        self
88    }
89
90    pub fn with_max_parallelism(mut self, n: usize) -> Self {
91        self.max_parallelism = n.clamp(1, 32);
92        self
93    }
94
95    /// Resolve the canonical `stack_ids::TraceCtx` for this config.
96    ///
97    /// Resolution order:
98    /// 1. `self.trace_ctx` if set (canonical path).
99    /// 2. `self.trace_id` converted via `TraceCtx::from_legacy_trace_id` (compat path).
100    /// 3. Generates a new `TraceCtx` if neither is set.
101    pub fn resolve_trace_ctx(&self) -> stack_ids::TraceCtx {
102        if let Some(ref ctx) = self.trace_ctx {
103            return ctx.clone();
104        }
105        match &self.trace_id {
106            Some(id) => stack_ids::TraceCtx::from_legacy_trace_id(id),
107            None => stack_ids::TraceCtx::generate(),
108        }
109    }
110
111    /// Set the canonical trace context.
112    ///
113    /// Also back-fills the legacy `trace_id` field for compat consumers.
114    pub fn with_trace_ctx(mut self, ctx: stack_ids::TraceCtx) -> Self {
115        self.trace_id = Some(ctx.to_legacy_trace_id().to_string());
116        self.trace_ctx = Some(ctx);
117        self
118    }
119}