diff --git a/autogpt/app/main.py b/autogpt/app/main.py index 10fd8fd8..036c7cd7 100644 --- a/autogpt/app/main.py +++ b/autogpt/app/main.py @@ -338,10 +338,7 @@ def run_interaction_loop( result = agent.execute(command_name, command_args, user_input) if result.status == "success": - logger.info( - str(result.results), - extra={"title": "SYSTEM:", "title_color": Fore.YELLOW}, - ) + logger.info(result, extra={"title": "SYSTEM:", "title_color": Fore.YELLOW}) elif result.status == "error": logger.warn( f"Command {command_name} returned an error: {result.error or result.reason}" diff --git a/autogpt/commands/execute_code.py b/autogpt/commands/execute_code.py index 98500cf7..77a678b6 100644 --- a/autogpt/commands/execute_code.py +++ b/autogpt/commands/execute_code.py @@ -122,7 +122,7 @@ def execute_python_file(filename: Path, agent: Agent) -> str: f"Auto-GPT is running in a Docker container; executing {file_path} directly..." ) result = subprocess.run( - ["python", str(file_path)], + ["python", "-B", str(file_path)], capture_output=True, encoding="utf8", cwd=agent.config.workspace_path, @@ -162,6 +162,7 @@ def execute_python_file(filename: Path, agent: Agent) -> str: image_name, [ "python", + "-B", file_path.relative_to(agent.workspace.root).as_posix(), ], volumes={ diff --git a/autogpt/commands/system.py b/autogpt/commands/system.py index 643b67fe..91cf6572 100644 --- a/autogpt/commands/system.py +++ b/autogpt/commands/system.py @@ -53,7 +53,7 @@ def task_complete(reason: str, agent: Agent) -> None: "required": True, } }, - available=lambda a: get_agent_context(a) is not None, + available=lambda a: bool(get_agent_context(a)), ) def close_context_item(index: int, agent: Agent) -> str: assert (context := get_agent_context(agent)) is not None diff --git a/autogpt/commands/web_selenium.py b/autogpt/commands/web_selenium.py index f801ffac..031f0acb 100644 --- a/autogpt/commands/web_selenium.py +++ b/autogpt/commands/web_selenium.py @@ -56,24 +56,24 @@ class BrowsingError(CommandExecutionError): @command( - "browse_website", - "Browses a Website", + "read_webpage", + "Read a webpage, and extract specific information from it if a question is specified.", { "url": {"type": "string", "description": "The URL to visit", "required": True}, "question": { "type": "string", - "description": "What you want to find on the website", - "required": True, + "description": "A question that you want to answer using the content of the webpage.", + "required": False, }, }, ) @validate_url -def browse_website(url: str, question: str, agent: Agent) -> str: +def read_webpage(url: str, agent: Agent, question: str = "") -> str: """Browse a website and return the answer and links to the user Args: url (str): The url of the website to browse - question (str): The question asked by the user + question (str): The question to answer using the content of the webpage Returns: str: The answer and links to the user and the webdriver @@ -85,16 +85,28 @@ def browse_website(url: str, question: str, agent: Agent) -> str: text = scrape_text_with_selenium(driver) links = scrape_links_with_selenium(driver, url) + return_literal_content = True + summarized = False if not text: return f"Website did not contain any text.\n\nLinks: {links}" elif count_string_tokens(text, agent.llm.name) > TOKENS_TO_TRIGGER_SUMMARY: - text = summarize_memorize_webpage(url, text, question, agent, driver) + text = summarize_memorize_webpage( + url, text, question or None, agent, driver + ) + return_literal_content = bool(question) + summarized = True # Limit links to LINKS_TO_RETURN if len(links) > LINKS_TO_RETURN: links = links[:LINKS_TO_RETURN] - return f"Answer gathered from website: {text}\n\nLinks: {links}" + text_fmt = f"'''{text}'''" if "\n" in text else f"'{text}'" + return ( + f"Page content{' (summary)' if summarized else ''}:" + if return_literal_content + else "Answer gathered from webpage:" + ) + f" {text_fmt}\n\nLinks: {links}" + except WebDriverException as e: # These errors are often quite long and include lots of context. # Just grab the first line. @@ -236,7 +248,7 @@ def close_browser(driver: WebDriver) -> None: def summarize_memorize_webpage( url: str, text: str, - question: str, + question: str | None, agent: Agent, driver: Optional[WebDriver] = None, ) -> str: diff --git a/autogpt/llm/api_manager.py b/autogpt/llm/api_manager.py index e1763a17..09d6a0db 100644 --- a/autogpt/llm/api_manager.py +++ b/autogpt/llm/api_manager.py @@ -45,7 +45,7 @@ class ApiManager(metaclass=Singleton): self.total_prompt_tokens += prompt_tokens self.total_completion_tokens += completion_tokens self.total_cost += prompt_tokens * model_info.prompt_token_cost / 1000 - if issubclass(type(model_info), CompletionModelInfo): + if isinstance(model_info, CompletionModelInfo): self.total_cost += ( completion_tokens * model_info.completion_token_cost / 1000 ) diff --git a/tests/Auto-GPT-test-cassettes b/tests/Auto-GPT-test-cassettes index 1588dcc0..baee81d4 160000 --- a/tests/Auto-GPT-test-cassettes +++ b/tests/Auto-GPT-test-cassettes @@ -1 +1 @@ -Subproject commit 1588dcc09cff5cf60012c84eaba9e84951155acb +Subproject commit baee81d40371d705dbae520d950923f373af48e0 diff --git a/tests/integration/test_web_selenium.py b/tests/integration/test_web_selenium.py index a4b945af..e935bb00 100644 --- a/tests/integration/test_web_selenium.py +++ b/tests/integration/test_web_selenium.py @@ -1,7 +1,7 @@ import pytest from autogpt.agents.agent import Agent -from autogpt.commands.web_selenium import BrowsingError, browse_website +from autogpt.commands.web_selenium import BrowsingError, read_webpage @pytest.mark.vcr @@ -11,7 +11,7 @@ def test_browse_website_nonexistent_url(agent: Agent, patched_api_requestor: Non question = "How to execute a barrel roll" with pytest.raises(BrowsingError, match=r"NAME_NOT_RESOLVED") as raised: - browse_website(url, question, agent) + read_webpage(url=url, question=question, agent=agent) # Sanity check that the response is not too long assert len(raised.exconly()) < 200