Skip to main content

ai_agents_tools/builtin/
echo.rs

1use 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    /// The message to echo back
26    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}