aether_core/testing/
agent_event_builder.rs1use crate::events::AgentEvent;
2use crate::events::ToolEvent;
3use llm::{ToolCallError, ToolCallRequest, ToolCallResult};
4use serde::Serialize;
5
6pub fn agent_event(message_id: &str) -> AgentEventBuilder {
7 AgentEventBuilder::new(message_id)
8}
9
10pub struct AgentEventBuilder {
11 message_id: String,
12 chunks: Vec<AgentEvent>,
13 full_text: String,
14}
15
16impl AgentEventBuilder {
17 pub fn new(message_id: &str) -> Self {
18 Self { message_id: message_id.to_string(), chunks: Vec::new(), full_text: String::new() }
19 }
20
21 pub fn text(mut self, chunks: &[&str]) -> Self {
22 for chunk in chunks {
23 self.chunks.push(AgentEvent::text(&self.message_id, chunk, false));
24 self.full_text.push_str(chunk);
25 }
26 self
27 }
28
29 pub fn tool_call<T: Serialize, U: Serialize>(
30 mut self,
31 tool_call_id: &str,
32 name: &str,
33 request: &T,
34 result: &U,
35 ) -> Self {
36 let request_json = serde_json::to_string(request).expect("Failed to serialize request");
37 let result_value = serde_json::to_value(result).expect("Failed to serialize result");
38 let result_yaml = serde_yml::to_string(&result_value).unwrap_or_else(|_| result_value.to_string());
39
40 self.push_tool_call_start(tool_call_id, name);
41 self.push_tool_call_chunk(tool_call_id, &request_json);
42
43 self.chunks.push(AgentEvent::Tool(ToolEvent::Result {
44 result: ToolCallResult {
45 id: tool_call_id.to_string(),
46 name: name.to_string(),
47 arguments: request_json,
48 result: result_yaml,
49 },
50 result_meta: None,
51 }));
52
53 self
54 }
55
56 pub fn tool_call_with_error<T: Serialize>(
57 mut self,
58 tool_call_id: &str,
59 name: &str,
60 request: &T,
61 error_message: &str,
62 ) -> Self {
63 let request_json = serde_json::to_string(request).expect("Failed to serialize request");
64
65 let error_result = format!("Tool execution error: {error_message}");
66
67 self.push_tool_call_start(tool_call_id, name);
68 self.push_tool_call_chunk(tool_call_id, &request_json);
69
70 self.chunks.push(AgentEvent::Tool(ToolEvent::Error {
71 error: ToolCallError {
72 id: tool_call_id.to_string(),
73 name: name.to_string(),
74 arguments: Some(request_json),
75 error: error_result,
76 },
77 }));
78
79 self
80 }
81
82 pub fn build(mut self) -> Vec<AgentEvent> {
83 self.chunks.push(AgentEvent::text(&self.message_id, &self.full_text, true));
84
85 self.chunks
86 }
87
88 fn push_tool_call_start(&mut self, tool_call_id: &str, name: &str) {
89 self.chunks.push(AgentEvent::Tool(ToolEvent::Call {
90 request: ToolCallRequest { id: tool_call_id.to_string(), name: name.to_string(), arguments: String::new() },
91 }));
92 }
93
94 fn push_tool_call_chunk(&mut self, tool_call_id: &str, chunk: &str) {
95 self.chunks.push(AgentEvent::Tool(ToolEvent::CallUpdate {
96 tool_call_id: tool_call_id.to_string(),
97 chunk: chunk.to_string(),
98 }));
99 }
100}