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