use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Origin {
Direct,
Agent,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChurnKind {
Add,
Remove,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SearchHitTrace {
pub tool_id: String,
pub score: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SearchStage {
pub name: String,
pub took_ms: u64,
pub top_score: Option<f64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TraceEvent {
Search {
query: String,
origin: Origin,
top_k: u32,
hits: Vec<SearchHitTrace>,
stages: Vec<SearchStage>,
took_ms: u64,
},
IndexChurn {
kind: ChurnKind,
tool_id: String,
},
InvokeStart {
tool_id: String,
args_size_bytes: u64,
},
InvokeEnd {
tool_id: String,
took_ms: u64,
},
InvokeError {
tool_id: String,
took_ms: u64,
error: String,
},
GatewaySearch {
query: String,
origin: Origin,
top_k: u32,
hits: u32,
took_ms: u64,
},
GatewayInvoke {
tool_id: String,
took_ms: u64,
},
GatewayError {
tool_id: String,
error: String,
},
UpstreamRegister {
server: String,
transport: String,
tool_count: u32,
},
UpstreamInvoke {
server: String,
tool_id: String,
took_ms: u64,
},
UpstreamError {
server: String,
tool_id: String,
error: String,
},
AuthRefresh {
upstream: String,
ok: bool,
},
AuthNeeds {
upstream: String,
},
AuthFlowStart {
upstream: String,
},
AuthFlowEnd {
upstream: String,
ok: bool,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TraceEnvelope {
pub v: u32,
pub ts: u64,
pub session_id: String,
#[serde(flatten)]
pub event: TraceEvent,
}