1use crate::swl::types::schema::StateSchema;
2use serde::{Deserialize, Serialize};
3use std::collections::BTreeMap;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6pub struct SwlDocument {
7 pub version: String,
8 pub name: String,
9 #[serde(default)]
10 pub description: Option<String>,
11 #[serde(default)]
12 pub metadata: Option<DocumentMetadata>,
13 #[serde(default)]
14 pub agents: BTreeMap<String, AgentDefinition>,
15 #[serde(default)]
16 pub workflows: BTreeMap<String, WorkflowDefinition>,
17 #[serde(default)]
18 pub guardrails: Vec<Guardrail>,
19 #[serde(default)]
20 pub telemetry: Option<TelemetryConfig>,
21 #[serde(default)]
22 pub dashboard: Option<DashboardConfig>,
23 #[serde(default)]
24 pub state: Option<StateSchema>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
28pub struct DocumentMetadata {
29 #[serde(default)]
30 pub author: Option<String>,
31 #[serde(default)]
32 pub tags: Vec<String>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
36pub struct AgentDefinition {
37 pub model: ModelSpec,
38 #[serde(default)]
39 pub role: Option<String>,
40 #[serde(default)]
41 pub instruction: Option<String>,
42 #[serde(default)]
43 pub tools: Vec<String>,
44 #[serde(default)]
45 pub output_key: Option<String>,
46 #[serde(default)]
47 pub sub_agents: Vec<String>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
51#[serde(untagged)]
52pub enum ModelSpec {
53 Simple(String),
54 Detailed(ModelConfig),
55}
56
57impl ModelSpec {
58 pub fn name(&self) -> &str {
59 match self {
60 ModelSpec::Simple(name) => name,
61 ModelSpec::Detailed(config) => config.name.as_str(),
62 }
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
67pub struct ModelConfig {
68 #[serde(default)]
69 pub provider: Option<String>,
70 pub name: String,
71 #[serde(default)]
72 pub temperature: Option<f64>,
73 #[serde(default)]
74 pub max_tokens: Option<u32>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
78pub struct WorkflowDefinition {
79 #[serde(rename = "type")]
80 pub workflow_type: WorkflowType,
81 #[serde(default)]
82 pub description: Option<String>,
83 #[serde(default)]
84 pub steps: Vec<WorkflowStep>,
85 #[serde(default)]
86 pub map: Option<MapStage>,
87 #[serde(default)]
88 pub reduce: Option<ReduceStage>,
89 #[serde(default)]
90 pub merge: Option<AggregateStage>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
94pub enum WorkflowType {
95 #[serde(rename = "sequential")]
96 Sequential,
97 #[serde(rename = "parallel")]
98 Parallel,
99 #[serde(rename = "map_reduce", alias = "map-reduce")]
100 MapReduce,
101 #[serde(rename = "conditional")]
102 Conditional,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
106pub struct WorkflowStep {
107 #[serde(default)]
108 pub name: Option<String>,
109 #[serde(default)]
110 pub delegate: Option<String>,
111 #[serde(default)]
112 pub agent: Option<String>,
113 #[serde(default)]
114 pub action: Option<String>,
115 #[serde(default)]
116 pub input: Option<serde_yaml::Value>,
117 #[serde(default)]
118 pub parallel: Option<ParallelStage>,
119 #[serde(default)]
120 pub guard: Option<Guardrail>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
124pub struct ParallelStage {
125 #[serde(default)]
126 pub branches: Vec<WorkflowStep>,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
130pub struct MapStage {
131 #[serde(default)]
132 pub targets: Vec<String>,
133 #[serde(default)]
134 pub input: Option<serde_yaml::Value>,
135 #[serde(default)]
136 pub parallel: Option<ParallelStage>,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
140#[serde(untagged)]
141pub enum ReduceStage {
142 Code(CodeBlock),
143 Aggregate(AggregateStage),
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
147pub struct AggregateStage {
148 pub agent: String,
149 #[serde(default)]
150 pub instruction: Option<String>,
151 #[serde(default)]
152 pub inputs: Vec<String>,
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
156pub struct CodeBlock {
157 pub language: CodeLanguage,
158 #[serde(alias = "content")]
159 pub code: String,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
163pub enum CodeLanguage {
164 #[serde(rename = "rust")]
165 Rust,
166 #[serde(rename = "python")]
167 Python,
168}
169
170#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
171pub struct Guardrail {
172 #[serde(default)]
173 pub name: Option<String>,
174 #[serde(default, rename = "type")]
175 pub guardrail_type: Option<String>,
176 pub condition: GuardCondition,
177 pub on_violation: String,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
181#[serde(untagged)]
182pub enum GuardCondition {
183 Inline(String),
184 Code(CodeBlock),
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
188pub struct TelemetryConfig {
189 #[serde(default)]
190 pub enabled: Option<bool>,
191 #[serde(default)]
192 pub traces: Vec<String>,
193 #[serde(default)]
194 pub metrics: Vec<String>,
195 #[serde(default)]
196 pub export: Option<TelemetryExport>,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
200pub struct TelemetryExport {
201 #[serde(rename = "type")]
202 pub export_type: String,
203 #[serde(default)]
204 pub path: Option<String>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
208pub struct DashboardConfig {
209 #[serde(default)]
210 pub layout: Option<String>,
211 #[serde(default)]
212 pub refresh: Option<String>,
213}
214
215#[cfg(test)]
216#[path = "../../../tests/unit/swl/parser/ast/ast_test.rs"]
217mod tests;