mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2025-12-18 06:24:20 +01:00
Merge branch 'master' into dev
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
OPENAI_API_KEY=your-openai-api-key
|
OPENAI_API_KEY=your-openai-api-key
|
||||||
ELEVENLABS_API_KEY=your-elevenlabs-api-key
|
ELEVENLABS_API_KEY=your-elevenlabs-api-key
|
||||||
SMART_LLM_MODEL="gpt-4"
|
SMART_LLM_MODEL="gpt-4"
|
||||||
FAST_LLM_MODEL="gpt-3.5-turbo"
|
FAST_LLM_MODEL="gpt-3.5-turbo"
|
||||||
|
GOOGLE_API_KEY=
|
||||||
|
CUSTOM_SEARCH_ENGINE_ID=
|
||||||
52
README.md
52
README.md
@@ -29,13 +29,22 @@ Your support is greatly appreciated
|
|||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [Features](#-features)
|
- [Auto-GPT: An Autonomous GPT-4 Experiment](#auto-gpt-an-autonomous-gpt-4-experiment)
|
||||||
- [Requirements](#-requirements)
|
- [Demo (30/03/2023):](#demo-30032023)
|
||||||
- [Installation](#-installation)
|
- [💖 Help Fund Auto-GPT's Development](#-help-fund-auto-gpts-development)
|
||||||
- [Usage](#-usage)
|
- [Table of Contents](#table-of-contents)
|
||||||
- [Limitations](#-limitations)
|
- [🚀 Features](#-features)
|
||||||
- [Disclaimer](#-disclaimer)
|
- [📋 Requirements](#-requirements)
|
||||||
- [Connect with Us on Twitter ](#-connect-with-us-on-twitter)
|
- [💾 Installation](#-installation)
|
||||||
|
- [🔧 Usage](#-usage)
|
||||||
|
- [🗣️ Speech Mode](#️-speech-mode)
|
||||||
|
- [🔍 Google API Keys Configuration](#-google-api-keys-configuration)
|
||||||
|
- [Setting up environment variables](#setting-up-environment-variables)
|
||||||
|
- [💀 Continuous Mode ⚠️](#-continuous-mode-️)
|
||||||
|
- [GPT3.5 ONLY Mode](#gpt35-only-mode)
|
||||||
|
- [⚠️ Limitations](#️-limitations)
|
||||||
|
- [🛡 Disclaimer](#-disclaimer)
|
||||||
|
- [🐦 Connect with Us on Twitter](#-connect-with-us-on-twitter)
|
||||||
|
|
||||||
|
|
||||||
## 🚀 Features
|
## 🚀 Features
|
||||||
@@ -100,6 +109,35 @@ python scripts/main.py --speak
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 🔍 Google API Keys Configuration
|
||||||
|
|
||||||
|
This section is optional, use the official google api if you are having issues with error 429 when running google search.
|
||||||
|
To use the `google_official_search` command, you need to set up your Google API keys in your environment variables.
|
||||||
|
|
||||||
|
1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
|
||||||
|
2. If you don't already have an account, create one and log in.
|
||||||
|
3. Create a new project by clicking on the "Select a Project" dropdown at the top of the page and clicking "New Project". Give it a name and click "Create".
|
||||||
|
4. Go to the [APIs & Services Dashboard](https://console.cloud.google.com/apis/dashboard) and click "Enable APIs and Services". Search for "Custom Search API" and click on it, then click "Enable".
|
||||||
|
5. Go to the [Credentials](https://console.cloud.google.com/apis/credentials) page and click "Create Credentials". Choose "API Key".
|
||||||
|
6. Copy the API key and set it as an environment variable named `GOOGLE_API_KEY` on your machine. See setting up environment variables below.
|
||||||
|
7. Go to the [Custom Search Engine](https://cse.google.com/cse/all) page and click "Add".
|
||||||
|
8. Set up your search engine by following the prompts. You can choose to search the entire web or specific sites.
|
||||||
|
9. Once you've created your search engine, click on "Control Panel" and then "Basics". Copy the "Search engine ID" and set it as an environment variable named `CUSTOM_SEARCH_ENGINE_ID` on your machine. See setting up environment variables below.
|
||||||
|
|
||||||
|
### Setting up environment variables
|
||||||
|
For Windows Users:
|
||||||
|
```
|
||||||
|
setx GOOGLE_API_KEY "YOUR_GOOGLE_API_KEY"
|
||||||
|
setx CUSTOM_SEARCH_ENGINE_ID "YOUR_CUSTOM_SEARCH_ENGINE_ID"
|
||||||
|
|
||||||
|
```
|
||||||
|
For macOS and Linux users:
|
||||||
|
```
|
||||||
|
export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"
|
||||||
|
export CUSTOM_SEARCH_ENGINE_ID="YOUR_CUSTOM_SEARCH_ENGINE_ID"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## 💀 Continuous Mode ⚠️
|
## 💀 Continuous Mode ⚠️
|
||||||
Run the AI **without** user authorisation, 100% automated.
|
Run the AI **without** user authorisation, 100% automated.
|
||||||
Continuous mode is not recommended.
|
Continuous mode is not recommended.
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ requests
|
|||||||
tiktoken==0.3.3
|
tiktoken==0.3.3
|
||||||
docker
|
docker
|
||||||
googlesearch-python
|
googlesearch-python
|
||||||
|
google-api-python-client #(https://developers.google.com/custom-search/v1/overview)
|
||||||
# Googlesearch python seems to be a bit cursed, anyone good at fixing thigns like this?
|
# Googlesearch python seems to be a bit cursed, anyone good at fixing thigns like this?
|
||||||
@@ -10,6 +10,9 @@ from file_operations import read_file, write_to_file, append_to_file, delete_fil
|
|||||||
from execute_code import execute_python_file
|
from execute_code import execute_python_file
|
||||||
from json_parser import fix_and_parse_json
|
from json_parser import fix_and_parse_json
|
||||||
from googlesearch import search
|
from googlesearch import search
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
from googleapiclient.errors import HttpError
|
||||||
|
|
||||||
cfg = Config()
|
cfg = Config()
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +49,13 @@ def execute_command(command_name, arguments):
|
|||||||
"""Execute the command and return the response"""
|
"""Execute the command and return the response"""
|
||||||
try:
|
try:
|
||||||
if command_name == "google":
|
if command_name == "google":
|
||||||
return google_search(arguments["input"])
|
|
||||||
|
# Check if the Google API key is set and use the official search method
|
||||||
|
# If the API key is not set or has only whitespaces, use the unofficial search method
|
||||||
|
if cfg.google_api_key and (cfg.google_api_key.strip() if cfg.google_api_key else None):
|
||||||
|
return google_official_search(arguments["input"])
|
||||||
|
else:
|
||||||
|
return google_search(arguments["input"])
|
||||||
elif command_name == "memory_add":
|
elif command_name == "memory_add":
|
||||||
return commit_memory(arguments["string"])
|
return commit_memory(arguments["string"])
|
||||||
elif command_name == "memory_del":
|
elif command_name == "memory_del":
|
||||||
@@ -112,6 +121,40 @@ def google_search(query, num_results=8):
|
|||||||
|
|
||||||
return json.dumps(search_results, ensure_ascii=False, indent=4)
|
return json.dumps(search_results, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
def google_official_search(query, num_results=8):
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
from googleapiclient.errors import HttpError
|
||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get the Google API key and Custom Search Engine ID from the config file
|
||||||
|
api_key = cfg.google_api_key
|
||||||
|
custom_search_engine_id = cfg.custom_search_engine_id
|
||||||
|
|
||||||
|
# Initialize the Custom Search API service
|
||||||
|
service = build("customsearch", "v1", developerKey=api_key)
|
||||||
|
|
||||||
|
# Send the search query and retrieve the results
|
||||||
|
result = service.cse().list(q=query, cx=custom_search_engine_id, num=num_results).execute()
|
||||||
|
|
||||||
|
# Extract the search result items from the response
|
||||||
|
search_results = result.get("items", [])
|
||||||
|
|
||||||
|
# Create a list of only the URLs from the search results
|
||||||
|
search_results_links = [item["link"] for item in search_results]
|
||||||
|
|
||||||
|
except HttpError as e:
|
||||||
|
# Handle errors in the API call
|
||||||
|
error_details = json.loads(e.content.decode())
|
||||||
|
|
||||||
|
# Check if the error is related to an invalid or missing API key
|
||||||
|
if error_details.get("error", {}).get("code") == 403 and "invalid API key" in error_details.get("error", {}).get("message", ""):
|
||||||
|
return "Error: The provided Google API key is invalid or missing."
|
||||||
|
else:
|
||||||
|
return f"Error: {e}"
|
||||||
|
|
||||||
|
# Return the list of search result URLs
|
||||||
|
return search_results_links
|
||||||
|
|
||||||
def browse_website(url):
|
def browse_website(url):
|
||||||
"""Return the results of a google search"""
|
"""Return the results of a google search"""
|
||||||
|
|||||||
@@ -37,11 +37,13 @@ class Config(metaclass=Singleton):
|
|||||||
|
|
||||||
self.openai_api_key = os.getenv("OPENAI_API_KEY")
|
self.openai_api_key = os.getenv("OPENAI_API_KEY")
|
||||||
self.elevenlabs_api_key = os.getenv("ELEVENLABS_API_KEY")
|
self.elevenlabs_api_key = os.getenv("ELEVENLABS_API_KEY")
|
||||||
|
|
||||||
|
self.google_api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
self.custom_search_engine_id = os.getenv("CUSTOM_SEARCH_ENGINE_ID")
|
||||||
|
|
||||||
# Initialize the OpenAI API client
|
# Initialize the OpenAI API client
|
||||||
openai.api_key = self.openai_api_key
|
openai.api_key = self.openai_api_key
|
||||||
|
|
||||||
|
|
||||||
def set_continuous_mode(self, value: bool):
|
def set_continuous_mode(self, value: bool):
|
||||||
"""Set the continuous mode value."""
|
"""Set the continuous mode value."""
|
||||||
self.continuous_mode = value
|
self.continuous_mode = value
|
||||||
@@ -68,11 +70,16 @@ class Config(metaclass=Singleton):
|
|||||||
|
|
||||||
def set_openai_api_key(self, value: str):
|
def set_openai_api_key(self, value: str):
|
||||||
"""Set the OpenAI API key value."""
|
"""Set the OpenAI API key value."""
|
||||||
self.apiopenai_api_key_key = value
|
self.openai_api_key = value
|
||||||
|
|
||||||
def set_elevenlabs_api_key(self, value: str):
|
def set_elevenlabs_api_key(self, value: str):
|
||||||
"""Set the ElevenLabs API key value."""
|
"""Set the ElevenLabs API key value."""
|
||||||
self.elevenlabs_api_key = value
|
self.elevenlabs_api_key = value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def set_google_api_key(self, value: str):
|
||||||
|
"""Set the Google API key value."""
|
||||||
|
self.google_api_key = value
|
||||||
|
|
||||||
|
def set_custom_search_engine_id(self, value: str):
|
||||||
|
"""Set the custom search engine ID value."""
|
||||||
|
self.custom_search_engine_id = value
|
||||||
@@ -34,6 +34,9 @@ def write_to_file(filename, text):
|
|||||||
"""Write text to a file"""
|
"""Write text to a file"""
|
||||||
try:
|
try:
|
||||||
filepath = safe_join(working_directory, filename)
|
filepath = safe_join(working_directory, filename)
|
||||||
|
directory = os.path.dirname(filepath)
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
os.makedirs(directory)
|
||||||
with open(filepath, "w") as f:
|
with open(filepath, "w") as f:
|
||||||
f.write(text)
|
f.write(text)
|
||||||
return "File written to successfully."
|
return "File written to successfully."
|
||||||
|
|||||||
@@ -54,65 +54,50 @@ def print_assistant_thoughts(assistant_reply):
|
|||||||
# Parse and print Assistant response
|
# Parse and print Assistant response
|
||||||
assistant_reply_json = fix_and_parse_json(assistant_reply)
|
assistant_reply_json = fix_and_parse_json(assistant_reply)
|
||||||
|
|
||||||
try:
|
assistant_thoughts_reasoning = None
|
||||||
assistant_thoughts = assistant_reply_json.get("thoughts")
|
assistant_thoughts_plan = None
|
||||||
if assistant_thoughts:
|
assistant_thoughts_speak = None
|
||||||
assistant_thoughts_text = assistant_thoughts.get("text")
|
assistant_thoughts_criticism = None
|
||||||
assistant_thoughts_reasoning = assistant_thoughts.get("reasoning")
|
assistant_thoughts = assistant_reply_json.get("thoughts", {})
|
||||||
assistant_thoughts_plan = assistant_thoughts.get("plan")
|
assistant_thoughts_text = assistant_thoughts.get("text")
|
||||||
assistant_thoughts_criticism = assistant_thoughts.get("criticism")
|
|
||||||
assistant_thoughts_speak = assistant_thoughts.get("speak")
|
if assistant_thoughts:
|
||||||
else:
|
assistant_thoughts_reasoning = assistant_thoughts.get("reasoning")
|
||||||
assistant_thoughts_text = None
|
assistant_thoughts_plan = assistant_thoughts.get("plan")
|
||||||
assistant_thoughts_reasoning = None
|
assistant_thoughts_criticism = assistant_thoughts.get("criticism")
|
||||||
assistant_thoughts_plan = None
|
assistant_thoughts_speak = assistant_thoughts.get("speak")
|
||||||
assistant_thoughts_criticism = None
|
|
||||||
assistant_thoughts_speak = None
|
print_to_console(f"{ai_name.upper()} THOUGHTS:", Fore.YELLOW, assistant_thoughts_text)
|
||||||
except Exception as e:
|
print_to_console("REASONING:", Fore.YELLOW, assistant_thoughts_reasoning)
|
||||||
assistant_thoughts_text = "The AI's response was unreadable."
|
|
||||||
|
|
||||||
print_to_console(
|
|
||||||
f"{ai_name.upper()} THOUGHTS:",
|
|
||||||
Fore.YELLOW,
|
|
||||||
assistant_thoughts_text)
|
|
||||||
print_to_console(
|
|
||||||
"REASONING:",
|
|
||||||
Fore.YELLOW,
|
|
||||||
assistant_thoughts_reasoning)
|
|
||||||
if assistant_thoughts_plan:
|
if assistant_thoughts_plan:
|
||||||
print_to_console("PLAN:", Fore.YELLOW, "")
|
print_to_console("PLAN:", Fore.YELLOW, "")
|
||||||
if assistant_thoughts_plan:
|
# If it's a list, join it into a string
|
||||||
# If it's a list, join it into a string
|
if isinstance(assistant_thoughts_plan, list):
|
||||||
if isinstance(assistant_thoughts_plan, list):
|
assistant_thoughts_plan = "\n".join(assistant_thoughts_plan)
|
||||||
assistant_thoughts_plan = "\n".join(assistant_thoughts_plan)
|
elif isinstance(assistant_thoughts_plan, dict):
|
||||||
elif isinstance(assistant_thoughts_plan, dict):
|
assistant_thoughts_plan = str(assistant_thoughts_plan)
|
||||||
assistant_thoughts_plan = str(assistant_thoughts_plan)
|
|
||||||
# Split the input_string using the newline character and dash
|
|
||||||
|
|
||||||
lines = assistant_thoughts_plan.split('\n')
|
|
||||||
|
|
||||||
# Iterate through the lines and print each one with a bullet
|
# Split the input_string using the newline character and dashes
|
||||||
# point
|
lines = assistant_thoughts_plan.split('\n')
|
||||||
for line in lines:
|
for line in lines:
|
||||||
# Remove any "-" characters from the start of the line
|
line = line.lstrip("- ")
|
||||||
line = line.lstrip("- ")
|
print_to_console("- ", Fore.GREEN, line.strip())
|
||||||
print_to_console("- ", Fore.GREEN, line.strip())
|
|
||||||
print_to_console(
|
|
||||||
"CRITICISM:",
|
|
||||||
Fore.YELLOW,
|
|
||||||
assistant_thoughts_criticism)
|
|
||||||
|
|
||||||
|
print_to_console("CRITICISM:", Fore.YELLOW, assistant_thoughts_criticism)
|
||||||
# Speak the assistant's thoughts
|
# Speak the assistant's thoughts
|
||||||
if cfg.speak_mode and assistant_thoughts_speak:
|
if cfg.speak_mode and assistant_thoughts_speak:
|
||||||
speak.say_text(assistant_thoughts_speak)
|
speak.say_text(assistant_thoughts_speak)
|
||||||
|
|
||||||
except json.decoder.JSONDecodeError:
|
except json.decoder.JSONDecodeError:
|
||||||
print_to_console("Error: Invalid JSON\n", Fore.RED, assistant_reply)
|
print_to_console("Error: Invalid JSON\n", Fore.RED, assistant_reply)
|
||||||
|
|
||||||
# All other errors, return "Error: + error message"
|
# All other errors, return "Error: + error message"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
call_stack = traceback.format_exc()
|
call_stack = traceback.format_exc()
|
||||||
print_to_console("Error: \n", Fore.RED, call_stack)
|
print_to_console("Error: \n", Fore.RED, call_stack)
|
||||||
|
|
||||||
|
|
||||||
def load_variables(config_file="config.yaml"):
|
def load_variables(config_file="config.yaml"):
|
||||||
"""Load variables from yaml file if it exists, otherwise prompt the user for input"""
|
"""Load variables from yaml file if it exists, otherwise prompt the user for input"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user