1use serde::{Deserialize, Serialize};
2
3pub const OBSERVATION_TYPES: &[&str] = &[
4 "bugfix",
5 "feature",
6 "refactor",
7 "discovery",
8 "decision",
9 "change",
10];
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Observation {
14 pub id: i64,
15 pub memory_session_id: String,
16 pub r#type: String,
17 pub title: Option<String>,
18 pub subtitle: Option<String>,
19 pub narrative: Option<String>,
20 pub facts: Option<String>,
21 pub concepts: Option<String>,
22 pub files_read: Option<String>,
23 pub files_modified: Option<String>,
24 pub discovery_tokens: Option<i64>,
25 pub created_at: String,
26 pub created_at_epoch: i64,
27 pub project: Option<String>,
28 pub status: String,
29 pub last_accessed_epoch: Option<i64>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub content_session_id: Option<String>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub branch: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub commit_sha: Option<String>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
42pub struct CompressedObservationSource {
43 pub compressed_observation_id: i64,
44 pub source_observation_id: i64,
45 pub source_hash: String,
46 #[serde(skip_serializing)]
47 pub source_snapshot_json: String,
48 pub source_created_at_epoch: i64,
49 pub compression_session_id: String,
50 pub created_at_epoch: i64,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct SessionSummary {
55 pub id: i64,
56 pub memory_session_id: String,
57 pub request: Option<String>,
58 pub completed: Option<String>,
59 pub decisions: Option<String>,
60 pub learned: Option<String>,
61 pub next_steps: Option<String>,
62 pub preferences: Option<String>,
63 pub created_at: String,
64 pub created_at_epoch: i64,
65 pub project: Option<String>,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub enum JobType {
70 Observation,
71 Summary,
72 Compress,
73 Dream,
74 CompileRules,
75 Cleanup,
76}
77
78impl JobType {
79 pub fn as_str(self) -> &'static str {
80 match self {
81 Self::Observation => "observation",
82 Self::Summary => "summary",
83 Self::Compress => "compress",
84 Self::Dream => "dream",
85 Self::CompileRules => "compile_rules",
86 Self::Cleanup => "cleanup",
87 }
88 }
89
90 pub fn from_db(raw: &str) -> anyhow::Result<Self> {
91 match raw {
92 "observation" => Ok(Self::Observation),
93 "summary" => Ok(Self::Summary),
94 "compress" => Ok(Self::Compress),
95 "dream" => Ok(Self::Dream),
96 "compile_rules" => Ok(Self::CompileRules),
97 "cleanup" => Ok(Self::Cleanup),
98 _ => anyhow::bail!("unknown job_type: {}", raw),
99 }
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct Job {
105 pub id: i64,
106 pub host: String,
107 pub job_type: JobType,
108 pub project: String,
109 pub session_id: Option<String>,
110 pub payload_json: String,
111 pub attempt_count: i64,
112 pub max_attempts: i64,
113}
114
115#[derive(Debug, Clone, PartialEq)]
116pub struct AiUsageEvent {
117 pub created_at: String,
118 pub project: Option<String>,
119 pub session_id: Option<String>,
120 pub operation: String,
121 pub executor: String,
122 pub model: Option<String>,
123 pub input_tokens: i64,
124 pub output_tokens: i64,
125 pub reasoning_tokens: i64,
126 pub cache_creation_tokens: i64,
127 pub cache_read_tokens: i64,
128 pub raw_input_tokens: i64,
129 pub raw_output_tokens: i64,
130 pub total_tokens: i64,
131 pub estimated_cost_usd: f64,
132 pub usage_source: String,
133 pub pricing_source: String,
134}
135
136#[derive(Debug, Clone, PartialEq)]
137pub struct DailyAiUsage {
138 pub day: String,
139 pub calls: i64,
140 pub input_tokens: i64,
141 pub output_tokens: i64,
142 pub reasoning_tokens: i64,
143 pub cache_creation_tokens: i64,
144 pub cache_read_tokens: i64,
145 pub total_tokens: i64,
146 pub estimated_cost_usd: f64,
147}
148
149#[derive(Debug, Clone, PartialEq)]
150pub struct WeeklyAiUsage {
151 pub week: String,
152 pub calls: i64,
153 pub input_tokens: i64,
154 pub output_tokens: i64,
155 pub reasoning_tokens: i64,
156 pub cache_creation_tokens: i64,
157 pub cache_read_tokens: i64,
158 pub total_tokens: i64,
159 pub estimated_cost_usd: f64,
160}
161
162#[derive(Debug, Clone, PartialEq)]
163pub struct AiUsageTotals {
164 pub calls: i64,
165 pub input_tokens: i64,
166 pub output_tokens: i64,
167 pub reasoning_tokens: i64,
168 pub cache_creation_tokens: i64,
169 pub cache_read_tokens: i64,
170 pub total_tokens: i64,
171 pub estimated_cost_usd: f64,
172}
173
174#[derive(Debug, Clone, PartialEq)]
175pub struct AiUsageSourceTotals {
176 pub usage_source: String,
177 pub pricing_source: String,
178 pub calls: i64,
179 pub total_tokens: i64,
180 pub estimated_cost_usd: f64,
181}
182
183#[derive(Debug, Clone, PartialEq)]
184pub struct AiUsageBreakdown {
185 pub project: Option<String>,
186 pub executor: String,
187 pub usage_source: String,
188 pub pricing_source: String,
189 pub calls: i64,
190 pub total_tokens: i64,
191 pub estimated_cost_usd: f64,
192}