Change how interpreter imports skills, and modify the schedule function
This commit is contained in:
parent
5c87a11263
commit
3a07d59391
|
@ -1,13 +1,13 @@
|
|||
from dotenv import load_dotenv
|
||||
load_dotenv() # take environment variables from .env.
|
||||
|
||||
from platformdirs import user_data_dir
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import json
|
||||
from pathlib import Path
|
||||
from interpreter import OpenInterpreter
|
||||
import shutil
|
||||
|
||||
|
||||
system_message = r"""
|
||||
|
@ -46,9 +46,11 @@ Store the user's tasks in a Python list called `tasks`.
|
|||
The user's current task list (it might be empty) is: {{ tasks }}
|
||||
When the user completes the current task, you should remove it from the list and read the next item by running `tasks = tasks[1:]\ntasks[0]`. Then, tell the user what the next task is.
|
||||
When the user tells you about a set of tasks, you should intelligently order tasks, batch similar tasks, and break down large tasks into smaller tasks (for this, you should consult the user and get their permission to break it down). Your goal is to manage the task list as intelligently as possible, to make the user as efficient and non-overwhelmed as possible. They will require a lot of encouragement, support, and kindness. Don't say too much about what's ahead of them— just try to focus them on each step at a time.
|
||||
After starting a task, you should check in with the user around the estimated completion time to see if the task is completed.
|
||||
To do this, schedule a reminder based on estimated completion time using the function `schedule(days=0, hours=0, mins=0, secs=0, datetime="valid date time", message="Your message here.")`. You'll receive the message at the time you scheduled it.
|
||||
THE SCHEDULE FUNCTION HAS ALREADY BEEN IMPORTED. YOU DON'T NEED TO IMPORT THE `schedule` FUNCTION.
|
||||
|
||||
After starting a task, you should check in with the user around the estimated completion time to see if the task is completed.
|
||||
To do this, schedule a reminder based on estimated completion time using the function `schedule(message="Your message here.", start="8am")`, WHICH HAS ALREADY BEEN IMPORTED. YOU DON'T NEED TO IMPORT THE `schedule` FUNCTION. IT IS AVAILABLE. You'll receive the message at the time you scheduled it. If the user says to monitor something, simply schedule it with an interval of a duration that makes sense for the problem by specifying an interval, like this: `schedule(message="Your message here.", interval="5m")`
|
||||
|
||||
|
||||
If there are tasks, you should guide the user through their list one task at a time, convincing them to move forward, giving a pep talk if need be.
|
||||
|
||||
# THE COMPUTER API
|
||||
|
@ -296,9 +298,39 @@ def configure_interpreter(interpreter: OpenInterpreter):
|
|||
|
||||
from platformdirs import user_data_dir
|
||||
|
||||
directory = os.path.join(user_data_dir("01"), "skills")
|
||||
interpreter.computer.skills.path = directory
|
||||
interpreter.computer.skills.import_skills()
|
||||
|
||||
|
||||
# Directory paths
|
||||
repo_skills_dir = os.path.join(os.path.dirname(__file__), "skills")
|
||||
user_data_skills_dir = os.path.join(user_data_dir("01"), "skills")
|
||||
|
||||
# Create the user data skills directory if it doesn't exist
|
||||
os.makedirs(user_data_skills_dir, exist_ok=True)
|
||||
|
||||
# Copy Python files from the repository skills directory to the user data skills directory, ignoring __init__.py files
|
||||
for filename in os.listdir(repo_skills_dir):
|
||||
if filename.endswith(".py") and filename != "__init__.py":
|
||||
src_file = os.path.join(repo_skills_dir, filename)
|
||||
dst_file = os.path.join(user_data_skills_dir, filename)
|
||||
shutil.copy2(src_file, dst_file)
|
||||
|
||||
interpreter.computer.debug = True
|
||||
interpreter.computer.skills.path = user_data_skills_dir
|
||||
|
||||
# Import skills
|
||||
interpreter.computer.save_skills = False
|
||||
|
||||
for file in glob.glob(os.path.join(interpreter.computer.skills.path, "*.py")):
|
||||
code_to_run = ""
|
||||
with open(file, "r") as f:
|
||||
code_to_run += f.read() + "\n"
|
||||
|
||||
print("IMPORTING SKILLS:\n", code_to_run)
|
||||
|
||||
for line in interpreter.computer.run("python", code_to_run, stream=True):
|
||||
print(line)
|
||||
|
||||
interpreter.computer.save_skills = True
|
||||
|
||||
|
||||
# Initialize user's task list
|
||||
|
|
|
@ -8,6 +8,7 @@ import json
|
|||
import queue
|
||||
import os
|
||||
import traceback
|
||||
import datetime
|
||||
from .utils.bytes_to_wav import bytes_to_wav
|
||||
import re
|
||||
from fastapi import FastAPI, Request
|
||||
|
@ -131,10 +132,10 @@ async def add_computer_message(request: Request):
|
|||
text = body.get("text")
|
||||
if not text:
|
||||
return {"error": "Missing 'text' in request body"}, 422
|
||||
message = {"role": "computer", "type": "console", "format": "output", "content": text}
|
||||
from_computer.put({"role": "computer", "type": "console", "format": "output", "start": True})
|
||||
from_computer.put(message)
|
||||
from_computer.put({"role": "computer", "type": "console", "format": "output", "end": True})
|
||||
message = {"role": "user", "type": "message", "content": text}
|
||||
await from_user.put({"role": "user", "type": "message", "start": True})
|
||||
await from_user.put(message)
|
||||
await from_user.put({"role": "user", "type": "message", "end": True})
|
||||
|
||||
|
||||
async def receive_messages(websocket: WebSocket):
|
||||
|
@ -382,7 +383,13 @@ async def main(server_host, server_port, llm_service, model, llm_supports_vision
|
|||
services_directory = os.path.join(application_directory, 'services')
|
||||
|
||||
service_dict = {'llm': llm_service, 'tts': tts_service, 'stt': stt_service}
|
||||
|
||||
|
||||
# Create a temp file with the session number
|
||||
session_file_path = os.path.join(user_data_dir('01'), '01-session.txt')
|
||||
with open(session_file_path, 'w') as session_file:
|
||||
session_id = int(datetime.datetime.now().timestamp() * 1000)
|
||||
session_file.write(str(session_id))
|
||||
|
||||
for service in service_dict:
|
||||
|
||||
service_directory = os.path.join(services_directory, service, service_dict[service])
|
||||
|
|
|
@ -1,34 +1,66 @@
|
|||
import threading
|
||||
import os
|
||||
from datetime import datetime
|
||||
import json
|
||||
import subprocess
|
||||
import requests
|
||||
from pytimeparse import parse
|
||||
from crontab import CronTab
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
from platformdirs import user_data_dir
|
||||
|
||||
|
||||
def send_request(message) -> None:
|
||||
url = "http://localhost:8000/"
|
||||
data = {"text": message}
|
||||
try:
|
||||
response = requests.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
except requests.RequestException as e:
|
||||
print(f"Request failed: {e}")
|
||||
|
||||
def schedule(days=0, hours=0, mins=0, secs=0, target_datetime=None, message="") -> None:
|
||||
"""Schedules a reminder after a specified delay or for a specific datetime. The delay is defined by days, hours, minutes, and seconds. If a target_datetime is provided, it schedules the reminder for that datetime instead."""
|
||||
def schedule(message="", start=None, interval=None) -> None:
|
||||
"""
|
||||
Schedules a task at a particular time, or at a particular interval
|
||||
"""
|
||||
if start and interval:
|
||||
raise ValueError("Cannot specify both start time and interval.")
|
||||
|
||||
if target_datetime is None:
|
||||
# Calculate the delay in seconds if no target_datetime is provided
|
||||
delay = days * 86400 + hours * 3600 + mins * 60 + secs
|
||||
else:
|
||||
# Calculate the delay in seconds from now until the target datetime
|
||||
now = datetime.now()
|
||||
delay = (target_datetime - now).total_seconds()
|
||||
# Ensure delay is non-negative
|
||||
delay = max(0, delay)
|
||||
if not start and not interval:
|
||||
raise ValueError("Either start time or interval must be specified.")
|
||||
|
||||
# Read the temp file to see what the current session is
|
||||
session_file_path = os.path.join(user_data_dir('01'), '01-session.txt')
|
||||
|
||||
with open(session_file_path, 'r') as session_file:
|
||||
file_session_value = session_file.read().strip()
|
||||
|
||||
# Create a timer
|
||||
timer = threading.Timer(delay, send_request, args=[message])
|
||||
|
||||
# Start the timer
|
||||
timer.start()
|
||||
prefixed_message = "AUTOMATED MESSAGE FROM SCHEDULER: " + message
|
||||
|
||||
# Escape the message and the json, cron is funky with quotes
|
||||
escaped_question = prefixed_message.replace('"', '\\"')
|
||||
json_data = f"{{\\\"text\\\": \\\"{escaped_question}\\\"}}"
|
||||
|
||||
command = f'''bash -c 'if [ "$(cat "{session_file_path}")" == "{file_session_value}" ]; then /usr/bin/curl -X POST -H "Content-Type: application/json" -d "{json_data}" http://localhost:8000/; fi' '''
|
||||
|
||||
cron = CronTab(user=True)
|
||||
job = cron.new(command=command)
|
||||
# Prefix with 01 dev preview so we can delete them all in the future
|
||||
job_id = "01-dev-preview-" + str(uuid4())
|
||||
job.set_comment(job_id)
|
||||
if start:
|
||||
try:
|
||||
start_time = datetime.strptime(start, "%Y-%m-%d %H:%M:%S")
|
||||
except ValueError:
|
||||
raise ValueError(f"Invalid datetime format: {start}.")
|
||||
job.setall(start_time)
|
||||
print(f"Task scheduled for {start_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
elif interval:
|
||||
seconds = parse(interval)
|
||||
if seconds <= 60:
|
||||
job.minute.every(1)
|
||||
print("Task scheduled every minute")
|
||||
elif seconds < 3600:
|
||||
minutes = max(int(seconds / 60), 1)
|
||||
job.minute.every(minutes)
|
||||
print(f"Task scheduled every {minutes} minutes")
|
||||
elif seconds < 86400:
|
||||
hours = max(int(seconds / 3600), 1)
|
||||
job.hour.every(hours)
|
||||
print(f"Task scheduled every {hours} hour(s)")
|
||||
else:
|
||||
days = max(int(seconds / 86400), 1)
|
||||
job.day.every(days)
|
||||
print(f"Task scheduled every {days} day(s)")
|
||||
|
||||
cron.write()
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -29,6 +29,9 @@ typer = "^0.9.0"
|
|||
platformdirs = "^4.2.0"
|
||||
rich = "^13.7.1"
|
||||
open-interpreter = {extras = ["os"], version = "^0.2.3"}
|
||||
dateparser = "^1.2.0"
|
||||
pytimeparse = "^1.1.8"
|
||||
python-crontab = "^3.0.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
|
Loading…
Reference in New Issue