//! Session log record types. One JSON object per line; assistant messages are stored verbatim. use serde::{Deserialize, Serialize}; use crate::{CallId, DataClass, Epoch, Hash32, SessionId, Timestamp}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct ToolCall { pub id: String, pub name: String, pub arguments: String, } /// What one completion cost. The same five numbers as `LogRecord::Usage`, without the time. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct Usage { pub cache_n: u64, pub prompt_n: u64, pub predicted_n: u64, pub reasoning_tokens: u64, pub thinking_capped: bool, } // JSON: {"type":"user","time":"…","content":"…"} ; the tag sits beside the fields; types are snake_case #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "type", rename_all = "snake_case", deny_unknown_fields)] pub enum LogRecord { SessionStart { time: Timestamp, session: SessionId, epoch: Epoch, slot: u32, baseline: Hash32, }, User { time: Timestamp, content: String, }, Assistant { time: Timestamp, content: Option, reasoning_content: Option, tool_calls: Vec, }, ToolResult { time: Timestamp, call: CallId, tool_call_id: String, content: String, class: DataClass, untrusted: bool, truncated: bool, }, Usage { time: Timestamp, cache_n: u64, prompt_n: u64, predicted_n: u64, reasoning_tokens: u64, thinking_capped: bool, }, CacheLoss { time: Timestamp, expected: u64, got: u64, }, EpochEnd { time: Timestamp, next: Epoch, summary: String, }, }