use bitrouter_ai::types::UsageOrigin;
use serde::{Deserialize, Serialize};
use super::pricing::{ChargeEvidence, ChargeStatus};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ReconciliationStatus {
#[default]
NotApplicable,
Pending,
Computed,
NotCharged,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MeteringSessionIdentity {
pub route_scope_id: String,
pub agent_harness: Option<String>,
pub controller_instance_id: Option<String>,
pub acp_session_id: Option<String>,
pub native_root_session_id: Option<String>,
pub native_agent_thread_id: Option<String>,
pub native_parent_agent_thread_id: Option<String>,
pub native_turn_id: Option<String>,
pub route_lease_id: Option<String>,
pub serialized: String,
}
impl ReconciliationStatus {
pub fn as_str(self) -> &'static str {
match self {
Self::NotApplicable => "not_applicable",
Self::Pending => "pending",
Self::Computed => "computed",
Self::NotCharged => "not_charged",
Self::Unknown => "unknown",
}
}
pub fn from_persisted(value: &str) -> Self {
match value {
"not_applicable" => Self::NotApplicable,
"pending" => Self::Pending,
"computed" => Self::Computed,
"not_charged" => Self::NotCharged,
_ => Self::Unknown,
}
}
}
#[derive(Debug, Clone)]
pub struct RequestMetric {
pub request_id: String,
pub user_id: String,
pub api_key_id: String,
pub launch_id: Option<String>,
pub session_identity: Option<MeteringSessionIdentity>,
pub router_id: Option<String>,
pub binding_digest: Option<String>,
pub original_selector: Option<String>,
pub model_id: String,
pub provider_id: String,
pub prompt_tokens: u64,
pub completion_tokens: u64,
pub reasoning_tokens: u64,
pub cache_read_tokens: u64,
pub cache_write_tokens: u64,
pub uncached_input_tokens: u64,
pub output_tokens: u64,
pub usage_origin: UsageOrigin,
pub raw_usage: Option<serde_json::Value>,
pub charge_status: ChargeStatus,
pub charge_evidence: ChargeEvidence,
pub reconciliation_status: ReconciliationStatus,
pub estimated_charge_micro_usd: i64,
pub latency_ms: u64,
pub generation_time_ms: u64,
pub streamed: bool,
pub error: Option<String>,
}