mertcobanov commited on
Commit
80b16e1
·
1 Parent(s): 25a2f38

Add todo management tools and refactor app configuration

Browse files
Files changed (3) hide show
  1. app.py +38 -41
  2. todo.jsonl +16 -0
  3. todo_agents.py +166 -0
app.py CHANGED
@@ -1,65 +1,62 @@
1
- from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
2
- import datetime
3
- import requests
4
- import pytz
5
  import yaml
6
- from tools.final_answer import FinalAnswerTool
 
 
 
 
 
 
 
7
 
8
  from Gradio_UI import GradioUI
9
-
10
- # Below is an example of a tool that does nothing. Amaze us with your creativity !
11
- @tool
12
- def my_cutom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
13
- #Keep this format for the description / args / args description but feel free to modify the tool
14
- """A tool that does nothing yet
15
- Args:
16
- arg1: the first argument
17
- arg2: the second argument
18
- """
19
- return "What magic will you build ?"
20
-
21
- @tool
22
- def get_current_time_in_timezone(timezone: str) -> str:
23
- """A tool that fetches the current local time in a specified timezone.
24
- Args:
25
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
26
- """
27
- try:
28
- # Create timezone object
29
- tz = pytz.timezone(timezone)
30
- # Get current time in that timezone
31
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
32
- return f"The current local time in {timezone} is: {local_time}"
33
- except Exception as e:
34
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
35
-
36
 
37
  final_answer = FinalAnswerTool()
 
 
38
  model = HfApiModel(
39
- max_tokens=2096,
40
- temperature=0.5,
41
- model_id='deepseek-ai/DeepSeek-R1-Distill-Qwen-32B',# it is possible that this model may be overloaded
42
- custom_role_conversions=None,
43
  )
44
 
 
 
 
 
 
 
45
 
46
  # Import tool from Hub
47
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
48
 
49
- with open("prompts.yaml", 'r') as stream:
50
  prompt_templates = yaml.safe_load(stream)
51
-
52
  agent = CodeAgent(
53
  model=model,
54
- tools=[final_answer], ## add your tools here (don't remove final answer)
 
 
 
 
 
 
55
  max_steps=6,
56
  verbosity_level=1,
57
  grammar=None,
58
  planning_interval=None,
59
  name=None,
60
  description=None,
61
- prompt_templates=prompt_templates
62
  )
63
 
64
 
65
- GradioUI(agent).launch()
 
 
 
 
 
1
  import yaml
2
+ from smolagents import (
3
+ CodeAgent,
4
+ DuckDuckGoSearchTool,
5
+ HfApiModel,
6
+ OpenAIServerModel,
7
+ load_tool,
8
+ tool,
9
+ )
10
 
11
  from Gradio_UI import GradioUI
12
+ from todo_agents import (
13
+ add_task,
14
+ get_current_time_in_timezone,
15
+ get_todays_tasks,
16
+ update_task_status,
17
+ )
18
+ from tools.final_answer import FinalAnswerTool
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  final_answer = FinalAnswerTool()
21
+
22
+ # Remote LLM
23
  model = HfApiModel(
24
+ max_tokens=2096,
25
+ temperature=0.5,
26
+ model_id="https://wxknx1kg971u7k1n.us-east-1.aws.endpoints.huggingface.cloud", # it is possible that this model may be overloaded
27
+ custom_role_conversions=None,
28
  )
29
 
30
+ # # Local LLM
31
+ # model = OpenAIServerModel(
32
+ # model_id="Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
33
+ # api_base="http://100.81.11.125:1234/v1",
34
+ # api_key="lm-studio",
35
+ # )
36
 
37
  # Import tool from Hub
38
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
39
 
40
+ with open("prompts.yaml", "r") as stream:
41
  prompt_templates = yaml.safe_load(stream)
42
+
43
  agent = CodeAgent(
44
  model=model,
45
+ tools=[
46
+ final_answer,
47
+ get_current_time_in_timezone,
48
+ get_todays_tasks,
49
+ add_task,
50
+ update_task_status,
51
+ ], ## add your tools here (don't remove final answer)
52
  max_steps=6,
53
  verbosity_level=1,
54
  grammar=None,
55
  planning_interval=None,
56
  name=None,
57
  description=None,
58
+ prompt_templates=prompt_templates,
59
  )
60
 
61
 
62
+ GradioUI(agent).launch()
todo.jsonl ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"id": "46aa6a55-573c-4325-87ab-5785bd2b72ad", "completed": true, "description": "Buy groceries (milk, bread, eggs)", "last_updated": "2024-03-21"}
2
+ {"id": "d6a05c8d-0fb7-4a68-be17-5b94e07bfc1c", "completed": false, "description": "Water the plants", "last_updated": "2025-02-11"}
3
+ {"id": "7bf3fef5-ed29-483a-81ef-a3c49dd00fc0", "completed": true, "description": "Take out trash", "last_updated": "2024-03-21"}
4
+ {"id": "b5936a2c-df6b-428c-a074-685e0b5c2bba", "completed": true, "description": "Call mom", "last_updated": "2024-03-21"}
5
+ {"id": "eedf7562-6c34-467e-be85-47bad8972005", "completed": false, "description": "Pay electricity bill", "last_updated": "2024-03-21"}
6
+ {"id": "841cff36-5319-4745-b3f5-8b90c3427d4f", "completed": true, "description": "Cut grass in backyard", "last_updated": "2024-03-21"}
7
+ {"id": "55423c2c-bd80-4221-a191-d9ec664dbcbe", "completed": true, "description": "Do laundry", "last_updated": "2025-02-11"}
8
+ {"id": "99fd044e-24fe-4190-9c49-84876fd24528", "completed": true, "description": "Clean bathroom", "last_updated": "2024-03-21"}
9
+ {"id": "d183d6ed-cd5a-4551-9520-e28e610a0f1c", "completed": true, "description": "Buy birthday gift for John", "last_updated": "2024-03-21"}
10
+ {"id": "3cc00430-07be-407f-91bb-3f61e41a6861", "completed": true, "description": "Schedule dentist appointment", "last_updated": "2025-02-11"}
11
+ {"id": "d8c9a03a-f932-49e6-aa15-b49623c2d681", "completed": true, "description": "Vacuum living room", "last_updated": "2024-03-21"}
12
+ {"id": "499dc82a-9e45-48eb-8847-e60c9195e3cd", "completed": true, "description": "Feed the cat", "last_updated": "2024-03-21"}
13
+ {"id": "0527b742-d522-47da-9c05-3f5d8da7cb9a", "completed": false, "description": "Pick up dry cleaning", "last_updated": "2024-03-21"}
14
+ {"id": "803c8862-f346-4024-81d8-76192ad49599", "completed": true, "description": "Buy new light bulbs", "last_updated": "2024-03-21"}
15
+ {"id": "65118069-b2a4-4ea3-b8e9-d7921381cbfc", "completed": true, "description": "Repair my computer", "last_updated": "2025-02-11"}
16
+ {"id": "723323ff-da01-47e0-8837-8feca576eb4e", "completed": false, "description": "Call my mom again", "last_updated": "2025-02-11"}
todo_agents.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datetime
2
+ import json
3
+ import uuid
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import Dict, List
7
+
8
+ import pytz
9
+ from smolagents import tool
10
+
11
+
12
+ @dataclass
13
+ class Task:
14
+ id: str = None
15
+ completed: bool = False
16
+ description: str = ""
17
+ last_updated: str = ""
18
+
19
+ def __post_init__(self):
20
+ if self.id is None:
21
+ self.id = str(uuid.uuid4())
22
+
23
+ def to_dict(self) -> Dict:
24
+ return {
25
+ "id": self.id,
26
+ "completed": self.completed,
27
+ "description": self.description,
28
+ "last_updated": self.last_updated,
29
+ }
30
+
31
+
32
+ class TodoManager:
33
+ def __init__(self, filepath: str = "todo.jsonl"):
34
+ self.filepath = Path(filepath)
35
+ if not self.filepath.exists():
36
+ self.filepath.write_text("")
37
+
38
+ def _read_tasks(self) -> List[Task]:
39
+ if not self.filepath.exists():
40
+ return []
41
+
42
+ try:
43
+ with self.filepath.open("r", encoding="utf-8") as file:
44
+ data = [json.loads(line) for line in file if line.strip()]
45
+
46
+ return [
47
+ Task(
48
+ description=item.get("description", item.get("task", "")),
49
+ completed=item.get("completed", item.get("status") == "✅"),
50
+ last_updated=item["last_updated"],
51
+ id=item.get("id"),
52
+ )
53
+ for item in data
54
+ ]
55
+ except json.JSONDecodeError:
56
+ return []
57
+
58
+ def _save_tasks(self, tasks: List[Task]):
59
+ with self.filepath.open("w") as file:
60
+ for task in tasks:
61
+ file.write(json.dumps(task.to_dict()) + "\n")
62
+
63
+
64
+ @tool
65
+ def get_current_time_in_timezone(timezone: str) -> str:
66
+ """A tool that fetches the current local time in a specified timezone.
67
+ Args:
68
+ timezone: A string representing a valid timezone (e.g., 'America/New_York').
69
+ """
70
+ try:
71
+ tz = pytz.timezone(timezone)
72
+ local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
73
+ return f"The current local time in {timezone} is: {local_time}"
74
+ except Exception as e:
75
+ return f"Error fetching time for timezone '{timezone}': {str(e)}"
76
+
77
+
78
+ @tool
79
+ def get_todays_tasks() -> str:
80
+ """List all tasks with their status and details.
81
+ Args:
82
+ None
83
+ Returns:
84
+ A formatted string containing all tasks with their status and IDs.
85
+ """
86
+ manager = TodoManager("./todo.jsonl")
87
+ tasks = manager._read_tasks()
88
+
89
+ if not tasks:
90
+ return "No tasks found"
91
+
92
+ pending = [t for t in tasks if not t.completed]
93
+ completed = [t for t in tasks if t.completed] # Uncomment this to show all tasks
94
+
95
+ output = [f"📅 Tasks Report for {datetime.date.today()}"]
96
+ output.append("\n🔴 Pending Tasks:")
97
+ output.extend(f"[{t.id[:8]}] {t.description}" for t in pending)
98
+ output.append("\n✅ Completed Tasks:") # Show both pending and completed tasks
99
+ output.extend(f"[{t.id[:8]}] {t.description}" for t in completed)
100
+ output.append(f"\nTotal: {len(pending)} pending, {len(completed)} completed")
101
+
102
+ return "\n".join(output)
103
+
104
+
105
+ @tool
106
+ def update_task_status(task_id: str) -> str:
107
+ """Toggle a task's completion status between complete and pending.
108
+ Args:
109
+ task_id: First 8 characters of the task's UUID (e.g., '65118069' from '65118069-b2a4-4ea3-b8e9-d7921381cbfc').
110
+ You can find task IDs in square brackets when listing tasks.
111
+ Returns:
112
+ Success message with task details if found and updated.
113
+ Error message if task not found or invalid input.
114
+ Examples:
115
+ > update_task_status('65118069')
116
+ "✅ Task [65118069] marked as complete: Repair my computer"
117
+ > update_task_status('65118069')
118
+ "✅ Task [65118069] marked as pending: Repair my computer"
119
+ """
120
+ # Validate task_id format
121
+ if not task_id or not isinstance(task_id, str) or len(task_id) < 1:
122
+ return "❌ Please provide a valid task ID"
123
+
124
+ try:
125
+ manager = TodoManager("./todo.jsonl")
126
+ tasks = manager._read_tasks()
127
+
128
+ if not tasks:
129
+ return "❌ No tasks found in the todo list"
130
+
131
+ # Find and update the task
132
+ for task in tasks:
133
+ if task.id.startswith(task_id):
134
+ task.completed = not task.completed
135
+ task.last_updated = datetime.date.today().strftime("%Y-%m-%d")
136
+ manager._save_tasks(tasks)
137
+ return f"✅ Task [{task_id}] marked as {'complete' if task.completed else 'pending'}: {task.description}"
138
+
139
+ return f"❌ No task found with ID '{task_id}'"
140
+
141
+ except (json.JSONDecodeError, IOError) as e:
142
+ return f"❌ Error accessing todo list: {str(e)}"
143
+ except Exception as e:
144
+ return f"❌ Unexpected error: {str(e)}"
145
+
146
+
147
+ @tool
148
+ def add_task(description: str) -> str:
149
+ """Add a new task to the todo list.
150
+ Args:
151
+ description: The text description of the task to add.
152
+ Returns:
153
+ A confirmation message indicating the task was added.
154
+ """
155
+ manager = TodoManager("./todo.jsonl")
156
+ tasks = manager._read_tasks()
157
+
158
+ new_task = Task(
159
+ description=description,
160
+ completed=False,
161
+ last_updated=datetime.date.today().strftime("%Y-%m-%d"),
162
+ )
163
+
164
+ tasks.append(new_task)
165
+ manager._save_tasks(tasks)
166
+ return f"✅ Added new task: {description}"