main
samerbam 1 year ago
parent 4fefe79304
commit 7d431b0b51

@ -0,0 +1,32 @@
# A Siri like AI Assistant
---
* Uses ChatGPT for general queries
* Uses Wolfram Alpha for anything math related
* Has built in NLP (using a NLI model) for determining if we can process query locally
* Frontend/Backend architecture for ability to deploy lightweight clients
## Skills
---
[ ] Alarms
[ ] Calendar
[ ] Gmail
[ ] ChatGPT
[ ] Reminders
[ ] Timers
[ ] Todos
[ ] Weather
[ ] Wolfram
[x] NLP
[x] Speech to Text (frontend for sure)
[ ] API
[ ] Authentication
[ ] General API
[ ] TTS
- generate audio on backend or frontend?
- Perks of backend is fast generation
- Cons of backend is large file transfers between devices, lots of internet usage
- Perks of frontend is less data transfer between devices requiring less internet usage
- Cons of frontend is slower generation

@ -1 +1,8 @@
# TODO: Handle all authentication stuff for verifying client is who we think it is in here. # TODO: Handle all authentication stuff for verifying client is who we think it is in here.
# Example: https://github.com/miguelgrinberg/REST-auth
# User/Pass for initial token and refresh token generation, this should
# OAuth2 style authentication
# Flask-RESTFul with
#

@ -7,11 +7,24 @@ from skills.timers import Timers
from skills.todos import Todos from skills.todos import Todos
from skills.weather import Weather from skills.weather import Weather
from skills.wolfram import Wolfram from skills.wolfram import Wolfram
from NLP import NLP
import sys
print(sys.version)
skills = [GPT(), Alarms(), Cal(), Gmail(), Reminders(), Timers(), Todos(), Weather(), Wolfram()] skills = [GPT(), Alarms(), Cal(), Gmail(), Reminders(), Timers(), Todos(), Weather(), Wolfram()]
skill_names = [skill.trigger_phrase for skill in skills]
print("test")
if __name__ == "__main__": if __name__ == "__main__":
print("Skill Trigger Phrases: ") # print("Skill Trigger Phrases: ")
for skill in skills:
print(skill.trigger_phrase) print(f"Active Skills: {skill_names}")
nlp = NLP()
# for skill in skills:
# print(skill.trigger_phrase)

@ -0,0 +1,4 @@
transformers
spacy
schedule
ctparse

@ -0,0 +1 @@
# TODO: Handle all authentication stuff for verifying client is who we think it is in here.

@ -1,44 +1,107 @@
from skills.config import ntfy_url
import requests import requests
if __name__ == "__main__": # Handle
from config import ntfy_url
else:
from skills.config import ntfy_url
import threading
import schedule
import time
# def job_that_executes_once():
# Do some work that only needs to happen once...
# return schedule.CancelJob
def run_continuously(schedule, interval=1):
# Borrowed from schedule documentation, why reinvent the wheel when its been created.
"""Continuously run, while executing pending jobs at each
elapsed time interval.
@return cease_continuous_run: threading. Event which can
be set to cease continuous run. Please note that it is
*intended behavior that run_continuously() does not run
missed jobs*. For example, if you've registered a job that
should run every minute and you set a continuous run
interval of one hour then your job won't be run 60 times
at each interval but only once.
"""
cease_continuous_run = threading.Event()
class ScheduleThread(threading.Thread):
@classmethod
def run(cls):
while not cease_continuous_run.is_set():
schedule.run_pending()
time.sleep(interval)
continuous_thread = ScheduleThread()
continuous_thread.start()
return cease_continuous_run
# while True:
# schedule.run_pending()
# time.sleep(1)
class Timers: class Timers:
def __init__(self): def __init__(self):
self.trigger_phrase = "timer" self.trigger_phrase = "timer"
self.timers = {} self.timers = {}
self.schedule = schedule.Scheduler()
def _notify(self, device_id, timer_name):
r = requests.post(f"https://ntfy.sh/{device_id}",
data=f"{timer_name}",
headers={
"Title": "Your timer is going off!",
"Priority": "default",
"Tags": "bell"
})
return r
def _add_timer(self, time, name): def _add_timer(self, time, name):
if len(self.timers) == 0:
self.stop_run_continuously = run_continuously()
self.timers[name] = time self.timers[name] = time
# duration =
self.schedule.every().day.at(time.strftime("%H:%M:%S", time.gmtime(duration))).do(self._trigger_timer(name)).tag(name)
# use https://schedule.readthedocs.io/en/stable/examples.html#run-a-job-once to trigger self._trigger_timer() # use https://schedule.readthedocs.io/en/stable/examples.html#run-a-job-once to trigger self._trigger_timer()
def _remove_timer(self, name): def _remove_timer(self, name):
del self.timers[name] del self.timers[name]
if len(self.timers) == 0:
self.stop_run_continuously.set()
def _trigger_timer(self, name): def _trigger_timer(self, name):
if name in self.timers: if name in self.timers:
r = requests.post(f"https://ntfy.sh/{ntfy_url}", res = self._notify(ntfy_url, name).text
data=f"{name}", print(res)
headers={
"Title": "Your timer is going off!", self._remove_timer(name)
"Priority": "default",
"Tags": "bell"
})
print(r.text)
#TODO: send ntfy.sh to device
#TODO: play timer done sound
# #TODO: play timer done sound
return schedule.CancelJob
def run(self, query): def get_remaining_time(self, name=""):
pass
# if name == "":
def run(self, query="", time=0, name=""):
if "add" in query: if "add" in query:
time = 0 #TODO: Natural Language parse time out of phrase self._add_timer(time, name)
self._add_timer(time)
return True # Return true to indicate success return True # Return true to indicate success
if "remove" in query: if "remove" in query:
time = 0 #TODO: Natural Language parse time out of phrase self._remove_timer(name)
self._remove_timer(time)
return True return True
return False # Return false to indicate failure return False # Return false to indicate failure
def _disable_timer_check_thread(self):
self.stop_run_continuously.set()
if __name__ == "__main__": if __name__ == "__main__":

@ -0,0 +1,10 @@
from ctparse import ctparse
from datetime import datetime
def parsetime(phrase):
ts = datetime.now()
return ctparse(phrase, ts=ts)
if __name__ == "__main__":
print(parsetime('May 5th 2:30 in the afternoon').ref_time)
Loading…
Cancel
Save