From 1e892bfb0519e6070c45d6f5b8338cc9f268c899 Mon Sep 17 00:00:00 2001 From: Tom Viner Date: Mon, 3 Apr 2023 00:07:18 +0100 Subject: [PATCH 01/11] don't depend on the path script is run from --- scripts/data.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/data.py b/scripts/data.py index 19473557..62a36e12 100644 --- a/scripts/data.py +++ b/scripts/data.py @@ -1,7 +1,12 @@ +from pathlib import Path + +FOLDER = Path(__file__).parent + + def load_prompt(): try: # Load the promt from data/prompt.txt - with open("data/prompt.txt", "r") as prompt_file: + with open(FOLDER / "data/prompt.txt", "r") as prompt_file: prompt = prompt_file.read() return prompt From 962a5bb76c1592f07a13248007c8ef5c775f404d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CPhilip?= Date: Mon, 3 Apr 2023 19:44:12 +0100 Subject: [PATCH 02/11] =?UTF-8?q?Fix=20Issue=20with=20command=20hallucinat?= =?UTF-8?q?ion=20=F0=9F=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes an issue where it hallucinates on "COMMANDS" 💭 --- scripts/data/prompt.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/data/prompt.txt b/scripts/data/prompt.txt index d17fa27a..bffbcc14 100644 --- a/scripts/data/prompt.txt +++ b/scripts/data/prompt.txt @@ -2,6 +2,7 @@ CONSTRAINTS: 1. ~4000 word limit for memory. Your memory is short, so immidiately save important information to long term memory and code to files. 2. No user assistance +3. Exclusively use the commands listed in double quotes e.g. "command name" COMMANDS: From 2af9cf853aac6b91a7fac26dfccc28d1c6bfa4cb Mon Sep 17 00:00:00 2001 From: Preston Jensen Date: Mon, 3 Apr 2023 20:12:11 -0600 Subject: [PATCH 03/11] human feedback in manual mode --- scripts/main.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index 97c05d7d..03f656b0 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -303,7 +303,7 @@ while True: Fore.CYAN, f"COMMAND = {Fore.CYAN}{command_name}{Style.RESET_ALL} ARGUMENTS = {Fore.CYAN}{arguments}{Style.RESET_ALL}") print( - "Enter 'y' to authorise command or 'n' to exit program...", + f"Enter 'y' to authorise command or 'n' to exit program, or enter feedback for {ai_name}...", flush=True) while True: console_input = input(Fore.MAGENTA + "Input:" + Style.RESET_ALL) @@ -314,16 +314,18 @@ while True: user_input = "EXIT" break else: - continue + user_input = console_input + command_name = "human_feedback" + break - if user_input != "GENERATE NEXT COMMAND JSON": - print("Exiting...", flush=True) - break - - print_to_console( + if user_input == "GENERATE NEXT COMMAND JSON": + print_to_console( "-=-=-=-=-=-=-= COMMAND AUTHORISED BY USER -=-=-=-=-=-=-=", Fore.MAGENTA, "") + elif user_input == "EXIT": + print("Exiting...", flush=True) + break else: # Print command print_to_console( @@ -332,10 +334,12 @@ while True: f"COMMAND = {Fore.CYAN}{command_name}{Style.RESET_ALL} ARGUMENTS = {Fore.CYAN}{arguments}{Style.RESET_ALL}") # Execute command - if command_name.lower() != "error": - result = f"Command {command_name} returned: {cmd.execute_command(command_name, arguments)}" - else: + if command_name.lower() == "error": result = f"Command {command_name} threw the following error: " + arguments + elif command_name == "human_feedback": + result = f"Human feedback: {user_input}" + else: + result = f"Command {command_name} returned: {cmd.execute_command(command_name, arguments)}" # Check if there's a result from the command append it to the message # history @@ -347,3 +351,4 @@ while True: chat.create_chat_message( "system", "Unable to execute command")) print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") + From 82da7f1681a1c2cb5dad310e396589b8a3d3ce71 Mon Sep 17 00:00:00 2001 From: yousefissa Date: Mon, 3 Apr 2023 22:19:32 -0700 Subject: [PATCH 04/11] fix assistant thoughts failure on string type --- scripts/main.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index 97c05d7d..a1c08018 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -52,6 +52,14 @@ def print_assistant_thoughts(assistant_reply): # Parse and print Assistant response assistant_reply_json = fix_and_parse_json(assistant_reply) + # Check if assistant_reply_json is a string and attempt to parse it into a JSON object + if isinstance(assistant_reply_json, str): + try: + assistant_reply_json = json.loads(assistant_reply_json) + except json.JSONDecodeError as e: + print_to_console("Error: Invalid JSON\n", Fore.RED, assistant_reply) + assistant_reply_json = {} + assistant_thoughts_reasoning = None assistant_thoughts_plan = None assistant_thoughts_speak = None @@ -90,10 +98,6 @@ def print_assistant_thoughts(assistant_reply): except json.decoder.JSONDecodeError: print_to_console("Error: Invalid JSON\n", Fore.RED, assistant_reply) - # All other errors, return "Error: + error message" - except Exception as e: - call_stack = traceback.format_exc() - print_to_console("Error: \n", Fore.RED, call_stack) def load_variables(config_file="config.yaml"): From 570c161e5e78a7edee74aacfc1164efa26680d1d Mon Sep 17 00:00:00 2001 From: yousefissa Date: Mon, 3 Apr 2023 22:21:42 -0700 Subject: [PATCH 05/11] add final exception handling back --- scripts/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/main.py b/scripts/main.py index a1c08018..86afec39 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -98,6 +98,10 @@ def print_assistant_thoughts(assistant_reply): except json.decoder.JSONDecodeError: print_to_console("Error: Invalid JSON\n", Fore.RED, assistant_reply) + # All other errors, return "Error: + error message" + except Exception as e: + call_stack = traceback.format_exc() + print_to_console("Error: \n", Fore.RED, call_stack) def load_variables(config_file="config.yaml"): From 68e4af8685dac029fc86ab9c43dcd451c1d96758 Mon Sep 17 00:00:00 2001 From: Master Blood Date: Mon, 3 Apr 2023 22:38:01 -0700 Subject: [PATCH 06/11] Added a default (free) library for text to speech Adds the gTTS (Google Text-to-Speech) Python library as a fallback for text-to-speech conversion in the speak.py file. The changes were made to ensure that users can still convert text to speech even if the ElevenLabs API key is not set or if the API encounters an error. Additionally, the requirements.txt file has been updated to include the new gTTS dependency. --- requirements.txt | 1 + scripts/speak.py | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 063931a9..7961106b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ pyyaml==6.0 readability-lxml==0.8.1 requests tiktoken==0.3.3 +gTTS==2.3.1 docker googlesearch-python google-api-python-client #(https://developers.google.com/custom-search/v1/overview) diff --git a/scripts/speak.py b/scripts/speak.py index 2fbcbed2..6fef41f8 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -3,6 +3,8 @@ from playsound import playsound import requests from config import Config cfg = Config() +import gtts + # TODO: Nicer names for these ids voices = ["ErXwobaYiN019PkySvjV", "EXAVITQu4vr4xnSDxMaL"] @@ -12,10 +14,9 @@ tts_headers = { "xi-api-key": cfg.elevenlabs_api_key } -def say_text(text, voice_index=0): +def eleven_labs_speech(text, voice_index=0): tts_url = "https://api.elevenlabs.io/v1/text-to-speech/{voice_id}".format( voice_id=voices[voice_index]) - formatted_message = {"text": text} response = requests.post( tts_url, headers=tts_headers, json=formatted_message) @@ -24,8 +25,24 @@ def say_text(text, voice_index=0): with open("speech.mpeg", "wb") as f: f.write(response.content) playsound("speech.mpeg") - # Delete audio file os.remove("speech.mpeg") + return True else: print("Request failed with status code:", response.status_code) print("Response content:", response.content) + return False + +def gtts_speech(text): + tts = gtts.gTTS(text) + tts.save("speech.mp3") + playsound("speech.mp3") + os.remove("speech.mp3") + +def say_text(text, voice_index=0): + if not cfg.elevenlabs_api_key: + gtts_speech(text) + else: + success = eleven_labs_speech() + if not success: + gtts_speech(text) + From 4650882d971a8edd2ac3ae29eef9bbdb210baeeb Mon Sep 17 00:00:00 2001 From: Zhaofeng Miao <522856232@qq.com> Date: Tue, 4 Apr 2023 16:37:23 +0800 Subject: [PATCH 07/11] fix(prompt): fix typos --- scripts/data/prompt.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/data/prompt.txt b/scripts/data/prompt.txt index d17fa27a..2cb73a8d 100644 --- a/scripts/data/prompt.txt +++ b/scripts/data/prompt.txt @@ -1,6 +1,6 @@ CONSTRAINTS: -1. ~4000 word limit for memory. Your memory is short, so immidiately save important information to long term memory and code to files. +1. ~4000 word limit for memory. Your memory is short, so immediately save important information to long term memory and code to files. 2. No user assistance COMMANDS: @@ -34,9 +34,9 @@ RESOURCES: PERFORMANCE EVALUATION: 1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities. -2. Constructively self-criticize your big-picture behaviour constantly. +2. Constructively self-criticize your big-picture behavior constantly. 3. Reflect on past decisions and strategies to refine your approach. -4. Every command has a cost, so be smart and efficent. Aim to complete tasks in the least number of steps. +4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps. You should only respond in JSON format as described below @@ -58,4 +58,4 @@ RESPONSE FORMAT: } } -Ensure the response can be parsed by Python json.loads \ No newline at end of file +Ensure the response can be parsed by Python json.loads From 4c66cd6f4a4e81aee56a87a1331ba7f92b70857c Mon Sep 17 00:00:00 2001 From: Toran Bruce Richards Date: Tue, 4 Apr 2023 10:00:40 +0100 Subject: [PATCH 08/11] Renames FOLDER to SRC_DIR --- scripts/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/data.py b/scripts/data.py index 62a36e12..f4d6eb0e 100644 --- a/scripts/data.py +++ b/scripts/data.py @@ -1,6 +1,6 @@ from pathlib import Path -FOLDER = Path(__file__).parent +SRC_DIR = Path(__file__).parent def load_prompt(): From 6d86444b6f67d853e6ce31015c0d179169896ade Mon Sep 17 00:00:00 2001 From: Toran Bruce Richards Date: Tue, 4 Apr 2023 10:00:53 +0100 Subject: [PATCH 09/11] Renames FOLDER to SRC_DIR --- scripts/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/data.py b/scripts/data.py index f4d6eb0e..bb4b296e 100644 --- a/scripts/data.py +++ b/scripts/data.py @@ -6,7 +6,7 @@ SRC_DIR = Path(__file__).parent def load_prompt(): try: # Load the promt from data/prompt.txt - with open(FOLDER / "data/prompt.txt", "r") as prompt_file: + with open(SRC_DIR/ "data/prompt.txt", "r") as prompt_file: prompt = prompt_file.read() return prompt From 8b3c2fee2e7530fb77f5493fffa6cc9c4918508d Mon Sep 17 00:00:00 2001 From: Toran Bruce Richards Date: Tue, 4 Apr 2023 10:03:30 +0100 Subject: [PATCH 10/11] Update scripts/data.py --- scripts/data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/data.py b/scripts/data.py index 7969d69c..a6ffdadf 100644 --- a/scripts/data.py +++ b/scripts/data.py @@ -11,7 +11,6 @@ def load_prompt(): # Load the promt from data/prompt.txt with open(SRC_DIR/ "data/prompt.txt", "r") as prompt_file: - prompt = prompt_file.read() return prompt From 4d4ff658abceeb5b38a2fe8dc43ce2749d82cf4a Mon Sep 17 00:00:00 2001 From: Toran Bruce Richards Date: Tue, 4 Apr 2023 10:04:02 +0100 Subject: [PATCH 11/11] Update scripts/data.py --- scripts/data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/data.py b/scripts/data.py index a6ffdadf..72a6bbfc 100644 --- a/scripts/data.py +++ b/scripts/data.py @@ -9,7 +9,6 @@ def load_prompt(): data_dir = file_dir / "data" prompt_file = data_dir / "prompt.txt" # Load the promt from data/prompt.txt - with open(SRC_DIR/ "data/prompt.txt", "r") as prompt_file: prompt = prompt_file.read()