//! Orchestrated Flow Step model for DAG-based workflow execution use heromodels_core::BaseModelData; use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// Extended FlowStep with orchestrator-specific fields #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OrchestratedFlowStep { /// Base model data (id, created_at, updated_at) pub base_data: BaseModelData, /// Name of the flow step pub name: String, /// Rhai script to execute pub script: String, /// IDs of steps this step depends on pub depends_on: Vec, /// Execution context (circle) pub context_id: String, /// Target worker for execution pub worker_id: String, /// Input parameters pub inputs: HashMap, /// Output results pub outputs: HashMap, } impl OrchestratedFlowStep { /// Create a new orchestrated flow step pub fn new(name: &str) -> Self { Self { base_data: BaseModelData::new(), name: name.to_string(), script: String::new(), depends_on: Vec::new(), context_id: String::new(), worker_id: String::new(), inputs: HashMap::new(), outputs: HashMap::new(), } } /// Set the script content pub fn script(mut self, script: &str) -> Self { self.script = script.to_string(); self } /// Add a dependency on another step pub fn depends_on(mut self, step_id: u32) -> Self { self.depends_on.push(step_id); self } /// Set the context ID pub fn context_id(mut self, context_id: &str) -> Self { self.context_id = context_id.to_string(); self } /// Set the worker ID pub fn worker_id(mut self, worker_id: &str) -> Self { self.worker_id = worker_id.to_string(); self } /// Add an input parameter pub fn input(mut self, key: &str, value: &str) -> Self { self.inputs.insert(key.to_string(), value.to_string()); self } /// Get the step ID pub fn id(&self) -> u32 { self.base_data.id } } #[cfg(test)] mod tests { use super::*; #[test] fn test_orchestrated_flow_step_builder() { let step = OrchestratedFlowStep::new("test_step") .script("let x = 1;") .context_id("test_context") .worker_id("test_worker") .input("key1", "value1"); assert_eq!(step.name, "test_step"); assert_eq!(step.script, "let x = 1;"); assert_eq!(step.context_id, "test_context"); assert_eq!(step.worker_id, "test_worker"); assert_eq!(step.inputs.get("key1"), Some(&"value1".to_string())); } } #[cfg(test)] mod tests { use super::*; #[test] fn test_orchestrated_flow_step_builder() { let step = OrchestratedFlowStep::new("test_step") .script("let x = 1;") .context_id("test_context") .worker_id("test_worker") .input("key1", "value1"); assert_eq!(step.flow_step.name, "test_step"); assert_eq!(step.script, "let x = 1;"); assert_eq!(step.context_id, "test_context"); assert_eq!(step.worker_id, "test_worker"); assert_eq!(step.inputs.get("key1"), Some(&"value1".to_string())); } }