AI butler Jarvis
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import datetime
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
from jarvis.functional_modules.caller_context import CallerContext
|
||||
from jarvis.functional_modules.functional_module import functional_module
|
||||
from jarvis.logger import logger
|
||||
from jarvis.utils.asynchttp import do_get, do_post
|
||||
|
||||
|
||||
def reg_or_not():
|
||||
google_calendar_service_address = os.getenv('DEMO_GOOGLE_CALENDAR_SERVICE_ADDRESS')
|
||||
if google_calendar_service_address is None or google_calendar_service_address.strip() == '':
|
||||
logger.warn(
|
||||
"'DEMO_GOOGLE_CALENDAR_SERVICE_ADDRESS' is not provided, google calendar function will not available")
|
||||
return
|
||||
|
||||
@functional_module(
|
||||
name="add_alarm",
|
||||
description="Create an alarm",
|
||||
signature={"date": "The alarm date, 'YYYY-mm-dd HH:MM:SS format'", "desc": "The event description"})
|
||||
async def add_alarm(context: CallerContext, date, desc):
|
||||
# date = "2023-05-10 14:56:59"
|
||||
now = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S").timestamp()
|
||||
# even we modify the tz of datetime, the timestamp does not change (stays to be UNIX timestamp with an offset).
|
||||
# so we adjust the timestamp mannually
|
||||
now -= context.get_tz_offset() * 3600
|
||||
result = await do_post(google_calendar_service_address + "/task/add", {
|
||||
"start_time": now,
|
||||
"end_time": now,
|
||||
"summary": desc,
|
||||
"description": desc
|
||||
})
|
||||
if not isinstance(result, dict):
|
||||
await context.reply_text("Sorry, failed to access calendar")
|
||||
return "Failed to access calendar"
|
||||
if result["code"] == 200:
|
||||
await context.reply_text(f"Alarm have been added: {desc} as {date}")
|
||||
return "Success"
|
||||
await context.reply_text(f"Sorry, failed to access calendar: {result['message']}")
|
||||
return result["message"]
|
||||
|
||||
@functional_module(
|
||||
name="delete_alarm",
|
||||
description="delete all alarms whose ID is in the list",
|
||||
signature={"IDs": "A list of alarm IDs to"})
|
||||
async def delete_alarm(context: CallerContext, IDs: List[str]):
|
||||
# get all tasks
|
||||
result = await do_get(google_calendar_service_address + "/tasks")
|
||||
if not isinstance(result, dict):
|
||||
await context.reply_text("Sorry, failed to access google calendar")
|
||||
return "Failed to query google calendar"
|
||||
if result["code"] != 200:
|
||||
await context.reply_text(f"Sorry, failed to access google calendar: {result['message']}")
|
||||
return result["message"]
|
||||
items = result["data"]
|
||||
if len(items) == 0:
|
||||
await context.reply_text("Sorry, you don't have any alarm now.")
|
||||
return "Canceled"
|
||||
|
||||
deleted = []
|
||||
all_event_ids = [item['id'] for item in items]
|
||||
for alarm_id in IDs:
|
||||
if alarm_id not in all_event_ids:
|
||||
continue
|
||||
# delete
|
||||
result = await do_post(google_calendar_service_address + f"/task/delete/{alarm_id}", "")
|
||||
if not isinstance(result, dict):
|
||||
logger.log(f"Failed to delete alarm: {alarm_id}")
|
||||
continue
|
||||
if result["code"] != 200:
|
||||
logger.log(
|
||||
f"Failed to delete alarm: {alarm_id}: {result['message']}")
|
||||
continue
|
||||
deleted.append(alarm_id)
|
||||
|
||||
if len(deleted) == 0:
|
||||
await context.reply_text("Sorry, failed to delete calendar event")
|
||||
return "Failed"
|
||||
|
||||
msg = "These alarms are deleted:"
|
||||
for alarm_id in deleted:
|
||||
for item in items:
|
||||
if item['id'] == alarm_id:
|
||||
msg += f'\n{item["summary"]}'
|
||||
break
|
||||
await context.reply_text(msg)
|
||||
return "Success"
|
||||
|
||||
@functional_module(
|
||||
name="query_alarm",
|
||||
description="query all existing alarm",
|
||||
signature={})
|
||||
async def query_alarm(context: CallerContext):
|
||||
result = await do_get(google_calendar_service_address + "/tasks")
|
||||
if not isinstance(result, dict):
|
||||
await context.reply_text("Sorry, failed to access google calendar")
|
||||
return "Failed to query google calendar"
|
||||
if result["code"] == 200:
|
||||
if len(result['data']) > 0:
|
||||
markdown = 'Here is your calendar:\n'
|
||||
# Reply a simplified version of md to GPT.
|
||||
# Ensure GPT is notified.
|
||||
markdown_to_gpt = '| ID | Date | Event |\n|----|----|----|'
|
||||
for item in result['data']:
|
||||
timestamp = item["start_time"] + context.get_tz_offset() * 3600
|
||||
time_str = datetime.datetime.fromtimestamp(
|
||||
timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
||||
markdown += f'\n· {time_str} UTC{context.get_tz_offset_str()}, {item["summary"]}'
|
||||
markdown_to_gpt += f'\n| {item["id"]} | {time_str} | {item["summary"]} |'
|
||||
await context.reply_text(markdown)
|
||||
return markdown_to_gpt
|
||||
else:
|
||||
await context.reply_text("You don't have any calendar event.")
|
||||
return "Success"
|
||||
await context.reply_text(f"Sorry, failed access google calendar: {result['message']}")
|
||||
return result["message"]
|
||||
|
||||
|
||||
reg_or_not()
|
||||
Reference in New Issue
Block a user