Skip to main content

ai_agent/tools/
ask.rs

1//! Ask user question tool.
2//!
3//! Provides tool for asking the user for input.
4
5use crate::types::*;
6
7/// AskUserQuestion tool - ask the user for input
8pub struct AskUserQuestionTool;
9
10impl AskUserQuestionTool {
11    pub fn new() -> Self {
12        Self
13    }
14
15    pub fn input_schema(&self) -> ToolInputSchema {
16        ToolInputSchema {
17            schema_type: "object".to_string(),
18            properties: serde_json::json!({
19                "question": {
20                    "type": "string",
21                    "description": "The question to ask the user"
22                },
23                "header": {
24                    "type": "string",
25                    "description": "Very short label displayed as a chip/tag"
26                },
27                "options": {
28                    "type": "array",
29                    "items": {
30                        "type": "object",
31                        "properties": {
32                            "label": { "type": "string" },
33                            "description": { "type": "string" }
34                        }
35                    },
36                    "description": "Available choices for this question"
37                },
38                "multiSelect": {
39                    "type": "boolean",
40                    "description": "Set to true to allow multiple answers"
41                }
42            }),
43            required: Some(vec![
44                "question".to_string(),
45                "header".to_string(),
46                "options".to_string(),
47            ]),
48        }
49    }
50
51    pub async fn execute(
52        &self,
53        input: serde_json::Value,
54        _context: &ToolContext,
55    ) -> Result<ToolResult, crate::error::AgentError> {
56        let question = input["question"].as_str().unwrap_or("");
57        let header = input["header"].as_str().unwrap_or("");
58
59        let options = input["options"]
60            .as_array()
61            .map(|arr| {
62                arr.iter()
63                    .filter_map(|v| v.get("label").and_then(|l| l.as_str()))
64                    .collect::<Vec<_>>()
65            })
66            .unwrap_or_default();
67
68        let response = format!(
69            "Asking user: {}\nHeader: {}\nOptions: {:?}\nNote: Full implementation would present these options to the user and wait for their response.",
70            question, header, options
71        );
72
73        Ok(ToolResult {
74            result_type: "text".to_string(),
75            tool_use_id: "ask_user_question".to_string(),
76            content: response,
77            is_error: Some(false),
78        })
79    }
80}
81
82impl Default for AskUserQuestionTool {
83    fn default() -> Self {
84        Self::new()
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_ask_user_question_schema() {
94        let tool = AskUserQuestionTool::new();
95        let schema = tool.input_schema();
96        assert!(schema.properties.get("question").is_some());
97        assert!(schema.properties.get("header").is_some());
98        assert!(schema.properties.get("options").is_some());
99    }
100}