ironflow_engine/config/
mod.rs1mod agent;
8mod approval;
9mod artifact;
10mod decision;
11pub mod delay;
12mod http;
13mod shell;
14mod workflow;
15
16pub use agent::AgentStepConfig;
17pub use approval::ApprovalConfig;
18pub use artifact::{ArtifactInput, ArtifactOutput};
19pub use decision::{DEFAULT_DECISION_MODEL, DecisionConfig};
20pub use delay::DelayConfig;
21pub use http::HttpConfig;
22pub use shell::ShellConfig;
23pub use workflow::WorkflowStepConfig;
24
25use ironflow_core::retry::RetryPolicy;
26use ironflow_store::entities::StepKind;
27use serde::{Deserialize, Serialize};
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
44#[serde(tag = "type", rename_all = "snake_case")]
45pub enum StepConfig {
46 Shell(ShellConfig),
48 Http(HttpConfig),
50 Agent(AgentStepConfig),
52 Workflow(WorkflowStepConfig),
54 Approval(ApprovalConfig),
56 Decision(DecisionConfig),
58 Delay(DelayConfig),
60}
61
62impl StepConfig {
63 pub fn allow_failure(&self) -> bool {
77 match self {
78 StepConfig::Shell(c) => c.allow_failure,
79 StepConfig::Http(c) => c.allow_failure,
80 StepConfig::Agent(c) => c.allow_failure,
81 StepConfig::Workflow(_)
82 | StepConfig::Approval(_)
83 | StepConfig::Decision(_)
84 | StepConfig::Delay(_) => false,
85 }
86 }
87
88 pub fn retry(&self) -> Option<&RetryPolicy> {
103 match self {
104 StepConfig::Shell(c) => c.retry.as_ref(),
105 StepConfig::Http(c) => c.retry.as_ref(),
106 StepConfig::Agent(c) => c.retry.as_ref(),
107 StepConfig::Workflow(c) => c.retry.as_ref(),
108 StepConfig::Approval(_) | StepConfig::Decision(_) | StepConfig::Delay(_) => None,
109 }
110 }
111
112 pub fn kind(&self) -> StepKind {
124 match self {
125 StepConfig::Shell(_) => StepKind::Shell,
126 StepConfig::Http(_) => StepKind::Http,
127 StepConfig::Agent(_) => StepKind::Agent,
128 StepConfig::Workflow(_) => StepKind::Workflow,
129 StepConfig::Approval(_) => StepKind::Approval,
130 StepConfig::Decision(_) => StepKind::Decision,
131 StepConfig::Delay(_) => StepKind::Custom("delay".to_string()),
132 }
133 }
134}
135
136impl From<ShellConfig> for StepConfig {
137 fn from(c: ShellConfig) -> Self {
138 StepConfig::Shell(c)
139 }
140}
141
142impl From<HttpConfig> for StepConfig {
143 fn from(c: HttpConfig) -> Self {
144 StepConfig::Http(c)
145 }
146}
147
148impl From<AgentStepConfig> for StepConfig {
149 fn from(c: AgentStepConfig) -> Self {
150 StepConfig::Agent(c)
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use ironflow_core::retry::RetryPolicy;
157
158 use super::*;
159
160 #[test]
161 fn retry_accessor_returns_policy_for_each_variant() {
162 let shell = StepConfig::Shell(ShellConfig::new("echo").retry_policy(RetryPolicy::new(2)));
163 assert_eq!(shell.retry().unwrap().max_retries(), 2);
164
165 let http = StepConfig::Http(HttpConfig::get("http://x").retry_policy(RetryPolicy::new(3)));
166 assert_eq!(http.retry().unwrap().max_retries(), 3);
167
168 let workflow = StepConfig::Workflow(
169 WorkflowStepConfig::new("build", serde_json::json!({}))
170 .retry_policy(RetryPolicy::new(4)),
171 );
172 assert_eq!(workflow.retry().unwrap().max_retries(), 4);
173
174 let agent = StepConfig::Agent(AgentStepConfig::new("test"));
175 assert!(agent.retry().is_none());
176
177 let approval = StepConfig::Approval(ApprovalConfig::new("ok?"));
178 assert!(approval.retry().is_none());
179 }
180
181 #[test]
182 fn serde_roundtrip() {
183 let configs = vec![
184 StepConfig::Shell(ShellConfig::new("echo test")),
185 StepConfig::Http(HttpConfig::get("http://example.com")),
186 StepConfig::Agent(AgentStepConfig::new("summarize")),
187 StepConfig::Workflow(WorkflowStepConfig::new("build", serde_json::json!({}))),
188 StepConfig::Approval(ApprovalConfig::new("Deploy to production?")),
189 StepConfig::Delay(DelayConfig::from_secs(60)),
190 ];
191
192 for config in configs {
193 let json = serde_json::to_string(&config).expect("serialize");
194 let back: StepConfig = serde_json::from_str(&json).expect("deserialize");
195 let json2 = serde_json::to_string(&back).expect("serialize2");
196 assert_eq!(json, json2);
197 }
198 }
199}