Skip to main content

ai_agent/tools/
tasks.rs

1// Source: /data/home/swei/claudecode/openclaudecode/src/tasks.ts
2//! Task management tools.
3//!
4//! Provides tools for creating, listing, updating, and getting tasks.
5
6pub const TASK_CREATE_TOOL_NAME: &str = "TaskCreate";
7
8use crate::types::*;
9
10/// TaskCreate tool - create a new task
11pub struct TaskCreateTool;
12
13impl TaskCreateTool {
14    pub fn new() -> Self {
15        Self
16    }
17
18    pub fn input_schema(&self) -> ToolInputSchema {
19        ToolInputSchema {
20            schema_type: "object".to_string(),
21            properties: serde_json::json!({
22                "subject": {
23                    "type": "string",
24                    "description": "A brief title for the task"
25                },
26                "description": {
27                    "type": "string",
28                    "description": "What needs to be done"
29                },
30                "activeForm": {
31                    "type": "string",
32                    "description": "Present continuous form shown in spinner when in_progress"
33                }
34            }),
35            required: Some(vec!["subject".to_string(), "description".to_string()]),
36        }
37    }
38
39    pub async fn execute(
40        &self,
41        input: serde_json::Value,
42        _context: &ToolContext,
43    ) -> Result<ToolResult, crate::error::AgentError> {
44        let subject = input["subject"].as_str().unwrap_or("");
45        let description = input["description"].as_str().unwrap_or("");
46        let active_form = input["activeForm"].as_str().unwrap_or(subject);
47
48        let response = format!(
49            "Task created: {}\nDescription: {}\nActive form: {}",
50            subject, description, active_form
51        );
52
53        Ok(ToolResult {
54            result_type: "text".to_string(),
55            tool_use_id: "task_create".to_string(),
56            content: response,
57            is_error: Some(false),
58        })
59    }
60}
61
62impl Default for TaskCreateTool {
63    fn default() -> Self {
64        Self::new()
65    }
66}
67
68/// TaskList tool - list all tasks
69pub struct TaskListTool;
70
71impl TaskListTool {
72    pub fn new() -> Self {
73        Self
74    }
75
76    pub fn input_schema(&self) -> ToolInputSchema {
77        ToolInputSchema {
78            schema_type: "object".to_string(),
79            properties: serde_json::json!({}),
80            required: None,
81        }
82    }
83
84    pub async fn execute(
85        &self,
86        _input: serde_json::Value,
87        _context: &ToolContext,
88    ) -> Result<ToolResult, crate::error::AgentError> {
89        let response = "Tasks:\n- (none)".to_string();
90
91        Ok(ToolResult {
92            result_type: "text".to_string(),
93            tool_use_id: "task_list".to_string(),
94            content: response,
95            is_error: Some(false),
96        })
97    }
98}
99
100impl Default for TaskListTool {
101    fn default() -> Self {
102        Self::new()
103    }
104}
105
106/// TaskUpdate tool - update a task
107pub struct TaskUpdateTool;
108
109impl TaskUpdateTool {
110    pub fn new() -> Self {
111        Self
112    }
113
114    pub fn input_schema(&self) -> ToolInputSchema {
115        ToolInputSchema {
116            schema_type: "object".to_string(),
117            properties: serde_json::json!({
118                "taskId": {
119                    "type": "string",
120                    "description": "The ID of the task to update"
121                },
122                "subject": {
123                    "type": "string",
124                    "description": "New subject for the task"
125                },
126                "description": {
127                    "type": "string",
128                    "description": "New description for the task"
129                },
130                "status": {
131                    "type": "string",
132                    "enum": ["pending", "in_progress", "completed", "deleted"],
133                    "description": "New status for the task"
134                },
135                "activeForm": {
136                    "type": "string",
137                    "description": "New active form"
138                }
139            }),
140            required: Some(vec!["taskId".to_string()]),
141        }
142    }
143
144    pub async fn execute(
145        &self,
146        input: serde_json::Value,
147        _context: &ToolContext,
148    ) -> Result<ToolResult, crate::error::AgentError> {
149        let task_id = input["taskId"].as_str().unwrap_or("");
150        let status = input["status"].as_str().unwrap_or("pending");
151
152        let response = format!("Task {} updated:\n- Status: {}", task_id, status);
153
154        Ok(ToolResult {
155            result_type: "text".to_string(),
156            tool_use_id: "task_update".to_string(),
157            content: response,
158            is_error: Some(false),
159        })
160    }
161}
162
163impl Default for TaskUpdateTool {
164    fn default() -> Self {
165        Self::new()
166    }
167}
168
169/// TaskGet tool - get a specific task
170pub struct TaskGetTool;
171
172impl TaskGetTool {
173    pub fn new() -> Self {
174        Self
175    }
176
177    pub fn input_schema(&self) -> ToolInputSchema {
178        ToolInputSchema {
179            schema_type: "object".to_string(),
180            properties: serde_json::json!({
181                "taskId": {
182                    "type": "string",
183                    "description": "The ID of the task to retrieve"
184                }
185            }),
186            required: Some(vec!["taskId".to_string()]),
187        }
188    }
189
190    pub async fn execute(
191        &self,
192        input: serde_json::Value,
193        _context: &ToolContext,
194    ) -> Result<ToolResult, crate::error::AgentError> {
195        let task_id = input["taskId"].as_str().unwrap_or("");
196
197        let response = format!(
198            "Task ID: {}\nStatus: pending\nSubject: (placeholder)\nDescription: (placeholder)",
199            task_id
200        );
201
202        Ok(ToolResult {
203            result_type: "text".to_string(),
204            tool_use_id: "task_get".to_string(),
205            content: response,
206            is_error: Some(false),
207        })
208    }
209}
210
211impl Default for TaskGetTool {
212    fn default() -> Self {
213        Self::new()
214    }
215}
216
217#[cfg(test)]
218mod tests {
219    use super::*;
220
221    #[test]
222    fn test_task_create_schema() {
223        let tool = TaskCreateTool::new();
224        let schema = tool.input_schema();
225        assert_eq!(schema.schema_type, "object");
226        assert!(schema.properties.get("subject").is_some());
227        assert!(schema.properties.get("description").is_some());
228    }
229
230    #[test]
231    fn test_task_list_schema() {
232        let tool = TaskListTool::new();
233        let schema = tool.input_schema();
234        assert_eq!(schema.schema_type, "object");
235    }
236
237    #[test]
238    fn test_task_update_schema() {
239        let tool = TaskUpdateTool::new();
240        let schema = tool.input_schema();
241        assert!(schema.properties.get("taskId").is_some());
242        assert!(schema.properties.get("status").is_some());
243    }
244
245    #[test]
246    fn test_task_get_schema() {
247        let tool = TaskGetTool::new();
248        let schema = tool.input_schema();
249        assert!(schema.properties.get("taskId").is_some());
250    }
251}