From 9cc70f665127b04ac9f442b327d3cbd0e3888faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=BC=9F=E9=9F=AC?= Date: Wed, 21 Aug 2024 15:15:27 +0800 Subject: [PATCH 1/8] update rolezero reply to human prompt --- metagpt/prompts/di/role_zero.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/metagpt/prompts/di/role_zero.py b/metagpt/prompts/di/role_zero.py index ce8c61dd5..8946de29a 100644 --- a/metagpt/prompts/di/role_zero.py +++ b/metagpt/prompts/di/role_zero.py @@ -220,20 +220,24 @@ However, you MUST respond to the user message by yourself directly, DON'T ask yo """ REPORT_TO_HUMAN_PROMPT = """ -# Restrictions -{requirements_constraints} +## Examlpe +example 1: +User requirement:开发贪吃蛇游戏 +reply: 贪吃蛇游戏的开发已经完成。所有文件(index.html、style.css和script.js)已经创建并经过审查。 -You have just finished all tasks. -Reply to the human requirements. -Do not output any other format. -Your reply is: +example 2: +User requirement: Crawl and extract all the herb names from the website, Tell me the number of herbs. +reply : The herb names have been successfully extracted and saved to the file /home/mgx/mgx/MetaGPT/src/herb_name.txt. A total of 8 herb names were extracted. +------------ + +Carefully review the history and respond to the user in the expected language to meet their requirements. +If you have any deliverables that are helpful in explaining the results (such as files, metrics, quantitative results, etc.), provide brief descriptions of them. +Your reply must be concise. +Directly output your reply content. Do not add any output format. """ SUMMARY_PROMPT = """ -# Restrictions -{requirements_constraints} - -You have just completed some tasks. -Summarize the tasks you have accomplished without including detailed information. -If there are any deliverables, list their descriptions and provide their file paths. +Summarize what you have accomplished lately. Be concise. +If you produce any deliverables, include their short descriptions and file paths. If there are any metrics or quantitative results, include them, too. +If the deliverable is code, only output the file path. """ From e3c56715ed94ea8af690405e950320cbca06a269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=BC=9F=E9=9F=AC?= Date: Wed, 21 Aug 2024 15:17:23 +0800 Subject: [PATCH 2/8] update example --- metagpt/prompts/di/role_zero.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/prompts/di/role_zero.py b/metagpt/prompts/di/role_zero.py index 8946de29a..b4d8e4fcc 100644 --- a/metagpt/prompts/di/role_zero.py +++ b/metagpt/prompts/di/role_zero.py @@ -227,7 +227,7 @@ reply: 贪吃蛇游戏的开发已经完成。所有文件(index.html、style. example 2: User requirement: Crawl and extract all the herb names from the website, Tell me the number of herbs. -reply : The herb names have been successfully extracted and saved to the file /home/mgx/mgx/MetaGPT/src/herb_name.txt. A total of 8 herb names were extracted. +reply : The herb names have been successfully extracted. A total of 8 herb names were extracted. ------------ From d9ab1ae85cecab65801c91617ebecea6d6893fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=BC=9F=E9=9F=AC?= Date: Wed, 21 Aug 2024 19:32:20 +0800 Subject: [PATCH 3/8] update prompt --- metagpt/prompts/di/role_zero.py | 5 +++-- metagpt/roles/di/role_zero.py | 10 ++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/metagpt/prompts/di/role_zero.py b/metagpt/prompts/di/role_zero.py index b4d8e4fcc..3356ab1c0 100644 --- a/metagpt/prompts/di/role_zero.py +++ b/metagpt/prompts/di/role_zero.py @@ -222,8 +222,8 @@ However, you MUST respond to the user message by yourself directly, DON'T ask yo REPORT_TO_HUMAN_PROMPT = """ ## Examlpe example 1: -User requirement:开发贪吃蛇游戏 -reply: 贪吃蛇游戏的开发已经完成。所有文件(index.html、style.css和script.js)已经创建并经过审查。 +User requirement: create a 2048 game +reply: The development of the 2048 game has been completed. All files (index.html, style.css, and script.js) have been created and reviewed. example 2: User requirement: Crawl and extract all the herb names from the website, Tell me the number of herbs. @@ -234,6 +234,7 @@ reply : The herb names have been successfully extracted. A total of 8 herb names Carefully review the history and respond to the user in the expected language to meet their requirements. If you have any deliverables that are helpful in explaining the results (such as files, metrics, quantitative results, etc.), provide brief descriptions of them. Your reply must be concise. +{lanaguge_restruction} Directly output your reply content. Do not add any output format. """ SUMMARY_PROMPT = """ diff --git a/metagpt/roles/di/role_zero.py b/metagpt/roles/di/role_zero.py index 260c937a5..37392673a 100644 --- a/metagpt/roles/di/role_zero.py +++ b/metagpt/roles/di/role_zero.py @@ -494,17 +494,15 @@ class RoleZero(Role): memory = self.rc.memory.get(self.memory_k) # Ensure reply to the human before the "end" command is executed. if not any(["reply_to_human" in memory.content for memory in self.get_memories(k=5)]): - reply_to_human_prompt = REPORT_TO_HUMAN_PROMPT.format( - requirements_constraints=self.requirements_constraints, - ) + pattern = r"\[Language Restrictions\](.*?)\n" + match = re.search(pattern, self.requirements_constraints, re.DOTALL) + reply_to_human_prompt = REPORT_TO_HUMAN_PROMPT.format(lanaguge_restruction=match.group(0) if match else "") reply_content = await self.llm.aask(self.llm.format_msg(memory + [UserMessage(reply_to_human_prompt)])) await self.reply_to_human(content=reply_content) self.rc.memory.add(AIMessage(content=reply_content, cause_by=RunCommand)) outputs = "" # Summary of the Completed Task and Deliverables if self.use_summary: - summary_prompt = SUMMARY_PROMPT.format( - requirements_constraints=self.requirements_constraints, - ) + summary_prompt = SUMMARY_PROMPT.format() outputs = await self.llm.aask(self.llm.format_msg(memory + [UserMessage(summary_prompt)])) return outputs From b68c139125213b4fa22f5e119f1c6bd1c8476eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 26 Aug 2024 14:07:02 +0800 Subject: [PATCH 4/8] feat: +omniparse timeout --- metagpt/configs/omniparse_config.py | 1 + metagpt/tools/libs/editor.py | 20 +++++++++++--------- metagpt/utils/omniparse_client.py | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/metagpt/configs/omniparse_config.py b/metagpt/configs/omniparse_config.py index bf1516fc8..ecae78697 100644 --- a/metagpt/configs/omniparse_config.py +++ b/metagpt/configs/omniparse_config.py @@ -3,3 +3,4 @@ from metagpt.utils.yaml_model import YamlModel class OmniParseConfig(YamlModel): url: str = "" + timeout: int = 600 diff --git a/metagpt/tools/libs/editor.py b/metagpt/tools/libs/editor.py index 240c28767..76f009fa6 100644 --- a/metagpt/tools/libs/editor.py +++ b/metagpt/tools/libs/editor.py @@ -3,7 +3,7 @@ import os import shutil import subprocess from pathlib import Path -from typing import List, Optional, Union +from typing import List, Optional, Tuple, Union from pydantic import BaseModel, ConfigDict @@ -251,15 +251,17 @@ class Editor(BaseModel): from metagpt.tools.libs import get_env_default from metagpt.utils.omniparse_client import OmniParseClient - base_url = await get_env_default(key="base_url", app_name="OmniParse", default_value="") - if not base_url: - base_url = await Editor._read_omniparse_config() + base_url1 = await get_env_default(key="base_url", app_name="OmniParse", default_value="") + timeout1 = await get_env_default(key="timeout", app_name="OmniParse", default_value="") + base_url2, timeout2 = await Editor._read_omniparse_config() + + base_url = base_url1 or base_url2 if not base_url: return None api_key = await get_env_default(key="api_key", app_name="OmniParse", default_value="") - v = await get_env_default(key="timeout", app_name="OmniParse", default_value="120") + timeout = timeout1 or timeout2 or 120 try: - timeout = int(v) or 120 + timeout = int(timeout) except ValueError: timeout = 120 @@ -287,8 +289,8 @@ class Editor(BaseModel): return result @staticmethod - async def _read_omniparse_config() -> str: + async def _read_omniparse_config() -> Tuple[str, int]: config = Config.default() if config.omniparse and config.omniparse.url: - return config.omniparse.url - return "" + return config.omniparse.url, config.omniparse.timeout + return "", 0 diff --git a/metagpt/utils/omniparse_client.py b/metagpt/utils/omniparse_client.py index cb2341944..361e84fd1 100644 --- a/metagpt/utils/omniparse_client.py +++ b/metagpt/utils/omniparse_client.py @@ -189,7 +189,7 @@ class OmniParseClient: # Do not verify if only byte data is provided return - file_ext = Path(verify_file_path).suffix + file_ext = Path(verify_file_path).suffix.lower() if file_ext not in allowed_file_extensions: raise ValueError(f"Not allowed {file_ext} File extension must be one of {allowed_file_extensions}") From 62140a6d560008f3e350785e239c08f0d6bd8a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 26 Aug 2024 16:42:26 +0800 Subject: [PATCH 5/8] feat: png -> svg --- metagpt/utils/mermaid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/utils/mermaid.py b/metagpt/utils/mermaid.py index 64996717e..008bb849d 100644 --- a/metagpt/utils/mermaid.py +++ b/metagpt/utils/mermaid.py @@ -38,7 +38,7 @@ async def mermaid_to_file( Returns: int: 0 if the conversion is successful, -1 if the conversion fails. """ - suffixes = suffixes or ["png"] + suffixes = suffixes or ["svg"] # Write the Mermaid code to a temporary file config = config if config else Config.default() dir_name = os.path.dirname(output_file_without_suffix) From 128552b9fbd6423919ea5594018ab1f25339e8dd Mon Sep 17 00:00:00 2001 From: shenchucheng Date: Mon, 26 Aug 2024 17:41:56 +0800 Subject: [PATCH 6/8] svg reporter --- metagpt/actions/design_api.py | 2 +- metagpt/actions/write_prd.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/metagpt/actions/design_api.py b/metagpt/actions/design_api.py index 86fa699bb..68a66d5a4 100644 --- a/metagpt/actions/design_api.py +++ b/metagpt/actions/design_api.py @@ -231,7 +231,7 @@ class WriteDesign(Action): async def _save_mermaid_file(self, data: str, pathname: Path): pathname.parent.mkdir(parents=True, exist_ok=True) await mermaid_to_file(self.config.mermaid.engine, data, pathname) - image_path = pathname.parent / f"{pathname.name}.png" + image_path = pathname.parent / f"{pathname.name}.svg" if image_path.exists(): await GalleryReporter().async_report(image_path, "path") diff --git a/metagpt/actions/write_prd.py b/metagpt/actions/write_prd.py index 4b2015145..7a04520d6 100644 --- a/metagpt/actions/write_prd.py +++ b/metagpt/actions/write_prd.py @@ -278,7 +278,7 @@ class WritePRD(Action): pathname = output_filename or self.repo.workdir / COMPETITIVE_ANALYSIS_FILE_REPO / Path(prd_doc.filename).stem pathname.parent.mkdir(parents=True, exist_ok=True) await mermaid_to_file(self.config.mermaid.engine, quadrant_chart, pathname) - image_path = pathname.parent / f"{pathname.name}.png" + image_path = pathname.parent / f"{pathname.name}.svg" if image_path.exists(): await GalleryReporter().async_report(image_path, "path") From 16e76179595f6f03f3ce9613c191f609692930b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Tue, 27 Aug 2024 14:30:56 +0800 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/tools/libs/editor.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/metagpt/tools/libs/editor.py b/metagpt/tools/libs/editor.py index 76f009fa6..e6f1525a4 100644 --- a/metagpt/tools/libs/editor.py +++ b/metagpt/tools/libs/editor.py @@ -251,15 +251,15 @@ class Editor(BaseModel): from metagpt.tools.libs import get_env_default from metagpt.utils.omniparse_client import OmniParseClient - base_url1 = await get_env_default(key="base_url", app_name="OmniParse", default_value="") - timeout1 = await get_env_default(key="timeout", app_name="OmniParse", default_value="") - base_url2, timeout2 = await Editor._read_omniparse_config() + env_base_url = await get_env_default(key="base_url", app_name="OmniParse", default_value="") + env_timeout = await get_env_default(key="timeout", app_name="OmniParse", default_value="") + conf_base_url, conf_timeout = await Editor._read_omniparse_config() - base_url = base_url1 or base_url2 + base_url = env_base_url or conf_base_url if not base_url: return None api_key = await get_env_default(key="api_key", app_name="OmniParse", default_value="") - timeout = timeout1 or timeout2 or 120 + timeout = env_timeout or conf_timeout or 120 try: timeout = int(timeout) except ValueError: From aae2bfe1fafc0df635ab648faa0d8949f93c6ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Tue, 27 Aug 2024 14:59:28 +0800 Subject: [PATCH 8/8] feat: default timeout 120 -> 600 --- metagpt/tools/libs/editor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metagpt/tools/libs/editor.py b/metagpt/tools/libs/editor.py index e6f1525a4..478903d9c 100644 --- a/metagpt/tools/libs/editor.py +++ b/metagpt/tools/libs/editor.py @@ -259,11 +259,11 @@ class Editor(BaseModel): if not base_url: return None api_key = await get_env_default(key="api_key", app_name="OmniParse", default_value="") - timeout = env_timeout or conf_timeout or 120 + timeout = env_timeout or conf_timeout or 600 try: timeout = int(timeout) except ValueError: - timeout = 120 + timeout = 600 try: if not await check_http_endpoint(url=base_url):