1use std::fmt;
13
14use serde::{Deserialize, Serialize};
15
16pub const OWNER_KIND_DAEMON: &str = "daemon";
22
23#[derive(Debug)]
29pub struct UnknownRuntimeEnum {
30 kind: &'static str,
31 value: String,
32}
33
34impl UnknownRuntimeEnum {
35 #[must_use]
36 pub fn new(kind: &'static str, value: &str) -> Self {
37 Self {
38 kind,
39 value: value.to_string(),
40 }
41 }
42}
43
44impl fmt::Display for UnknownRuntimeEnum {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(f, "unknown {} value `{}`", self.kind, self.value)
47 }
48}
49
50impl std::error::Error for UnknownRuntimeEnum {}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
55#[serde(rename_all = "snake_case")]
56pub enum TaskStatus {
57 Queued,
58 Running,
59 WaitingForApproval,
60 Blocked,
61 Completed,
62 Failed,
63 Cancelled,
64}
65
66impl TaskStatus {
67 #[must_use]
68 pub fn as_str(self) -> &'static str {
69 match self {
70 Self::Queued => "queued",
71 Self::Running => "running",
72 Self::WaitingForApproval => "waiting_for_approval",
73 Self::Blocked => "blocked",
74 Self::Completed => "completed",
75 Self::Failed => "failed",
76 Self::Cancelled => "cancelled",
77 }
78 }
79
80 pub fn from_db(value: &str) -> std::result::Result<Self, UnknownRuntimeEnum> {
88 match value {
89 "queued" => Ok(Self::Queued),
90 "running" => Ok(Self::Running),
91 "waiting_for_approval" => Ok(Self::WaitingForApproval),
92 "blocked" => Ok(Self::Blocked),
93 "completed" => Ok(Self::Completed),
94 "failed" => Ok(Self::Failed),
95 "cancelled" => Ok(Self::Cancelled),
96 other => Err(UnknownRuntimeEnum::new("task status", other)),
97 }
98 }
99}
100
101impl fmt::Display for TaskStatus {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.write_str(self.as_str())
104 }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108#[serde(rename_all = "snake_case")]
109pub enum TaskPriority {
110 Low,
111 Normal,
112 High,
113}
114
115impl TaskPriority {
116 #[must_use]
117 pub fn as_str(self) -> &'static str {
118 match self {
119 Self::Low => "low",
120 Self::Normal => "normal",
121 Self::High => "high",
122 }
123 }
124
125 pub fn from_db(value: &str) -> std::result::Result<Self, UnknownRuntimeEnum> {
133 match value {
134 "low" => Ok(Self::Low),
135 "normal" => Ok(Self::Normal),
136 "high" => Ok(Self::High),
137 other => Err(UnknownRuntimeEnum::new("task priority", other)),
138 }
139 }
140}
141
142impl fmt::Display for TaskPriority {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.write_str(self.as_str())
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
149#[serde(rename_all = "snake_case")]
150pub enum ProcessStatus {
151 Running,
152 Exited,
153 Unknown,
154}
155
156impl ProcessStatus {
157 #[must_use]
158 pub fn as_str(self) -> &'static str {
159 match self {
160 Self::Running => "running",
161 Self::Exited => "exited",
162 Self::Unknown => "unknown",
163 }
164 }
165
166 pub fn from_db(value: &str) -> std::result::Result<Self, UnknownRuntimeEnum> {
174 match value {
175 "running" => Ok(Self::Running),
176 "exited" => Ok(Self::Exited),
177 "unknown" => Ok(Self::Unknown),
178 other => Err(UnknownRuntimeEnum::new("process status", other)),
179 }
180 }
181}
182
183#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
184pub struct TaskRecord {
185 pub id: String,
186 pub title: String,
187 pub status: TaskStatus,
188 pub priority: TaskPriority,
189 pub project_path: String,
190 pub model_id: String,
191 pub conversation_id: Option<String>,
192 pub created_at: String,
193 pub updated_at: String,
194 pub final_report: Option<String>,
195 pub prompt: Option<String>,
199}
200
201#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
202pub struct TaskTimelineEvent {
203 pub id: i64,
204 pub task_id: String,
205 pub kind: String,
206 pub message: String,
207 pub created_at: String,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
211pub struct SessionRecord {
212 pub id: String,
213 pub project_path: String,
214 pub model_id: String,
215 pub title: Option<String>,
216 pub conversation_path: Option<String>,
217 pub created_at: String,
218 pub updated_at: String,
219 pub total_tokens: Option<i64>,
220}
221
222#[derive(Debug, Clone, PartialEq, Eq)]
223pub struct NewSession {
224 pub id: Option<String>,
225 pub project_path: String,
226 pub model_id: String,
227 pub title: Option<String>,
228 pub conversation_path: Option<String>,
229 pub total_tokens: Option<i64>,
230}
231
232#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
238pub struct MessageRecord {
239 pub id: i64,
240 pub session_id: String,
241 pub role: String,
242 pub content_json: String,
243 pub created_at: String,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub struct NewTask {
248 pub title: String,
249 pub project_path: String,
250 pub model_id: String,
251 pub priority: TaskPriority,
252 pub conversation_id: Option<String>,
253 pub owner_kind: Option<String>,
259 pub prompt: Option<String>,
262}
263
264impl NewTask {
265 pub fn new(
266 title: impl Into<String>,
267 project_path: impl Into<String>,
268 model_id: impl Into<String>,
269 ) -> Self {
270 Self {
271 title: title.into(),
272 project_path: project_path.into(),
273 model_id: model_id.into(),
274 priority: TaskPriority::Normal,
275 conversation_id: None,
276 owner_kind: None,
277 prompt: None,
278 }
279 }
280
281 #[must_use]
285 pub fn daemon_owned(mut self) -> Self {
286 self.owner_kind = Some(OWNER_KIND_DAEMON.to_string());
287 self
288 }
289
290 pub fn with_prompt(mut self, prompt: impl Into<String>) -> Self {
292 self.prompt = Some(prompt.into());
293 self
294 }
295
296 #[must_use]
297 pub fn with_priority(mut self, priority: TaskPriority) -> Self {
298 self.priority = priority;
299 self
300 }
301}
302
303#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
304pub struct ApprovalRecord {
305 pub id: String,
306 pub task_id: Option<String>,
307 pub proposed_action: String,
308 pub risk_classification: String,
309 pub policy_decision: String,
310 pub user_decision: Option<String>,
311 pub args_summary: Option<String>,
312 pub checkpoint_id: Option<String>,
313 pub pending_action_json: Option<String>,
314 pub created_at: String,
315 pub decided_at: Option<String>,
316 pub archived_at: Option<String>,
317 pub archive_reason: Option<String>,
318}
319
320#[derive(Debug, Clone, PartialEq, Eq)]
321pub struct NewApproval {
322 pub task_id: Option<String>,
323 pub proposed_action: String,
324 pub risk_classification: String,
325 pub policy_decision: String,
326 pub args_summary: Option<String>,
327 pub checkpoint_id: Option<String>,
328 pub pending_action_json: Option<String>,
329}
330
331#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
332pub struct ToolRunRecord {
333 pub id: String,
334 pub task_id: Option<String>,
335 pub turn_id: Option<String>,
336 pub call_id: Option<String>,
337 pub tool_name: String,
338 pub status: String,
339 pub args_json: Option<String>,
340 pub output_json: Option<String>,
341 pub started_at: String,
342 pub finished_at: Option<String>,
343}
344
345#[derive(Debug, Clone, PartialEq, Eq)]
346pub struct NewToolRun {
347 pub id: Option<String>,
348 pub task_id: Option<String>,
349 pub turn_id: Option<String>,
350 pub call_id: Option<String>,
351 pub tool_name: String,
352 pub args_json: Option<String>,
353}
354
355#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
356pub struct ProcessRecord {
357 pub id: String,
358 pub task_id: Option<String>,
359 pub pid: u32,
360 pub command: String,
361 pub cwd: Option<String>,
362 pub log_path: Option<String>,
363 pub detected_url: Option<String>,
364 pub status: ProcessStatus,
365 pub health: Option<String>,
366 pub created_at: String,
367 pub updated_at: String,
368}
369
370#[derive(Debug, Clone, PartialEq, Eq)]
371pub struct NewProcess {
372 pub id: Option<String>,
373 pub task_id: Option<String>,
374 pub pid: u32,
375 pub command: String,
376 pub cwd: Option<String>,
377 pub log_path: Option<String>,
378 pub detected_url: Option<String>,
379 pub status: ProcessStatus,
380 pub health: Option<String>,
381}
382
383#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
384pub struct CheckpointRecord {
385 pub id: String,
386 pub task_id: Option<String>,
387 pub project_path: String,
388 pub snapshot_path: String,
389 pub changed_files_json: String,
390 pub pending_action_json: Option<String>,
391 pub approval_id: Option<String>,
392 pub created_at: String,
393 pub archived_at: Option<String>,
394 pub archive_reason: Option<String>,
395 pub session_id: Option<String>,
399 pub message_index: Option<i64>,
404}
405
406#[derive(Debug, Clone, PartialEq, Eq)]
407pub struct NewCheckpoint {
408 pub id: Option<String>,
409 pub task_id: Option<String>,
410 pub project_path: String,
411 pub snapshot_path: String,
412 pub changed_files_json: String,
413 pub pending_action_json: Option<String>,
414 pub approval_id: Option<String>,
415 pub session_id: Option<String>,
416 pub message_index: Option<i64>,
417}
418
419pub const OUTCOME_SOURCE_VERIFIER: &str = "verifier";
426pub const OUTCOME_SOURCE_USER: &str = "user";
427pub const OUTCOME_SOURCE_MODEL: &str = "model";
428pub const OUTCOME_SOURCE_SYSTEM: &str = "system";
429
430pub const OUTCOME_LABEL_SUCCESS: &str = "success";
434pub const OUTCOME_LABEL_FAILURE: &str = "failure";
435pub const OUTCOME_LABEL_PARTIAL: &str = "partial";
436pub const OUTCOME_LABEL_ACCEPTED: &str = "accepted";
437pub const OUTCOME_LABEL_REJECTED: &str = "rejected";
438pub const OUTCOME_LABEL_UNKNOWN: &str = "unknown";
439
440#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
446pub struct OutcomeRecord {
447 pub id: String,
448 pub task_id: Option<String>,
449 pub tool_run_id: Option<String>,
450 pub kind: String,
453 pub label: String,
455 pub reward: Option<f64>,
458 pub source: String,
460 pub detail_json: Option<String>,
463 pub created_at: String,
464}
465
466#[derive(Debug, Clone, PartialEq)]
467pub struct NewOutcome {
468 pub id: Option<String>,
469 pub task_id: Option<String>,
470 pub tool_run_id: Option<String>,
471 pub kind: String,
472 pub label: String,
473 pub reward: Option<f64>,
474 pub source: String,
475 pub detail_json: Option<String>,
476}
477
478#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
479pub struct CompactionRecord {
480 pub id: String,
481 pub task_id: Option<String>,
482 pub session_id: Option<String>,
483 pub source_token_estimate: Option<i64>,
484 pub summary_token_count: Option<i64>,
485 pub preserved_turns: Option<i64>,
486 pub archive_path: Option<String>,
487 pub verification_status: Option<String>,
488 pub created_at: String,
489}
490
491#[derive(Debug, Clone, PartialEq, Eq)]
492pub struct NewCompaction {
493 pub id: Option<String>,
494 pub task_id: Option<String>,
495 pub session_id: Option<String>,
496 pub source_token_estimate: Option<i64>,
497 pub summary_token_count: Option<i64>,
498 pub preserved_turns: Option<i64>,
499 pub archive_path: Option<String>,
500 pub verification_status: Option<String>,
501}
502
503#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
504pub struct PluginInstallRecord {
505 pub id: String,
506 pub name: String,
507 pub source: String,
508 pub version: Option<String>,
509 pub enabled: bool,
510 pub manifest_json: String,
511 pub installed_at: String,
512 pub updated_at: String,
513}
514
515#[derive(Debug, Clone, PartialEq, Eq)]
516pub struct NewPluginInstall {
517 pub id: Option<String>,
518 pub name: String,
519 pub source: String,
520 pub version: Option<String>,
521 pub enabled: bool,
522 pub manifest_json: String,
523}
524
525#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
526pub struct ProviderProbeRecord {
527 pub provider: String,
528 pub model_id: String,
529 pub capability_key: String,
530 pub capability_value: String,
531 pub confidence: String,
532 pub error: Option<String>,
533 pub probed_at: String,
534}
535
536#[derive(Debug, Clone, PartialEq, Eq)]
537pub struct NewProviderProbe {
538 pub provider: String,
539 pub model_id: String,
540 pub capability_key: String,
541 pub capability_value: String,
542 pub confidence: String,
543 pub error: Option<String>,
544}
545
546#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
547pub struct PairingTokenRecord {
548 pub id: String,
549 pub token_hash: String,
550 pub label: Option<String>,
551 pub enabled: bool,
552 pub created_at: String,
553 pub last_used_at: Option<String>,
554 pub expires_at: Option<String>,
556}