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
110pub use crate::skill::manifest::{FailureAction, RetryConfig, VarType, Variable};
111
112#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
114#[serde(rename_all = "snake_case")]
115pub enum NotifyLevel {
116 #[default]
117 Silent,
118 Normal,
119 Alert,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct NotifyConfig {
125 #[serde(default)]
126 pub on_success: NotifyLevel,
127 #[serde(default = "default_alert")]
128 pub on_failure: NotifyLevel,
129 #[serde(default = "default_normal")]
130 pub on_anomaly: NotifyLevel,
131}
132
133fn default_alert() -> NotifyLevel {
134 NotifyLevel::Alert
135}
136fn default_normal() -> NotifyLevel {
137 NotifyLevel::Normal
138}
139
140impl Default for NotifyConfig {
141 fn default() -> Self {
142 Self {
143 on_success: NotifyLevel::Silent,
144 on_failure: NotifyLevel::Alert,
145 on_anomaly: NotifyLevel::Normal,
146 }
147 }
148}
149
150#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
152#[serde(rename_all = "lowercase")]
153pub enum Permission {
154 #[default]
156 Read,
157 Write,
159 #[serde(rename = "execute_only")]
161 ExecuteOnly,
162}