diff --git a/metagpt/prompts/di/role_zero.py b/metagpt/prompts/di/role_zero.py index 5bf1e15fc..408bb838d 100644 --- a/metagpt/prompts/di/role_zero.py +++ b/metagpt/prompts/di/role_zero.py @@ -7,6 +7,8 @@ Note: 1. If you keeping encountering errors, unexpected situation, or you are not sure of proceeding, use RoleZero.ask_human to ask for help. 2. Carefully review your progress at the current task, if your actions so far has not fulfilled the task instruction, you should continue with current task. Otherwise, finish current task by Plan.finish_current_task explicitly. 3. Each time you finish a task, use RoleZero.reply_to_human to report your progress. +4. Don't forget to append task first when all existing tasks are finished and new tasks are required. +5. Avoid repeating tasks you have already completed. And end loop when all requirements are met. """ # To ensure compatibility with hard-coded experience, do not add any other content between "# Example" and "# Available Commands". CMD_PROMPT = """ @@ -43,7 +45,7 @@ If you finish current task, you will automatically take the next task in the exi Pay close attention to what you have done. Be different with your previous action. # Your commands in a json array, in the following output format with correct command_name and args. If there is nothing to do, use the pass or end command: -Some text indicating your thoughts, such as how you should update the plan status, respond to inquiry, or seek for help. Then a json array of commands. You must output ONE and ONLY ONE json array. DON'T output multiple json arrays with thoughts between them. +Some text indicating your thoughts before JSON is required, such as what tasks have been completed, what tasks are next, how you should update the plan status, respond to inquiry, or seek for help. Then a json array of commands. You must output ONE and ONLY ONE json array. DON'T output multiple json arrays with thoughts between them. ```json [ {{ diff --git a/metagpt/prompts/task_type.py b/metagpt/prompts/task_type.py index 312421c21..2e4af4c1d 100644 --- a/metagpt/prompts/task_type.py +++ b/metagpt/prompts/task_type.py @@ -56,6 +56,6 @@ The current task is about converting image into webpage code. please note the fo # Prompt for taking on "web_scraping" tasks WEB_SCRAPING_PROMPT = """ -- Remember to view and print the necessary HTML content in a separate task to understand the structure first before scraping data. +- Remember to view and print the necessary HTML content in a separate task to understand the structure first before scraping data. Such as `html_content = await view_page_element_to_scrape(...)\nprint(html_content)`. - Since the data required by user may not correspond directly to the actual HTML element names, you should thoroughly analyze the HTML structure and meanings of all elements in the executing result first. Ensure the `class_` in your code should derived from the actual HTML structure directly, not based on your knowledge. To ensure it, analyse the most suitable location of the 'class_' in the actual HTML content before code. """ diff --git a/metagpt/roles/di/data_analyst.py b/metagpt/roles/di/data_analyst.py index 2b1bb10b1..c52127527 100644 --- a/metagpt/roles/di/data_analyst.py +++ b/metagpt/roles/di/data_analyst.py @@ -105,5 +105,7 @@ class DataAnalyst(RoleZero): status = 'Success' if success else 'Failed' output = CODE_STATUS.format(code=code, status=status, result=result) + if success: + output += 'The code written has been executed successfully.' self.rc.working_memory.clear() return output diff --git a/metagpt/strategy/experience_retriever.py b/metagpt/strategy/experience_retriever.py index 7a943fc7f..0f805d44c 100644 --- a/metagpt/strategy/experience_retriever.py +++ b/metagpt/strategy/experience_retriever.py @@ -640,8 +640,10 @@ class KeywordExpRetriever(ExpRetriever): return DEPLOY_EXAMPLE elif "issue" in context.lower(): return FIX_ISSUE_EXAMPLE - elif "https:" or "http:" in context.lower(): - return WEB_SCRAPING_EXAMPLE + elif "https:" in context.lower() or "http:" in context.lower(): + if "search" in context.lower() or "click" in context.lower(): + return WEB_SCRAPING_EXAMPLE + return WEB_SCRAPING_EXAMPLE_SIMPLE elif exp_type == "task": if "diagnose" in context.lower(): return SEARCH_SYMBOL_EXAMPLE @@ -918,7 +920,7 @@ Explanation: The requirement is to scrape data from a website and extract inform "task_id": "1", "dependent_task_ids": [], "instruction": "Navigate to the yelp website.", - "assignee": "Browser" + "assignee": "David" } }, { @@ -927,7 +929,7 @@ Explanation: The requirement is to scrape data from a website and extract inform "task_id": "2", "dependent_task_ids": ["1"], "instruction": "Search for restaurants with the keyword 'beef'.", - "assignee": "Browser" + "assignee": "David" } }, { @@ -936,7 +938,7 @@ Explanation: The requirement is to scrape data from a website and extract inform "task_id": "3", "dependent_task_ids": ["2"], "instruction": "View the html content of the search result page before scrap data to understand the structure.", - "assignee": "DataAnalyst" + "assignee": "David" } }, { @@ -945,7 +947,7 @@ Explanation: The requirement is to scrape data from a website and extract inform "task_id": "4", "dependent_task_ids": ["3"], "instruction": "Parse the html content to scrape the restaurant names and print it.", - "assignee": "DataAnalyst" + "assignee": "David" } } ] @@ -953,7 +955,6 @@ Explanation: The requirement is to scrape data from a website and extract inform ## action 2 Explanation: To search for restaurants, I will now go to the website https://www.yelp.com/ first. -Here is the command to navigate to the website: ```json [ @@ -968,7 +969,6 @@ Here is the command to navigate to the website: ## action 3 Explanation: Since the Browser has successfully navigated to the website, and I find that the element id of the search box is 53. I will finish the current task and then use the Browser tool to type the keyword `beef` in the search box and press enter. -Here is the command to finish the current task and type the keyword: ```json [ @@ -989,7 +989,6 @@ Here is the command to finish the current task and type the keyword: ## action 4 Explanation: Since the Browser has successfully search the keyword `beef`, I will finish the current task and then write code to view the html content of the page. -Here is the command to finish the current task and view the html content: ```json [ @@ -1005,8 +1004,7 @@ Here is the command to finish the current task and view the html content: ``` ## action 5 -Explanation: Since the DataAnalyst has successfully viewed the html content of the page, I will finish the current task and then write code to parse the html content and extract the restaurant names. -Here is the command to finish the current task and parse the html content: +Explanation: Since I has successfully viewed the html content in the context, I will first finish the current task and then write code to parse the html content and extract the restaurant names. ```json [ @@ -1022,3 +1020,62 @@ Here is the command to finish the current task and parse the html content: ... """ + + +WEB_SCRAPING_EXAMPLE_SIMPLE = """ +## action 1 +User Requirement: List the restaurant names on the website https://www.yelp.com/search?find_desc=beef&find_loc=New+York%2C+NY. +Explanation: The requirement is to scrape data from a website and extract information about restaurants. The process involves retrieving and presenting the data in a structured format. + +```json +[ + { + "command_name": "Plan.append_task", + "args": { + "task_id": "1", + "dependent_task_ids": [], + "instruction": "View the html content of the page before scrap data to understand the structure.", + "assignee": "David" + } + }, + { + "command_name": "Plan.append_task", + "args": { + "task_id": "2", + "dependent_task_ids": ["1"], + "instruction": "Parse the html content to scrape the restaurant names and print it.", + "assignee": "David" + } + } +] +``` + +## action 2 +Explanation: To scrap data from the website, I will first view the html content of the page. + +```json +[ + { + "command_name": "DataAnalyst.write_and_exec_code", + "args": {} + } +] +``` + +## action 3 +Explanation: Since I has successfully viewed the html content in the context, I will first finish the current task and then write code to parse the html content and extract the restaurant names. + +```json +[ + { + "command_name": "Plan.finish_current_task", + "args": {} + }, + { + "command_name": "DataAnalyst.write_and_exec_code", + "args": {} + } +] +``` +... +""" diff --git a/metagpt/strategy/planner.py b/metagpt/strategy/planner.py index 95ad1f5cc..d195cc03b 100644 --- a/metagpt/strategy/planner.py +++ b/metagpt/strategy/planner.py @@ -47,7 +47,7 @@ PLAN_STATUS = """ {current_task_result} ## Task Guidance -Write code for the incomplete sections of 'Current Task'. And avoid duplicating code from 'Finished Tasks', such as repeated import of packages, reading data, etc. +Write code for the incomplete sections of 'Current Task'. And avoid duplicating code from 'Finished Tasks' and 'Finished Section of Current Task', such as repeated import of packages, reading data, etc. Specifically, {guidance} """ diff --git a/metagpt/tools/libs/browser.py b/metagpt/tools/libs/browser.py index 4a6d13eec..a458109e6 100644 --- a/metagpt/tools/libs/browser.py +++ b/metagpt/tools/libs/browser.py @@ -162,7 +162,7 @@ class Browser: await self._wait_until_page_idle(page) self.accessibility_tree = await get_accessibility_tree(page) await self.reporter.async_report(page, "page") - return f"SUCCESS, URL: {page.url}" + return f"SUCCESS, URL: {page.url} have been loaded." def _register_page_event(self, page: Page): page.last_busy_time = time.time()