1use serde::{Deserialize, Serialize};
4
5use crate::message::AgentMessage;
6use crate::session_event::{CompactionReason, CompactionResult};
7
8pub type AgentEventSink = Box<dyn Fn(AgentEvent) + Send + Sync>;
10
11#[non_exhaustive]
13#[derive(Debug, Clone, Serialize, Deserialize)]
14#[serde(tag = "type")]
15pub enum AgentEvent {
16 AgentStart,
18 AgentEnd { messages: Vec<AgentMessage> },
20 TurnStart,
22 TurnEnd {
24 message: AgentMessage,
25 tool_results: Vec<opi_ai::message::ToolResultMessage>,
26 },
27 MessageStart { message: AgentMessage },
29 MessageUpdate {
31 message: AgentMessage,
32 #[serde(
33 serialize_with = "serde_json_bridge::serialize",
34 deserialize_with = "deserialize_boxed_stream_event"
35 )]
36 assistant_event: Box<opi_ai::stream::AssistantStreamEvent>,
37 },
38 MessageEnd { message: AgentMessage },
40 ToolExecutionStart {
42 tool_call_id: String,
43 tool_name: String,
44 args: serde_json::Value,
45 },
46 ToolExecutionUpdate {
48 tool_call_id: String,
49 tool_name: String,
50 args: serde_json::Value,
51 partial_result: serde_json::Value,
52 },
53 ToolExecutionEnd {
55 tool_call_id: String,
56 tool_name: String,
57 result: serde_json::Value,
58 details: Option<serde_json::Value>,
59 is_error: bool,
60 },
61 QueueUpdate {
63 steering: Vec<String>,
64 follow_up: Vec<String>,
65 },
66 AutoRetryStart {
68 attempt: u32,
69 max_attempts: u32,
70 delay_ms: u64,
71 error_message: String,
72 },
73 AutoRetryEnd {
75 success: bool,
76 attempt: u32,
77 final_error: Option<String>,
78 },
79 CompactionStart { reason: CompactionReason },
81 CompactionEnd {
83 reason: CompactionReason,
84 result: Option<CompactionResult>,
85 aborted: bool,
86 error_message: Option<String>,
87 },
88 SessionPersistError { message: String },
90}
91
92fn deserialize_boxed_stream_event<'de, D>(
93 deserializer: D,
94) -> Result<Box<opi_ai::stream::AssistantStreamEvent>, D::Error>
95where
96 D: serde::Deserializer<'de>,
97{
98 let v = serde_json::Value::deserialize(deserializer)?;
99 let event: opi_ai::stream::AssistantStreamEvent =
100 serde_json::from_value(v).map_err(serde::de::Error::custom)?;
101 Ok(Box::new(event))
102}
103
104mod serde_json_bridge {
105 use serde::{Serialize as _, Serializer};
106
107 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 T: serde::Serialize,
110 S: Serializer,
111 {
112 serde_json::to_value(value)
113 .map_err(serde::ser::Error::custom)
114 .and_then(|v| v.serialize(serializer))
115 }
116}