1#[derive(Clone, Debug)]
8pub enum AgentEvent {
9 TurnStart {
11 turn: u32,
13 },
14
15 TextDelta {
17 text: String,
19 },
20
21 ToolCall {
23 id: String,
25 name: String,
27 input: serde_json::Value,
29 },
30
31 ToolResult {
33 id: String,
35 name: String,
37 output: String,
39 success: bool,
41 },
42
43 TextComplete {
45 text: String,
47 },
48
49 TurnEnd {
51 turn: u32,
53 reason: TurnEndReason,
55 },
56
57 Error {
59 message: String,
61 },
62}
63
64#[derive(Clone, Debug, PartialEq, Eq)]
66pub enum TurnEndReason {
67 EndTurn,
69 ToolUse,
71 MaxTurns,
73 MaxTokens,
75 Error,
77}
78
79pub type EventSender = tokio::sync::mpsc::Sender<AgentEvent>;
81
82pub type EventReceiver = tokio::sync::mpsc::Receiver<AgentEvent>;
84
85pub fn event_channel(buffer: usize) -> (EventSender, EventReceiver) {
87 tokio::sync::mpsc::channel(buffer)
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn turn_end_reason_equality() {
96 assert_eq!(TurnEndReason::EndTurn, TurnEndReason::EndTurn);
97 assert_ne!(TurnEndReason::EndTurn, TurnEndReason::ToolUse);
98 }
99
100 #[tokio::test]
101 async fn event_channel_send_receive() {
102 let (tx, mut rx) = event_channel(8);
103 let send_result = tx.send(AgentEvent::TurnStart { turn: 1 }).await;
104 assert!(send_result.is_ok());
105
106 let event = rx.recv().await;
107 match event {
108 Some(AgentEvent::TurnStart { turn }) => {
109 assert_eq!(turn, 1);
110 }
111 _ => panic!("Expected TurnStart event"),
112 }
113 }
114
115 #[tokio::test]
116 async fn event_channel_text_delta() {
117 let (tx, mut rx) = event_channel(8);
118 let _ = tx
119 .send(AgentEvent::TextDelta {
120 text: "Hello".into(),
121 })
122 .await;
123
124 match rx.recv().await {
125 Some(AgentEvent::TextDelta { text }) => {
126 assert_eq!(text, "Hello");
127 }
128 _ => panic!("Expected TextDelta event"),
129 }
130 }
131
132 #[tokio::test]
133 async fn event_channel_tool_result() {
134 let (tx, mut rx) = event_channel(8);
135 let _ = tx
136 .send(AgentEvent::ToolResult {
137 id: "tool_1".into(),
138 name: "bash".into(),
139 output: "done".into(),
140 success: true,
141 })
142 .await;
143
144 match rx.recv().await {
145 Some(AgentEvent::ToolResult {
146 id,
147 name,
148 output,
149 success,
150 }) => {
151 assert_eq!(id, "tool_1");
152 assert_eq!(name, "bash");
153 assert_eq!(output, "done");
154 assert!(success);
155 }
156 _ => panic!("Expected ToolResult event"),
157 }
158 }
159
160 #[test]
161 fn agent_event_debug() {
162 let event = AgentEvent::Error {
163 message: "test error".into(),
164 };
165 let debug_str = format!("{event:?}");
166 assert!(debug_str.contains("test error"));
167 }
168}