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 pub primary_model: String,
120}
121
122pub struct SessionResult {
125 pub session_id: String,
126 pub project: String,
127 pub turn_details: Vec<TurnDetail>,
128 pub agent_summary: AgentSummary,
129 pub total_tokens: AggregatedTokens,
130 pub total_cost: f64,
131 pub stop_reason_counts: HashMap<String, usize>,
132 pub duration_minutes: f64,
134 pub max_context: u64,
135 pub compaction_count: usize,
136 pub cache_write_5m_pct: f64, pub cache_write_1h_pct: f64, pub model: String, }
140
141#[derive(Debug)]
142pub struct TurnDetail {
143 pub turn_number: usize,
144 pub timestamp: DateTime<Utc>,
145 pub model: String,
146 pub input_tokens: u64,
147 pub output_tokens: u64,
148 pub cache_write_5m_tokens: u64, pub cache_write_1h_tokens: u64, pub cache_read_tokens: u64,
151 pub context_size: u64,
152 pub cache_hit_rate: f64,
153 pub cost: f64,
154 pub cost_breakdown: TurnCostBreakdown, pub stop_reason: Option<String>,
156 pub is_agent: bool,
157 pub is_compaction: bool, pub context_delta: i64, pub user_text: Option<String>, pub assistant_text: Option<String>, pub tool_names: Vec<String>, }
163
164#[derive(Debug, Default)]
165pub struct AgentSummary {
166 pub total_agent_turns: usize,
167 pub agent_output_tokens: u64,
168 pub agent_cost: f64,
169}
170
171#[derive(Debug)]
175pub struct SessionSummary {
176 pub session_id: String,
177 pub project_display_name: String,
178 pub first_timestamp: Option<DateTime<Utc>>,
179 pub duration_minutes: f64,
180 pub model: String, pub turn_count: usize,
182 pub agent_turn_count: usize,
183 pub output_tokens: u64,
184 pub context_tokens: u64,
185 pub max_context: u64,
186 pub cache_hit_rate: f64, pub cache_write_5m_pct: f64, pub compaction_count: usize,
189 pub cost: f64,
190 pub tool_use_count: usize, pub top_tools: Vec<(String, usize)>, pub turn_details: Option<Vec<TurnDetail>>, }
194
195pub struct TrendResult {
198 pub entries: Vec<TrendEntry>,
199 pub group_label: String, }
201
202pub struct TrendEntry {
203 pub label: String, pub date: NaiveDate,
205 pub session_count: usize,
206 pub turn_count: usize,
207 pub tokens: AggregatedTokens,
208 pub cost: f64,
209 pub models: HashMap<String, u64>,
210 pub cost_by_category: CostByCategory,
212}
213
214pub type DailyStats = TrendEntry;