From 0573b2ade6cb44927d0702bdd276f01405ee33d9 Mon Sep 17 00:00:00 2001 From: DawgZter Date: Thu, 6 Apr 2023 23:17:42 +1000 Subject: [PATCH 01/30] Update Pinecone API Key Setup instructions for clarity Minor improvement in sentence clarity for Pinecone setup instructions. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a89c5d03b7e2..7e3749005776 100644 --- a/README.md +++ b/README.md @@ -142,8 +142,7 @@ export CUSTOM_SEARCH_ENGINE_ID="YOUR_CUSTOM_SEARCH_ENGINE_ID" ## 🌲 Pinecone API Key Setup -Pinecone enable a vector based memory so a vast memory can be stored and only relevant memories -are loaded for the agent at any given time. +Pinecone enables the storage of vast amounts of vector-based memory, allowing for only relevant memories to be loaded for the agent at any given time. 1. Go to app.pinecone.io and make an account if you don't already have one. 2. Choose the `Starter` plan to avoid being charged. From 287a76b03c36e3cd8458c7dc6e414fd71b8259fc Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Sun, 9 Apr 2023 10:04:03 +0100 Subject: [PATCH 02/30] add basic logging --- scripts/main.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/main.py b/scripts/main.py index 10f9d0dcaa0b..61d178d739db 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -16,7 +16,15 @@ import traceback import yaml import argparse +import logging +def configure_logging(): + logging.basicConfig(filename='log.txt', + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%H:%M:%S', + level=logging.DEBUG) + return logging.getLogger('AutoGPT') def print_to_console( title, @@ -26,10 +34,12 @@ def print_to_console( min_typing_speed=0.05, max_typing_speed=0.01): global cfg + global logger if speak_text and cfg.speak_mode: speak.say_text(f"{title}. {content}") print(title_color + title + " " + Style.RESET_ALL, end="") if content: + logger.info(title + ': ' + content) if isinstance(content, list): content = " ".join(content) words = content.split() @@ -270,6 +280,7 @@ def parse_arguments(): # TODO: fill in llm values here cfg = Config() +logger = configure_logging() parse_arguments() ai_name = "" prompt = construct_prompt() From b87d126e324059db3b47863dbe8e5d852234196b Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Sun, 9 Apr 2023 10:06:30 +0100 Subject: [PATCH 03/30] update print_to_console to log to a text file Uses python logging module to output progress to a text file log.txt --- scripts/main.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/main.py b/scripts/main.py index 10f9d0dcaa0b..d9b7204c2535 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -16,7 +16,15 @@ import traceback import yaml import argparse +import logging +def configure_logging(): + logging.basicConfig(filename='log.txt', + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%H:%M:%S', + level=logging.DEBUG) + return logging.getLogger('AutoGPT') def print_to_console( title, @@ -26,10 +34,12 @@ def print_to_console( min_typing_speed=0.05, max_typing_speed=0.01): global cfg + global logger if speak_text and cfg.speak_mode: speak.say_text(f"{title}. {content}") print(title_color + title + " " + Style.RESET_ALL, end="") if content: + logger.info(title + ': ' + content) if isinstance(content, list): content = " ".join(content) words = content.split() @@ -270,6 +280,7 @@ def parse_arguments(): # TODO: fill in llm values here cfg = Config() +logger = configure_logging() parse_arguments() ai_name = "" prompt = construct_prompt() @@ -355,7 +366,7 @@ def parse_arguments(): f"COMMAND = {Fore.CYAN}{command_name}{Style.RESET_ALL} ARGUMENTS = {Fore.CYAN}{arguments}{Style.RESET_ALL}") # Execute command - if command_name.lower() == "error": + if command_name.lower().startswith( "error" ): result = f"Command {command_name} threw the following error: " + arguments elif command_name == "human_feedback": result = f"Human feedback: {user_input}" @@ -381,3 +392,4 @@ def parse_arguments(): "system", "Unable to execute command")) print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") + From 41f5cd6b389d4999c081691577b6d90087371780 Mon Sep 17 00:00:00 2001 From: Sma Das Date: Sun, 9 Apr 2023 20:53:32 -0400 Subject: [PATCH 04/30] Created `utils.py` --- scripts/utils.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 scripts/utils.py diff --git a/scripts/utils.py b/scripts/utils.py new file mode 100644 index 000000000000..bab9ac9684a7 --- /dev/null +++ b/scripts/utils.py @@ -0,0 +1,6 @@ +def clean_input(prompt: str=''): + try: + return input(prompt) + except KeyboardInterrupt: + exit(0) + From 9ef82275cad16080e313767fb4e8e424a371efe2 Mon Sep 17 00:00:00 2001 From: Sma Das Date: Sun, 9 Apr 2023 20:55:38 -0400 Subject: [PATCH 05/30] Updated `main.py` to use `clean_input` --- scripts/main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index f96afeb16341..038ed2db83dd 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -1,6 +1,7 @@ import json import random import commands as cmd +import utils from memory import get_memory import data import chat @@ -119,12 +120,12 @@ def load_variables(config_file="config.yaml"): # Prompt the user for input if config file is missing or empty values if not ai_name: - ai_name = input("Name your AI: ") + ai_name = utils.clean_input("Name your AI: ") if ai_name == "": ai_name = "Entrepreneur-GPT" if not ai_role: - ai_role = input(f"{ai_name} is: ") + ai_role = utils.clean_input(f"{ai_name} is: ") if ai_role == "": ai_role = "an AI designed to autonomously develop and run businesses with the sole goal of increasing your net worth." @@ -134,7 +135,7 @@ def load_variables(config_file="config.yaml"): print("Enter nothing to load defaults, enter nothing when finished.") ai_goals = [] for i in range(5): - ai_goal = input(f"Goal {i+1}: ") + ai_goal = utils.clean_input(f"Goal {i+1}: ") if ai_goal == "": break ai_goals.append(ai_goal) @@ -166,7 +167,7 @@ def construct_prompt(): Fore.GREEN, f"Would you like me to return to being {config.ai_name}?", speak_text=True) - should_continue = input(f"""Continue with the last settings? + should_continue = utils.clean_input(f"""Continue with the last settings? Name: {config.ai_name} Role: {config.ai_role} Goals: {config.ai_goals} @@ -200,7 +201,7 @@ def prompt_user(): "Name your AI: ", Fore.GREEN, "For example, 'Entrepreneur-GPT'") - ai_name = input("AI Name: ") + ai_name = utils.clean_input("AI Name: ") if ai_name == "": ai_name = "Entrepreneur-GPT" @@ -215,7 +216,7 @@ def prompt_user(): "Describe your AI's role: ", Fore.GREEN, "For example, 'an AI designed to autonomously develop and run businesses with the sole goal of increasing your net worth.'") - ai_role = input(f"{ai_name} is: ") + ai_role = utils.clean_input(f"{ai_name} is: ") if ai_role == "": ai_role = "an AI designed to autonomously develop and run businesses with the sole goal of increasing your net worth." @@ -227,7 +228,7 @@ def prompt_user(): print("Enter nothing to load defaults, enter nothing when finished.", flush=True) ai_goals = [] for i in range(5): - ai_goal = input(f"{Fore.LIGHTBLUE_EX}Goal{Style.RESET_ALL} {i+1}: ") + ai_goal = utils.clean_input(f"{Fore.LIGHTBLUE_EX}Goal{Style.RESET_ALL} {i+1}: ") if ai_goal == "": break ai_goals.append(ai_goal) @@ -323,7 +324,7 @@ def parse_arguments(): f"Enter 'y' to authorise command, 'y -N' to run N continuous commands, 'n' to exit program, or enter feedback for {ai_name}...", flush=True) while True: - console_input = input(Fore.MAGENTA + "Input:" + Style.RESET_ALL) + console_input = utils.clean_input(Fore.MAGENTA + "Input:" + Style.RESET_ALL) if console_input.lower() == "y": user_input = "GENERATE NEXT COMMAND JSON" break From 34560901175de1b2bd3d7b855c52876b099b59c2 Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 04:21:23 +0200 Subject: [PATCH 06/30] replace gtts with macos tts --- scripts/speak.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/scripts/speak.py b/scripts/speak.py index 13517d366f9a..eab7b6601fc0 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -3,11 +3,12 @@ import requests from config import Config cfg = Config() -import gtts +# Remove the import of gtts +# import gtts -# TODO: Nicer names for these ids -voices = ["ErXwobaYiN019PkySvjV", "EXAVITQu4vr4xnSDxMaL"] +# Change voices to macOS voice identifiers +voices = ["com.apple.speech.synthesis.voice.siri_female", "com.apple.speech.synthesis.voice.siri_male"] tts_headers = { "Content-Type": "application/json", @@ -32,17 +33,14 @@ def eleven_labs_speech(text, voice_index=0): 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") +# Use macOS built-in TTS instead of gtts +def macos_tts_speech(text, voice_index=1): + os.system(f'say "{text}"') def say_text(text, voice_index=0): if not cfg.elevenlabs_api_key: - gtts_speech(text) + macos_tts_speech(text, voice_index) else: success = eleven_labs_speech(text, voice_index) if not success: - gtts_speech(text) - + macos_tts_speech(text, voice_index) From 33c8fe627a58429942e8219b5a79d264ee680ae0 Mon Sep 17 00:00:00 2001 From: pratiksinghchauhan Date: Mon, 10 Apr 2023 11:39:52 +0530 Subject: [PATCH 07/30] improve performance and removed code duplication --- scripts/browse.py | 19 ++++++++----------- scripts/commands.py | 13 +++++++------ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/scripts/browse.py b/scripts/browse.py index 0fda3d7b06ab..70f754e0b63c 100644 --- a/scripts/browse.py +++ b/scripts/browse.py @@ -5,14 +5,17 @@ cfg = Config() -def scrape_text(url): +def get_website_content(url): response = requests.get(url, headers=cfg.user_agent_header) - # Check if the response contains an HTTP error if response.status_code >= 400: return "Error: HTTP " + str(response.status_code) + " error" + return response + - soup = BeautifulSoup(response.text, "html.parser") + +def scrape_text(website_content): + soup = BeautifulSoup(website_content.text, "html.parser") for script in soup(["script", "style"]): script.extract() @@ -39,14 +42,8 @@ def format_hyperlinks(hyperlinks): return formatted_links -def scrape_links(url): - response = requests.get(url, headers=cfg.user_agent_header) - - # Check if the response contains an HTTP error - if response.status_code >= 400: - return "error" - - soup = BeautifulSoup(response.text, "html.parser") +def scrape_links(website_content): + soup = BeautifulSoup(website_content.text, "html.parser") for script in soup(["script", "style"]): script.extract() diff --git a/scripts/commands.py b/scripts/commands.py index ba5383957abe..4f94cebbbebc 100644 --- a/scripts/commands.py +++ b/scripts/commands.py @@ -163,8 +163,9 @@ def google_official_search(query, num_results=8): return search_results_links def browse_website(url, question): - summary = get_text_summary(url, question) - links = get_hyperlinks(url) + website_content = browse.get_website_content(url) + summary = get_text_summary(website_content, question) + links = get_hyperlinks(website_content) # Limit links to 5 if len(links) > 5: @@ -175,14 +176,14 @@ def browse_website(url, question): return result -def get_text_summary(url, question): - text = browse.scrape_text(url) +def get_text_summary(website_content, question): + text = browse.scrape_text(website_content) summary = browse.summarize_text(text, question) return """ "Result" : """ + summary -def get_hyperlinks(url): - link_list = browse.scrape_links(url) +def get_hyperlinks(website_content): + link_list = browse.scrape_links(website_content) return link_list From 13467259b4722b45cba098a225609f8e09bbef3f Mon Sep 17 00:00:00 2001 From: pratiksinghchauhan Date: Mon, 10 Apr 2023 12:07:37 +0530 Subject: [PATCH 08/30] fix: #323 Error communicating with OpenAI --- .env.template | 6 +++--- README.md | 2 +- scripts/config.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.env.template b/.env.template index 525cd61c5f4e..8dcdc37ccb66 100644 --- a/.env.template +++ b/.env.template @@ -7,8 +7,8 @@ FAST_LLM_MODEL="gpt-3.5-turbo" GOOGLE_API_KEY= CUSTOM_SEARCH_ENGINE_ID= USE_AZURE=False -OPENAI_API_BASE=your-base-url-for-azure -OPENAI_API_VERSION=api-version-for-azure -OPENAI_DEPLOYMENT_ID=deployment-id-for-azure +OPENAI_AZURE_API_BASE=your-base-url-for-azure +OPENAI_AZURE_API_VERSION=api-version-for-azure +OPENAI_AZURE_DEPLOYMENT_ID=deployment-id-for-azure IMAGE_PROVIDER=dalle HUGGINGFACE_API_TOKEN= \ No newline at end of file diff --git a/README.md b/README.md index ba80818d0e9f..f581274c5cf6 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ pip install -r requirements.txt 4. Rename `.env.template` to `.env` and fill in your `OPENAI_API_KEY`. If you plan to use Speech Mode, fill in your `ELEVEN_LABS_API_KEY` as well. - Obtain your OpenAI API key from: https://platform.openai.com/account/api-keys. - Obtain your ElevenLabs API key from: https://elevenlabs.io. You can view your xi-api-key using the "Profile" tab on the website. - - If you want to use GPT on an Azure instance, set `USE_AZURE` to `True` and provide the `OPENAI_API_BASE`, `OPENAI_API_VERSION` and `OPENAI_DEPLOYMENT_ID` values as explained here: https://pypi.org/project/openai/ in the `Microsoft Azure Endpoints` section + - If you want to use GPT on an Azure instance, set `USE_AZURE` to `True` and provide the `OPENAI_AZURE_API_BASE`, `OPENAI_AZURE_API_VERSION` and `OPENAI_AZURE_DEPLOYMENT_ID` values as explained here: https://pypi.org/project/openai/ in the `Microsoft Azure Endpoints` section ## 🔧 Usage diff --git a/scripts/config.py b/scripts/config.py index 4d7adec1c0f5..0e8ea3203b37 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -44,9 +44,9 @@ def __init__(self): self.use_azure = False self.use_azure = os.getenv("USE_AZURE") == 'True' if self.use_azure: - self.openai_api_base = os.getenv("OPENAI_API_BASE") - self.openai_api_version = os.getenv("OPENAI_API_VERSION") - self.openai_deployment_id = os.getenv("OPENAI_DEPLOYMENT_ID") + self.openai_api_base = os.getenv("OPENAI_AZURE_API_BASE") + self.openai_api_version = os.getenv("OPENAI_AZURE_API_VERSION") + self.openai_deployment_id = os.getenv("OPENAI_AZURE_DEPLOYMENT_ID") openai.api_type = "azure" openai.api_base = self.openai_api_base openai.api_version = self.openai_api_version From 156739788aa471304fc5c6eaf9254cd4619fa459 Mon Sep 17 00:00:00 2001 From: pratiksinghchauhan Date: Mon, 10 Apr 2023 12:31:37 +0530 Subject: [PATCH 09/30] removed un necessary changes --- scripts/browse.py | 28 +++++++++++++++++++--------- scripts/commands.py | 15 ++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/scripts/browse.py b/scripts/browse.py index 70f754e0b63c..7eeaaf4d9414 100644 --- a/scripts/browse.py +++ b/scripts/browse.py @@ -5,17 +5,21 @@ cfg = Config() -def get_website_content(url): - response = requests.get(url, headers=cfg.user_agent_header) +def scrape_text(url): + # Most basic check if the URL is valid: + if not url.startswith('http'): + return "Error: Invalid URL" + + try: + response = requests.get(url, headers=cfg.user_agent_header) + except requests.exceptions.RequestException as e: + return "Error: " + str(e) + # Check if the response contains an HTTP error if response.status_code >= 400: return "Error: HTTP " + str(response.status_code) + " error" - return response - - -def scrape_text(website_content): - soup = BeautifulSoup(website_content.text, "html.parser") + soup = BeautifulSoup(response.text, "html.parser") for script in soup(["script", "style"]): script.extract() @@ -42,8 +46,14 @@ def format_hyperlinks(hyperlinks): return formatted_links -def scrape_links(website_content): - soup = BeautifulSoup(website_content.text, "html.parser") +def scrape_links(url): + response = requests.get(url, headers=cfg.user_agent_header) + + # Check if the response contains an HTTP error + if response.status_code >= 400: + return "error" + + soup = BeautifulSoup(response.text, "html.parser") for script in soup(["script", "style"]): script.extract() diff --git a/scripts/commands.py b/scripts/commands.py index 4f94cebbbebc..76139b5c6250 100644 --- a/scripts/commands.py +++ b/scripts/commands.py @@ -106,6 +106,8 @@ def execute_command(command_name, arguments): return execute_python_file(arguments["file"]) elif command_name == "generate_image": return generate_image(arguments["prompt"]) + elif command_name == "do_nothing": + return "No action performed." elif command_name == "task_complete": shutdown() else: @@ -163,9 +165,8 @@ def google_official_search(query, num_results=8): return search_results_links def browse_website(url, question): - website_content = browse.get_website_content(url) - summary = get_text_summary(website_content, question) - links = get_hyperlinks(website_content) + summary = get_text_summary(url, question) + links = get_hyperlinks(url) # Limit links to 5 if len(links) > 5: @@ -176,14 +177,14 @@ def browse_website(url, question): return result -def get_text_summary(website_content, question): - text = browse.scrape_text(website_content) +def get_text_summary(url, question): + text = browse.scrape_text(url) summary = browse.summarize_text(text, question) return """ "Result" : """ + summary -def get_hyperlinks(website_content): - link_list = browse.scrape_links(website_content) +def get_hyperlinks(url): + link_list = browse.scrape_links(url) return link_list From 9cea7c0f61ce4ec6c5b7b087678f55012c249f45 Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 08:11:54 +0100 Subject: [PATCH 10/30] Update main.py --- scripts/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index 6ec026d323da..2f134e0cc8cd 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -395,5 +395,5 @@ def parse_arguments(): chat.create_chat_message( "system", "Unable to execute command")) print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") - - + + From 2fb06a3db5051808d5529f48ba074f62c1323c8f Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 08:14:48 +0100 Subject: [PATCH 11/30] trying to get the right amount of spacing / newlines at the end of main.py! --- scripts/main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index 2f134e0cc8cd..1bb708c42974 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -395,5 +395,3 @@ def parse_arguments(): chat.create_chat_message( "system", "Unable to execute command")) print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") - - From 2facc3e2cb65e72f21e329eb691f445be8599295 Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 11:11:03 +0200 Subject: [PATCH 12/30] add config for mac os tts --- .env.template | 3 ++- scripts/speak.py | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.env.template b/.env.template index 525cd61c5f4e..f9a74c9ca4a3 100644 --- a/.env.template +++ b/.env.template @@ -11,4 +11,5 @@ OPENAI_API_BASE=your-base-url-for-azure OPENAI_API_VERSION=api-version-for-azure OPENAI_DEPLOYMENT_ID=deployment-id-for-azure IMAGE_PROVIDER=dalle -HUGGINGFACE_API_TOKEN= \ No newline at end of file +HUGGINGFACE_API_TOKEN= +USE_MAC_OS_TTS=False diff --git a/scripts/speak.py b/scripts/speak.py index eab7b6601fc0..1ffad846413c 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -3,12 +3,10 @@ import requests from config import Config cfg = Config() +import gtts -# Remove the import of gtts -# import gtts - -# Change voices to macOS voice identifiers -voices = ["com.apple.speech.synthesis.voice.siri_female", "com.apple.speech.synthesis.voice.siri_male"] +# TODO: Nicer names for these ids +voices = ["ErXwobaYiN019PkySvjV", "EXAVITQu4vr4xnSDxMaL"] tts_headers = { "Content-Type": "application/json", @@ -33,14 +31,21 @@ def eleven_labs_speech(text, voice_index=0): print("Response content:", response.content) return False -# Use macOS built-in TTS instead of gtts -def macos_tts_speech(text, voice_index=1): +def gtts_speech(text): + tts = gtts.gTTS(text) + tts.save("speech.mp3") + playsound("speech.mp3") + os.remove("speech.mp3") + +def macos_tts_speech(text): os.system(f'say "{text}"') def say_text(text, voice_index=0): if not cfg.elevenlabs_api_key: - macos_tts_speech(text, voice_index) + if cfg.use_mac_os_tts == 'True': + macos_tts_speech(text) + gtts(text) else: success = eleven_labs_speech(text, voice_index) if not success: - macos_tts_speech(text, voice_index) + gtts_speech()(text) From 205a0c84cf0ba8690a0b49a0a498ceedb5ac987d Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 11:18:17 +0200 Subject: [PATCH 13/30] fix config read --- scripts/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/config.py b/scripts/config.py index 4d7adec1c0f5..b15d6f909acb 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -52,6 +52,8 @@ def __init__(self): openai.api_version = self.openai_api_version self.elevenlabs_api_key = os.getenv("ELEVENLABS_API_KEY") + + self.use_mac_os_tts = os.getenv("USE_MAC_OS_TTS") self.google_api_key = os.getenv("GOOGLE_API_KEY") self.custom_search_engine_id = os.getenv("CUSTOM_SEARCH_ENGINE_ID") From 64eb882947b09f4ad6c0e024fa327051c9c308be Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 11:20:58 +0200 Subject: [PATCH 14/30] fix code messup of assistant --- scripts/config.py | 1 + scripts/speak.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/config.py b/scripts/config.py index b15d6f909acb..e9168efe5d90 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -53,6 +53,7 @@ def __init__(self): self.elevenlabs_api_key = os.getenv("ELEVENLABS_API_KEY") + self.use_mac_os_tts = False self.use_mac_os_tts = os.getenv("USE_MAC_OS_TTS") self.google_api_key = os.getenv("GOOGLE_API_KEY") diff --git a/scripts/speak.py b/scripts/speak.py index 1ffad846413c..cdb92e0786df 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -44,7 +44,8 @@ def say_text(text, voice_index=0): if not cfg.elevenlabs_api_key: if cfg.use_mac_os_tts == 'True': macos_tts_speech(text) - gtts(text) + else: + gtts(text) else: success = eleven_labs_speech(text, voice_index) if not success: From 1946b564a1d870029c2164914fd815356b780062 Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 11:22:24 +0200 Subject: [PATCH 15/30] fix gtts_speech --- scripts/speak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/speak.py b/scripts/speak.py index cdb92e0786df..e5b839fdf182 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -45,7 +45,7 @@ def say_text(text, voice_index=0): if cfg.use_mac_os_tts == 'True': macos_tts_speech(text) else: - gtts(text) + gtts_speech(text) else: success = eleven_labs_speech(text, voice_index) if not success: From ed16bba0ca0ae57c8d9ad1fcaae9555b3d7ed264 Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 11:22:47 +0200 Subject: [PATCH 16/30] fix gtts_speech --- scripts/speak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/speak.py b/scripts/speak.py index e5b839fdf182..485381dc5c00 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -49,4 +49,4 @@ def say_text(text, voice_index=0): else: success = eleven_labs_speech(text, voice_index) if not success: - gtts_speech()(text) + gtts_speech(text) From ec239734c59dd7b0feb9261fc0d4a8008308c72b Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 14:15:30 +0200 Subject: [PATCH 17/30] fix whitespace --- scripts/speak.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/speak.py b/scripts/speak.py index ed52a433abdc..c48d090bd10f 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -47,6 +47,7 @@ def say_text(text, voice_index=0): macos_tts_speech(text) else: gtts_speech(text) + else: success = eleven_labs_speech(text, voice_index) if not success: From 7e9941e5b1b560f33e2ad4ed7d05c47af961ec75 Mon Sep 17 00:00:00 2001 From: Wlad Date: Mon, 10 Apr 2023 14:17:18 +0200 Subject: [PATCH 18/30] fix whitespace --- scripts/speak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/speak.py b/scripts/speak.py index c48d090bd10f..c47a9f75277d 100644 --- a/scripts/speak.py +++ b/scripts/speak.py @@ -47,8 +47,8 @@ def say_text(text, voice_index=0): macos_tts_speech(text) else: gtts_speech(text) - else: success = eleven_labs_speech(text, voice_index) if not success: gtts_speech(text) + From d304740f9d727b0561f76bcaa649a2800be98ba1 Mon Sep 17 00:00:00 2001 From: Phoebe Bright Date: Mon, 10 Apr 2023 14:17:56 +0100 Subject: [PATCH 19/30] Update .env.template Remove quotes for model variables that can lead to the model not being recognised and error num_tokens_from_messages() is not implemented for model --- .env.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.env.template b/.env.template index 525cd61c5f4e..8185cc66af8b 100644 --- a/.env.template +++ b/.env.template @@ -2,8 +2,8 @@ PINECONE_API_KEY=your-pinecone-api-key PINECONE_ENV=your-pinecone-region OPENAI_API_KEY=your-openai-api-key ELEVENLABS_API_KEY=your-elevenlabs-api-key -SMART_LLM_MODEL="gpt-4" -FAST_LLM_MODEL="gpt-3.5-turbo" +SMART_LLM_MODEL=gpt-4 +FAST_LLM_MODEL=gpt-3.5-turbo GOOGLE_API_KEY= CUSTOM_SEARCH_ENGINE_ID= USE_AZURE=False @@ -11,4 +11,4 @@ OPENAI_API_BASE=your-base-url-for-azure OPENAI_API_VERSION=api-version-for-azure OPENAI_DEPLOYMENT_ID=deployment-id-for-azure IMAGE_PROVIDER=dalle -HUGGINGFACE_API_TOKEN= \ No newline at end of file +HUGGINGFACE_API_TOKEN= From fa8461be9de417a5b84322de116f02157a235a7e Mon Sep 17 00:00:00 2001 From: onekum <55006697+onekum@users.noreply.github.com> Date: Mon, 10 Apr 2023 09:21:43 -0400 Subject: [PATCH 20/30] Restrict browse from accessing local files --- scripts/browse.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/browse.py b/scripts/browse.py index c15214e7dd4b..4a73d92320d8 100644 --- a/scripts/browse.py +++ b/scripts/browse.py @@ -11,6 +11,10 @@ def scrape_text(url): if not url.startswith('http'): return "Error: Invalid URL" + # Restrict access to local files + if url.startswith('file://') or url.startswith('file://localhost'): + return "Error: Access to local files is restricted" + try: response = requests.get(url, headers=cfg.user_agent_header) except requests.exceptions.RequestException as e: @@ -126,4 +130,4 @@ def summarize_text(text, question): max_tokens=300, ) - return final_summary \ No newline at end of file + return final_summary From 527e084f39c7c05406a42c9b83ebd87c3194b231 Mon Sep 17 00:00:00 2001 From: yoshikouki Date: Mon, 10 Apr 2023 22:57:41 +0900 Subject: [PATCH 21/30] Remove unnecessary assignments --- scripts/commands.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/commands.py b/scripts/commands.py index 073ecc56a97b..ce5d04ff48ad 100644 --- a/scripts/commands.py +++ b/scripts/commands.py @@ -42,9 +42,6 @@ def get_command(response): # Use an empty dictionary if 'args' field is not present in 'command' object arguments = command.get("args", {}) - if not arguments: - arguments = {} - return command_name, arguments except json.decoder.JSONDecodeError: return "Error:", "Invalid JSON" From cd07115a39fa30f28c4f85ad4c776a2cfb817260 Mon Sep 17 00:00:00 2001 From: Sma Das Date: Mon, 10 Apr 2023 11:29:15 -0400 Subject: [PATCH 22/30] Removed trailing whitespace --- scripts/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/main.py b/scripts/main.py index bd1c088d20cb..71e72cd4c3e9 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -138,7 +138,7 @@ def load_variables(config_file="config.yaml"): if ai_name == "": ai_name = "Entrepreneur-GPT" - if not ai_role: + if not ai_role: ai_role = utils.clean_input(f"{ai_name} is: ") if ai_role == "": ai_role = "an AI designed to autonomously develop and run businesses with the sole goal of increasing your net worth." @@ -182,7 +182,7 @@ def construct_prompt(): Fore.GREEN, f"Would you like me to return to being {config.ai_name}?", speak_text=True) - should_continue = utils.clean_input(f"""Continue with the last settings? + should_continue = utils.clean_input(f"""Continue with the last settings? Name: {config.ai_name} Role: {config.ai_role} Goals: {config.ai_goals} @@ -282,7 +282,7 @@ def parse_arguments(): if args.debug: print_to_console("Debug Mode: ", Fore.GREEN, "ENABLED") - cfg.set_debug_mode(True) + cfg.set_debug_mode(True) if args.gpt3only: print_to_console("GPT3.5 Only Mode: ", Fore.GREEN, "ENABLED") From 5c1c3f9c7e9be6cfec4cca255123f81756ba0d10 Mon Sep 17 00:00:00 2001 From: Sma Das Date: Mon, 10 Apr 2023 11:31:43 -0400 Subject: [PATCH 23/30] Added exit message on `KeyboardInterrupt` --- scripts/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/utils.py b/scripts/utils.py index bab9ac9684a7..5039796fbd18 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -2,5 +2,7 @@ def clean_input(prompt: str=''): try: return input(prompt) except KeyboardInterrupt: + print("You interrupted Auto-GPT") + print("Quitting...") exit(0) From b60c7518b0640ae224f989a2cd964b37e0ca90bf Mon Sep 17 00:00:00 2001 From: onekum <55006697+onekum@users.noreply.github.com> Date: Mon, 10 Apr 2023 12:10:28 -0400 Subject: [PATCH 24/30] Rework local file address blocks add `def check_local_file_access`, which defines and checks for local file address prefixes; use it to restrict access --- scripts/browse.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/browse.py b/scripts/browse.py index 4a73d92320d8..09f376a70a29 100644 --- a/scripts/browse.py +++ b/scripts/browse.py @@ -5,6 +5,11 @@ cfg = Config() +# Define and check for local file address prefixes +def check_local_file_access(url): + local_prefixes = ['file:///', 'file://localhost', 'http://localhost', 'https://localhost'] + return any(url.startswith(prefix) for prefix in local_prefixes) + def scrape_text(url): """Scrape text from a webpage""" # Most basic check if the URL is valid: @@ -12,7 +17,7 @@ def scrape_text(url): return "Error: Invalid URL" # Restrict access to local files - if url.startswith('file://') or url.startswith('file://localhost'): + if check_local_file_access(url): return "Error: Access to local files is restricted" try: From c9701a330294fc9eba1de3669ceae313fc735ea7 Mon Sep 17 00:00:00 2001 From: Andy Melnikov Date: Mon, 10 Apr 2023 18:17:11 +0200 Subject: [PATCH 25/30] Remove trailing whitespace throughout --- scripts/ai_config.py | 10 +++++----- scripts/ai_functions.py | 2 +- scripts/config.py | 2 +- scripts/main.py | 2 +- tests/test_browse_scrape_text.py | 12 ++++++------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/ai_config.py b/scripts/ai_config.py index 8fabf3dcee34..1d5832c18231 100644 --- a/scripts/ai_config.py +++ b/scripts/ai_config.py @@ -34,7 +34,7 @@ def __init__(self, ai_name: str="", ai_role: str="", ai_goals: list=[]) -> None: @classmethod def load(cls: object, config_file: str=SAVE_FILE) -> object: """ - Returns class object with parameters (ai_name, ai_role, ai_goals) loaded from yaml file if yaml file exists, + Returns class object with parameters (ai_name, ai_role, ai_goals) loaded from yaml file if yaml file exists, else returns class with no parameters. Parameters: @@ -42,7 +42,7 @@ def load(cls: object, config_file: str=SAVE_FILE) -> object: config_file (int): The path to the config yaml file. DEFAULT: "../ai_settings.yaml" Returns: - cls (object): A instance of given cls object + cls (object): A instance of given cls object """ try: @@ -61,11 +61,11 @@ def save(self, config_file: str=SAVE_FILE) -> None: """ Saves the class parameters to the specified file yaml file path as a yaml file. - Parameters: + Parameters: config_file(str): The path to the config yaml file. DEFAULT: "../ai_settings.yaml" Returns: - None + None """ config = {"ai_name": self.ai_name, "ai_role": self.ai_role, "ai_goals": self.ai_goals} @@ -76,7 +76,7 @@ def construct_full_prompt(self) -> str: """ Returns a prompt to the user with the class information in an organized fashion. - Parameters: + Parameters: None Returns: diff --git a/scripts/ai_functions.py b/scripts/ai_functions.py index dc774b37cbb6..8ad77441dc31 100644 --- a/scripts/ai_functions.py +++ b/scripts/ai_functions.py @@ -27,7 +27,7 @@ def evaluate_code(code: str) -> List[str]: def improve_code(suggestions: List[str], code: str) -> str: """ - A function that takes in code and suggestions and returns a response from create chat completion api call. + A function that takes in code and suggestions and returns a response from create chat completion api call. Parameters: suggestions (List): A list of suggestions around what needs to be improved. diff --git a/scripts/config.py b/scripts/config.py index 1eb74b2bc790..06af2b0586db 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -37,7 +37,7 @@ def __init__(self): self.continuous_mode = False self.speak_mode = False - self.fast_llm_model = os.getenv("FAST_LLM_MODEL", "gpt-3.5-turbo") + self.fast_llm_model = os.getenv("FAST_LLM_MODEL", "gpt-3.5-turbo") self.smart_llm_model = os.getenv("SMART_LLM_MODEL", "gpt-4") self.fast_token_limit = int(os.getenv("FAST_TOKEN_LIMIT", 4000)) self.smart_token_limit = int(os.getenv("SMART_TOKEN_LIMIT", 8000)) diff --git a/scripts/main.py b/scripts/main.py index 3dfcaa157e1c..4481b1ff2960 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -281,7 +281,7 @@ def parse_arguments(): if args.debug: print_to_console("Debug Mode: ", Fore.GREEN, "ENABLED") - cfg.set_debug_mode(True) + cfg.set_debug_mode(True) if args.gpt3only: print_to_console("GPT3.5 Only Mode: ", Fore.GREEN, "ENABLED") diff --git a/tests/test_browse_scrape_text.py b/tests/test_browse_scrape_text.py index 27ebc0f693a6..bfc3b4251d36 100644 --- a/tests/test_browse_scrape_text.py +++ b/tests/test_browse_scrape_text.py @@ -37,7 +37,7 @@ class TestScrapeText: - # Tests that scrape_text() returns the expected text when given a valid URL. + # Tests that scrape_text() returns the expected text when given a valid URL. def test_scrape_text_with_valid_url(self, mocker): # Mock the requests.get() method to return a response with expected text expected_text = "This is some sample text" @@ -50,7 +50,7 @@ def test_scrape_text_with_valid_url(self, mocker): url = "http://www.example.com" assert scrape_text(url) == expected_text - # Tests that the function returns an error message when an invalid or unreachable url is provided. + # Tests that the function returns an error message when an invalid or unreachable url is provided. def test_invalid_url(self, mocker): # Mock the requests.get() method to raise an exception mocker.patch("requests.get", side_effect=requests.exceptions.RequestException) @@ -60,7 +60,7 @@ def test_invalid_url(self, mocker): error_message = scrape_text(url) assert "Error:" in error_message - # Tests that the function returns an empty string when the html page contains no text to be scraped. + # Tests that the function returns an empty string when the html page contains no text to be scraped. def test_no_text(self, mocker): # Mock the requests.get() method to return a response with no text mock_response = mocker.Mock() @@ -72,7 +72,7 @@ def test_no_text(self, mocker): url = "http://www.example.com" assert scrape_text(url) == "" - # Tests that the function returns an error message when the response status code is an http error (>=400). + # Tests that the function returns an error message when the response status code is an http error (>=400). def test_http_error(self, mocker): # Mock the requests.get() method to return a response with a 404 status code mocker.patch('requests.get', return_value=mocker.Mock(status_code=404)) @@ -83,7 +83,7 @@ def test_http_error(self, mocker): # Check that the function returns an error message assert result == "Error: HTTP 404 error" - # Tests that scrape_text() properly handles HTML tags. + # Tests that scrape_text() properly handles HTML tags. def test_scrape_text_with_html_tags(self, mocker): # Create a mock response object with HTML containing tags html = "

This is bold text.

" @@ -96,4 +96,4 @@ def test_scrape_text_with_html_tags(self, mocker): result = scrape_text("https://www.example.com") # Check that the function properly handles HTML tags - assert result == "This is bold text." \ No newline at end of file + assert result == "This is bold text." From a5b48790fc8266de45f52c393799f9100c418909 Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 19:37:32 +0100 Subject: [PATCH 26/30] Delete ai_settings.yaml --- ai_settings.yaml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 ai_settings.yaml diff --git a/ai_settings.yaml b/ai_settings.yaml deleted file mode 100644 index 1271a6e211df..000000000000 --- a/ai_settings.yaml +++ /dev/null @@ -1,6 +0,0 @@ -ai_goals: -- Increase net worth -- Grow Twitter Account -- Develop and manage multiple businesses autonomously -ai_name: Test -ai_role: Test1 From 818920e22faa82cc91821102caef5312e0ea985e Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 19:48:42 +0100 Subject: [PATCH 27/30] restore default ai_settings --- ai_settings.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ai_settings.yaml diff --git a/ai_settings.yaml b/ai_settings.yaml new file mode 100644 index 000000000000..b37ba849f916 --- /dev/null +++ b/ai_settings.yaml @@ -0,0 +1,7 @@ +ai_goals: +- Increase net worth. +- Develop and manage multiple businesses autonomously. +- Play to your strengths as a Large Language Model. +ai_name: Entrepreneur-GPT +ai_role: an AI designed to autonomously develop and run businesses with the sole goal + of increasing your net worth. From c6bdb0f0baf14d84b349330d24d692470e0ff35d Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 19:50:13 +0100 Subject: [PATCH 28/30] remove trailing newline --- scripts/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/main.py b/scripts/main.py index 469a71c180d5..0ba652939c26 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -415,4 +415,4 @@ def parse_arguments(): full_message_history.append( chat.create_chat_message( "system", "Unable to execute command")) - print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") + print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") \ No newline at end of file From f69e46208e213090cbbf6c329e67466575975d62 Mon Sep 17 00:00:00 2001 From: Richard Beales Date: Mon, 10 Apr 2023 19:50:56 +0100 Subject: [PATCH 29/30] remove trailing newline --- scripts/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/main.py b/scripts/main.py index 0ba652939c26..ca75eb240da4 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -415,4 +415,5 @@ def parse_arguments(): full_message_history.append( chat.create_chat_message( "system", "Unable to execute command")) - print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") \ No newline at end of file + print_to_console("SYSTEM: ", Fore.YELLOW, "Unable to execute command") + From 3146d97a89e59502bfa05a95c64338b279fcfbe8 Mon Sep 17 00:00:00 2001 From: amit9021 Date: Mon, 10 Apr 2023 23:46:08 +0300 Subject: [PATCH 30/30] README pinecone link added --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 118131e46345..dae392c3ed56 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Your support is greatly appreciated ## 📋 Requirements - [Python 3.8 or later](https://www.tutorialspoint.com/how-to-install-python-in-windows) - OpenAI API key -- PINECONE API key +- [PINECONE API key](https://www.pinecone.io/) Optional: - ElevenLabs Key (If you want the AI to speak)