Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,7 +4,7 @@ from typing import Optional, Dict, Any
|
|
4 |
from composio_llamaindex import ComposioToolSet, App, Action
|
5 |
from datetime import datetime, timedelta
|
6 |
from collections import defaultdict, Counter
|
7 |
-
from
|
8 |
import gradio as gr
|
9 |
import os
|
10 |
import json
|
@@ -117,80 +117,36 @@ class CalendarService:
|
|
117 |
|
118 |
return stats
|
119 |
|
120 |
-
def
|
121 |
try:
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
"single_events": True,
|
132 |
-
"max_results": 2500,
|
133 |
-
"order_by": "startTime"
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
|
|
140 |
)
|
141 |
|
142 |
-
if events_response["successfull"]:
|
143 |
-
stats = self.analyze_calendar_events(events_response)
|
144 |
-
|
145 |
-
# Create a prompt for the LLM with the stats
|
146 |
-
prompt = f"""Based on the following calendar statistics, analyze which tech billionaire this person's schedule most resembles and provide brief comments for each metric:
|
147 |
-
|
148 |
-
Stats:
|
149 |
-
- Total meetings this year: {stats['total_meetings_this_year']}
|
150 |
-
- Total time in meetings: {stats['total_time_spent']}
|
151 |
-
- Busiest month: {stats['busiest_month']}
|
152 |
-
- Busiest day: {stats['busiest_day']}
|
153 |
-
- Average meeting duration: {stats['average_meeting_duration']}
|
154 |
-
- Most common meeting time: {stats['most_common_meeting_time']}
|
155 |
-
- Most frequent collaborator: {stats['most_frequent_participant']}
|
156 |
-
|
157 |
-
Please provide:
|
158 |
-
1. Which tech billionaire's schedule this most resembles and why
|
159 |
-
2. A one-sentence comment for each of the above metrics
|
160 |
-
Format your response as JSON with keys: 'billionaire_match' and 'metric_comments'
|
161 |
-
|
162 |
-
Dont make any extra comments before or after. Just give the required output and shut up. Dont send any sentences saying like here's your response, or the output is generated"""
|
163 |
-
|
164 |
-
llm_analysis = llm.complete(prompt)
|
165 |
-
|
166 |
-
try:
|
167 |
-
llm_json = json.loads(llm_analysis)
|
168 |
-
except json.JSONDecodeError:
|
169 |
-
llm_json = {
|
170 |
-
"billionaire_match": "Analysis unavailable",
|
171 |
-
"metric_comments": "Comments unavailable"
|
172 |
-
}
|
173 |
-
|
174 |
-
# Add LLM analysis to stats
|
175 |
-
stats.update({
|
176 |
-
"schedule_analysis": llm_json["billionaire_match"],
|
177 |
-
"metric_insights": llm_json["metric_comments"]
|
178 |
-
})
|
179 |
-
|
180 |
-
return APIResponse(
|
181 |
-
success=True,
|
182 |
-
data=stats
|
183 |
-
)
|
184 |
-
else:
|
185 |
-
return APIResponse(
|
186 |
-
success=False,
|
187 |
-
error=events_response["error"] or "Failed to fetch calendar events"
|
188 |
-
)
|
189 |
-
|
190 |
except Exception as e:
|
191 |
return APIResponse(
|
192 |
success=False,
|
193 |
-
error=f"Failed to
|
194 |
)
|
195 |
|
196 |
def check_status(self, entity_id: str) -> APIResponse:
|
@@ -218,50 +174,92 @@ Dont make any extra comments before or after. Just give the required output and
|
|
218 |
)
|
219 |
|
220 |
def generate_wrapped(self, entity_id: str) -> APIResponse:
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
}
|
235 |
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
|
254 |
-
|
|
|
|
|
|
|
|
|
255 |
return APIResponse(
|
256 |
success=False,
|
257 |
-
error=
|
258 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
260 |
def create_gradio_api():
|
261 |
service = CalendarService()
|
262 |
|
263 |
def handle_connection(entity_id: str, redirect_url: Optional[str] = None) -> str:
|
264 |
-
response = service.
|
265 |
return response.to_json()
|
266 |
|
267 |
def check_status(entity_id: str) -> str:
|
|
|
4 |
from composio_llamaindex import ComposioToolSet, App, Action
|
5 |
from datetime import datetime, timedelta
|
6 |
from collections import defaultdict, Counter
|
7 |
+
from llama_index_llms_openai import OpenAI
|
8 |
import gradio as gr
|
9 |
import os
|
10 |
import json
|
|
|
117 |
|
118 |
return stats
|
119 |
|
120 |
+
def initiate_connection(self, entity_id: str, redirect_url: Optional[str] = None) -> APIResponse:
|
121 |
try:
|
122 |
+
if not redirect_url:
|
123 |
+
redirect_url = "https://yourwebsite.com/connection/success"
|
124 |
+
|
125 |
+
connection_request = self.toolset.initiate_connection(
|
126 |
+
entity_id=entity_id,
|
127 |
+
app=App.GOOGLECALENDAR
|
128 |
+
)
|
129 |
|
130 |
+
self.connections[entity_id] = {
|
131 |
+
'status': ConnectionStatus.PENDING.value,
|
132 |
+
'redirect_url': connection_request.redirectUrl,
|
133 |
+
'created_at': datetime.now().isoformat()
|
|
|
|
|
|
|
134 |
}
|
135 |
|
136 |
+
return APIResponse(
|
137 |
+
success=True,
|
138 |
+
data={
|
139 |
+
'status': ConnectionStatus.PENDING.value,
|
140 |
+
'redirect_url': connection_request.redirectUrl,
|
141 |
+
'wait_time': 60,
|
142 |
+
'message': "Please authenticate using the provided link."
|
143 |
+
}
|
144 |
)
|
145 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
except Exception as e:
|
147 |
return APIResponse(
|
148 |
success=False,
|
149 |
+
error=f"Failed to initiate connection: {str(e)}"
|
150 |
)
|
151 |
|
152 |
def check_status(self, entity_id: str) -> APIResponse:
|
|
|
174 |
)
|
175 |
|
176 |
def generate_wrapped(self, entity_id: str) -> APIResponse:
|
177 |
+
try:
|
178 |
+
# Get current year's start and end dates
|
179 |
+
current_year = datetime.now().year
|
180 |
+
time_min = f"{current_year},1,1,0,0,0"
|
181 |
+
time_max = f"{current_year},12,31,23,59,59"
|
182 |
+
|
183 |
+
request_params = {
|
184 |
+
"calendar_id": "primary",
|
185 |
+
"timeMin": time_min,
|
186 |
+
"timeMax": time_max,
|
187 |
+
"single_events": True,
|
188 |
+
"max_results": 2500,
|
189 |
+
"order_by": "startTime"
|
190 |
+
}
|
191 |
+
|
192 |
+
events_response = self.toolset.execute_action(
|
193 |
+
action=Action.GOOGLECALENDAR_FIND_EVENT,
|
194 |
+
params=request_params,
|
195 |
+
entity_id=entity_id
|
196 |
+
)
|
197 |
+
|
198 |
+
if events_response["successfull"]:
|
199 |
+
stats = self.analyze_calendar_events(events_response)
|
200 |
|
201 |
+
# Get tech billionaire comparison
|
202 |
+
billionaire_prompt = f"""Based on these calendar stats, which tech billionaire's schedule does this most resemble and why?
|
203 |
+
Stats:
|
204 |
+
- {stats['total_meetings_this_year']} total meetings
|
205 |
+
- {stats['total_time_spent']} total time in meetings
|
206 |
+
- Most active on {stats['busiest_day']}s
|
207 |
+
- Busiest month is {stats['busiest_month']}
|
208 |
+
- Average meeting duration: {stats['average_meeting_duration']}
|
209 |
|
210 |
+
Return as JSON with format: {{"name": "billionaire name", "reason": "explanation"}}
|
211 |
+
"""
|
212 |
+
|
213 |
+
# Get comments for each stat
|
214 |
+
stats_prompt = f"""Analyze these calendar stats and write a brief, insightful one-sentence comment for each metric:
|
215 |
+
- Total meetings: {stats['total_meetings_this_year']}
|
216 |
+
- Total time in meetings: {stats['total_time_spent']}
|
217 |
+
- Busiest month: {stats['busiest_month']}
|
218 |
+
- Busiest day: {stats['busiest_day']}
|
219 |
+
- Average meeting duration: {stats['average_meeting_duration']}
|
220 |
+
- Most common meeting time: {stats['most_common_meeting_time']}
|
221 |
+
- Most frequent participant: {stats['most_frequent_participant']}
|
222 |
+
|
223 |
+
Return as JSON with format: {{"total_meetings_comment": "", "time_spent_comment": "", "busiest_times_comment": "", "collaborator_comment": "", "habits_comment": ""}}
|
224 |
+
"""
|
225 |
+
|
226 |
+
# Make LLM calls
|
227 |
+
try:
|
228 |
+
billionaire_response = json.loads(llm.complete(billionaire_prompt))
|
229 |
+
stats_comments = json.loads(llm.complete(stats_prompt))
|
230 |
+
|
231 |
+
# Add new fields to stats
|
232 |
+
stats["schedule_analysis"] = billionaire_response
|
233 |
+
stats["metric_insights"] = stats_comments
|
234 |
+
except (json.JSONDecodeError, Exception) as e:
|
235 |
+
print(f"Error processing LLM responses: {e}")
|
236 |
+
# Add empty defaults if LLM processing fails
|
237 |
+
stats["schedule_analysis"] = {"name": "Unknown", "reason": "Analysis unavailable"}
|
238 |
+
stats["metric_insights"] = {"total_meetings_comment": "", "time_spent_comment": "",
|
239 |
+
"busiest_times_comment": "", "collaborator_comment": "",
|
240 |
+
"habits_comment": ""}
|
241 |
|
242 |
+
return APIResponse(
|
243 |
+
success=True,
|
244 |
+
data=stats
|
245 |
+
)
|
246 |
+
else:
|
247 |
return APIResponse(
|
248 |
success=False,
|
249 |
+
error=events_response["error"] or "Failed to fetch calendar events"
|
250 |
)
|
251 |
+
|
252 |
+
except Exception as e:
|
253 |
+
return APIResponse(
|
254 |
+
success=False,
|
255 |
+
error=f"Failed to generate wrapped: {str(e)}"
|
256 |
+
)
|
257 |
|
258 |
def create_gradio_api():
|
259 |
service = CalendarService()
|
260 |
|
261 |
def handle_connection(entity_id: str, redirect_url: Optional[str] = None) -> str:
|
262 |
+
response = service.initiate_connection(entity_id, redirect_url)
|
263 |
return response.to_json()
|
264 |
|
265 |
def check_status(entity_id: str) -> str:
|