floopy/types/export.rs
1use serde::Deserialize;
2
3/// One row of the decision export.
4#[derive(Debug, Clone, Deserialize)]
5pub struct ExportedDecisionRow {
6 /// The originating request id.
7 pub request_id: String,
8 /// Session the request belonged to, if any.
9 pub session_id: Option<String>,
10 /// Owning organization id.
11 pub organization_id: String,
12 /// Resolved upstream provider.
13 pub provider: Option<String>,
14 /// Resolved upstream model.
15 pub model: Option<String>,
16 /// Terminal status of the request.
17 pub status: String,
18 /// End-to-end latency in milliseconds.
19 pub latency_ms: Option<i64>,
20 /// Cost in micro-USD.
21 pub cost_micro_usd: Option<i64>,
22 /// Whether caching was enabled.
23 pub cache_enabled: Option<bool>,
24 /// Detected threat label, if any.
25 pub threat: Option<String>,
26 /// RFC3339 creation timestamp.
27 pub created_at: String,
28}
29
30/// The terminal record of the JSONL export: how many rows were emitted and
31/// whether the result was truncated.
32#[derive(Debug, Clone, Deserialize)]
33pub struct ExportTrailer {
34 /// Number of rows emitted before the trailer.
35 pub rows_emitted: i64,
36 /// Whether the export was truncated server-side.
37 pub truncated: bool,
38 /// Reason for truncation, if any.
39 pub reason: Option<String>,
40}
41
42/// Selects the export window and (server-side) format. The SDK always parses
43/// the JSONL stream; `format` is accepted for parity with the gateway.
44#[derive(Debug, Clone)]
45pub struct ExportDecisionsParams {
46 /// Inclusive lower bound (RFC3339). Required.
47 pub from: String,
48 /// Inclusive upper bound (RFC3339). Required.
49 pub to: String,
50 /// Optional server-side format hint (`"jsonl"` / `"csv"`).
51 pub format: Option<String>,
52}
53
54impl ExportDecisionsParams {
55 /// A window with the default (JSONL) format.
56 #[must_use]
57 pub fn new(from: impl Into<String>, to: impl Into<String>) -> Self {
58 Self {
59 from: from.into(),
60 to: to.into(),
61 format: None,
62 }
63 }
64
65 pub(crate) fn query(&self) -> Vec<(String, String)> {
66 let mut q = vec![
67 ("from".to_owned(), self.from.clone()),
68 ("to".to_owned(), self.to.clone()),
69 ];
70 if let Some(f) = &self.format {
71 q.push(("format".to_owned(), f.clone()));
72 }
73 q
74 }
75}