Merge pull request #38 from shivenmian/u/shivenmian/teach
feat: teach mode + accumulator fixes
This commit is contained in:
commit
a6882e6124
|
@ -6,6 +6,7 @@
|
|||
ALL_LOCAL=False
|
||||
WHISPER_MODEL_NAME="ggml-tiny.en.bin"
|
||||
WHISPER_MODEL_URL="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/"
|
||||
TEACH_MODE=False
|
||||
|
||||
# Uncomment to set your OpenAI API key
|
||||
# OPENAI_API_KEY=sk-...
|
||||
|
|
|
@ -329,5 +329,6 @@ class Device:
|
|||
listener.start()
|
||||
|
||||
def start(self):
|
||||
asyncio.run(self.start_async())
|
||||
p.terminate()
|
||||
if os.getenv('TEACH_MODE') == "False":
|
||||
asyncio.run(self.start_async())
|
||||
p.terminate()
|
|
@ -20,7 +20,7 @@ from .i import configure_interpreter
|
|||
from interpreter import interpreter
|
||||
import ngrok
|
||||
from ..utils.accumulator import Accumulator
|
||||
|
||||
from .teach import teach
|
||||
from .utils.logs import setup_logging
|
||||
from .utils.logs import logger
|
||||
setup_logging()
|
||||
|
@ -288,27 +288,30 @@ from uvicorn import Config, Server
|
|||
if __name__ == "__main__":
|
||||
|
||||
async def main():
|
||||
# Start listening
|
||||
asyncio.create_task(listener())
|
||||
if os.getenv('TEACH_MODE') == "True":
|
||||
teach()
|
||||
else:
|
||||
# Start listening
|
||||
asyncio.create_task(listener())
|
||||
|
||||
# Start watching the kernel if it's your job to do that
|
||||
if os.getenv('CODE_RUNNER') == "server":
|
||||
asyncio.create_task(put_kernel_messages_into_queue(from_computer))
|
||||
# Start watching the kernel if it's your job to do that
|
||||
if os.getenv('CODE_RUNNER') == "server":
|
||||
asyncio.create_task(put_kernel_messages_into_queue(from_computer))
|
||||
|
||||
server_url = os.getenv('SERVER_URL')
|
||||
if not server_url:
|
||||
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
|
||||
parsed_url = urllib.parse.urlparse(server_url)
|
||||
server_url = os.getenv('SERVER_URL')
|
||||
if not server_url:
|
||||
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
|
||||
parsed_url = urllib.parse.urlparse(server_url)
|
||||
|
||||
# Set up Ngrok
|
||||
ngrok_auth_token = os.getenv('NGROK_AUTHTOKEN')
|
||||
if ngrok_auth_token is not None:
|
||||
await setup_ngrok(ngrok_auth_token, parsed_url)
|
||||
|
||||
logger.info("Starting `server.py`...")
|
||||
# Set up Ngrok
|
||||
ngrok_auth_token = os.getenv('NGROK_AUTHTOKEN')
|
||||
if ngrok_auth_token is not None:
|
||||
await setup_ngrok(ngrok_auth_token, parsed_url)
|
||||
|
||||
logger.info("Starting `server.py`...")
|
||||
|
||||
config = Config(app, host=parsed_url.hostname, port=parsed_url.port, lifespan='on')
|
||||
server = Server(config)
|
||||
await server.serve()
|
||||
config = Config(app, host=parsed_url.hostname, port=parsed_url.port, lifespan='on')
|
||||
server = Server(config)
|
||||
await server.serve()
|
||||
|
||||
asyncio.run(main())
|
|
@ -0,0 +1,75 @@
|
|||
from datetime import datetime
|
||||
from .utils.logs import setup_logging, logger
|
||||
import tkinter as tk
|
||||
import tkinter.simpledialog
|
||||
from interpreter import interpreter
|
||||
from tkinter import messagebox
|
||||
from ..utils.accumulator import Accumulator
|
||||
import time
|
||||
import os
|
||||
import textwrap
|
||||
|
||||
setup_logging()
|
||||
accumulator = Accumulator()
|
||||
class Skill:
|
||||
def __init__(self, name: str):
|
||||
self.skill_name = name
|
||||
self.steps = []
|
||||
self.code = ""
|
||||
|
||||
def to_camel_case(text):
|
||||
words = text.split()
|
||||
camel_case_string = words[0].lower() + ''.join(word.title() for word in words[1:])
|
||||
return camel_case_string
|
||||
|
||||
def generate_python_code(function_name, code):
|
||||
code_string = f'def {to_camel_case(function_name)}():\n'
|
||||
code_string += f' """{function_name}"""\n'
|
||||
indented_code = textwrap.indent(code, ' ')
|
||||
code_string += indented_code + '\n'
|
||||
return code_string
|
||||
|
||||
def generate_python_steps(function_name, steps):
|
||||
code_string = f'def {to_camel_case(function_name)}():\n'
|
||||
code_string += f' """{function_name}"""\n'
|
||||
code_string += f' print({steps})\n'
|
||||
return code_string
|
||||
|
||||
def teach():
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
|
||||
skill_name = tkinter.simpledialog.askstring("Skill Name", "Please enter the name for the skill:")
|
||||
skill = Skill(skill_name)
|
||||
while True:
|
||||
step = tkinter.simpledialog.askstring("Next Step", "Enter the next step (or 'end' to finish): ")
|
||||
logger.info(f"Performing step: {step}")
|
||||
if step == "end":
|
||||
break
|
||||
|
||||
chunk_code = ""
|
||||
interpreter.computer.languages = [l for l in interpreter.computer.languages if l.name.lower() == "python"]
|
||||
interpreter.force_task_completion = True
|
||||
for chunk in interpreter.chat(step, stream=True, display=False):
|
||||
if "format" in chunk and chunk["format"] == "execution":
|
||||
content = chunk["content"]
|
||||
language = content["format"]
|
||||
code = content["content"]
|
||||
chunk_code += code
|
||||
interpreter.computer.run(code, language)
|
||||
time.sleep(0.05)
|
||||
accumulator.accumulate(chunk)
|
||||
|
||||
isCorrect = messagebox.askyesno("To Proceed?", "Did I do this step right?")
|
||||
if isCorrect:
|
||||
skill.steps.append(step)
|
||||
skill.code += chunk_code
|
||||
|
||||
# Uncomment this incase you want steps instead of code
|
||||
#python_code = generate_python_steps(skill.skill_name, skill.steps)
|
||||
|
||||
python_code = generate_python_code(skill.skill_name, skill.code)
|
||||
SKILLS_DIR = os.path.dirname(__file__) + "/skills"
|
||||
filename = os.path.join(SKILLS_DIR, f"{skill.skill_name.replace(' ', '_')}.py")
|
||||
with open(filename, "w") as file:
|
||||
file.write(python_code)
|
|
@ -26,7 +26,11 @@ class Accumulator:
|
|||
if "content" not in self.message:
|
||||
self.message["content"] = chunk["content"]
|
||||
else:
|
||||
self.message["content"] += chunk["content"]
|
||||
if type(chunk["content"]) == dict:
|
||||
# dict concatenation cannot happen, so we see if chunk is a dict
|
||||
self.message["content"]["content"] += chunk["content"]["content"]
|
||||
else:
|
||||
self.message["content"] += chunk["content"]
|
||||
return None
|
||||
|
||||
if "end" in chunk:
|
||||
|
|
|
@ -36,6 +36,12 @@ if [[ "$@" == *"--server"* ]]; then
|
|||
export SERVER_START="True"
|
||||
fi
|
||||
|
||||
# Check if "--teach" is passed as an argument
|
||||
if [[ "$@" == *"--teach"* ]]; then
|
||||
# If "--teach" is passed, set TEACH_MODE to True
|
||||
export TEACH_MODE="True"
|
||||
fi
|
||||
|
||||
# Check if "--client" is passed as an argument
|
||||
if [[ "$@" == *"--client"* ]]; then
|
||||
# If "--client" is passed, set CLIENT_START to True
|
||||
|
|
|
@ -58,6 +58,10 @@ The `--local` flag will install and run the [whisper.cpp](https://github.com/gge
|
|||
01 --local --server --expose # Expose a local server
|
||||
```
|
||||
|
||||
**Teach Mode (experimental)**
|
||||
|
||||
Running `01 --teach` runs 01 in teach mode, where you can add your own skills for Open Interpreter to use, through an easy-to-follow GUI.
|
||||
|
||||
<br>
|
||||
|
||||
## Setup for development:
|
||||
|
|
Loading…
Reference in New Issue