Skip to main content

car_workflow/
result.rs

1//! Workflow execution result types.
2
3use 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/// Overall workflow execution result.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct WorkflowResult {
14    pub workflow_id: String,
15    pub workflow_name: String,
16    pub status: WorkflowStatus,
17    /// Results for each stage that executed (in execution order).
18    pub stages: Vec<StageResult>,
19    /// Compensation records (in compensation order, reverse of execution).
20    pub compensations: Vec<CompensationResult>,
21    pub duration_ms: f64,
22    pub timestamp: DateTime<Utc>,
23    /// Final workflow state snapshot.
24    #[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    /// All stages completed successfully.
38    Completed,
39    /// A stage failed and no compensation was attempted.
40    Failed,
41    /// A stage failed and all compensations succeeded.
42    Compensated,
43    /// A stage failed and some compensations also failed.
44    PartiallyCompensated,
45}
46
47/// Result of a single stage execution.
48#[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/// The typed output of a stage, depending on its step type.
69#[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/// Record of a compensation attempt.
86#[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}