1use crate::core::event::{Event, SessionRecord};
5use crate::metrics::types::{FileFact, ToolSpanView};
6use serde::{Deserialize, Serialize};
7use std::collections::{HashMap, HashSet};
8
9#[derive(Debug, Clone)]
11pub struct Inputs {
12 pub window_start_ms: u64,
13 pub window_end_ms: u64,
14 pub events: Vec<(SessionRecord, Event)>,
16 pub files_touched: Vec<(String, String)>,
17 pub skills_used: Vec<(String, String)>,
18 pub tool_spans: Vec<ToolSpanView>,
19 pub skills_used_recent_slugs: HashSet<String>,
21 pub usage_lookback_ms: u64,
22 pub skill_files_on_disk: Vec<SkillFileOnDisk>,
23 pub rule_files_on_disk: Vec<SkillFileOnDisk>,
25 pub rules_used_recent_slugs: HashSet<String>,
26 pub file_facts: HashMap<String, FileFact>,
27 pub aggregates: RetroAggregates,
28}
29
30#[derive(Debug, Clone)]
31pub struct SkillFileOnDisk {
32 pub slug: String,
33 pub size_bytes: u64,
35 pub mtime_ms: u64,
36}
37
38#[derive(Debug, Clone, Default)]
39pub struct RetroAggregates {
40 pub unique_session_ids: HashSet<String>,
41 pub tool_event_counts: HashMap<String, u64>,
42 pub tool_cost_usd_e6: HashMap<String, i64>,
43 pub model_session_counts: HashMap<String, u64>,
44 pub total_cost_usd_e6: i64,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
49pub struct Bet {
50 pub id: String,
52 pub heuristic_id: String,
53 pub title: String,
54 pub hypothesis: String,
55 pub expected_tokens_saved_per_week: f64,
56 pub effort_minutes: u32,
57 pub evidence: Vec<String>,
58 pub apply_step: String,
59 #[serde(default)]
60 pub evidence_recency_ms: u64,
61}
62
63impl Bet {
64 pub fn score(&self) -> f64 {
65 self.expected_tokens_saved_per_week / (self.effort_minutes as f64 + 1.0)
66 }
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
70pub struct RetroMeta {
71 pub week_label: String,
72 pub span_start_ms: u64,
73 pub span_end_ms: u64,
74 pub session_count: u64,
75 pub total_cost_usd_e6: i64,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
79pub struct RetroStats {
80 pub sessions: u64,
81 pub total_cost_usd_e6: i64,
82 pub top_model: Option<String>,
83 pub top_model_pct: Option<u64>,
84 pub top_tool: Option<String>,
85 pub top_tool_pct: Option<u64>,
86 pub median_session_minutes: Option<u64>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
91pub struct Report {
92 pub meta: RetroMeta,
93 pub top_bets: Vec<Bet>,
94 pub skipped_deduped: Vec<String>,
95 pub stats: RetroStats,
96}