Skip to content

Commit

Permalink
Refactor prompts into package, make the prompt able to be stored with…
Browse files Browse the repository at this point in the history
… the AI config and changed. Fix settings file.
  • Loading branch information
BillSchumacher committed Apr 16, 2023
1 parent 1af463b commit b7a29e7
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 36 deletions.
9 changes: 6 additions & 3 deletions autogpt/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Main script for the autogpt package."""
import logging
import os
from pathlib import Path
from colorama import Fore
from autogpt.agent.agent import Agent
from autogpt.args import parse_arguments
Expand All @@ -8,7 +10,9 @@
from autogpt.logs import logger
from autogpt.memory import get_memory

from autogpt.prompt import construct_prompt
from autogpt.prompts.prompt import construct_prompt
from autogpt.plugins import load_plugins


# Load environment variables from .env file

Expand Down Expand Up @@ -36,8 +40,7 @@ def main() -> None:
loaded_plugins.append(plugin())

if loaded_plugins:
print(f"\nPlugins found: {len(loaded_plugins)}\n"
"--------------------")
print(f"\nPlugins found: {len(loaded_plugins)}\n" "--------------------")
for plugin in loaded_plugins:
print(f"{plugin._name}: {plugin._version} - {plugin._description}")

Expand Down
2 changes: 1 addition & 1 deletion autogpt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def execute_command(command_name: str, arguments):
elif command_name == "generate_image":
return generate_image(arguments["prompt"])
elif command_name == "send_tweet":
return send_tweet(arguments['text'])
return send_tweet(arguments["text"])
elif command_name == "do_nothing":
return "No action performed."
elif command_name == "task_complete":
Expand Down
6 changes: 4 additions & 2 deletions autogpt/commands/audio_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ def read_audio(audio):
headers = {"Authorization": f"Bearer {api_token}"}

if api_token is None:
raise ValueError("You need to set your Hugging Face API token in the config file.")
raise ValueError(
"You need to set your Hugging Face API token in the config file."
)

response = requests.post(
api_url,
headers=headers,
data=audio,
)

text = json.loads(response.content.decode("utf-8"))['text']
text = json.loads(response.content.decode("utf-8"))["text"]
return "The audio says: " + text
6 changes: 3 additions & 3 deletions autogpt/commands/twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

def send_tweet(tweet_text):
consumer_key = os.environ.get("TW_CONSUMER_KEY")
consumer_secret= os.environ.get("TW_CONSUMER_SECRET")
access_token= os.environ.get("TW_ACCESS_TOKEN")
access_token_secret= os.environ.get("TW_ACCESS_TOKEN_SECRET")
consumer_secret = os.environ.get("TW_CONSUMER_SECRET")
access_token = os.environ.get("TW_ACCESS_TOKEN")
access_token_secret = os.environ.get("TW_ACCESS_TOKEN_SECRET")
# Authenticate to Twitter
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
Expand Down
18 changes: 12 additions & 6 deletions autogpt/config/ai_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
A module that contains the AIConfig class object that contains the configuration
"""
import os
from pathlib import Path
from typing import List, Optional, Type
import yaml

from autogpt.prompts.generator import PromptGenerator


class AIConfig:
"""
Expand Down Expand Up @@ -35,9 +38,10 @@ def __init__(
self.ai_name = ai_name
self.ai_role = ai_role
self.ai_goals = ai_goals
self.prompt_generator = None

# Soon this will go in a folder where it remembers more stuff about the run(s)
SAVE_FILE = os.path.join(os.path.dirname(__file__), "..", "ai_settings.yaml")
SAVE_FILE = Path(os.getcwd()) / "ai_settings.yaml"

@staticmethod
def load(config_file: str = SAVE_FILE) -> "AIConfig":
Expand Down Expand Up @@ -86,7 +90,7 @@ def save(self, config_file: str = SAVE_FILE) -> None:
with open(config_file, "w", encoding="utf-8") as file:
yaml.dump(config, file, allow_unicode=True)

def construct_full_prompt(self) -> str:
def construct_full_prompt(self, prompt_generator: Optional[PromptGenerator] = None) -> str:
"""
Returns a prompt to the user with the class information in an organized fashion.
Expand All @@ -105,14 +109,16 @@ def construct_full_prompt(self) -> str:
""
)

from autogpt.prompt import get_prompt

from autogpt.prompts.prompt import build_default_prompt_generator
# Construct full prompt
full_prompt = (
f"You are {self.ai_name}, {self.ai_role}\n{prompt_start}\n\nGOALS:\n\n"
)
for i, goal in enumerate(self.ai_goals):
full_prompt += f"{i+1}. {goal}\n"

full_prompt += f"\n\n{get_prompt()}"
if prompt_generator is None:
prompt_generator = build_default_prompt_generator()
prompt_generator.goals = self.ai_goals
self.prompt_generator = prompt_generator
full_prompt += f"\n\n{prompt_generator.generate_prompt_string()}"
return full_prompt
5 changes: 2 additions & 3 deletions scripts/plugins.py → autogpt/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def inspect_zip_for_module(zip_path: str, debug: bool = False) -> Optional[str]:
Returns:
Optional[str]: The name of the module if found, else None.
"""
with zipfile.ZipFile(zip_path, 'r') as zfile:
with zipfile.ZipFile(zip_path, "r") as zfile:
for name in zfile.namelist():
if name.endswith("__init__.py"):
if debug:
Expand Down Expand Up @@ -68,7 +68,6 @@ def load_plugins(plugins_path: Path, debug: bool = False) -> List[Module]:
continue
a_module = getattr(zipped_module, key)
a_keys = dir(a_module)
if '_abc_impl' in a_keys and \
a_module.__name__ != 'AutoGPTPluginTemplate':
if "_abc_impl" in a_keys and a_module.__name__ != "AutoGPTPluginTemplate":
plugin_modules.append(a_module)
return plugin_modules
Empty file added autogpt/prompts/__init__.py
Empty file.
14 changes: 12 additions & 2 deletions autogpt/promptgenerator.py → autogpt/prompts/generator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" A module for generating custom prompt strings."""
import json
from typing import Any, Dict, List
from typing import Any, Callable, Dict, List, Optional


class PromptGenerator:
Expand All @@ -18,6 +18,7 @@ def __init__(self) -> None:
self.commands = []
self.resources = []
self.performance_evaluation = []
self.goals = []
self.response_format = {
"thoughts": {
"text": "thought",
Expand All @@ -38,7 +39,13 @@ def add_constraint(self, constraint: str) -> None:
"""
self.constraints.append(constraint)

def add_command(self, command_label: str, command_name: str, args=None) -> None:
def add_command(
self,
command_label: str,
command_name: str,
args=None,
function: Optional[Callable] = None,
) -> None:
"""
Add a command to the commands list with a label, name, and optional arguments.
Expand All @@ -47,6 +54,8 @@ def add_command(self, command_label: str, command_name: str, args=None) -> None:
command_name (str): The name of the command.
args (dict, optional): A dictionary containing argument names and their
values. Defaults to None.
function (callable, optional): A callable function to be called when
the command is executed. Defaults to None.
"""
if args is None:
args = {}
Expand All @@ -57,6 +66,7 @@ def add_command(self, command_label: str, command_name: str, args=None) -> None:
"label": command_label,
"name": command_name,
"args": command_args,
"function": function,
}

self.commands.append(command)
Expand Down
18 changes: 4 additions & 14 deletions autogpt/prompt.py → autogpt/prompts/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
from autogpt.config.ai_config import AIConfig
from autogpt.config.config import Config
from autogpt.logs import logger
from autogpt.promptgenerator import PromptGenerator
from autogpt.config import Config
from autogpt.prompts.generator import PromptGenerator
from autogpt.setup import prompt_user
from autogpt.utils import clean_input

CFG = Config()


def get_prompt() -> str:
def build_default_prompt_generator() -> PromptGenerator:
"""
This function generates a prompt string that includes various constraints,
commands, resources, and performance evaluations.
Expand All @@ -19,9 +18,6 @@ def get_prompt() -> str:
str: The generated prompt string.
"""

# Initialize the Config object
cfg = Config()

# Initialize the PromptGenerator object
prompt_generator = PromptGenerator()

Expand Down Expand Up @@ -84,11 +80,10 @@ def get_prompt() -> str:
("Generate Image", "generate_image", {"prompt": "<prompt>"}),
("Convert Audio to text", "read_audio_from_file", {"file": "<file>"}),
("Send Tweet", "send_tweet", {"text": "<text>"}),

]

# Only add shell command to the prompt if the AI is allowed to execute it
if cfg.execute_local_commands:
if CFG.execute_local_commands:
commands.append(
(
"Execute Shell Command, non-interactive commands only",
Expand Down Expand Up @@ -135,8 +130,7 @@ def get_prompt() -> str:
" the least number of steps."
)

# Generate the prompt string
return prompt_generator.generate_prompt_string()
return prompt_generator


def construct_prompt() -> str:
Expand Down Expand Up @@ -171,8 +165,4 @@ def construct_prompt() -> str:
config = prompt_user()
config.save()

# Get rid of this global:
global ai_name
ai_name = config.ai_name

return config.construct_full_prompt()
2 changes: 1 addition & 1 deletion tests/test_prompt_generator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from unittest import TestCase

from autogpt.promptgenerator import PromptGenerator
from autogpt.prompts.generator import PromptGenerator


class TestPromptGenerator(TestCase):
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/test_browse_scrape_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ def test_scrape_text_with_valid_url(self, mocker):
# 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.Session.get", side_effect=requests.exceptions.RequestException)
mocker.patch(
"requests.Session.get", side_effect=requests.exceptions.RequestException
)

# Call the function with an invalid URL and assert that it returns an error message
url = "http://www.invalidurl.com"
Expand Down

0 comments on commit b7a29e7

Please sign in to comment.