Skip to main content

kaizen/visualization/
types.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3use crate::core::event::{Event, SessionRecord};
4use crate::store::SpanNode;
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, Default, Serialize, Deserialize)]
8pub struct VisualizationReport {
9    pub generated_at_ms: u64,
10    pub workspace: String,
11    pub totals: VisualizationTotals,
12    pub activity: ActivityReport,
13    pub sessions: Vec<TraceSummary>,
14    #[serde(default)]
15    pub session_page: SessionPageMeta,
16    pub selected: Option<TraceDetail>,
17    pub quality: DataQuality,
18}
19
20#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
21pub struct SessionSearchInput {
22    pub q: String,
23    pub offset: usize,
24}
25
26#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
27pub struct SessionPageMeta {
28    pub filtered_total: usize,
29    pub offset: usize,
30    pub limit: usize,
31    pub next_offset: Option<usize>,
32}
33
34#[derive(Clone, Debug, Default, Serialize, Deserialize)]
35pub struct VisualizationTotals {
36    pub session_count: u64,
37    pub running_count: u64,
38    pub event_count: u64,
39    pub error_count: u64,
40    pub tool_call_count: u64,
41    pub cost_usd_e6: i64,
42    pub tokens: TokenTotals,
43}
44
45#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
46pub struct TokenTotals {
47    pub input: u64,
48    pub output: u64,
49    pub reasoning: u64,
50    pub cache_read: u64,
51    pub cache_create: u64,
52    pub total: u64,
53}
54
55#[derive(Clone, Debug, Default, Serialize, Deserialize)]
56pub struct ActivityReport {
57    pub metric: ActivityMetric,
58    pub day_bins: Vec<ActivityBin>,
59    pub week_bins: Vec<ActivityBin>,
60}
61
62#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
63#[serde(rename_all = "snake_case")]
64pub enum ActivityMetric {
65    #[default]
66    Events,
67    Sessions,
68    Tokens,
69    Cost,
70}
71
72#[derive(Clone, Debug, Default, Serialize, Deserialize)]
73pub struct ActivityBin {
74    pub start_ms: u64,
75    pub end_ms: u64,
76    pub event_count: u64,
77    pub session_count: u64,
78    pub token_total: u64,
79    pub cost_usd_e6: i64,
80    pub active_by_agent: Vec<(String, u64)>,
81    pub dominant_agent: Option<String>,
82    pub dominant_kind: Option<String>,
83    pub heat: f64,
84    pub is_break: bool,
85}
86
87#[derive(Clone, Debug, Serialize, Deserialize)]
88pub struct TraceSummary {
89    pub id: String,
90    pub agent: String,
91    pub model: Option<String>,
92    pub status: DerivedStatus,
93    pub status_reason: String,
94    pub started_at_ms: u64,
95    pub ended_at_ms: Option<u64>,
96    pub last_event_ms: Option<u64>,
97    pub event_count: u64,
98    pub error_count: u64,
99    pub tool_call_count: u64,
100    pub cost_usd_e6: i64,
101    pub tokens: TokenTotals,
102    pub top_tools: Vec<(String, u64)>,
103}
104
105#[derive(Clone, Debug, Serialize, Deserialize)]
106pub struct TraceDetail {
107    pub session: SessionRecord,
108    #[serde(default)]
109    pub prompt: Option<String>,
110    pub events: Vec<Event>,
111    pub spans: Vec<SpanNode>,
112    pub files: Vec<String>,
113}
114
115#[derive(Clone, Debug, Default, Serialize, Deserialize)]
116pub struct DataQuality {
117    pub token_coverage_pct: f64,
118    pub cost_coverage_pct: f64,
119    pub partial_cost_sessions: u64,
120    pub adapter_errors: Vec<String>,
121    pub stale_scan: bool,
122    pub warnings: Vec<String>,
123}
124
125#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
126#[serde(rename_all = "snake_case")]
127pub enum DerivedStatus {
128    Active,
129    WaitingOnTool,
130    Idle,
131    Done,
132    Errored,
133    Orphaned,
134}