agentforge_core/
shadow.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7#[serde(rename_all = "snake_case")]
8pub enum ShadowRunStatus {
9 Pending,
10 Running,
11 Complete,
12 Error,
13}
14
15impl std::fmt::Display for ShadowRunStatus {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 match self {
18 ShadowRunStatus::Pending => write!(f, "pending"),
19 ShadowRunStatus::Running => write!(f, "running"),
20 ShadowRunStatus::Complete => write!(f, "complete"),
21 ShadowRunStatus::Error => write!(f, "error"),
22 }
23 }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
28#[serde(rename_all = "snake_case")]
29pub enum DimensionOutcome {
30 Win,
31 Loss,
32 Tie,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct DimensionComparison {
38 pub dimension: String,
39 pub champion_score: f64,
40 pub candidate_score: f64,
41 pub outcome: DimensionOutcome,
42 pub delta: f64,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct ShadowComparison {
48 pub run_id: Uuid,
49 pub champion_agent_id: Uuid,
50 pub candidate_agent_id: Uuid,
51 pub traffic_fraction: f64,
53 pub total_requests: u32,
54 pub champion_aggregate_score: f64,
55 pub candidate_aggregate_score: f64,
56 pub aggregate_delta: f64,
57 pub per_dimension: Vec<DimensionComparison>,
58 pub candidate_wins: bool,
60 pub compared_at: DateTime<Utc>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct ShadowRun {
66 pub id: Uuid,
67 pub champion_agent_id: Uuid,
68 pub candidate_agent_id: Uuid,
69 pub traffic_percent: u8,
71 pub status: ShadowRunStatus,
72 pub comparison: Option<ShadowComparison>,
73 pub error_message: Option<String>,
74 pub created_at: DateTime<Utc>,
75 pub started_at: Option<DateTime<Utc>>,
76 pub completed_at: Option<DateTime<Utc>>,
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn status_display() {
85 assert_eq!(ShadowRunStatus::Pending.to_string(), "pending");
86 assert_eq!(ShadowRunStatus::Complete.to_string(), "complete");
87 }
88}