use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct RunOutcome {
pub response: Option<String>,
pub model: String,
pub provider: String,
pub usage: Usage,
pub timings: Timings,
pub stop_reason: StopReason,
pub tool_calls: Vec<ToolCallRecord>,
pub transcript: Vec<TranscriptEntry>,
pub consult: Option<serde_json::Value>,
pub applied_caps: AppliedCaps,
pub error: Option<ErrorPayload>,
}
#[derive(Debug, Clone, Serialize)]
pub struct Usage {
pub input_tokens: u64,
pub output_tokens: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct Timings {
pub total_ms: u64,
pub ttfb_ms: Option<u64>,
pub per_turn_ms: Vec<u64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum StopReason {
Done,
MaxToolCalls,
Denied,
Error,
}
#[derive(Debug, Clone, Serialize)]
pub struct ToolCallRecord {
pub name: String,
pub input: serde_json::Value,
pub result: String,
pub ms: u64,
pub ok: bool,
}
#[derive(Debug, Clone, Serialize)]
pub struct TranscriptEntry {
pub role: String,
pub content: String,
pub tool_calls: Option<Vec<ToolCallRecord>>,
}
#[derive(Debug, Clone, Serialize)]
pub struct AppliedCaps {
pub max_tool_calls: u32,
pub max_tool_calls_clamped: bool,
pub timeout_secs: Option<u64>,
pub system_override_applied: bool,
}
#[derive(Debug, Clone, Serialize)]
pub struct ErrorPayload {
pub message: String,
pub kind: ErrorKind,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ErrorKind {
InputInvalid,
DbCorrupt,
WrongPassphrase,
PassphraseUnavailable,
TierDenied,
Provider,
Timeout,
Runtime,
}
#[derive(Debug, Clone)]
pub enum SystemPolicy {
Operator(String),
CallerOverride(String),
}
impl SystemPolicy {
#[must_use]
pub fn text(&self) -> &str {
match self {
Self::Operator(s) | Self::CallerOverride(s) => s,
}
}
}