Skip to main content

agent_code_lib/tools/
todo_write.rs

1//! TodoWrite tool: manage a structured todo list.
2
3use async_trait::async_trait;
4use serde_json::json;
5
6use super::{Tool, ToolContext, ToolResult};
7use crate::error::ToolError;
8
9pub struct TodoWriteTool;
10
11#[async_trait]
12impl Tool for TodoWriteTool {
13    fn name(&self) -> &'static str {
14        "TodoWrite"
15    }
16
17    fn description(&self) -> &'static str {
18        "Write or update a structured todo list for tracking work items."
19    }
20
21    fn input_schema(&self) -> serde_json::Value {
22        json!({
23            "type": "object",
24            "required": ["todos"],
25            "properties": {
26                "todos": {
27                    "type": "array",
28                    "description": "List of todo items",
29                    "items": {
30                        "type": "object",
31                        "required": ["id", "content", "status"],
32                        "properties": {
33                            "id": {
34                                "type": "string",
35                                "description": "Unique identifier"
36                            },
37                            "content": {
38                                "type": "string",
39                                "description": "Todo description"
40                            },
41                            "status": {
42                                "type": "string",
43                                "enum": ["pending", "in_progress", "done"],
44                                "description": "Current status"
45                            },
46                            "priority": {
47                                "type": "string",
48                                "enum": ["high", "medium", "low"],
49                                "description": "Priority level"
50                            }
51                        }
52                    }
53                }
54            }
55        })
56    }
57
58    fn is_read_only(&self) -> bool {
59        true // Todos are metadata, not file changes.
60    }
61
62    fn is_concurrency_safe(&self) -> bool {
63        true
64    }
65
66    async fn call(
67        &self,
68        input: serde_json::Value,
69        _ctx: &ToolContext,
70    ) -> Result<ToolResult, ToolError> {
71        let todos = input
72            .get("todos")
73            .and_then(|v| v.as_array())
74            .ok_or_else(|| ToolError::InvalidInput("'todos' array is required".into()))?;
75
76        let mut lines = Vec::new();
77        for todo in todos {
78            let id = todo.get("id").and_then(|v| v.as_str()).unwrap_or("?");
79            let content = todo.get("content").and_then(|v| v.as_str()).unwrap_or("");
80            let status = todo
81                .get("status")
82                .and_then(|v| v.as_str())
83                .unwrap_or("pending");
84            let marker = match status {
85                "done" => "[x]",
86                "in_progress" => "[~]",
87                _ => "[ ]",
88            };
89            lines.push(format!("{marker} {id}: {content}"));
90        }
91
92        Ok(ToolResult::success(format!(
93            "Todo list ({} items):\n{}",
94            todos.len(),
95            lines.join("\n")
96        )))
97    }
98}