agent_code_lib/tools/
todo_write.rs1use 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 }
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}