ai_agents_tools/builtin/
echo.rs1use async_trait::async_trait;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use crate::generate_schema;
7use ai_agents_core::{Tool, ToolResult};
8
9pub struct EchoTool;
10
11impl EchoTool {
12 pub fn new() -> Self {
13 Self
14 }
15}
16
17impl Default for EchoTool {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23#[derive(Debug, Deserialize, JsonSchema)]
24struct EchoInput {
25 message: String,
27}
28
29#[derive(Debug, Serialize, Deserialize)]
30struct EchoOutput {
31 message: String,
32 length: usize,
33}
34
35#[async_trait]
36impl Tool for EchoTool {
37 fn id(&self) -> &str {
38 "echo"
39 }
40
41 fn name(&self) -> &str {
42 "Echo"
43 }
44
45 fn description(&self) -> &str {
46 "Echoes back the input message. Useful for testing."
47 }
48
49 fn input_schema(&self) -> Value {
50 generate_schema::<EchoInput>()
51 }
52
53 async fn execute(&self, args: Value) -> ToolResult {
54 let input: EchoInput = match serde_json::from_value(args) {
55 Ok(input) => input,
56 Err(e) => return ToolResult::error(format!("Invalid input: {}", e)),
57 };
58
59 let output = EchoOutput {
60 length: input.message.len(),
61 message: input.message,
62 };
63
64 match serde_json::to_string(&output) {
65 Ok(json) => ToolResult::ok(json),
66 Err(e) => ToolResult::error(format!("Serialization error: {}", e)),
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[tokio::test]
76 async fn test_echo() {
77 let echo = EchoTool::new();
78 let result = echo
79 .execute(serde_json::json!({"message": "Hello, world!"}))
80 .await;
81
82 assert!(result.success);
83 let output: EchoOutput = serde_json::from_str(&result.output).unwrap();
84 assert_eq!(output.message, "Hello, world!");
85 assert_eq!(output.length, 13);
86 }
87
88 #[tokio::test]
89 async fn test_invalid_input() {
90 let echo = EchoTool::new();
91 let result = echo
92 .execute(serde_json::json!({"wrong_field": "test"}))
93 .await;
94 assert!(!result.success);
95 }
96}