1use serde::{Deserialize, Serialize};
6
7use crate::knowledge::KnowledgeBase;
8use crate::schedule::Capability;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Workflow {
15 #[serde(flatten)]
17 pub base: KnowledgeBase,
18
19 #[serde(default)]
21 pub steps: Vec<Step>,
22
23 #[serde(default)]
25 pub variables: Vec<Variable>,
26
27 #[serde(default)]
29 pub source_sessions: Vec<String>,
30
31 #[serde(default)]
33 pub trigger: String,
34
35 #[serde(default)]
37 pub tools: Vec<String>,
38
39 #[serde(default)]
41 pub published_version: u32,
42
43 #[serde(default)]
45 pub permission: Permission,
46
47 #[serde(default, skip_serializing_if = "Option::is_none")]
49 pub schedule: Option<String>,
50
51 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub id: Option<String>,
54
55 #[serde(default, skip_serializing_if = "Option::is_none")]
57 pub notify: Option<NotifyConfig>,
58
59 #[serde(default, skip_serializing_if = "Vec::is_empty")]
61 pub requires: Vec<Capability>,
62}
63
64impl std::ops::Deref for Workflow {
66 type Target = KnowledgeBase;
67 fn deref(&self) -> &KnowledgeBase {
68 &self.base
69 }
70}
71impl std::ops::DerefMut for Workflow {
72 fn deref_mut(&mut self) -> &mut KnowledgeBase {
73 &mut self.base
74 }
75}
76
77#[derive(Debug, Clone, Default, Serialize, Deserialize)]
79pub struct Step {
80 pub order: u32,
82 pub description: String,
84 #[serde(default)]
86 pub command: Option<String>,
87 #[serde(default)]
89 pub tool: Option<String>,
90 #[serde(default)]
92 pub needs_approval: bool,
93 #[serde(default)]
95 pub on_failure: FailureAction,
96
97 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub breakpoint: Option<bool>,
100
101 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub retry: Option<RetryConfig>,
104
105 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub timeout_secs: Option<u64>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct RetryConfig {
113 pub max_retries: u32,
114 #[serde(default)]
115 pub backoff_secs: Option<u64>,
116}
117
118#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
120#[serde(rename_all = "lowercase")]
121pub enum FailureAction {
122 Skip,
124 #[default]
126 Abort,
127 Retry,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct Variable {
134 pub name: String,
136 #[serde(rename = "type", default)]
138 pub var_type: VarType,
139 #[serde(default)]
141 pub required: bool,
142 #[serde(default)]
144 pub default_value: Option<String>,
145 #[serde(default)]
147 pub description: String,
148}
149
150#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
152#[serde(rename_all = "lowercase")]
153pub enum VarType {
154 #[default]
155 String,
156 Path,
157 Url,
158 Number,
159 Bool,
160 Array,
162}
163
164impl std::fmt::Display for VarType {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 match self {
167 VarType::String => write!(f, "string"),
168 VarType::Path => write!(f, "path"),
169 VarType::Url => write!(f, "url"),
170 VarType::Number => write!(f, "number"),
171 VarType::Bool => write!(f, "bool"),
172 VarType::Array => write!(f, "array"),
173 }
174 }
175}
176
177#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
179#[serde(rename_all = "snake_case")]
180pub enum NotifyLevel {
181 #[default]
182 Silent,
183 Normal,
184 Alert,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct NotifyConfig {
190 #[serde(default)]
191 pub on_success: NotifyLevel,
192 #[serde(default = "default_alert")]
193 pub on_failure: NotifyLevel,
194 #[serde(default = "default_normal")]
195 pub on_anomaly: NotifyLevel,
196}
197
198fn default_alert() -> NotifyLevel {
199 NotifyLevel::Alert
200}
201fn default_normal() -> NotifyLevel {
202 NotifyLevel::Normal
203}
204
205impl Default for NotifyConfig {
206 fn default() -> Self {
207 Self {
208 on_success: NotifyLevel::Silent,
209 on_failure: NotifyLevel::Alert,
210 on_anomaly: NotifyLevel::Normal,
211 }
212 }
213}
214
215#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
217#[serde(rename_all = "lowercase")]
218pub enum Permission {
219 #[default]
221 Read,
222 Write,
224 #[serde(rename = "execute_only")]
226 ExecuteOnly,
227}