KamalamSivakumar commited on
Commit
506d0f4
·
verified ·
1 Parent(s): 40d3002

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +196 -196
agent.py CHANGED
@@ -1,196 +1,196 @@
1
- from google.adk.agents import Agent
2
- from google.adk.tools import BaseTool, ToolContext
3
- from google.adk.models import LlmRequest, LlmResponse
4
- from google.adk.tools import FunctionTool
5
- from google.adk.agents import Agent
6
- import requests
7
- from datetime import datetime, timedelta
8
- from typing import List, Optional
9
- import json
10
- from datetime import datetime, timedelta
11
- from typing import Optional, List, Dict
12
- from dateutil import parser
13
- import requests
14
-
15
- class ExtractScheduleDetailsTool(BaseTool):
16
- def __init__(self):
17
- super().__init__(
18
- name="extract_schedule_details",
19
- description="Extracts date, time, and attendee emails from a task description."
20
- )
21
-
22
- async def run_llm(self, tool_context: ToolContext, task: str) -> Dict:
23
- prompt = f"""
24
- You will be given a user task. Extract the following if present:
25
- - date (in YYYY-MM-DD)
26
- - time (in HH:MM 24-hr format)
27
- - location
28
- - attendees (only email addresses)
29
-
30
- Respond in JSON like this:
31
- {{
32
- "date": "...",
33
- "time": "...",
34
- "location": "...",
35
- "attendees": ["[email protected]", "[email protected]"]
36
- }}
37
-
38
- If any field is missing, set it to null or empty list.
39
- Task: {task}
40
- """
41
- llm_request = LlmRequest(prompt=prompt.strip())
42
- llm_response: LlmResponse = await tool_context.llm.complete(llm_request)
43
- try:
44
- return json.loads(llm_response.text)
45
- except Exception:
46
- return {"date": None, "time": None, "location": None, "attendees": []}
47
-
48
- # -- TOOL 1: Decompose Task --
49
- class DecomposeTaskTool(BaseTool):
50
- def __init__(self):
51
- super().__init__(
52
- name="decompose_task",
53
- description="Decomposes a task into subtasks and estimates XP using prompting."
54
- )
55
-
56
- async def run_llm(self, tool_context: ToolContext, task: str) -> str:
57
- prompt = f"""
58
- You are an intelligent task planner that receives a user task and decides whether the task needs to be broken down into subtasks.
59
-
60
- Respond in the following format:
61
-
62
- ---
63
- task: {task}
64
-
65
- If the task is simple and doesn’t need subtasks:
66
- subtasks required: 0
67
- note: This task is straightforward and does not require subtasking.
68
-
69
- If the task needs to be broken down:
70
- subtasks required: <number of subtasks>
71
- subtask1: <subtask description> | XP: <estimated XP>
72
- subtask2: <subtask description> | XP: <estimated XP>
73
- ...
74
- total XP: <sum of all XP values>
75
- ---
76
-
77
- Guidelines:
78
- - Skip subtasks for trivial tasks like “water the plants”.
79
- - XP should reflect effort (sum up to 100 if fully scoped).
80
- """
81
- llm_request = LlmRequest(prompt=prompt.strip())
82
- llm_response: LlmResponse = await tool_context.llm.complete(llm_request)
83
- return llm_response.text.strip()
84
-
85
- async def run(self, tool_context: ToolContext, task: str) -> str:
86
- return await self.run_llm(tool_context, task)
87
-
88
- # -- TOOL 2: Estimate XP --
89
- class EstimateXPTool(BaseTool):
90
- def __init__(self):
91
- super().__init__(
92
- name="estimate_xp",
93
- description="Estimates XP score for subtasks."
94
- )
95
-
96
- async def run(self, tool_context: ToolContext, task: str, subtasks: List[str]) -> Dict:
97
- xp_per_subtask = {}
98
- for i, subtask in enumerate(subtasks):
99
- xp_per_subtask[subtask] = 10 + 5 * i
100
- total_xp = sum(xp_per_subtask.values())
101
-
102
- return {
103
- "status": "success",
104
- "report": {
105
- "task": task,
106
- "subtasks_required": len(subtasks),
107
- "subtask_details": [{"subtask": s, "xp": xp_per_subtask[s]} for s in subtasks],
108
- "total_xp": total_xp
109
- }
110
- }
111
-
112
- def schedule_event(
113
- date: str,
114
- time: Optional[str] = None,
115
- location: str = "",
116
- description: str = "",
117
- attendees: Optional[List[Dict[str,str]]] = None
118
- ) -> str:
119
- event_details = {
120
- "summary": description,
121
- "location": location,
122
- "description": description,
123
- "timeZone": "Asia/Kolkata"
124
- }
125
-
126
- try:
127
- if time and time.lower() != "unknown":
128
- # Try to parse the time using dateutil for flexibility
129
- parsed_time = parser.parse(time)
130
- start_datetime = datetime.strptime(date, "%Y-%m-%d").replace(
131
- hour=parsed_time.hour, minute=parsed_time.minute, second=0
132
- )
133
- end_datetime = start_datetime + timedelta(minutes=30)
134
-
135
- # Format to ISO strings for scheduling
136
- event_details["start"] = start_datetime.isoformat()
137
- event_details["end"] = end_datetime.isoformat()
138
- else:
139
- # # All-day event
140
- event_details["start"] = date
141
- event_details["end"] = date
142
- # event_details["allDay"] = True
143
-
144
- except Exception as e:
145
- return f"Error parsing time: {str(e)}"
146
-
147
- if attendees:
148
- event_details["attendees"] = [email for email in attendees]
149
-
150
- try:
151
- print(event_details) #http://127.0.0.1:5000/schedule
152
- response = requests.post("https://e04c-49-206-114-222.ngrok-free.app/schedule", json=event_details) #https://d49c-49-206-114-222.ngrok-free.app
153
- if response.status_code == 200:
154
- return f"Event scheduled: {description} on {date}"
155
- else:
156
- return f"Failed to schedule event. Server response: {response.text}"
157
- except Exception as e:
158
- return f"Error during scheduling: {str(e)}"
159
-
160
- schedule_event_tool = FunctionTool(func=schedule_event)
161
-
162
- # -- ROOT AGENT --
163
- root_agent = Agent(
164
- name="personaliser",
165
- description="Agent to gamify tasks and create calendar events.",
166
- model="gemini-2.0-flash",
167
- instruction=("""
168
- You are a productivity assistant that gamifies and schedules tasks.
169
-
170
- Your workflow:
171
- 1. Detect the task.
172
- 2. Gamify it using `decompose_task` and `estimate_xp`.
173
- 3. Use `extract_schedule_details` to identify if a date/time is mentioned.
174
- 4. If the task has:
175
- - a date
176
- - a valid description (the task itself)
177
- Then call `schedule_event`.
178
-
179
- Always summarize in this format:
180
- - Main Task
181
- - Subtasks (with XP)
182
- - Total XP
183
- - Event Details (date, time, location, attendees)
184
-
185
- **Important**:
186
- - Never show internal tool names, JSON structures, or debug logs to the user.
187
- - Your tone should be friendly, helpful, and focused on making the user's tasks more enjoyable and efficient.
188
- - If the task is trivial (e.g., “water the plants”), skip subtasks but still assign an XP score and acknowledge completion."""
189
- ),
190
- tools=[
191
- DecomposeTaskTool(),
192
- EstimateXPTool(),
193
- ExtractScheduleDetailsTool(),
194
- schedule_event_tool
195
- ]
196
- )
 
1
+ from google.adk.agents import Agent
2
+ from google.adk.tools import BaseTool, ToolContext
3
+ from google.adk.models import LlmRequest, LlmResponse
4
+ from google.adk.tools import FunctionTool
5
+ from google.adk.agents import Agent
6
+ import requests
7
+ from datetime import datetime, timedelta
8
+ from typing import List, Optional
9
+ import json
10
+ from datetime import datetime, timedelta
11
+ from typing import Optional, List, Dict
12
+ from dateutil import parser
13
+ import requests
14
+
15
+ class ExtractScheduleDetailsTool(BaseTool):
16
+ def __init__(self):
17
+ super().__init__(
18
+ name="extract_schedule_details",
19
+ description="Extracts date, time, and attendee emails from a task description."
20
+ )
21
+
22
+ async def run_llm(self, tool_context: ToolContext, task: str) -> Dict:
23
+ prompt = f"""
24
+ You will be given a user task. Extract the following if present:
25
+ - date (in YYYY-MM-DD)
26
+ - time (in HH:MM 24-hr format)
27
+ - location
28
+ - attendees (only email addresses)
29
+
30
+ Respond in JSON like this:
31
+ {{
32
+ "date": "...",
33
+ "time": "...",
34
+ "location": "...",
35
+ "attendees": ["[email protected]", "[email protected]"]
36
+ }}
37
+
38
+ If any field is missing, set it to null or empty list.
39
+ Task: {task}
40
+ """
41
+ llm_request = LlmRequest(prompt=prompt.strip())
42
+ llm_response: LlmResponse = await tool_context.llm.complete(llm_request)
43
+ try:
44
+ return json.loads(llm_response.text)
45
+ except Exception:
46
+ return {"date": None, "time": None, "location": None, "attendees": []}
47
+
48
+ # -- TOOL 1: Decompose Task --
49
+ class DecomposeTaskTool(BaseTool):
50
+ def __init__(self):
51
+ super().__init__(
52
+ name="decompose_task",
53
+ description="Decomposes a task into subtasks and estimates XP using prompting."
54
+ )
55
+
56
+ async def run_llm(self, tool_context: ToolContext, task: str) -> str:
57
+ prompt = f"""
58
+ You are an intelligent task planner that receives a user task and decides whether the task needs to be broken down into subtasks.
59
+
60
+ Respond in the following format:
61
+
62
+ ---
63
+ task: {task}
64
+
65
+ If the task is simple and doesn’t need subtasks:
66
+ subtasks required: 0
67
+ note: This task is straightforward and does not require subtasking.
68
+
69
+ If the task needs to be broken down:
70
+ subtasks required: <number of subtasks>
71
+ subtask1: <subtask description> | XP: <estimated XP>
72
+ subtask2: <subtask description> | XP: <estimated XP>
73
+ ...
74
+ total XP: <sum of all XP values>
75
+ ---
76
+
77
+ Guidelines:
78
+ - Skip subtasks for trivial tasks like “water the plants”.
79
+ - XP should reflect effort (sum up to 100 if fully scoped).
80
+ """
81
+ llm_request = LlmRequest(prompt=prompt.strip())
82
+ llm_response: LlmResponse = await tool_context.llm.complete(llm_request)
83
+ return llm_response.text.strip()
84
+
85
+ async def run(self, tool_context: ToolContext, task: str) -> str:
86
+ return await self.run_llm(tool_context, task)
87
+
88
+ # -- TOOL 2: Estimate XP --
89
+ class EstimateXPTool(BaseTool):
90
+ def __init__(self):
91
+ super().__init__(
92
+ name="estimate_xp",
93
+ description="Estimates XP score for subtasks."
94
+ )
95
+
96
+ async def run(self, tool_context: ToolContext, task: str, subtasks: List[str]) -> Dict:
97
+ xp_per_subtask = {}
98
+ for i, subtask in enumerate(subtasks):
99
+ xp_per_subtask[subtask] = 10 + 5 * i
100
+ total_xp = sum(xp_per_subtask.values())
101
+
102
+ return {
103
+ "status": "success",
104
+ "report": {
105
+ "task": task,
106
+ "subtasks_required": len(subtasks),
107
+ "subtask_details": [{"subtask": s, "xp": xp_per_subtask[s]} for s in subtasks],
108
+ "total_xp": total_xp
109
+ }
110
+ }
111
+
112
+ def schedule_event(
113
+ date: str,
114
+ time: Optional[str] = None,
115
+ location: str = "",
116
+ description: str = "",
117
+ attendees: Optional[List[Dict[str,str]]] = None
118
+ ) -> str:
119
+ event_details = {
120
+ "summary": description,
121
+ "location": location,
122
+ "description": description,
123
+ "timeZone": "Asia/Kolkata"
124
+ }
125
+
126
+ try:
127
+ if time and time.lower() != "unknown":
128
+ # Try to parse the time using dateutil for flexibility
129
+ parsed_time = parser.parse(time)
130
+ start_datetime = datetime.strptime(date, "%Y-%m-%d").replace(
131
+ hour=parsed_time.hour, minute=parsed_time.minute, second=0
132
+ )
133
+ end_datetime = start_datetime + timedelta(minutes=30)
134
+
135
+ # Format to ISO strings for scheduling
136
+ event_details["start"] = start_datetime.isoformat()
137
+ event_details["end"] = end_datetime.isoformat()
138
+ else:
139
+ # # All-day event
140
+ event_details["start"] = date
141
+ event_details["end"] = date
142
+ # event_details["allDay"] = True
143
+
144
+ except Exception as e:
145
+ return f"Error parsing time: {str(e)}"
146
+
147
+ if attendees:
148
+ event_details["attendees"] = [email for email in attendees]
149
+
150
+ try:
151
+ print(event_details) #http://127.0.0.1:5000/schedule
152
+ response = requests.post("http://localhost:7861/schedule", json=event_details) #https://d49c-49-206-114-222.ngrok-free.app
153
+ if response.status_code == 200:
154
+ return f"Event scheduled: {description} on {date}"
155
+ else:
156
+ return f"Failed to schedule event. Server response: {response.text}"
157
+ except Exception as e:
158
+ return f"Error during scheduling: {str(e)}"
159
+
160
+ schedule_event_tool = FunctionTool(func=schedule_event)
161
+
162
+ # -- ROOT AGENT --
163
+ root_agent = Agent(
164
+ name="personaliser",
165
+ description="Agent to gamify tasks and create calendar events.",
166
+ model="gemini-2.0-flash",
167
+ instruction=("""
168
+ You are a productivity assistant that gamifies and schedules tasks.
169
+
170
+ Your workflow:
171
+ 1. Detect the task.
172
+ 2. Gamify it using `decompose_task` and `estimate_xp`.
173
+ 3. Use `extract_schedule_details` to identify if a date/time is mentioned.
174
+ 4. If the task has:
175
+ - a date
176
+ - a valid description (the task itself)
177
+ Then call `schedule_event`.
178
+
179
+ Always summarize in this format:
180
+ - Main Task
181
+ - Subtasks (with XP)
182
+ - Total XP
183
+ - Event Details (date, time, location, attendees)
184
+
185
+ **Important**:
186
+ - Never show internal tool names, JSON structures, or debug logs to the user.
187
+ - Your tone should be friendly, helpful, and focused on making the user's tasks more enjoyable and efficient.
188
+ - If the task is trivial (e.g., “water the plants”), skip subtasks but still assign an XP score and acknowledge completion."""
189
+ ),
190
+ tools=[
191
+ DecomposeTaskTool(),
192
+ EstimateXPTool(),
193
+ ExtractScheduleDetailsTool(),
194
+ schedule_event_tool
195
+ ]
196
+ )