1pub mod extract;
2pub mod redact;
3
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct CaptureRecord {
11 pub seq: u64,
12 pub session_id: String,
13 pub request_id: Option<String>,
14 pub started_at: DateTime<Utc>,
15 pub ended_at: Option<DateTime<Utc>>,
16 pub duration_ms: Option<u64>,
17 pub ttft_ms: Option<u64>,
18 pub request: RequestPart,
19 pub response: Option<ResponsePart>,
20 pub usage: Option<Usage>,
21 pub model: Option<String>,
22 pub error: Option<CaptureError>,
23 #[serde(default)]
24 pub partial: bool,
25 pub schema_version: u32,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct RequestPart {
30 pub method: String,
31 pub path: String,
32 pub headers: BTreeMap<String, String>,
33 pub body: Value,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ResponsePart {
38 pub status: u16,
39 pub headers: BTreeMap<String, String>,
40 pub body_reassembled: Option<Value>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub raw_sse_text: Option<String>,
43 pub raw_sse_frames_count: u64,
44}
45
46#[derive(Debug, Clone, Default, Serialize, Deserialize)]
47pub struct Usage {
48 pub input_tokens: u64,
49 pub output_tokens: u64,
50 #[serde(default)]
51 pub cache_creation_input_tokens: u64,
52 #[serde(default)]
53 pub cache_read_input_tokens: u64,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct CaptureError {
58 pub kind: ErrorKind,
59 pub message: String,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63#[serde(rename_all = "snake_case")]
64pub enum ErrorKind {
65 UpstreamUnreachable,
66 TlsHandshakeFailed,
67 SseTruncated,
68 ReassembleFailed,
69 UpstreamHttpError,
70}
71
72#[derive(Debug, Clone, Serialize)]
73#[serde(tag = "type", rename_all = "snake_case")]
74pub enum CaptureEvent {
75 RequestStarted {
76 session_id: String,
77 seq: u64,
78 started_at: DateTime<Utc>,
79 model: Option<String>,
80 },
81 RequestCompleted {
82 session_id: String,
83 seq: u64,
84 duration_ms: u64,
85 status: u16,
86 request_id: Option<String>,
87 usage: Option<Usage>,
88 has_error: bool,
89 },
90}