use serde::{Deserialize, Serialize};
use crate::event::AgentEvent;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CompactionReason {
Manual,
Threshold,
Overflow,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompactionResult {
pub summary: String,
pub first_kept_entry_id: String,
pub tokens_before: u64,
pub tokens_after: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ThinkingLevel {
None,
Low,
Medium,
High,
}
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AgentSessionEvent {
Agent {
#[serde(with = "agent_event_serde")]
event: AgentEvent,
},
QueueUpdate {
steering: Vec<String>,
follow_up: Vec<String>,
},
CompactionStart {
reason: CompactionReason,
},
CompactionEnd {
reason: CompactionReason,
result: Option<CompactionResult>,
aborted: bool,
will_retry: bool,
error_message: Option<String>,
},
AutoRetryStart {
attempt: u32,
max_attempts: u32,
delay_ms: u64,
error_message: String,
},
AutoRetryEnd {
success: bool,
attempt: u32,
final_error: Option<String>,
},
SessionInfoChanged {
session_id: String,
name: Option<String>,
},
ThinkingLevelChanged {
level: ThinkingLevel,
},
#[serde(rename = "session_summary")]
SessionSummary {
session_id: String,
model: String,
turns: u32,
tokens: SessionTokenTotals,
#[serde(skip_serializing_if = "Option::is_none")]
cost_usd: Option<SessionCostTotals>,
},
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct SessionTokenTotals {
pub input: u64,
pub output: u64,
pub cache_read: u64,
pub cache_write: u64,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct SessionCostTotals {
pub input: f64,
pub output: f64,
pub cache_read: f64,
pub cache_write: f64,
pub total: f64,
}
mod agent_event_serde {
use crate::event::AgentEvent;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<S>(event: &AgentEvent, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serde_json::to_value(event)
.map_err(serde::ser::Error::custom)
.and_then(|v| v.serialize(serializer))
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<AgentEvent, D::Error>
where
D: Deserializer<'de>,
{
let v = serde_json::Value::deserialize(deserializer)?;
serde_json::from_value(v).map_err(serde::de::Error::custom)
}
}