wesichain_graph/
config.rs1#[derive(Clone, Debug)]
2pub struct ExecutionConfig {
3 pub max_steps: Option<usize>,
4 pub max_duration: Option<std::time::Duration>,
5 pub node_timeout: Option<std::time::Duration>,
6 pub max_visits: Option<u32>,
7 pub max_loop_iterations: Option<u32>,
8 pub cycle_detection: bool,
9 pub cycle_window: usize,
10 pub interrupt_before: Vec<String>,
11 pub interrupt_after: Vec<String>,
12}
13
14impl Default for ExecutionConfig {
15 fn default() -> Self {
16 Self {
17 max_steps: Some(50),
18 max_duration: None,
19 node_timeout: None,
20 max_visits: Some(10),
21 max_loop_iterations: Some(15),
22 cycle_detection: true,
23 cycle_window: 20,
24 interrupt_before: Vec::new(),
25 interrupt_after: Vec::new(),
26 }
27 }
28}
29
30impl ExecutionConfig {
31 pub fn merge(&self, overrides: &ExecutionOptions) -> Self {
32 Self {
33 max_steps: overrides.max_steps.or(self.max_steps),
34 max_duration: overrides.max_duration.or(self.max_duration),
35 node_timeout: overrides.node_timeout.or(self.node_timeout),
36 max_visits: overrides.max_visits.or(self.max_visits),
37 max_loop_iterations: overrides.max_loop_iterations.or(self.max_loop_iterations),
38 cycle_detection: overrides.cycle_detection.unwrap_or(self.cycle_detection),
39 cycle_window: overrides.cycle_window.unwrap_or(self.cycle_window),
40 interrupt_before: if !overrides.interrupt_before.is_empty() {
41 overrides.interrupt_before.clone()
42 } else {
43 self.interrupt_before.clone()
44 },
45 interrupt_after: if !overrides.interrupt_after.is_empty() {
46 overrides.interrupt_after.clone()
47 } else {
48 self.interrupt_after.clone()
49 },
50 }
51 }
52}
53
54use std::sync::Arc;
55use tokio::sync::mpsc;
56use wesichain_core::{AgentEvent, RunConfig};
57
58use crate::Observer;
59
60#[derive(Clone, Default)]
61pub struct ExecutionOptions {
62 pub max_steps: Option<usize>,
63 pub max_duration: Option<std::time::Duration>,
64 pub node_timeout: Option<std::time::Duration>,
65 pub max_visits: Option<u32>,
66 pub max_loop_iterations: Option<u32>,
67 pub cycle_detection: Option<bool>,
68 pub cycle_window: Option<usize>,
69 pub interrupt_before: Vec<String>,
70 pub interrupt_after: Vec<String>,
71 pub initial_queue: Option<Vec<(String, u64)>>,
72 pub initial_step: Option<usize>,
73 pub checkpoint_thread_id: Option<String>,
74 pub auto_resume: bool,
75 pub run_config: Option<RunConfig>,
76 pub observer: Option<Arc<dyn Observer>>,
77 pub agent_event_sender: Option<mpsc::Sender<AgentEvent>>,
78 pub agent_event_thread_id: Option<String>,
79}
80
81impl std::fmt::Debug for ExecutionOptions {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 f.debug_struct("ExecutionOptions")
84 .field("max_steps", &self.max_steps)
85 .field("max_duration", &self.max_duration)
86 .field("node_timeout", &self.node_timeout)
87 .field("max_visits", &self.max_visits)
88 .field("max_loop_iterations", &self.max_loop_iterations)
89 .field("cycle_detection", &self.cycle_detection)
90 .field("cycle_window", &self.cycle_window)
91 .field("interrupt_before", &self.interrupt_before)
92 .field("interrupt_after", &self.interrupt_after)
93 .field(
95 "initial_queue_len",
96 &self.initial_queue.as_ref().map(|q| q.len()),
97 )
98 .field("checkpoint_thread_id", &self.checkpoint_thread_id)
99 .field("auto_resume", &self.auto_resume)
100 .field("run_config", &self.run_config.is_some())
101 .field("observer", &self.observer.is_some())
102 .field("agent_event_sender", &self.agent_event_sender.is_some())
103 .field("agent_event_thread_id", &self.agent_event_thread_id)
104 .finish()
105 }
106}