| from colorama import Fore, Style |
|
|
| from autogpt.app import execute_command, get_command |
| from autogpt.chat import chat_with_ai, create_chat_message |
| from autogpt.config import Config |
| from autogpt.json_utils.json_fix_llm import fix_json_using_multiple_techniques |
| from autogpt.json_utils.utilities import validate_json |
| from autogpt.logs import logger, print_assistant_thoughts |
| from autogpt.speech import say_text |
| from autogpt.spinner import Spinner |
| from autogpt.utils import clean_input |
|
|
|
|
| class Agent: |
| """Agent class for interacting with Auto-GPT. |
| |
| Attributes: |
| ai_name: The name of the agent. |
| memory: The memory object to use. |
| full_message_history: The full message history. |
| next_action_count: The number of actions to execute. |
| system_prompt: The system prompt is the initial prompt that defines everything the AI needs to know to achieve its task successfully. |
| Currently, the dynamic and customizable information in the system prompt are ai_name, description and goals. |
| |
| triggering_prompt: The last sentence the AI will see before answering. For Auto-GPT, this prompt is: |
| Determine which next command to use, and respond using the format specified above: |
| The triggering prompt is not part of the system prompt because between the system prompt and the triggering |
| prompt we have contextual information that can distract the AI and make it forget that its goal is to find the next task to achieve. |
| SYSTEM PROMPT |
| CONTEXTUAL INFORMATION (memory, previous conversations, anything relevant) |
| TRIGGERING PROMPT |
| |
| The triggering prompt reminds the AI about its short term meta task (defining the next task) |
| """ |
|
|
| def __init__( |
| self, |
| ai_name, |
| memory, |
| full_message_history, |
| next_action_count, |
| system_prompt, |
| triggering_prompt, |
| ): |
| self.ai_name = ai_name |
| self.memory = memory |
| self.full_message_history = full_message_history |
| self.next_action_count = next_action_count |
| self.system_prompt = system_prompt |
| self.triggering_prompt = triggering_prompt |
|
|
| def start_interaction_loop(self): |
| |
| cfg = Config() |
| loop_count = 0 |
| command_name = None |
| arguments = None |
| user_input = "" |
|
|
| while True: |
| |
| loop_count += 1 |
| if ( |
| cfg.continuous_mode |
| and cfg.continuous_limit > 0 |
| and loop_count > cfg.continuous_limit |
| ): |
| logger.typewriter_log( |
| "Continuous Limit Reached: ", Fore.YELLOW, f"{cfg.continuous_limit}" |
| ) |
| break |
|
|
| |
| with Spinner("Thinking... "): |
| assistant_reply = chat_with_ai( |
| self.system_prompt, |
| self.triggering_prompt, |
| self.full_message_history, |
| self.memory, |
| cfg.fast_token_limit, |
| ) |
|
|
| assistant_reply_json = fix_json_using_multiple_techniques(assistant_reply) |
|
|
| |
| if assistant_reply_json != {}: |
| validate_json(assistant_reply_json, "llm_response_format_1") |
| |
| try: |
| print_assistant_thoughts(self.ai_name, assistant_reply_json) |
| command_name, arguments = get_command(assistant_reply_json) |
| |
| if cfg.speak_mode: |
| say_text(f"I want to execute {command_name}") |
| except Exception as e: |
| logger.error("Error: \n", str(e)) |
|
|
| if not cfg.continuous_mode and self.next_action_count == 0: |
| |
| |
| |
| logger.typewriter_log( |
| "NEXT ACTION: ", |
| Fore.CYAN, |
| f"COMMAND = {Fore.CYAN}{command_name}{Style.RESET_ALL} " |
| f"ARGUMENTS = {Fore.CYAN}{arguments}{Style.RESET_ALL}", |
| ) |
| print( |
| "Enter 'y' to authorise command, 'y -N' to run N continuous " |
| "commands, 'n' to exit program, or enter feedback for " |
| f"{self.ai_name}...", |
| flush=True, |
| ) |
| while True: |
| console_input = clean_input( |
| Fore.MAGENTA + "Input:" + Style.RESET_ALL |
| ) |
| if console_input.lower().strip() == "y": |
| user_input = "GENERATE NEXT COMMAND JSON" |
| break |
| elif console_input.lower().strip() == "": |
| print("Invalid input format.") |
| continue |
| elif console_input.lower().startswith("y -"): |
| try: |
| self.next_action_count = abs( |
| int(console_input.split(" ")[1]) |
| ) |
| user_input = "GENERATE NEXT COMMAND JSON" |
| except ValueError: |
| print( |
| "Invalid input format. Please enter 'y -n' where n is" |
| " the number of continuous tasks." |
| ) |
| continue |
| break |
| elif console_input.lower() == "n": |
| user_input = "EXIT" |
| break |
| else: |
| user_input = console_input |
| command_name = "human_feedback" |
| break |
|
|
| if user_input == "GENERATE NEXT COMMAND JSON": |
| logger.typewriter_log( |
| "-=-=-=-=-=-=-= COMMAND AUTHORISED BY USER -=-=-=-=-=-=-=", |
| Fore.MAGENTA, |
| "", |
| ) |
| elif user_input == "EXIT": |
| print("Exiting...", flush=True) |
| break |
| else: |
| |
| logger.typewriter_log( |
| "NEXT ACTION: ", |
| Fore.CYAN, |
| f"COMMAND = {Fore.CYAN}{command_name}{Style.RESET_ALL}" |
| f" ARGUMENTS = {Fore.CYAN}{arguments}{Style.RESET_ALL}", |
| ) |
|
|
| |
| if command_name is not None and 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}" |
| else: |
| result = ( |
| f"Command {command_name} returned: " |
| f"{execute_command(command_name, arguments)}" |
| ) |
| if self.next_action_count > 0: |
| self.next_action_count -= 1 |
|
|
| memory_to_add = ( |
| f"Assistant Reply: {assistant_reply} " |
| f"\nResult: {result} " |
| f"\nHuman Feedback: {user_input} " |
| ) |
|
|
| self.memory.add(memory_to_add) |
|
|
| |
| |
| if result is not None: |
| self.full_message_history.append(create_chat_message("system", result)) |
| logger.typewriter_log("SYSTEM: ", Fore.YELLOW, result) |
| else: |
| self.full_message_history.append( |
| create_chat_message("system", "Unable to execute command") |
| ) |
| logger.typewriter_log( |
| "SYSTEM: ", Fore.YELLOW, "Unable to execute command" |
| ) |
|
|