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