Skip to main content

selfware/swl/parser/
ast.rs

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;