From eb8b3e662278095f7c7b2ffebae872aadc4a6d5f Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Thu, 13 Apr 2023 21:01:00 -0400 Subject: [PATCH 1/8] add gitpython --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 2fec1b16..ab1920c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,3 +25,4 @@ pre-commit black sourcery isort +gitpython==3.1.31 From 4d8de551b54f7b83157757a4e4b30f59ef917319 Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Thu, 13 Apr 2023 21:03:19 -0400 Subject: [PATCH 2/8] add prompt, env example, config --- .env.template | 10 ++++++++++ autogpt/config/config.py | 3 +++ autogpt/prompt.py | 1 + 3 files changed, 14 insertions(+) diff --git a/.env.template b/.env.template index b8140dd8..9013560f 100644 --- a/.env.template +++ b/.env.template @@ -99,6 +99,16 @@ IMAGE_PROVIDER=dalle # HUGGINGFACE_API_TOKEN - HuggingFace API token (Example: my-huggingface-api-token) HUGGINGFACE_API_TOKEN=your-huggingface-api-token +################################################################################ +### GIT Provider for repository actions +################################################################################ + +### GITHUB +# GITHUB_API_KEY - Github API key / PAT (Example: github_pat_123) +# GITHUB_USERNAME - Github username +GITHUB_API_KEY=github_pat_123 +GITHUB_USERNAME=your-github-username + ################################################################################ ### SEARCH PROVIDER ################################################################################ diff --git a/autogpt/config/config.py b/autogpt/config/config.py index 667c8178..1fe4a870 100644 --- a/autogpt/config/config.py +++ b/autogpt/config/config.py @@ -55,6 +55,9 @@ class Config(metaclass=Singleton): self.use_brian_tts = False self.use_brian_tts = os.getenv("USE_BRIAN_TTS") + + self.github_api_key = os.getenv("GITHUB_API_KEY") + self.github_username = os.getenv("GITHUB_USERNAME") self.google_api_key = os.getenv("GOOGLE_API_KEY") self.custom_search_engine_id = os.getenv("CUSTOM_SEARCH_ENGINE_ID") diff --git a/autogpt/prompt.py b/autogpt/prompt.py index 050c2560..20492978 100644 --- a/autogpt/prompt.py +++ b/autogpt/prompt.py @@ -55,6 +55,7 @@ def get_prompt() -> str: ), ("List GPT Agents", "list_agents", {}), ("Delete GPT Agent", "delete_agent", {"key": ""}), + ("Clone Repository", "clone_repository", {"repository_url": "", "clone_path": ""}), ("Write to file", "write_to_file", {"file": "", "text": ""}), ("Read file", "read_file", {"file": ""}), ("Append to file", "append_to_file", {"file": "", "text": ""}), From 0569d6652fbffa665de6e42403a48783fbede8ce Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Thu, 13 Apr 2023 21:39:08 -0400 Subject: [PATCH 3/8] add command --- autogpt/commands.py | 311 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 autogpt/commands.py diff --git a/autogpt/commands.py b/autogpt/commands.py new file mode 100644 index 00000000..1e8e9047 --- /dev/null +++ b/autogpt/commands.py @@ -0,0 +1,311 @@ +from autogpt import browse +import json +from autogpt.memory import get_memory +import datetime +import autogpt.agent_manager as agents +from autogpt import speak +from autogpt.config import Config +import autogpt.ai_functions as ai +from autogpt.file_operations import read_file, write_to_file, append_to_file, delete_file, search_files +from autogpt.execute_code import execute_python_file, execute_shell +from autogpt.json_parser import fix_and_parse_json +from autogpt.image_gen import generate_image +from duckduckgo_search import ddg +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError + +cfg = Config() + + +def is_valid_int(value): + try: + int(value) + return True + except ValueError: + return False + + +def get_command(response): + """Parse the response and return the command name and arguments""" + try: + response_json = fix_and_parse_json(response) + + if "command" not in response_json: + return "Error:" , "Missing 'command' object in JSON" + + command = response_json["command"] + + if "name" not in command: + return "Error:", "Missing 'name' field in 'command' object" + + command_name = command["name"] + + # Use an empty dictionary if 'args' field is not present in 'command' object + arguments = command.get("args", {}) + + return command_name, arguments + except json.decoder.JSONDecodeError: + return "Error:", "Invalid JSON" + # All other errors, return "Error: + error message" + except Exception as e: + return "Error:", str(e) + + +def execute_command(command_name, arguments): + """Execute the command and return the result""" + memory = get_memory(cfg) + + try: + if command_name == "google": + + # 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": + return memory.add(arguments["string"]) + elif command_name == "start_agent": + return start_agent( + arguments["name"], + arguments["task"], + arguments["prompt"]) + elif command_name == "message_agent": + return message_agent(arguments["key"], arguments["message"]) + elif command_name == "list_agents": + return list_agents() + elif command_name == "delete_agent": + return delete_agent(arguments["key"]) + elif command_name == "get_text_summary": + return get_text_summary(arguments["url"], arguments["question"]) + elif command_name == "get_hyperlinks": + return get_hyperlinks(arguments["url"]) + elif command_name == "clone_repository": + return clone_repository(arguments["repo_url"], arguments["clone_path"]) + elif command_name == "read_file": + return read_file(arguments["file"]) + elif command_name == "write_to_file": + return write_to_file(arguments["file"], arguments["text"]) + elif command_name == "append_to_file": + return append_to_file(arguments["file"], arguments["text"]) + elif command_name == "delete_file": + return delete_file(arguments["file"]) + elif command_name == "search_files": + return search_files(arguments["directory"]) + elif command_name == "browse_website": + return browse_website(arguments["url"], arguments["question"]) + # TODO: Change these to take in a file rather than pasted code, if + # non-file is given, return instructions "Input should be a python + # filepath, write your code to file and try again" + elif command_name == "evaluate_code": + return ai.evaluate_code(arguments["code"]) + elif command_name == "improve_code": + return ai.improve_code(arguments["suggestions"], arguments["code"]) + elif command_name == "write_tests": + return ai.write_tests(arguments["code"], arguments.get("focus")) + elif command_name == "execute_python_file": # Add this command + return execute_python_file(arguments["file"]) + elif command_name == "execute_shell": + if cfg.execute_local_commands: + return execute_shell(arguments["command_line"]) + else: + return "You are not allowed to run local shell commands. To execute shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' in your config. Do not attempt to bypass the restriction." + 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: + return f"Unknown command '{command_name}'. Please refer to the 'COMMANDS' list for available commands and only respond in the specified JSON format." + # All errors, return "Error: + error message" + except Exception as e: + return "Error: " + str(e) + + +def get_datetime(): + """Return the current date and time""" + return "Current date and time: " + \ + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + +def google_search(query, num_results=8): + """Return the results of a google search""" + search_results = [] + for j in ddg(query, max_results=num_results): + search_results.append(j) + + return json.dumps(search_results, ensure_ascii=False, indent=4) + + +def google_official_search(query, num_results=8): + """Return the results of a google search using the official Google API""" + 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, question): + """Browse a website and return the summary and links""" + summary = get_text_summary(url, question) + links = get_hyperlinks(url) + + # Limit links to 5 + if len(links) > 5: + links = links[:5] + + result = f"""Website Content Summary: {summary}\n\nLinks: {links}""" + + return result + + +def get_text_summary(url, question): + """Return the results of a google search""" + text = browse.scrape_text(url) + summary = browse.summarize_text(url, text, question) + return """ "Result" : """ + summary + + +def get_hyperlinks(url): + """Return the results of a google search""" + link_list = browse.scrape_links(url) + return link_list + + +def commit_memory(string): + """Commit a string to memory""" + _text = f"""Committing memory with string "{string}" """ + mem.permanent_memory.append(string) + return _text + + +def delete_memory(key): + """Delete a memory with a given key""" + if key >= 0 and key < len(mem.permanent_memory): + _text = "Deleting memory with key " + str(key) + del mem.permanent_memory[key] + print(_text) + return _text + else: + print("Invalid key, cannot delete memory.") + return None + + +def overwrite_memory(key, string): + """Overwrite a memory with a given key and string""" + # Check if the key is a valid integer + if is_valid_int(key): + key_int = int(key) + # Check if the integer key is within the range of the permanent_memory list + if 0 <= key_int < len(mem.permanent_memory): + _text = "Overwriting memory with key " + str(key) + " and string " + string + # Overwrite the memory slot with the given integer key and string + mem.permanent_memory[key_int] = string + print(_text) + return _text + else: + print(f"Invalid key '{key}', out of range.") + return None + # Check if the key is a valid string + elif isinstance(key, str): + _text = "Overwriting memory with key " + key + " and string " + string + # Overwrite the memory slot with the given string key and string + mem.permanent_memory[key] = string + print(_text) + return _text + else: + print(f"Invalid key '{key}', must be an integer or a string.") + return None + + +def shutdown(): + """Shut down the program""" + print("Shutting down...") + quit() + + +def start_agent(name, task, prompt, model=cfg.fast_llm_model): + """Start an agent with a given name, task, and prompt""" + global cfg + + # Remove underscores from name + voice_name = name.replace("_", " ") + + first_message = f"""You are {name}. Respond with: "Acknowledged".""" + agent_intro = f"{voice_name} here, Reporting for duty!" + + # Create agent + if cfg.speak_mode: + speak.say_text(agent_intro, 1) + key, ack = agents.create_agent(task, first_message, model) + + if cfg.speak_mode: + speak.say_text(f"Hello {voice_name}. Your task is as follows. {task}.") + + # Assign task (prompt), get response + agent_response = message_agent(key, prompt) + + return f"Agent {name} created with key {key}. First response: {agent_response}" + + +def message_agent(key, message): + """Message an agent with a given key and message""" + global cfg + + # Check if the key is a valid integer + if is_valid_int(key): + agent_response = agents.message_agent(int(key), message) + # Check if the key is a valid string + elif isinstance(key, str): + agent_response = agents.message_agent(key, message) + else: + return "Invalid key, must be an integer or a string." + + # Speak response + if cfg.speak_mode: + speak.say_text(agent_response, 1) + return agent_response + + +def list_agents(): + """List all agents""" + return agents.list_agents() + + +def delete_agent(key): + """Delete an agent with a given key""" + result = agents.delete_agent(key) + if not result: + return f"Agent {key} does not exist." + return f"Agent {key} deleted." From 4f9d5b9e32fb03c71c0260e443dcae60d19a4e5f Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Thu, 13 Apr 2023 22:36:47 -0400 Subject: [PATCH 4/8] commands, git on docker --- Dockerfile | 4 ++++ autogpt/commands.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3ae1ac12..5c1822b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,10 @@ # Use an official Python base image from the Docker Hub FROM python:3.11-slim +# Install git +RUN apt-get -y update +RUN apt-get -y install git + # Set environment variables ENV PIP_NO_CACHE_DIR=yes \ PYTHONUNBUFFERED=1 \ diff --git a/autogpt/commands.py b/autogpt/commands.py index 1e8e9047..e8f1c1d1 100644 --- a/autogpt/commands.py +++ b/autogpt/commands.py @@ -82,7 +82,7 @@ def execute_command(command_name, arguments): elif command_name == "get_hyperlinks": return get_hyperlinks(arguments["url"]) elif command_name == "clone_repository": - return clone_repository(arguments["repo_url"], arguments["clone_path"]) + return clone_repository(arguments["repository_url"], arguments["clone_path"]) elif command_name == "read_file": return read_file(arguments["file"]) elif command_name == "write_to_file": From 5f5eac61e3824739bca34e06e439208f81b55773 Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Thu, 13 Apr 2023 22:37:22 -0400 Subject: [PATCH 5/8] clone repo method --- scripts/git_operations.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 scripts/git_operations.py diff --git a/scripts/git_operations.py b/scripts/git_operations.py new file mode 100644 index 00000000..3309192c --- /dev/null +++ b/scripts/git_operations.py @@ -0,0 +1,13 @@ +import git +from config import Config + +cfg = Config() + +def clone_repository(repo_url, clone_path): + """Clone a github repository locally""" + split_url = repo_url.split("//") + auth_repo_url = f"//{cfg.github_username}:{cfg.github_api_key}@".join(split_url) + git.Repo.clone_from(auth_repo_url, clone_path) + result = f"""Cloned {repo_url} to {clone_path}""" + + return result \ No newline at end of file From 11faf42c7eecdab97fc92fc8d2a03ae7177e9c60 Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Fri, 14 Apr 2023 16:11:55 -0400 Subject: [PATCH 6/8] move git operations --- autogpt/commands.py | 1 + {scripts => autogpt}/git_operations.py | 0 2 files changed, 1 insertion(+) rename {scripts => autogpt}/git_operations.py (100%) diff --git a/autogpt/commands.py b/autogpt/commands.py index e8f1c1d1..eeedcad3 100644 --- a/autogpt/commands.py +++ b/autogpt/commands.py @@ -10,6 +10,7 @@ from autogpt.file_operations import read_file, write_to_file, append_to_file, de from autogpt.execute_code import execute_python_file, execute_shell from autogpt.json_parser import fix_and_parse_json from autogpt.image_gen import generate_image +from autogpt.git_operations import clone_repository from duckduckgo_search import ddg from googleapiclient.discovery import build from googleapiclient.errors import HttpError diff --git a/scripts/git_operations.py b/autogpt/git_operations.py similarity index 100% rename from scripts/git_operations.py rename to autogpt/git_operations.py From 99c4f93ee343bb7806c17b20a511acb81e5f833e Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Sat, 15 Apr 2023 10:59:40 -0400 Subject: [PATCH 7/8] fix rebasing --- autogpt/app.py | 3 + autogpt/commands.py | 312 ----------------------- autogpt/{ => commands}/git_operations.py | 0 3 files changed, 3 insertions(+), 312 deletions(-) delete mode 100644 autogpt/commands.py rename autogpt/{ => commands}/git_operations.py (100%) diff --git a/autogpt/app.py b/autogpt/app.py index 0adfde5d..c8300d59 100644 --- a/autogpt/app.py +++ b/autogpt/app.py @@ -22,6 +22,7 @@ from autogpt.memory import get_memory from autogpt.processing.text import summarize_text from autogpt.speech import say_text from autogpt.commands.web_selenium import browse_website +from autogpt.commands.git_operations import clone_repository CFG = Config() @@ -124,6 +125,8 @@ def execute_command(command_name: str, arguments): return get_text_summary(arguments["url"], arguments["question"]) elif command_name == "get_hyperlinks": return get_hyperlinks(arguments["url"]) + elif command_name == "clone_repository": + return clone_repository(arguments["repository_url"], arguments["clone_path"]) elif command_name == "read_file": return read_file(arguments["file"]) elif command_name == "write_to_file": diff --git a/autogpt/commands.py b/autogpt/commands.py deleted file mode 100644 index eeedcad3..00000000 --- a/autogpt/commands.py +++ /dev/null @@ -1,312 +0,0 @@ -from autogpt import browse -import json -from autogpt.memory import get_memory -import datetime -import autogpt.agent_manager as agents -from autogpt import speak -from autogpt.config import Config -import autogpt.ai_functions as ai -from autogpt.file_operations import read_file, write_to_file, append_to_file, delete_file, search_files -from autogpt.execute_code import execute_python_file, execute_shell -from autogpt.json_parser import fix_and_parse_json -from autogpt.image_gen import generate_image -from autogpt.git_operations import clone_repository -from duckduckgo_search import ddg -from googleapiclient.discovery import build -from googleapiclient.errors import HttpError - -cfg = Config() - - -def is_valid_int(value): - try: - int(value) - return True - except ValueError: - return False - - -def get_command(response): - """Parse the response and return the command name and arguments""" - try: - response_json = fix_and_parse_json(response) - - if "command" not in response_json: - return "Error:" , "Missing 'command' object in JSON" - - command = response_json["command"] - - if "name" not in command: - return "Error:", "Missing 'name' field in 'command' object" - - command_name = command["name"] - - # Use an empty dictionary if 'args' field is not present in 'command' object - arguments = command.get("args", {}) - - return command_name, arguments - except json.decoder.JSONDecodeError: - return "Error:", "Invalid JSON" - # All other errors, return "Error: + error message" - except Exception as e: - return "Error:", str(e) - - -def execute_command(command_name, arguments): - """Execute the command and return the result""" - memory = get_memory(cfg) - - try: - if command_name == "google": - - # 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": - return memory.add(arguments["string"]) - elif command_name == "start_agent": - return start_agent( - arguments["name"], - arguments["task"], - arguments["prompt"]) - elif command_name == "message_agent": - return message_agent(arguments["key"], arguments["message"]) - elif command_name == "list_agents": - return list_agents() - elif command_name == "delete_agent": - return delete_agent(arguments["key"]) - elif command_name == "get_text_summary": - return get_text_summary(arguments["url"], arguments["question"]) - elif command_name == "get_hyperlinks": - return get_hyperlinks(arguments["url"]) - elif command_name == "clone_repository": - return clone_repository(arguments["repository_url"], arguments["clone_path"]) - elif command_name == "read_file": - return read_file(arguments["file"]) - elif command_name == "write_to_file": - return write_to_file(arguments["file"], arguments["text"]) - elif command_name == "append_to_file": - return append_to_file(arguments["file"], arguments["text"]) - elif command_name == "delete_file": - return delete_file(arguments["file"]) - elif command_name == "search_files": - return search_files(arguments["directory"]) - elif command_name == "browse_website": - return browse_website(arguments["url"], arguments["question"]) - # TODO: Change these to take in a file rather than pasted code, if - # non-file is given, return instructions "Input should be a python - # filepath, write your code to file and try again" - elif command_name == "evaluate_code": - return ai.evaluate_code(arguments["code"]) - elif command_name == "improve_code": - return ai.improve_code(arguments["suggestions"], arguments["code"]) - elif command_name == "write_tests": - return ai.write_tests(arguments["code"], arguments.get("focus")) - elif command_name == "execute_python_file": # Add this command - return execute_python_file(arguments["file"]) - elif command_name == "execute_shell": - if cfg.execute_local_commands: - return execute_shell(arguments["command_line"]) - else: - return "You are not allowed to run local shell commands. To execute shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' in your config. Do not attempt to bypass the restriction." - 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: - return f"Unknown command '{command_name}'. Please refer to the 'COMMANDS' list for available commands and only respond in the specified JSON format." - # All errors, return "Error: + error message" - except Exception as e: - return "Error: " + str(e) - - -def get_datetime(): - """Return the current date and time""" - return "Current date and time: " + \ - datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - -def google_search(query, num_results=8): - """Return the results of a google search""" - search_results = [] - for j in ddg(query, max_results=num_results): - search_results.append(j) - - return json.dumps(search_results, ensure_ascii=False, indent=4) - - -def google_official_search(query, num_results=8): - """Return the results of a google search using the official Google API""" - 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, question): - """Browse a website and return the summary and links""" - summary = get_text_summary(url, question) - links = get_hyperlinks(url) - - # Limit links to 5 - if len(links) > 5: - links = links[:5] - - result = f"""Website Content Summary: {summary}\n\nLinks: {links}""" - - return result - - -def get_text_summary(url, question): - """Return the results of a google search""" - text = browse.scrape_text(url) - summary = browse.summarize_text(url, text, question) - return """ "Result" : """ + summary - - -def get_hyperlinks(url): - """Return the results of a google search""" - link_list = browse.scrape_links(url) - return link_list - - -def commit_memory(string): - """Commit a string to memory""" - _text = f"""Committing memory with string "{string}" """ - mem.permanent_memory.append(string) - return _text - - -def delete_memory(key): - """Delete a memory with a given key""" - if key >= 0 and key < len(mem.permanent_memory): - _text = "Deleting memory with key " + str(key) - del mem.permanent_memory[key] - print(_text) - return _text - else: - print("Invalid key, cannot delete memory.") - return None - - -def overwrite_memory(key, string): - """Overwrite a memory with a given key and string""" - # Check if the key is a valid integer - if is_valid_int(key): - key_int = int(key) - # Check if the integer key is within the range of the permanent_memory list - if 0 <= key_int < len(mem.permanent_memory): - _text = "Overwriting memory with key " + str(key) + " and string " + string - # Overwrite the memory slot with the given integer key and string - mem.permanent_memory[key_int] = string - print(_text) - return _text - else: - print(f"Invalid key '{key}', out of range.") - return None - # Check if the key is a valid string - elif isinstance(key, str): - _text = "Overwriting memory with key " + key + " and string " + string - # Overwrite the memory slot with the given string key and string - mem.permanent_memory[key] = string - print(_text) - return _text - else: - print(f"Invalid key '{key}', must be an integer or a string.") - return None - - -def shutdown(): - """Shut down the program""" - print("Shutting down...") - quit() - - -def start_agent(name, task, prompt, model=cfg.fast_llm_model): - """Start an agent with a given name, task, and prompt""" - global cfg - - # Remove underscores from name - voice_name = name.replace("_", " ") - - first_message = f"""You are {name}. Respond with: "Acknowledged".""" - agent_intro = f"{voice_name} here, Reporting for duty!" - - # Create agent - if cfg.speak_mode: - speak.say_text(agent_intro, 1) - key, ack = agents.create_agent(task, first_message, model) - - if cfg.speak_mode: - speak.say_text(f"Hello {voice_name}. Your task is as follows. {task}.") - - # Assign task (prompt), get response - agent_response = message_agent(key, prompt) - - return f"Agent {name} created with key {key}. First response: {agent_response}" - - -def message_agent(key, message): - """Message an agent with a given key and message""" - global cfg - - # Check if the key is a valid integer - if is_valid_int(key): - agent_response = agents.message_agent(int(key), message) - # Check if the key is a valid string - elif isinstance(key, str): - agent_response = agents.message_agent(key, message) - else: - return "Invalid key, must be an integer or a string." - - # Speak response - if cfg.speak_mode: - speak.say_text(agent_response, 1) - return agent_response - - -def list_agents(): - """List all agents""" - return agents.list_agents() - - -def delete_agent(key): - """Delete an agent with a given key""" - result = agents.delete_agent(key) - if not result: - return f"Agent {key} does not exist." - return f"Agent {key} deleted." diff --git a/autogpt/git_operations.py b/autogpt/commands/git_operations.py similarity index 100% rename from autogpt/git_operations.py rename to autogpt/commands/git_operations.py From 71abd6f2e408dd0d9f75ede3afcc7f8e78ee7f72 Mon Sep 17 00:00:00 2001 From: Eddie Cohen Date: Sat, 15 Apr 2023 11:15:18 -0400 Subject: [PATCH 8/8] linting --- autogpt/commands/git_operations.py | 3 ++- autogpt/config/config.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/autogpt/commands/git_operations.py b/autogpt/commands/git_operations.py index 3309192c..87232589 100644 --- a/autogpt/commands/git_operations.py +++ b/autogpt/commands/git_operations.py @@ -3,6 +3,7 @@ from config import Config cfg = Config() + def clone_repository(repo_url, clone_path): """Clone a github repository locally""" split_url = repo_url.split("//") @@ -10,4 +11,4 @@ def clone_repository(repo_url, clone_path): git.Repo.clone_from(auth_repo_url, clone_path) result = f"""Cloned {repo_url} to {clone_path}""" - return result \ No newline at end of file + return result diff --git a/autogpt/config/config.py b/autogpt/config/config.py index 1fe4a870..acaf9267 100644 --- a/autogpt/config/config.py +++ b/autogpt/config/config.py @@ -55,7 +55,7 @@ class Config(metaclass=Singleton): self.use_brian_tts = False self.use_brian_tts = os.getenv("USE_BRIAN_TTS") - + self.github_api_key = os.getenv("GITHUB_API_KEY") self.github_username = os.getenv("GITHUB_USERNAME")