1pub mod overview;
2pub mod project;
3pub mod session;
4pub mod trend;
5pub mod validate;
6
7use crate::data::models::{GlobalDataQuality, TokenUsage};
8use chrono::{DateTime, NaiveDate, Utc};
9use std::collections::HashMap;
10
11#[derive(Debug, Default, Clone)]
14pub struct AggregatedTokens {
15 pub input_tokens: u64,
16 pub output_tokens: u64,
17 pub cache_creation_tokens: u64, pub cache_write_5m_tokens: u64, pub cache_write_1h_tokens: u64, pub cache_read_tokens: u64,
21 pub turns: usize,
22}
23
24impl AggregatedTokens {
25 pub fn add_usage(&mut self, usage: &TokenUsage) {
26 self.input_tokens += usage.input_tokens.unwrap_or(0);
27 self.output_tokens += usage.output_tokens.unwrap_or(0);
28 self.cache_creation_tokens += usage.cache_creation_input_tokens.unwrap_or(0);
29 self.cache_read_tokens += usage.cache_read_input_tokens.unwrap_or(0);
30
31 if let Some(ref detail) = usage.cache_creation {
33 self.cache_write_5m_tokens += detail.ephemeral_5m_input_tokens.unwrap_or(0);
34 self.cache_write_1h_tokens += detail.ephemeral_1h_input_tokens.unwrap_or(0);
35 }
36
37 self.turns += 1;
38 }
39
40 pub fn context_tokens(&self) -> u64 {
41 self.input_tokens + self.cache_creation_tokens + self.cache_read_tokens
42 }
43}
44
45#[derive(Debug, Clone, Default)]
48pub struct TurnCostBreakdown {
49 pub input_cost: f64,
50 pub output_cost: f64,
51 pub cache_write_5m_cost: f64,
52 pub cache_write_1h_cost: f64,
53 pub cache_read_cost: f64,
54 pub total: f64,
55}
56
57#[derive(Debug, Default)]
58pub struct CostByCategory {
59 pub input_cost: f64,
60 pub output_cost: f64,
61 pub cache_write_5m_cost: f64,
62 pub cache_write_1h_cost: f64,
63 pub cache_read_cost: f64,
64}
65
66pub struct OverviewResult {
69 pub total_sessions: usize,
70 pub total_turns: usize,
71 pub total_agent_turns: usize,
72 pub tokens_by_model: HashMap<String, AggregatedTokens>,
73 pub cost_by_model: HashMap<String, f64>,
74 pub total_cost: f64,
75 pub hourly_distribution: [usize; 24],
76 pub quality: GlobalDataQuality,
77 pub subscription_value: Option<SubscriptionValue>,
78 pub weekday_hour_matrix: [[usize; 24]; 7], pub tool_counts: Vec<(String, usize)>, pub cost_by_category: CostByCategory, pub session_summaries: Vec<SessionSummary>, pub total_output_tokens: u64,
84 pub total_context_tokens: u64,
85 pub avg_cache_hit_rate: f64,
86 pub cache_savings: CacheSavings,
87}
88
89#[derive(Debug, Default)]
91pub struct CacheSavings {
92 pub total_saved: f64, pub without_cache_cost: f64, pub with_cache_cost: f64, pub savings_pct: f64, pub by_model: Vec<(String, f64)>, }
98
99pub struct SubscriptionValue {
100 pub monthly_price: f64,
101 pub api_equivalent: f64,
102 pub value_multiplier: f64,
103}
104
105pub struct ProjectResult {
108 pub projects: Vec<ProjectSummary>,
109}
110
111pub struct ProjectSummary {
112 pub name: String,
113 pub display_name: String,
114 pub session_count: usize,
115 pub total_turns: usize,
116 pub agent_turns: usize,
117 pub tokens: AggregatedTokens,
118 pub cost: f64,
119}
120
121pub struct SessionResult {
124 pub session_id: String,
125 pub project: String,
126 pub turn_details: Vec<TurnDetail>,
127 pub agent_summary: AgentSummary,
128 pub total_tokens: AggregatedTokens,
129 pub total_cost: f64,
130 pub stop_reason_counts: HashMap<String, usize>,
131 pub duration_minutes: f64,
133 pub max_context: u64,
134 pub compaction_count: usize,
135 pub cache_write_5m_pct: f64, pub cache_write_1h_pct: f64, pub model: String, }
139
140#[derive(Debug)]
141pub struct TurnDetail {
142 pub turn_number: usize,
143 pub timestamp: DateTime<Utc>,
144 pub model: String,
145 pub input_tokens: u64,
146 pub output_tokens: u64,
147 pub cache_write_5m_tokens: u64, pub cache_write_1h_tokens: u64, pub cache_read_tokens: u64,
150 pub context_size: u64,
151 pub cache_hit_rate: f64,
152 pub cost: f64,
153 pub cost_breakdown: TurnCostBreakdown, pub stop_reason: Option<String>,
155 pub is_agent: bool,
156 pub is_compaction: bool, pub context_delta: i64, pub user_text: Option<String>, pub assistant_text: Option<String>, pub tool_names: Vec<String>, }
162
163#[derive(Debug, Default)]
164pub struct AgentSummary {
165 pub total_agent_turns: usize,
166 pub agent_output_tokens: u64,
167 pub agent_cost: f64,
168}
169
170#[derive(Debug)]
174pub struct SessionSummary {
175 pub session_id: String,
176 pub project_display_name: String,
177 pub first_timestamp: Option<DateTime<Utc>>,
178 pub duration_minutes: f64,
179 pub model: String, pub turn_count: usize,
181 pub agent_turn_count: usize,
182 pub output_tokens: u64,
183 pub context_tokens: u64,
184 pub max_context: u64,
185 pub cache_hit_rate: f64, pub cache_write_5m_pct: f64, pub compaction_count: usize,
188 pub cost: f64,
189 pub tool_use_count: usize, pub top_tools: Vec<(String, usize)>, pub turn_details: Option<Vec<TurnDetail>>, }
193
194pub struct TrendResult {
197 pub entries: Vec<TrendEntry>,
198 pub group_label: String, }
200
201pub struct TrendEntry {
202 pub label: String, pub date: NaiveDate,
204 pub session_count: usize,
205 pub turn_count: usize,
206 pub tokens: AggregatedTokens,
207 pub cost: f64,
208 pub models: HashMap<String, u64>,
209 pub cost_by_category: CostByCategory,
211}
212
213pub type DailyStats = TrendEntry;