kaizen/store/sqlite/
visualization.rs1use super::*;
4
5mod activity;
6mod aggregates;
7mod sessions;
8
9#[derive(Clone, Copy, Debug, Default)]
10pub(crate) struct TokenRead {
11 pub(crate) input: u64,
12 pub(crate) output: u64,
13 pub(crate) reasoning: u64,
14 pub(crate) cache_read: u64,
15 pub(crate) cache_create: u64,
16}
17
18#[derive(Clone, Debug, Default)]
19pub(crate) struct ReportTotalsRead {
20 pub(crate) session_count: u64,
21 pub(crate) running_count: u64,
22 pub(crate) event_count: u64,
23 pub(crate) error_count: u64,
24 pub(crate) tool_call_count: u64,
25 pub(crate) cost_usd_e6: i64,
26 pub(crate) tokens: TokenRead,
27 pub(crate) token_event_count: u64,
28 pub(crate) cost_event_count: u64,
29 pub(crate) cost_session_count: u64,
30}
31
32#[derive(Clone, Debug)]
33pub(crate) struct SessionSummaryRead {
34 pub(crate) session: SessionRecord,
35 pub(crate) last_event_ms: Option<u64>,
36 pub(crate) event_count: u64,
37 pub(crate) error_count: u64,
38 pub(crate) tool_call_count: u64,
39 pub(crate) cost_usd_e6: i64,
40 pub(crate) tokens: TokenRead,
41 pub(crate) top_tools: Vec<(String, u64)>,
42}
43
44#[derive(Clone, Copy, Debug)]
45pub(crate) struct ActivityWindow {
46 pub(crate) start_ms: u64,
47 pub(crate) end_ms: u64,
48 pub(crate) width_ms: u64,
49}
50
51#[derive(Clone, Debug, Default)]
52pub(crate) struct ActivityTotalRead {
53 pub(crate) bin: usize,
54 pub(crate) event_count: u64,
55 pub(crate) session_count: u64,
56 pub(crate) token_total: u64,
57 pub(crate) cost_usd_e6: i64,
58}
59
60#[derive(Clone, Debug)]
61pub(crate) struct ActivityCountRead {
62 pub(crate) bin: usize,
63 pub(crate) name: String,
64 pub(crate) count: u64,
65}
66
67#[derive(Clone, Debug, Default)]
68pub(crate) struct ActivityRead {
69 pub(crate) totals: Vec<ActivityTotalRead>,
70 pub(crate) agents: Vec<ActivityCountRead>,
71 pub(crate) kinds: Vec<ActivityCountRead>,
72}
73
74impl Store {
75 pub fn files_for_session(&self, session_id: &str) -> Result<Vec<String>> {
76 self.limited_files_for_session(session_id, usize::MAX)
77 }
78
79 pub(crate) fn limited_files_for_session(
80 &self,
81 session_id: &str,
82 limit: usize,
83 ) -> Result<Vec<String>> {
84 let mut stmt = self.conn.prepare(
85 "SELECT path FROM files_touched
86 WHERE session_id = ?1 ORDER BY path ASC LIMIT ?2",
87 )?;
88 let rows = stmt.query_map(params![session_id, sql_limit(limit)], |row| row.get(0))?;
89 rows.map(|row| row.map_err(Into::into)).collect()
90 }
91}
92
93fn sql_limit(limit: usize) -> i64 {
94 limit.min(i64::MAX as usize) as i64
95}