1use crate::types::{ThreadId, TokenUsage, ToolResult, ToolTier};
16use serde::{Deserialize, Serialize};
17use std::time::Duration;
18
19#[derive(Clone, Debug, Serialize, Deserialize)]
22#[serde(tag = "type", rename_all = "snake_case")]
23pub enum AgentEvent {
24 Start { thread_id: ThreadId, turn: usize },
26
27 Thinking { text: String },
29
30 TextDelta { delta: String },
32
33 Text { text: String },
35
36 ToolCallStart {
38 id: String,
39 name: String,
40 display_name: String,
41 input: serde_json::Value,
42 tier: ToolTier,
43 },
44
45 ToolCallEnd {
47 id: String,
48 name: String,
49 display_name: String,
50 result: ToolResult,
51 },
52
53 ToolProgress {
55 id: String,
57 name: String,
59 display_name: String,
61 stage: String,
63 message: String,
65 data: Option<serde_json::Value>,
67 },
68
69 ToolRequiresConfirmation {
72 id: String,
73 name: String,
74 input: serde_json::Value,
75 description: String,
76 },
77
78 TurnComplete { turn: usize, usage: TokenUsage },
80
81 Done {
83 thread_id: ThreadId,
84 total_turns: usize,
85 total_usage: TokenUsage,
86 duration: Duration,
87 },
88
89 Error { message: String, recoverable: bool },
91
92 ContextCompacted {
94 original_count: usize,
96 new_count: usize,
98 original_tokens: usize,
100 new_tokens: usize,
102 },
103
104 SubagentProgress {
106 subagent_id: String,
108 subagent_name: String,
110 tool_name: String,
112 tool_context: String,
114 completed: bool,
116 success: bool,
118 tool_count: u32,
120 total_tokens: u64,
122 },
123}
124
125impl AgentEvent {
126 #[must_use]
127 pub const fn start(thread_id: ThreadId, turn: usize) -> Self {
128 Self::Start { thread_id, turn }
129 }
130
131 #[must_use]
132 pub fn thinking(text: impl Into<String>) -> Self {
133 Self::Thinking { text: text.into() }
134 }
135
136 #[must_use]
137 pub fn text_delta(delta: impl Into<String>) -> Self {
138 Self::TextDelta {
139 delta: delta.into(),
140 }
141 }
142
143 #[must_use]
144 pub fn text(text: impl Into<String>) -> Self {
145 Self::Text { text: text.into() }
146 }
147
148 #[must_use]
149 pub fn tool_call_start(
150 id: impl Into<String>,
151 name: impl Into<String>,
152 display_name: impl Into<String>,
153 input: serde_json::Value,
154 tier: ToolTier,
155 ) -> Self {
156 Self::ToolCallStart {
157 id: id.into(),
158 name: name.into(),
159 display_name: display_name.into(),
160 input,
161 tier,
162 }
163 }
164
165 #[must_use]
166 pub fn tool_call_end(
167 id: impl Into<String>,
168 name: impl Into<String>,
169 display_name: impl Into<String>,
170 result: ToolResult,
171 ) -> Self {
172 Self::ToolCallEnd {
173 id: id.into(),
174 name: name.into(),
175 display_name: display_name.into(),
176 result,
177 }
178 }
179
180 #[must_use]
181 pub fn tool_progress(
182 id: impl Into<String>,
183 name: impl Into<String>,
184 display_name: impl Into<String>,
185 stage: impl Into<String>,
186 message: impl Into<String>,
187 data: Option<serde_json::Value>,
188 ) -> Self {
189 Self::ToolProgress {
190 id: id.into(),
191 name: name.into(),
192 display_name: display_name.into(),
193 stage: stage.into(),
194 message: message.into(),
195 data,
196 }
197 }
198
199 #[must_use]
200 pub const fn done(
201 thread_id: ThreadId,
202 total_turns: usize,
203 total_usage: TokenUsage,
204 duration: Duration,
205 ) -> Self {
206 Self::Done {
207 thread_id,
208 total_turns,
209 total_usage,
210 duration,
211 }
212 }
213
214 #[must_use]
215 pub fn error(message: impl Into<String>, recoverable: bool) -> Self {
216 Self::Error {
217 message: message.into(),
218 recoverable,
219 }
220 }
221
222 #[must_use]
223 pub const fn context_compacted(
224 original_count: usize,
225 new_count: usize,
226 original_tokens: usize,
227 new_tokens: usize,
228 ) -> Self {
229 Self::ContextCompacted {
230 original_count,
231 new_count,
232 original_tokens,
233 new_tokens,
234 }
235 }
236}