1#![allow(dead_code)]
11
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(tag = "type")]
17pub enum Event {
18 #[serde(rename = "pipe.started")]
19 PipeStarted(PipeStarted),
20
21 #[serde(rename = "pipe.completed")]
22 PipeCompleted(PipeCompleted),
23
24 #[serde(rename = "pipe.aborted")]
25 PipeAborted(PipeAborted),
26
27 #[serde(rename = "node.started")]
28 NodeStarted(NodeStarted),
29
30 #[serde(rename = "node.completed")]
31 NodeCompleted(NodeCompleted),
32
33 #[serde(rename = "node.failed")]
34 NodeFailed(NodeFailed),
35
36 #[serde(rename = "gate.passed")]
37 GatePassed(GatePassed),
38
39 #[serde(rename = "iteration.started")]
40 IterationStarted(IterationStarted),
41}
42
43impl Event {
44 pub fn event_type(&self) -> &'static str {
46 match self {
47 Event::PipeStarted(_) => "pipe.started",
48 Event::PipeCompleted(_) => "pipe.completed",
49 Event::PipeAborted(_) => "pipe.aborted",
50 Event::NodeStarted(_) => "node.started",
51 Event::NodeCompleted(_) => "node.completed",
52 Event::NodeFailed(_) => "node.failed",
53 Event::GatePassed(_) => "gate.passed",
54 Event::IterationStarted(_) => "iteration.started",
55 }
56 }
57
58 pub fn run_id(&self) -> &str {
60 match self {
61 Event::PipeStarted(e) => &e.run_id,
62 Event::PipeCompleted(e) => &e.run_id,
63 Event::PipeAborted(e) => &e.run_id,
64 Event::NodeStarted(e) => &e.run_id,
65 Event::NodeCompleted(e) => &e.run_id,
66 Event::NodeFailed(e) => &e.run_id,
67 Event::GatePassed(e) => &e.run_id,
68 Event::IterationStarted(e) => &e.run_id,
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
75#[serde(rename_all = "snake_case")]
76pub enum NodeKind {
77 Command,
78 Prompt,
79 Bash,
80 Loop,
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "snake_case")]
87pub enum GateMethod {
88 Hook,
89 HumanCli,
90 McpTool,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
95#[serde(rename_all = "snake_case")]
96pub enum ErrorKind {
97 HostMissing,
98 Timeout,
99 Blocked,
100 GateFailed,
101 GateTimeout,
102 Crash,
103 MaxIterationsExceeded,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct NodeError {
109 pub kind: ErrorKind,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct Input {
119 pub key: String,
120 pub value: String,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct PipeStarted {
129 pub id: String,
130 pub ts: String,
131 pub run_id: String,
132 pub pipe: String,
133 #[serde(default, skip_serializing_if = "Vec::is_empty")]
134 pub inputs: Vec<Input>,
135 #[serde(default, skip_serializing_if = "String::is_empty")]
136 pub distro_version: String,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct PipeCompleted {
141 pub id: String,
142 pub ts: String,
143 pub run_id: String,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct PipeAborted {
148 pub id: String,
149 pub ts: String,
150 pub run_id: String,
151 pub reason: String,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct NodeStarted {
156 pub id: String,
157 pub ts: String,
158 pub run_id: String,
159 pub node_id: String,
160 pub kind: NodeKind,
161 #[serde(default, skip_serializing_if = "Option::is_none")]
162 pub name: Option<String>,
163 #[serde(default, skip_serializing_if = "Option::is_none")]
164 pub model: Option<String>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct NodeCompleted {
169 pub id: String,
170 pub ts: String,
171 pub run_id: String,
172 pub node_id: String,
173 pub output_path: String,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct NodeFailed {
182 pub id: String,
183 pub ts: String,
184 pub run_id: String,
185 pub node_id: String,
186 pub error: NodeError,
187 #[serde(default, skip_serializing_if = "Option::is_none")]
194 pub message: Option<String>,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct GatePassed {
199 pub id: String,
200 pub ts: String,
201 pub run_id: String,
202 pub node_id: String,
203 pub gate: String,
204 pub method: GateMethod,
205 #[serde(default, skip_serializing_if = "Option::is_none")]
211 pub stdout: Option<String>,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct IterationStarted {
223 pub id: String,
224 pub ts: String,
225 pub run_id: String,
226 pub node_id: String,
227 pub iteration: u32,
228 pub byte_offset: u64,
229}