Remove unnecessary changes

This commit is contained in:
Zamil Majdy
2024-05-20 18:14:39 +07:00
parent 9f6e25664c
commit dfa77739c3
3 changed files with 0 additions and 817 deletions

View File

@@ -14,11 +14,6 @@ from autogpt.app.main import _configure_llm_provider, run_interaction_loop
LOG_DIR = Path(__file__).parent / "logs"
from dotenv import load_dotenv
load_dotenv()
configure_logging(debug=True)
def run_specific_agent(task: str, continuous_mode: bool = False) -> None:
agent = bootstrap_agent(task, continuous_mode)

View File

@@ -1,805 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"import logging\n",
"\n",
"from dotenv import load_dotenv\n",
"\n",
"from autogpt.logs.config import configure_logging\n",
"from autogpt.core.resource.model_providers import MultiProvider\n",
"\n",
"load_dotenv()\n",
"configure_logging(debug=True)\n",
"\n",
"llm = MultiProvider()\n",
"logger = logging.getLogger()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prompt"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"import logging\n",
"import re\n",
"\n",
"from pydantic import BaseModel, Field\n",
"\n",
"from autogpt.config.ai_directives import AIDirectives\n",
"from autogpt.config.ai_profile import AIProfile\n",
"from autogpt.core.prompting import PromptStrategy\n",
"from autogpt.core.prompting.schema import ChatPrompt, LanguageModelClassification\n",
"from autogpt.core.resource.model_providers import ChatMessage\n",
"from autogpt.core.resource.model_providers.schema import AssistantChatMessage, CompletionModelFunction\n",
"from autogpt.core.utils.json_schema import JSONSchema\n",
"from autogpt.core.utils.json_utils import extract_dict_from_json\n",
"from autogpt.models.utils import ModelWithSummary\n",
"from autogpt.prompts.utils import format_numbered_list\n",
"from autogpt.utils.exceptions import InvalidAgentResponseError\n",
"\n",
"_RESPONSE_INTERFACE_NAME = \"AssistantResponse\"\n",
"\n",
"\n",
"class AssistantThoughts(ModelWithSummary):\n",
" observations: str = Field(\n",
" ..., description=\"Relevant observations from your last action (if any)\"\n",
" )\n",
" self_criticism: str = Field(..., description=\"Constructive self-criticism\")\n",
" reasoning: str = Field(..., description=\"Reasoning towards a new plan\")\n",
" plan: list[str] = Field(\n",
" ..., description=\"Short list that conveys your long-term plan. Parallelize where possible.\"\n",
" )\n",
"\n",
" def summary(self) -> str:\n",
" return self.reasoning\n",
"\n",
"\n",
"class OneShotFlowAgentActionProposal(BaseModel):\n",
" thoughts: AssistantThoughts\n",
" immediate_plan: str = Field(\n",
" ..., description=\"We will be running an iterative process to execute the plan, \"\n",
" \"Write the partial / immediate plan to execute your plan as detailed and efficiently as possible without the help of the reasoning/intelligence. \"\n",
" \"The plan should describe the output of the immediate plan, so that the next iteration can be executed by taking the output into account. \"\n",
" \"Try to do as much as possible without making any assumption or uninformed guesses. Avoid large output at all costs!!!\"\n",
" \"Format: Objective[Objective of this iteration, explain what's the use of this iteration for the next one] Plan[Plan that does not require any reasoning or intelligence] Output[Output of the plan / should be small, avoid whole file output]\"\n",
" )\n",
" python_code: str = Field(\n",
" ..., description=(\n",
" \"Write the fully-functional Python code of the immediate plan. The output of the immediate plan should be a print statement, avoid printing the whole content!. \"\n",
" \"Use ONLY the listed available functions and built-in Python features. \"\n",
" \"Leverage the given magic functions to implement function calls for which the \"\n",
" \"arguments can't be determined yet.\"\n",
" )\n",
" )\n",
"\n",
"FINAL_INSTRUCTION: str = (\n",
" # \"Determine exactly one command to use next based on the given goals \"\n",
" # \"and the progress you have made so far, \"\n",
" # \"and respond using the JSON schema specified previously:\"\n",
" \"Write Python code to execute your plan as efficiently as possible. \"\n",
" \"Your code will be executed directly without any editing: \"\n",
" \"if it doesn't work you will be held responsible. \"\n",
" \"Use ONLY the listed available functions and built-in Python features. \"\n",
" \"Do not make uninformed assumptions (e.g. about the content or format of an unknown file). \"\n",
" \"Leverage the given magic functions to implement function calls for which the \"\n",
" \"arguments can't be determined yet. Reduce the amount of unnecessary data passed into \"\n",
" \"these magic functions where possible, because magic costs money and magically \"\n",
" \"processing large amounts of data is expensive.\"\n",
")\n",
"\n",
"\n",
"class OneShotFlowAgentPromptStrategy(PromptStrategy):\n",
" def __init__(self):\n",
" self.response_schema = JSONSchema.from_dict(OneShotFlowAgentActionProposal.schema())\n",
" self.logger = logging.getLogger(self.__class__.__name__)\n",
"\n",
" @property\n",
" def model_classification(self) -> LanguageModelClassification:\n",
" return LanguageModelClassification.FAST_MODEL # FIXME: dynamic switching\n",
"\n",
" def build_prompt(\n",
" self,\n",
" *,\n",
" messages: list[ChatMessage],\n",
" task: str,\n",
" ai_profile: AIProfile,\n",
" ai_directives: AIDirectives,\n",
" functions: list[CompletionModelFunction],\n",
" **extras,\n",
" ) -> ChatPrompt:\n",
" \"\"\"Constructs and returns a prompt with the following structure:\n",
" 1. System prompt\n",
" 3. `cycle_instruction`\n",
" \"\"\"\n",
" system_prompt, response_prefill = self.build_system_prompt(\n",
" ai_profile=ai_profile,\n",
" ai_directives=ai_directives,\n",
" functions=functions,\n",
" )\n",
"\n",
" final_instruction_msg = ChatMessage.user(FINAL_INSTRUCTION)\n",
"\n",
" return ChatPrompt(\n",
" messages=[\n",
" ChatMessage.system(system_prompt),\n",
" ChatMessage.user(f'\"\"\"{task}\"\"\"'),\n",
" *messages,\n",
" final_instruction_msg,\n",
" ],\n",
" prefill_response=response_prefill,\n",
" )\n",
"\n",
" def build_system_prompt(\n",
" self,\n",
" ai_profile: AIProfile,\n",
" ai_directives: AIDirectives,\n",
" functions: list[CompletionModelFunction],\n",
" ) -> tuple[str, str]:\n",
" \"\"\"\n",
" Builds the system prompt.\n",
"\n",
" Returns:\n",
" str: The system prompt body\n",
" str: The desired start for the LLM's response; used to steer the output\n",
" \"\"\"\n",
" response_fmt_instruction, response_prefill = self.response_format_instruction()\n",
" system_prompt_parts = (\n",
" self._generate_intro_prompt(ai_profile)\n",
" + [\n",
" \"## Your Task\\n\"\n",
" \"The user will specify a task for you to execute, in triple quotes,\"\n",
" \" in the next message. Your job is to complete the task, \"\n",
" \"and terminate when your task is done.\"\n",
" ]\n",
" + [\n",
" \"## Available Functions\\n\"\n",
" + self._generate_function_headers(functions)\n",
" ]\n",
" + [\"## RESPONSE FORMAT\\n\" + response_fmt_instruction]\n",
" )\n",
"\n",
" # Join non-empty parts together into paragraph format\n",
" return (\n",
" \"\\n\\n\".join(filter(None, system_prompt_parts)).strip(\"\\n\"),\n",
" response_prefill,\n",
" )\n",
"\n",
" def response_format_instruction(self) -> tuple[str, str]:\n",
" response_schema = self.response_schema.copy(deep=True)\n",
"\n",
" # Unindent for performance\n",
" response_format = re.sub(\n",
" r\"\\n\\s+\",\n",
" \"\\n\",\n",
" response_schema.to_typescript_object_interface(_RESPONSE_INTERFACE_NAME),\n",
" )\n",
" response_prefill = f'{{\\n \"{list(response_schema.properties.keys())[0]}\":'\n",
"\n",
" return (\n",
" (\n",
" f\"YOU MUST ALWAYS RESPOND WITH A JSON OBJECT OF THE FOLLOWING TYPE:\\n\"\n",
" f\"{response_format}\"\n",
" ),\n",
" response_prefill,\n",
" )\n",
"\n",
" def _generate_intro_prompt(self, ai_profile: AIProfile) -> list[str]:\n",
" \"\"\"Generates the introduction part of the prompt.\n",
"\n",
" Returns:\n",
" list[str]: A list of strings forming the introduction part of the prompt.\n",
" \"\"\"\n",
" return [\n",
" f\"You are {ai_profile.ai_name}, {ai_profile.ai_role.rstrip('.')}.\",\n",
" # \"Your decisions must always be made independently without seeking \"\n",
" # \"user assistance. Play to your strengths as an LLM and pursue \"\n",
" # \"simple strategies with no legal complications.\",\n",
" ]\n",
"\n",
" def _generate_function_headers(self, funcs: list[CompletionModelFunction]) -> str:\n",
" return \"\\n\\n\".join(f.fmt_header() for f in funcs)\n",
"\n",
" def parse_response_content(\n",
" self,\n",
" response: AssistantChatMessage,\n",
" ) -> OneShotFlowAgentActionProposal:\n",
" if not response.content:\n",
" raise InvalidAgentResponseError(\"Assistant response has no text content\")\n",
"\n",
" self.logger.debug(\n",
" \"LLM response content:\"\n",
" + (\n",
" f\"\\n{response.content}\"\n",
" if \"\\n\" in response.content\n",
" else f\" '{response.content}'\"\n",
" )\n",
" )\n",
" assistant_reply_dict = extract_dict_from_json(response.content)\n",
" self.logger.debug(\n",
" \"Parsing object extracted from LLM response:\\n\"\n",
" f\"{json.dumps(assistant_reply_dict, indent=4)}\"\n",
" )\n",
"\n",
" parsed_response = OneShotFlowAgentActionProposal.parse_obj(assistant_reply_dict)\n",
" if not parsed_response.python_code:\n",
" raise ValueError(\"python_code is empty\")\n",
" return parsed_response"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
"tools = [\n",
" CompletionModelFunction(\n",
" name=\"web_search\",\n",
" description=\"Searches the web\",\n",
" parameters={\n",
" \"query\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The search query\",\n",
" required=True,\n",
" ),\n",
" \"num_results\": JSONSchema(\n",
" type=JSONSchema.Type.INTEGER,\n",
" description=\"The number of results to return\",\n",
" minimum=1,\n",
" maximum=10,\n",
" required=False,\n",
" ),\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"read_webpage\",\n",
" description=(\n",
" \"Read a webpage, and extract specific information from it.\"\n",
" \" You must specify either topics_of_interest,\"\n",
" \" a question, or get_raw_content.\"\n",
" ),\n",
" parameters={\n",
" \"url\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The URL to visit\",\n",
" required=True,\n",
" ),\n",
" \"topics_of_interest\": JSONSchema(\n",
" type=JSONSchema.Type.ARRAY,\n",
" items=JSONSchema(type=JSONSchema.Type.STRING),\n",
" description=(\n",
" \"A list of topics about which you want to extract information \"\n",
" \"from the page.\"\n",
" ),\n",
" required=False,\n",
" ),\n",
" \"question\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=(\n",
" \"A question you want to answer using the content of the webpage.\"\n",
" ),\n",
" required=False,\n",
" ),\n",
" \"get_raw_content\": JSONSchema(\n",
" type=JSONSchema.Type.BOOLEAN,\n",
" description=(\n",
" \"If true, the unprocessed content of the webpage will be returned. \"\n",
" \"This consumes a lot of tokens, so use it with caution.\"\n",
" ),\n",
" required=False,\n",
" ),\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"read_file\",\n",
" description=\"Read a file and return the contents\",\n",
" parameters={\n",
" \"filename\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The path of the file to read\",\n",
" required=True,\n",
" )\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"write_file\",\n",
" description=\"Write a file, creating it if necessary. If the file exists, it is overwritten.\",\n",
" parameters={\n",
" \"filename\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The name of the file to write to\",\n",
" required=True,\n",
" ),\n",
" \"contents\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The contents to write to the file\",\n",
" required=True,\n",
" ),\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"list_folder\",\n",
" description=\"List files in a folder recursively\",\n",
" parameters={\n",
" \"folder\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The folder to list files in\",\n",
" required=True,\n",
" )\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"ask_user\",\n",
" description=\"If you need more details or information regarding the given task, \"\n",
" \"you can ask the user for input.\",\n",
" parameters={\n",
" \"question\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The question or prompt to the user\",\n",
" required=True,\n",
" )\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"extract_value_with_ai\",\n",
" description=\"Magic function to extract information from a body with arbitrary format \"\n",
" \"into a variable of the specified type.\",\n",
" parameters={\n",
" \"input\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" required=True,\n",
" ),\n",
" \"instruction\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"Instruction on what information to extract and how to format the output\",\n",
" required=True,\n",
" ),\n",
" \"output_type\": JSONSchema(\n",
" type=JSONSchema.Type.TYPE,\n",
" default=str,\n",
" ),\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"extract_information\",\n",
" description=\"Extract information from a document\",\n",
" parameters={\n",
" \"document_content\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" required=True,\n",
" ),\n",
" \"topics_of_interest\": JSONSchema(\n",
" type=JSONSchema.Type.ARRAY,\n",
" items=JSONSchema(type=JSONSchema.Type.STRING),\n",
" required=True,\n",
" ),\n",
" },\n",
" ),\n",
" CompletionModelFunction(\n",
" name=\"implement_function_arguments\",\n",
" description=(\n",
" \"Magic function which, IF provided enough information, \"\n",
" \"will generate the keyword arguments necessary for a specific function.\"\n",
" ),\n",
" parameters={\n",
" \"target_function\": JSONSchema(\n",
" type=JSONSchema.Type.STRING,\n",
" description=\"The function for which to generate arguments\",\n",
" ),\n",
" \"**kwargs\": JSONSchema(\n",
" description=(\n",
" \"Any keyword arguments containing information that should be used \"\n",
" \"to determine the arguments for target_function.\"\n",
" )\n",
" ),\n",
" },\n",
" )\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"============== list ==============\n",
"Length: 5 messages\n",
"----------------- SYSTEM -----------------\n",
"You are , .\n",
"\n",
"## Your Task\n",
"The user will specify a task for you to execute, in triple quotes, in the next message. Your job is to complete the task, and terminate when your task is done.\n",
"\n",
"## Available Functions\n",
"def web_search(query: str, num_results: int = None):\n",
" \"\"\"\n",
" Searches the web\n",
" \n",
" Params:\n",
" query: The search query\n",
" num_results: The number of results to return\n",
" \"\"\"\n",
" ...\n",
"\n",
"def read_webpage(url: str, topics_of_interest: list[str] = None, question: str = None, get_raw_content: bool = None):\n",
" \"\"\"\n",
" Read a webpage, and extract specific information from it. You must specify either topics_of_interest, a question, or get_raw_content.\n",
" \n",
" Params:\n",
" url: The URL to visit\n",
" topics_of_interest: A list of topics about which you want to extract information from the page.\n",
" question: A question you want to answer using the content of the webpage.\n",
" get_raw_content: If true, the unprocessed content of the webpage will be returned. This consumes a lot of tokens, so use it with caution.\n",
" \"\"\"\n",
" ...\n",
"\n",
"def read_file(filename: str):\n",
" \"\"\"\n",
" Read a file and return the contents\n",
" \n",
" Params:\n",
" filename: The path of the file to read\n",
" \"\"\"\n",
" ...\n",
"\n",
"def write_file(filename: str, contents: str):\n",
" \"\"\"\n",
" Write a file, creating it if necessary. If the file exists, it is overwritten.\n",
" \n",
" Params:\n",
" filename: The name of the file to write to\n",
" contents: The contents to write to the file\n",
" \"\"\"\n",
" ...\n",
"\n",
"def list_folder(folder: str):\n",
" \"\"\"\n",
" List files in a folder recursively\n",
" \n",
" Params:\n",
" folder: The folder to list files in\n",
" \"\"\"\n",
" ...\n",
"\n",
"def ask_user(question: str):\n",
" \"\"\"\n",
" If you need more details or information regarding the given task, you can ask the user for input.\n",
" \n",
" Params:\n",
" question: The question or prompt to the user\n",
" \"\"\"\n",
" ...\n",
"\n",
"def extract_value_with_ai(input: str, instruction: str, output_type: type= <class 'str'>):\n",
" \"\"\"\n",
" Magic function to extract information from a body with arbitrary format into a variable of the specified type.\n",
" \n",
" Params:\n",
" instruction: Instruction on what information to extract and how to format the output\n",
" \"\"\"\n",
" ...\n",
"\n",
"def extract_information(document_content: str, topics_of_interest: list[str]):\n",
" \"\"\"\n",
" Extract information from a document\n",
" \n",
" Params:\n",
" \n",
" \"\"\"\n",
" ...\n",
"\n",
"def implement_function_arguments(target_function: str = None, **kwargs: Any = None):\n",
" \"\"\"\n",
" Magic function which, IF provided enough information, will generate the keyword arguments necessary for a specific function.\n",
" \n",
" Params:\n",
" target_function: The function for which to generate arguments\n",
" **kwargs: Any keyword arguments containing information that should be used to determine the arguments for target_function.\n",
" \"\"\"\n",
" ...\n",
"\n",
"## RESPONSE FORMAT\n",
"YOU MUST ALWAYS RESPOND WITH A JSON OBJECT OF THE FOLLOWING TYPE:\n",
"interface AssistantResponse {\n",
"thoughts: {\n",
"// Relevant observations from your last action (if any)\n",
"observations: string;\n",
"// Constructive self-criticism\n",
"self_criticism: string;\n",
"// Reasoning towards a new plan\n",
"reasoning: string;\n",
"// Short list that conveys your long-term plan. Parallelize where possible.\n",
"plan: Array<string>;\n",
"};\n",
"// We will be running an iterative process to execute the plan, Write the partial / immediate plan to execute your plan as detailed and efficiently as possible without the help of the reasoning/intelligence. The plan should describe the output of the immediate plan, so that the next iteration can be executed by taking the output into account. Try to do as much as possible without making any assumption or uninformed guesses. Avoid large output at all costs!!!Format: Objective[Objective of this iteration, explain what's the use of this iteration for the next one] Plan[Plan that does not require any reasoning or intelligence] Output[Output of the plan / should be small, avoid whole file output]\n",
"immediate_plan: string;\n",
"// Write the fully-functional Python code of the immediate plan. The output of the immediate plan should be a print statement, avoid printing the whole content!. Use ONLY the listed available functions and built-in Python features. Leverage the given magic functions to implement function calls for which the arguments can't be determined yet.\n",
"python_code: string;\n",
"}\n",
"------------------ USER ------------------\n",
"\"\"\"Figure out from file1.csv and file2.csv how much was spent on utilities\"\"\"\n",
"----------------- SYSTEM -----------------\n",
"## Context\n",
"<FolderContextItem description=\"The contents of the folder '.' in the workspace\" src=\".\" index=\"1\">\n",
"<file>file1.csv</file>\n",
"<file>file2.csv</file>\n",
"</FolderContextItem>\n",
"\n",
"When a context item is no longer needed and you are not done yet, you can hide the item by specifying its index in the list above to `close_context_item`.\n",
"----------------- SYSTEM -----------------\n",
"Previous plan:\n",
"1. \n",
"Plan: Objective[Read file1.csv to understand its structure and content] Plan[Read content of 'file1.csv' using the read_file function] Output[Print out the first few lines of file1.csv to deduce information about utilities spending from its structure]\n",
"Output: ID,CATEGORY,AMOUNT\n",
"1,Utilities,100\n",
"2,Food,200\n",
"3,Utilities,150\n",
"4,Transport,50\n",
"5,Utilities,120\n",
"6,Food,180\n",
"7,Utilities,130\n",
"8,Transport,70\n",
"9,Utilities,140\n",
"10,Food,220\n",
"\n",
"2. \n",
"Plan: Objective[Read the first few lines of 'file2.csv' to understand its structure] Plan[Read content of 'file2.csv' using the read_file function and output the first few lines] Output[Provide structure of 'file2.csv' to verify it matches 'file1.csv']\n",
"Output: ID,CATEGORY,AMOUNT\n",
"1,Utilities,123\n",
"2,Food,200\n",
"4,Utilities,151\n",
"4,Transport,50\n",
"5,Utilities,120\n",
"6,Food,180\n",
"7,Utilities,130\n",
"8,Transport,70\n",
"9,Utilities,140\n",
"10,Food,220\n",
"\n",
"------------------ USER ------------------\n",
"Write Python code to execute your plan as efficiently as possible. Your code will be executed directly without any editing: if it doesn't work you will be held responsible. Use ONLY the listed available functions and built-in Python features. Do not make uninformed assumptions (e.g. about the content or format of an unknown file). Leverage the given magic functions to implement function calls for which the arguments can't be determined yet. Reduce the amount of unnecessary data passed into these magic functions where possible, because magic costs money and magically processing large amounts of data is expensive.\n",
"==========================================\n",
"\n",
"2024-05-11 10:27:36,657 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mclose.started\u001b[0m\n",
"2024-05-11 10:27:36,659 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mclose.complete\u001b[0m\n",
"2024-05-11 10:27:36,659 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mconnect_tcp.started host='api.openai.com' port=443 local_address=None timeout=5.0 socket_options=None\u001b[0m\n",
"2024-05-11 10:27:36,708 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mconnect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x11b888ec0>\u001b[0m\n",
"2024-05-11 10:27:36,709 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mstart_tls.started ssl_context=<ssl.SSLContext object at 0x11c124950> server_hostname='api.openai.com' timeout=5.0\u001b[0m\n",
"2024-05-11 10:27:36,729 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mstart_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x11b8893d0>\u001b[0m\n",
"2024-05-11 10:27:36,730 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_headers.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:36,730 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_headers.complete\u001b[0m\n",
"2024-05-11 10:27:36,731 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_body.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:36,731 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_body.complete\u001b[0m\n",
"2024-05-11 10:27:36,732 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_headers.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:57,435 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Date', b'Sat, 11 May 2024 08:27:57 GMT'), (b'Content-Type', b'application/json'), (b'Transfer-Encoding', b'chunked'), (b'Connection', b'keep-alive'), (b'openai-organization', b'significant-gravitas'), (b'openai-processing-ms', b'20457'), (b'openai-version', b'2020-10-01'), (b'strict-transport-security', b'max-age=15724800; includeSubDomains'), (b'x-ratelimit-limit-requests', b'10000'), (b'x-ratelimit-limit-tokens', b'2000000'), (b'x-ratelimit-remaining-requests', b'9999'), (b'x-ratelimit-remaining-tokens', b'1998414'), (b'x-ratelimit-reset-requests', b'6ms'), (b'x-ratelimit-reset-tokens', b'47ms'), (b'x-request-id', b'req_8b76a07434fc268fa8448f9e10f21de6'), (b'CF-Cache-Status', b'DYNAMIC'), (b'Server', b'cloudflare'), (b'CF-RAY', b'8820ca72c8ef247e-ZAG'), (b'Content-Encoding', b'gzip'), (b'alt-svc', b'h3=\":443\"; ma=86400')])\u001b[0m\n",
"2024-05-11 10:27:57,438 \u001b[34mINFO\u001b[0m _client.py:1729 HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
"2024-05-11 10:27:57,439 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_body.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:57,441 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_body.complete\u001b[0m\n",
"2024-05-11 10:27:57,442 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mresponse_closed.started\u001b[0m\n",
"2024-05-11 10:27:57,443 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mresponse_closed.complete\u001b[0m\n",
"2024-05-11 10:27:57,445 \u001b[90mDEBUG\u001b[0m openai.py:638 \u001b[90mCompletion usage: 1407 input, 419 output - $0.02664\u001b[0m\n",
"2024-05-11 10:27:57,445 \u001b[90mDEBUG\u001b[0m 2794315326.py:188 \u001b[90mLLM response content:\n",
"```python\n",
"def process_csv_file(filename):\n",
" # Read the CSV file into memory\n",
" content = read_file(filename)\n",
" # Split the content into lines\n",
" lines = content.strip().split('\\n')\n",
" \n",
" # Extract the header line\n",
" headers = lines[0].split(',')\n",
" \n",
" # Find the index of the 'CATEGORY' and 'AMOUNT' columns to ensure we collect the correct data\n",
" try:\n",
" category_index = headers.index('CATEGORY')\n",
" amount_index = headers.index('AMOUNT')\n",
" except ValueError:\n",
" # In case one of the necessary columns is missing\n",
" return f\"Error: One of the columns 'CATEGORY' or 'AMOUNT' is missing in {filename}\"\n",
" \n",
" # Initialize variable to sum utilities\n",
" total_utilities_spent = 0\n",
" \n",
" # Iterate over each line after the header\n",
" for line in lines[1:]:\n",
" fields = line.split(',')\n",
" # Check if the category is 'Utilities' and add the amount to total\n",
" if fields[category_index].strip() == 'Utilities':\n",
" try:\n",
" total_utilities_spent += float(fields[amount_index])\n",
" except ValueError:\n",
" # In case the amount is not a valid float\n",
" return f\"Error: Non-numeric amount in {filename}\"\n",
" \n",
" return total_utilities_spent\n",
"\n",
"# Process both files and sum the utilities expenses\n",
"total_utilities_spent_file1 = process_csv_file('file1.csv')\n",
"total_utilities_spent_file2 = process_csv_file('file2.csv')\n",
"\n",
"if isinstance(total_utilities_spent_file1, float) and isinstance(total_utilities_spent_file2, float):\n",
" grand_total = total_utilities_spent_file1 + total_utilities_spent_file2\n",
" print(f\"Total spent on utilities: {grand_total}\")\n",
"else:\n",
" # Handle errors if any\n",
" if not isinstance(total_utilities_spent_file1, float):\n",
" print(total_utilities_spent_file1)\n",
" if not isinstance(total_utilities_spent_file2, float):\n",
" print(total_utilities_spent_file2)\n",
"```\u001b[0m\n",
"2024-05-11 10:27:57,447 \u001b[90mDEBUG\u001b[0m json_utils.py:38 \u001b[90mJSON parse errors:\n",
"('Unknown identifier', 'python')\n",
"Unexpected text after end of JSON value\u001b[0m\n",
"2024-05-11 10:27:57,448 \u001b[90mDEBUG\u001b[0m openai.py:467 \u001b[90mParsing failed on response: '''ChatCompletionMessage(content='```python\\ndef process_csv_file(filename):\\n # Read the CSV file into memory\\n content = read_file(filename)\\n # Split the content into lines\\n lines = content.strip().split(\\'\\\\n\\')\\n \\n # Extract the header line\\n headers = lines[0].split(\\',\\')\\n \\n # Find the index of the \\'CATEGORY\\' and \\'AMOUNT\\' columns to ensure we collect the correct data\\n try:\\n category_index = headers.index(\\'CATEGORY\\')\\n amount_index = headers.index(\\'AMOUNT\\')\\n except ValueError:\\n # In case one of the necessary columns is missing\\n return f\"Error: One of the columns \\'CATEGORY\\' or \\'AMOUNT\\' is missing in {filename}\"\\n \\n # Initialize variable to sum utilities\\n total_utilities_spent = 0\\n \\n # Iterate over each line after the header\\n for line in lines[1:]:\\n fields = line.split(\\',\\')\\n # Check if the category is \\'Utilities\\' and add the amount to total\\n if fields[category_index].strip() == \\'Utilities\\':\\n try:\\n total_utilities_spent += float(fields[amount_index])\\n except ValueError:\\n # In case the amount is not a valid float\\n return f\"Error: Non-numeric amount in {filename}\"\\n \\n return total_utilities_spent\\n\\n# Process both files and sum the utilities expenses\\ntotal_utilities_spent_file1 = process_csv_file(\\'file1.csv\\')\\ntotal_utilities_spent_file2 = process_csv_file(\\'file2.csv\\')\\n\\nif isinstance(total_utilities_spent_file1, float) and isinstance(total_utilities_spent_file2, float):\\n grand_total = total_utilities_spent_file1 + total_utilities_spent_file2\\n print(f\"Total spent on utilities: {grand_total}\")\\nelse:\\n # Handle errors if any\\n if not isinstance(total_utilities_spent_file1, float):\\n print(total_utilities_spent_file1)\\n if not isinstance(total_utilities_spent_file2, float):\\n print(total_utilities_spent_file2)\\n```', role='assistant', function_call=None, tool_calls=None)'''\u001b[0m\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-05-11 10:27:57,448 \u001b[33mWARNING\u001b[0m openai.py:473 \u001b[33mParsing attempt #1 failed: ValueError: ('Failed to parse JSON string: python\\ndef process_csv_file(filename):\\n # Read the CSV file into memory\\n content = read_file(filename)\\n # Split the content into lines\\n lines = content.strip().split(\\'\\\\n\\')\\n \\n # Extract the header line\\n headers = lines[0].split(\\',\\')\\n \\n # Find the index of the \\'CATEGORY\\' and \\'AMOUNT\\' columns to ensure we collect the correct data\\n try:\\n category_index = headers.index(\\'CATEGORY\\')\\n amount_index = headers.index(\\'AMOUNT\\')\\n except ValueError:\\n # In case one of the necessary columns is missing\\n return f\"Error: One of the columns \\'CATEGORY\\' or \\'AMOUNT\\' is missing in {filename}\"\\n \\n # Initialize variable to sum utilities\\n total_utilities_spent = 0\\n \\n # Iterate over each line after the header\\n for line in lines[1:]:\\n fields = line.split(\\',\\')\\n # Check if the category is \\'Utilities\\' and add the amount to total\\n if fields[category_index].strip() == \\'Utilities\\':\\n try:\\n total_utilities_spent += float(fields[amount_index])\\n except ValueError:\\n # In case the amount is not a valid float\\n return f\"Error: Non-numeric amount in {filename}\"\\n \\n return total_utilities_spent\\n\\n# Process both files and sum the utilities expenses\\ntotal_utilities_spent_file1 = process_csv_file(\\'file1.csv\\')\\ntotal_utilities_spent_file2 = process_csv_file(\\'file2.csv\\')\\n\\nif isinstance(total_utilities_spent_file1, float) and isinstance(total_utilities_spent_file2, float):\\n grand_total = total_utilities_spent_file1 + total_utilities_spent_file2\\n print(f\"Total spent on utilities: {grand_total}\")\\nelse:\\n # Handle errors if any\\n if not isinstance(total_utilities_spent_file1, float):\\n print(total_utilities_spent_file1)\\n if not isinstance(total_utilities_spent_file2, float):\\n print(total_utilities_spent_file2)', JSONDecodeError('Unknown identifier', 'python', position=position_marker(offset=0,line=1,column=0), severity='error'), JSONDecodeError('Unexpected text after end of JSON value', position=position_marker(offset=7,line=2,column=0), severity='error'))\u001b[0m\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2024-05-11 10:27:57,456 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_headers.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:57,457 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_headers.complete\u001b[0m\n",
"2024-05-11 10:27:57,458 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_body.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:27:57,459 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90msend_request_body.complete\u001b[0m\n",
"2024-05-11 10:27:57,459 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_headers.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:28:12,244 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Date', b'Sat, 11 May 2024 08:28:12 GMT'), (b'Content-Type', b'application/json'), (b'Transfer-Encoding', b'chunked'), (b'Connection', b'keep-alive'), (b'openai-organization', b'significant-gravitas'), (b'openai-processing-ms', b'14429'), (b'openai-version', b'2020-10-01'), (b'strict-transport-security', b'max-age=15724800; includeSubDomains'), (b'x-ratelimit-limit-requests', b'10000'), (b'x-ratelimit-limit-tokens', b'2000000'), (b'x-ratelimit-remaining-requests', b'9999'), (b'x-ratelimit-remaining-tokens', b'1997371'), (b'x-ratelimit-reset-requests', b'6ms'), (b'x-ratelimit-reset-tokens', b'78ms'), (b'x-request-id', b'req_9703e9c849bcfa1f9f369a5ea408f341'), (b'CF-Cache-Status', b'DYNAMIC'), (b'Server', b'cloudflare'), (b'CF-RAY', b'8820caf45d97247e-ZAG'), (b'Content-Encoding', b'gzip'), (b'alt-svc', b'h3=\":443\"; ma=86400')])\u001b[0m\n",
"2024-05-11 10:28:12,245 \u001b[34mINFO\u001b[0m _client.py:1729 HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
"2024-05-11 10:28:12,246 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_body.started request=<Request [b'POST']>\u001b[0m\n",
"2024-05-11 10:28:12,248 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mreceive_response_body.complete\u001b[0m\n",
"2024-05-11 10:28:12,249 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mresponse_closed.started\u001b[0m\n",
"2024-05-11 10:28:12,249 \u001b[90mDEBUG\u001b[0m _trace.py:85 \u001b[90mresponse_closed.complete\u001b[0m\n",
"2024-05-11 10:28:12,252 \u001b[90mDEBUG\u001b[0m openai.py:638 \u001b[90mCompletion usage: 2391 input, 417 output - $0.03642\u001b[0m\n",
"2024-05-11 10:28:12,252 \u001b[90mDEBUG\u001b[0m 2794315326.py:188 \u001b[90mLLM response content:\n",
"{\n",
" \"thoughts\": {\n",
" \"observations\": \"The user has asked for a code script that sums the amount spent on utilities as listed in two CSV files: 'file1.csv' and 'file2.csv'. Both files follow the same format with headers 'ID', 'CATEGORY', and 'AMOUNT'.\",\n",
" \"self_criticism\": \"The detailed structure and way of accumulating the data were determined. Ready to implement the code.\",\n",
" \"reasoning\": \"To get the total amount spent on utilities from both files, we should read each file, filter out the rows where the category is 'Utilities', sum the 'AMOUNT' column for those rows, and sum the totals from both files.\",\n",
" \"plan\": [\n",
" \"Read the data from 'file1.csv'\",\n",
" \"Extract entries related to 'Utilities' and sum the 'AMOUNT' values\",\n",
" \"Repeat the process for 'file2.csv'\",\n",
" \"Add the results from both files to get the total utilities expense\",\n",
" \"Provide the final output summarizing the total spent on utilities\"\n",
" ]\n",
" },\n",
" \"immediate_plan\": \"Objective[Extract expenses related to 'Utilities' from 'file1.csv' and 'file2.csv', and sum them up] Plan[Read content of 'file1.csv' and 'file2.csv', extract lines with 'Utilities', sum the amounts, and output the total spend on utilities] Output[Sum of the amounts spent on utilities]\",\n",
" \"python_code\": \"total_utilities_sum_file1 = sum(float(line.split(',')[2].strip()) for line in read_file('file1.csv').splitlines()[1:] if 'Utilities' in line)\\ntotal_utilities_sum_file2 = sum(float(line.split(',')[2].strip()) for line in read_file('file2.csv').splitlines()[1:] if 'Utilities' in line)\\ntotal_spent_on_utilities = total_utilities_sum_file1 + total_utilities_sum_file2\\nprint(f'Total spent on utilities: {total_spent_on_utilities}')\" \n",
"}\u001b[0m\n",
"2024-05-11 10:28:12,255 \u001b[90mDEBUG\u001b[0m 2794315326.py:197 \u001b[90mParsing object extracted from LLM response:\n",
"{\n",
" \"thoughts\": {\n",
" \"observations\": \"The user has asked for a code script that sums the amount spent on utilities as listed in two CSV files: 'file1.csv' and 'file2.csv'. Both files follow the same format with headers 'ID', 'CATEGORY', and 'AMOUNT'.\",\n",
" \"self_criticism\": \"The detailed structure and way of accumulating the data were determined. Ready to implement the code.\",\n",
" \"reasoning\": \"To get the total amount spent on utilities from both files, we should read each file, filter out the rows where the category is 'Utilities', sum the 'AMOUNT' column for those rows, and sum the totals from both files.\",\n",
" \"plan\": [\n",
" \"Read the data from 'file1.csv'\",\n",
" \"Extract entries related to 'Utilities' and sum the 'AMOUNT' values\",\n",
" \"Repeat the process for 'file2.csv'\",\n",
" \"Add the results from both files to get the total utilities expense\",\n",
" \"Provide the final output summarizing the total spent on utilities\"\n",
" ]\n",
" },\n",
" \"immediate_plan\": \"Objective[Extract expenses related to 'Utilities' from 'file1.csv' and 'file2.csv', and sum them up] Plan[Read content of 'file1.csv' and 'file2.csv', extract lines with 'Utilities', sum the amounts, and output the total spend on utilities] Output[Sum of the amounts spent on utilities]\",\n",
" \"python_code\": \"total_utilities_sum_file1 = sum(float(line.split(',')[2].strip()) for line in read_file('file1.csv').splitlines()[1:] if 'Utilities' in line)\\ntotal_utilities_sum_file2 = sum(float(line.split(',')[2].strip()) for line in read_file('file2.csv').splitlines()[1:] if 'Utilities' in line)\\ntotal_spent_on_utilities = total_utilities_sum_file1 + total_utilities_sum_file2\\nprint(f'Total spent on utilities: {total_spent_on_utilities}')\"\n",
"}\u001b[0m\n",
"2024-05-11 10:28:12,256 \u001b[90mDEBUG\u001b[0m openai.py:451 \u001b[90mTotal cost for 2 attempts: $0.06306\u001b[0m\n",
"total_utilities_sum_file1 = sum(float(line.split(',')[2].strip()) for line in read_file('file1.csv').splitlines()[1:] if 'Utilities' in line)\n",
"total_utilities_sum_file2 = sum(float(line.split(',')[2].strip()) for line in read_file('file2.csv').splitlines()[1:] if 'Utilities' in line)\n",
"total_spent_on_utilities = total_utilities_sum_file1 + total_utilities_sum_file2\n",
"print(f'Total spent on utilities: {total_spent_on_utilities}')\n"
]
}
],
"source": [
"from autogpt.core.resource.model_providers.anthropic import AnthropicModelName\n",
"from autogpt.core.resource.model_providers.openai import OpenAIModelName\n",
"from autogpt.core.runner.client_lib.logging.helpers import dump_prompt\n",
"\n",
"prompter = OneShotFlowAgentPromptStrategy()\n",
"\n",
"prev_plan = [\n",
" (\n",
" \"Objective[Read file1.csv to understand its structure and content] Plan[Read content of 'file1.csv' using the read_file function] Output[Print out the first few lines of file1.csv to deduce information about utilities spending from its structure]\",\n",
" \"ID,CATEGORY,AMOUNT\\n1,Utilities,100\\n2,Food,200\\n3,Utilities,150\\n4,Transport,50\\n5,Utilities,120\\n6,Food,180\\n7,Utilities,130\\n8,Transport,70\\n9,Utilities,140\\n10,Food,220\\n\",\n",
" ),\n",
" (\n",
" \"Objective[Read the first few lines of 'file2.csv' to understand its structure] Plan[Read content of 'file2.csv' using the read_file function and output the first few lines] Output[Provide structure of 'file2.csv' to verify it matches 'file1.csv']\",\n",
" \"ID,CATEGORY,AMOUNT\\n1,Utilities,123\\n2,Food,200\\n4,Utilities,151\\n4,Transport,50\\n5,Utilities,120\\n6,Food,180\\n7,Utilities,130\\n8,Transport,70\\n9,Utilities,140\\n10,Food,220\\n\",\n",
" )\n",
"]\n",
"\n",
"prompt = prompter.build_prompt(\n",
" task=\"Figure out from file1.csv and file2.csv how much was spent on utilities\",\n",
" messages=[\n",
" ChatMessage.system(\n",
" \"## Context\\n\"\n",
" '<FolderContextItem '\n",
" 'description=\"The contents of the folder \\'.\\' in the workspace\" '\n",
" 'src=\".\" index=\"1\">\\n'\n",
" \"<file>file1.csv</file>\\n\"\n",
" \"<file>file2.csv</file>\\n\"\n",
" \"</FolderContextItem>\"\n",
" \"\\n\\n\"\n",
" \"When a context item is no longer needed and you are not done yet, \"\n",
" \"you can hide the item by specifying its index in the list above \"\n",
" f\"to `close_context_item`.\",\n",
" ),\n",
" ChatMessage.system(\n",
" \"Previous plan:\\n\" +\n",
" format_numbered_list([f\"\\nPlan: {plan[0]}\\nOutput: {plan[1]}\" for plan in prev_plan]),\n",
" ),\n",
" ],\n",
" ai_profile=AIProfile(),\n",
" ai_directives=AIDirectives(),\n",
" functions=tools,\n",
")\n",
"print(dump_prompt(prompt))\n",
"\n",
"result = await llm.create_chat_completion(\n",
" # model_name=AnthropicModelName.CLAUDE3_OPUS_v1,\n",
" model_name=OpenAIModelName.GPT4_TURBO,\n",
" model_prompt=prompt.messages,\n",
" prefill_response=prompt.prefill_response,\n",
" completion_parser=prompter.parse_response_content,\n",
")\n",
"\n",
"print(result.parsed_result.python_code)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -211,13 +211,6 @@ class FunctionVisitor(ast.NodeVisitor):
)
self.objectsIdx.append(node.lineno)
"""Some class are simply used as a type and doesn't have any new fields"""
# if not is_implemented:
# raise ValidationError(
# f"Class {node.name} is not implemented. "
# f"Please complete the implementation of this class!"
# )
def visit(self, node):
if (
isinstance(node, ast.Assign)