1
1
"""Todo list management tool for agents."""
2
2
3
3
import uuid
4
+ from collections .abc import Callable
4
5
from dataclasses import dataclass , field
5
6
from enum import Enum
6
- from typing import Any , Literal , Callable
7
+ from typing import Any , Literal
8
+
9
+ from pydantic import BaseModel
7
10
8
11
9
12
class TaskStatus (str , Enum ):
10
13
"""Task status options."""
14
+
11
15
PENDING = "pending"
12
16
IN_PROGRESS = "in_progress"
13
17
COMPLETED = "completed"
14
18
15
19
16
- @dataclass
17
- class Task :
20
+ class Task (BaseModel ):
18
21
"""Simple task representation."""
22
+
19
23
id : str
20
24
description : str
21
25
status : TaskStatus = TaskStatus .PENDING
22
26
order : int = 0
23
27
summary : str | None = None
28
+ parent_id : str | None = None
24
29
25
30
26
31
@dataclass
27
32
class TodoList :
28
33
"""Simple todo list for one agent run."""
34
+
29
35
tasks : list [Task ] = field (default_factory = list )
30
36
current_index : int = 0
31
37
@@ -35,7 +41,7 @@ def get_current_task(self) -> Task | None:
35
41
return self .tasks [self .current_index ]
36
42
return None
37
43
38
- def advance_to_next (self ):
44
+ def advance_to_next (self ) -> None :
39
45
"""Move to next task."""
40
46
self .current_index += 1
41
47
@@ -49,18 +55,14 @@ def create_tasks(self, task_descriptions: list[str]) -> dict[str, Any]:
49
55
self .current_index = 0
50
56
51
57
for i , desc in enumerate (task_descriptions ):
52
- task = Task (
53
- id = str (uuid .uuid4 ()),
54
- description = desc .strip (),
55
- order = i
56
- )
58
+ task = Task (id = str (uuid .uuid4 ()), description = desc .strip (), order = i )
57
59
self .tasks .append (task )
58
60
59
61
return {
60
62
"action" : "create" ,
61
63
"tasks" : [{"id" : t .id , "description" : t .description , "order" : t .order } for t in self .tasks ],
62
64
"total_count" : len (self .tasks ),
63
- "message" : f"Created { len (task_descriptions )} tasks"
65
+ "message" : f"Created { len (task_descriptions )} tasks" ,
64
66
}
65
67
66
68
def get_current (self ) -> dict [str , Any ]:
@@ -71,14 +73,14 @@ def get_current(self) -> dict[str, Any]:
71
73
"action" : "get_current" ,
72
74
"current_task" : None ,
73
75
"all_completed" : True ,
74
- "message" : "All tasks completed!"
76
+ "message" : "All tasks completed!" ,
75
77
}
76
78
77
79
return {
78
80
"action" : "get_current" ,
79
81
"current_task" : {"id" : current .id , "description" : current .description , "status" : current .status .value },
80
82
"progress" : f"{ self .current_index + 1 } /{ len (self .tasks )} " ,
81
- "message" : f"Current task: { current .description } "
83
+ "message" : f"Current task: { current .description } " ,
82
84
}
83
85
84
86
def start_current_task (self ) -> dict [str , Any ]:
@@ -91,7 +93,7 @@ def start_current_task(self) -> dict[str, Any]:
91
93
return {
92
94
"action" : "start_task" ,
93
95
"task" : {"id" : current .id , "description" : current .description , "status" : current .status .value },
94
- "message" : f"Started task: { current .description } "
96
+ "message" : f"Started task: { current .description } " ,
95
97
}
96
98
97
99
def complete_current_task (self , summary : str ) -> dict [str , Any ]:
@@ -119,19 +121,15 @@ def complete_current_task(self, summary: str) -> dict[str, Any]:
119
121
"next_task" : {"id" : next_task .id , "description" : next_task .description } if next_task else None ,
120
122
"progress" : f"{ completed_count } /{ len (self .tasks )} " ,
121
123
"all_completed" : next_task is None ,
122
- "message" : f"Completed: { current .description } "
124
+ "message" : f"Completed: { current .description } " ,
123
125
}
124
126
125
127
def get_final_summary (self ) -> dict [str , Any ]:
126
128
"""Get comprehensive final summary of all completed work."""
127
129
completed_tasks = [t for t in self .tasks if t .status == TaskStatus .COMPLETED ]
128
130
129
131
if not completed_tasks :
130
- return {
131
- "action" : "get_final_summary" ,
132
- "final_summary" : "" ,
133
- "message" : "No completed tasks found."
134
- }
132
+ return {"action" : "get_final_summary" , "final_summary" : "" , "message" : "No completed tasks found." }
135
133
136
134
# Create comprehensive final summary
137
135
final_content = []
@@ -147,7 +145,7 @@ def get_final_summary(self) -> dict[str, Any]:
147
145
"action" : "get_final_summary" ,
148
146
"final_summary" : final_summary ,
149
147
"total_completed" : len (completed_tasks ),
150
- "message" : f"Final summary with { len (completed_tasks )} completed tasks."
148
+ "message" : f"Final summary with { len (completed_tasks )} completed tasks." ,
151
149
}
152
150
153
151
@@ -163,6 +161,7 @@ def create_todo_manager(todo_list: TodoList) -> Callable[..., dict[str, Any]]:
163
161
Returns:
164
162
A todo_manager function that operates on the provided TodoList
165
163
"""
164
+
166
165
def todo_manager (
167
166
action : Literal ["create" , "get_current" , "start_task" , "complete_task" , "get_final_summary" ],
168
167
tasks : list [str ] | None = None ,
@@ -216,4 +215,4 @@ def get_todo_instruction_tpl(task_range: tuple[int, int] = (3, 5)) -> str:
216
215
217
216
IMPORTANT: Task summaries should be DETAILED and COMPREHENSIVE (3-5 sentences).
218
217
Include specific information, recommendations, and actionable details.
219
- """
218
+ """
0 commit comments