| 154 | } |
| 155 | |
| 156 | pub async fn record_event(&self, run_id: &str, event: AgentEvent) -> Option<RunSnapshot> { |
| 157 | let mut events = self.events.write().await; |
| 158 | let run_events = events.get_mut(run_id)?; |
| 159 | let sequence = run_events.len(); |
| 160 | run_events.push(RunEventRecord { |
| 161 | sequence, |
| 162 | timestamp_ms: now_ms(), |
| 163 | event: event.clone(), |
| 164 | }); |
| 165 | // FIFO-trim event buffer past per-run cap. |
| 166 | if let Some(cap) = self.max_events_per_run { |
| 167 | if run_events.len() > cap { |
| 168 | let excess = run_events.len() - cap; |
| 169 | run_events.drain(..excess); |
| 170 | } |
| 171 | } |
| 172 | drop(events); |
| 173 | |
| 174 | let mut runs = self.runs.write().await; |
| 175 | let run = runs.get_mut(run_id)?; |
| 176 | apply_event_to_snapshot(run, &event); |
| 177 | run.event_count += 1; |
| 178 | run.updated_at_ms = now_ms(); |
| 179 | Some(run.clone()) |
| 180 | } |
| 181 | |
| 182 | pub async fn mark_failed(&self, run_id: &str, error: impl Into<String>) -> Option<RunSnapshot> { |
| 183 | let mut runs = self.runs.write().await; |