lellm_graph/
node_context.rs1use crate::branch_state::BranchState;
10use crate::event::FlowEvent;
11use crate::state::State;
12use crate::stream_emitter::StreamEmitter;
13use crate::workflow_state::WorkflowState;
14
15#[derive(Debug, Clone)]
19pub enum ExecutionSignal {
20 Pause {
22 barrier_id: crate::event::BarrierId,
23 timeout: Option<std::time::Duration>,
24 },
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum NextAction {
32 Next,
34 Goto(String),
36 End,
38}
39
40#[derive(Debug, Default)]
44pub struct ExecutionControl {
45 next: Option<NextAction>,
46 signal: Option<ExecutionSignal>,
47}
48
49impl ExecutionControl {
50 pub fn new() -> Self {
51 Self::default()
52 }
53
54 pub fn goto(&mut self, target: impl Into<String>) {
56 self.next = Some(NextAction::Goto(target.into()));
57 }
58
59 pub fn end(&mut self) {
61 self.next = Some(NextAction::End);
62 }
63
64 pub fn pause(
66 &mut self,
67 barrier_id: crate::event::BarrierId,
68 timeout: Option<std::time::Duration>,
69 ) {
70 self.signal = Some(ExecutionSignal::Pause {
71 barrier_id,
72 timeout,
73 });
74 }
75
76 pub fn take(&mut self) -> (NextAction, Option<ExecutionSignal>) {
78 let next = self.next.take().unwrap_or(NextAction::Next);
79 let signal = self.signal.take();
80 (next, signal)
81 }
82}
83
84#[derive(Debug, Clone, Default)]
88pub struct NodeMetadata {
89 pub token_cost: f64,
91 pub has_side_effects: bool,
93}
94
95pub struct NodeContext<'a, S: WorkflowState = State> {
114 state: &'a mut S,
116 branch: &'a mut BranchState,
118 stream: Option<&'a StreamEmitter>,
120 control: ExecutionControl,
122 metadata: NodeMetadata,
124 effects: Vec<S::Effect>,
126 flow_events: Vec<FlowEvent>,
128}
129
130impl<'a, S: WorkflowState> NodeContext<'a, S> {
131 pub fn new(
133 state: &'a mut S,
134 branch: &'a mut BranchState,
135 stream: Option<&'a StreamEmitter>,
136 ) -> Self {
137 Self {
138 state,
139 branch,
140 stream,
141 control: ExecutionControl::new(),
142 metadata: NodeMetadata::default(),
143 effects: Vec::new(),
144 flow_events: Vec::new(),
145 }
146 }
147
148 pub fn state(&self) -> &S {
150 self.state
151 }
152
153 pub fn state_mut(&mut self) -> &mut S {
155 self.state
156 }
157
158 pub fn branch(&self) -> &BranchState {
160 self.branch
161 }
162
163 pub fn branch_mut(&mut self) -> &mut BranchState {
165 self.branch
166 }
167
168 pub fn emit(&self, chunk: crate::stream_chunk::StreamChunk) {
172 if let Some(stream) = &self.stream {
173 stream.emit(chunk);
174 }
175 }
176
177 pub fn emit_flow_event(&mut self, event: FlowEvent) {
179 self.flow_events.push(event);
180 }
181
182 pub fn goto(&mut self, target: impl Into<String>) {
186 self.control.goto(target);
187 }
188
189 pub fn end(&mut self) {
191 self.control.end();
192 }
193
194 pub fn pause(
196 &mut self,
197 barrier_id: crate::event::BarrierId,
198 timeout: Option<std::time::Duration>,
199 ) {
200 self.control.pause(barrier_id, timeout);
201 }
202
203 pub fn set_token_cost(&mut self, cost: f64) {
207 self.metadata.token_cost = cost;
208 }
209
210 pub fn set_has_side_effects(&mut self) {
212 self.metadata.has_side_effects = true;
213 }
214
215 pub fn emit_effect(&mut self, effect: S::Effect) {
221 self.effects.push(effect);
222 }
223
224 pub fn consume_effects(&mut self) -> Vec<S::Effect> {
226 std::mem::take(&mut self.effects)
227 }
228
229 pub fn effects_len(&self) -> usize {
231 self.effects.len()
232 }
233
234 pub fn take_control(&mut self) -> (NextAction, Option<ExecutionSignal>) {
238 self.control.take()
239 }
240
241 pub fn take_metadata(&mut self) -> NodeMetadata {
243 std::mem::take(&mut self.metadata)
244 }
245
246 pub fn stream(&self) -> Option<&'a StreamEmitter> {
248 self.stream
249 }
250
251 pub fn take_flow_events(&mut self) -> Vec<FlowEvent> {
253 std::mem::take(&mut self.flow_events)
254 }
255}