1use std::collections::HashMap;
4
5use car_ir::ProposalResult;
6use car_multi::AgentOutput;
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct WorkflowResult {
14 pub workflow_id: String,
15 pub workflow_name: String,
16 pub status: WorkflowStatus,
17 pub stages: Vec<StageResult>,
19 pub compensations: Vec<CompensationResult>,
21 pub duration_ms: f64,
22 pub timestamp: DateTime<Utc>,
23 #[serde(default)]
25 pub final_state: HashMap<String, Value>,
26}
27
28impl WorkflowResult {
29 pub fn succeeded(&self) -> bool {
30 self.status == WorkflowStatus::Completed
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum WorkflowStatus {
37 Completed,
39 Failed,
41 Compensated,
43 PartiallyCompensated,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct StageResult {
50 pub stage_id: String,
51 pub stage_name: String,
52 pub status: StageStatus,
53 pub output: StageOutput,
54 pub duration_ms: f64,
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub error: Option<String>,
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
60#[serde(rename_all = "snake_case")]
61pub enum StageStatus {
62 Succeeded,
63 Failed,
64 Skipped,
65 Compensated,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(tag = "type", rename_all = "snake_case")]
71pub enum StageOutput {
72 Pattern {
73 outputs: Vec<AgentOutput>,
74 final_answer: String,
75 },
76 Proposal {
77 result: ProposalResult,
78 },
79 SubWorkflow {
80 result: Box<WorkflowResult>,
81 },
82 Empty,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct CompensationResult {
88 pub for_stage_id: String,
89 pub status: StageStatus,
90 pub duration_ms: f64,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
92 pub error: Option<String>,
93}