mojentic/llm/tools/
tell_user_tool.rs1use crate::error::Result;
2use crate::llm::tools::{FunctionDescriptor, LlmTool, ToolDescriptor};
3use serde_json::{json, Value};
4use std::collections::HashMap;
5
6#[derive(Clone)]
35pub struct TellUserTool;
36
37impl TellUserTool {
38 pub fn new() -> Self {
40 Self
41 }
42}
43
44impl Default for TellUserTool {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl LlmTool for TellUserTool {
51 fn run(&self, args: &HashMap<String, Value>) -> Result<Value> {
52 let message = args.get("message").and_then(|v| v.as_str()).unwrap_or("");
53
54 println!("\n\n\nMESSAGE FROM ASSISTANT:\n{}", message);
55
56 Ok(json!("Message delivered to user."))
57 }
58
59 fn descriptor(&self) -> ToolDescriptor {
60 ToolDescriptor {
61 r#type: "function".to_string(),
62 function: FunctionDescriptor {
63 name: "tell_user".to_string(),
64 description: "Display a message to the user without expecting a response. Use this to send important intermediate information to the user as you work on completing their request.".to_string(),
65 parameters: json!({
66 "type": "object",
67 "properties": {
68 "message": {
69 "type": "string",
70 "description": "The important message you want to display to the user."
71 }
72 },
73 "required": ["message"]
74 }),
75 },
76 }
77 }
78 fn clone_box(&self) -> Box<dyn LlmTool> {
79 Box::new(self.clone())
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn test_descriptor() {
89 let tool = TellUserTool::new();
90 let descriptor = tool.descriptor();
91
92 assert_eq!(descriptor.r#type, "function");
93 assert_eq!(descriptor.function.name, "tell_user");
94 assert!(descriptor.function.description.contains("Display a message to the user"));
95
96 let params = &descriptor.function.parameters;
98 assert_eq!(params["type"], "object");
99 assert!(params["properties"]["message"].is_object());
100 assert_eq!(params["properties"]["message"]["type"], "string");
101 assert!(params["required"].as_array().unwrap().contains(&json!("message")));
102 }
103
104 #[test]
105 fn test_run_with_message() {
106 let tool = TellUserTool::new();
107 let mut args = HashMap::new();
108 args.insert("message".to_string(), json!("This is an important update"));
109
110 let result = tool.run(&args).unwrap();
111
112 assert_eq!(result, json!("Message delivered to user."));
113 }
114
115 #[test]
116 fn test_run_without_message() {
117 let tool = TellUserTool::new();
118 let args = HashMap::new();
119
120 let result = tool.run(&args).unwrap();
121
122 assert_eq!(result, json!("Message delivered to user."));
123 }
124
125 #[test]
126 fn test_tool_matches() {
127 let tool = TellUserTool::new();
128 assert!(tool.matches("tell_user"));
129 assert!(!tool.matches("other_tool"));
130 }
131
132 #[test]
133 fn test_multiline_message() {
134 let tool = TellUserTool::new();
135 let mut args = HashMap::new();
136 args.insert("message".to_string(), json!("Line 1\nLine 2\nLine 3"));
137
138 let result = tool.run(&args).unwrap();
139
140 assert_eq!(result, json!("Message delivered to user."));
141 }
142
143 #[test]
144 fn test_default_implementation() {
145 let tool = TellUserTool;
146 let descriptor = tool.descriptor();
147
148 assert_eq!(descriptor.function.name, "tell_user");
149 }
150}