From 33ac8c51092611f1ea61e18caa87362dd062c77f Mon Sep 17 00:00:00 2001 From: garylin2099 Date: Thu, 5 Sep 2024 10:42:04 +0800 Subject: [PATCH 1/7] increase mem window --- metagpt/roles/di/role_zero.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/roles/di/role_zero.py b/metagpt/roles/di/role_zero.py index f0df0aa4b..da26796d5 100644 --- a/metagpt/roles/di/role_zero.py +++ b/metagpt/roles/di/role_zero.py @@ -83,7 +83,7 @@ class RoleZero(Role): # Others command_rsp: str = "" # the raw string containing the commands commands: list[dict] = [] # commands to be executed - memory_k: int = 100 # number of memories (messages) to use as historical context + memory_k: int = 200 # number of memories (messages) to use as historical context use_fixed_sop: bool = False requirements_constraints: str = "" # the constraints in user requirements use_summary: bool = True # whether to summarize at the end From 35075134c254cbd1caabfc3a69014af839d32308 Mon Sep 17 00:00:00 2001 From: zhouhangeng Date: Thu, 5 Sep 2024 16:16:03 +0800 Subject: [PATCH 2/7] =?UTF-8?q?update:=20cr=E5=A2=9E=E5=8A=A0=E5=85=9C?= =?UTF-8?q?=E5=BA=95=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/ext/cr/actions/code_review.py | 9 ++++++++- metagpt/roles/di/engineer2.py | 6 +++++- metagpt/tools/libs/cr.py | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/metagpt/ext/cr/actions/code_review.py b/metagpt/ext/cr/actions/code_review.py index 5f861c3e3..7ee452194 100644 --- a/metagpt/ext/cr/actions/code_review.py +++ b/metagpt/ext/cr/actions/code_review.py @@ -18,7 +18,7 @@ from metagpt.ext.cr.utils.cleaner import ( from metagpt.ext.cr.utils.schema import Point from metagpt.logs import logger from metagpt.utils.common import parse_json_code_block -from metagpt.utils.report import EditorReporter +from metagpt.utils.report import EditorReporter, ThoughtReporter CODE_REVIEW_PROMPT_TEMPLATE = """ NOTICE @@ -175,13 +175,16 @@ class CodeReview(Action): async def cr_by_points(self, patch: PatchSet, points: list[Point]): comments = [] + valid_patch_count = 0 for patched_file in patch: if not patched_file: continue if patched_file.path.endswith(".py"): points = [p for p in points if p.language == "Python"] + valid_patch_count += 1 elif patched_file.path.endswith(".java"): points = [p for p in points if p.language == "Java"] + valid_patch_count += 1 else: continue group_points = [points[i : i + 3] for i in range(0, len(points), 3)] @@ -198,6 +201,10 @@ class CodeReview(Action): c["commented_file"] = patched_file_path comments.extend(comments_batch) + if valid_patch_count == 0: + await ThoughtReporter().async_report(value={"type": "limit", "classify": "language"}) + raise ValueError("Only code reviews for Python and Java languages are supported.") + return comments async def run(self, patch: PatchSet, points: list[Point], output_file: str): diff --git a/metagpt/roles/di/engineer2.py b/metagpt/roles/di/engineer2.py index 4600e3254..bcd5f5738 100644 --- a/metagpt/roles/di/engineer2.py +++ b/metagpt/roles/di/engineer2.py @@ -13,6 +13,7 @@ from metagpt.prompts.di.engineer2 import ( from metagpt.roles.di.role_zero import RoleZero from metagpt.schema import UserMessage from metagpt.strategy.experience_retriever import ENGINEER_EXAMPLE +from metagpt.tools.libs.cr import CodeReview from metagpt.tools.libs.terminal import Terminal from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import CodeParser, awrite @@ -28,14 +29,17 @@ class Engineer2(RoleZero): terminal: Terminal = Field(default_factory=Terminal, exclude=True) - tools: list[str] = ["Plan", "Editor:read", "RoleZero", "Terminal:run_command", "Engineer2"] + tools: list[str] = ["Plan", "Editor:read", "RoleZero", "Terminal:run_command", "Engineer2", "SearchEnhancedQA", "CodeReview"] def _update_tool_execution(self): # validate = ValidateAndRewriteCode() + cr = CodeReview() self.tool_execution_map.update( { "Terminal.run_command": self.terminal.run_command, "Engineer2.write_new_code": self.write_new_code, + "CodeReview.review": cr.review, + "CodeReview.fix": cr.fix, # "ValidateAndRewriteCode.run": validate.run, # "ValidateAndRewriteCode": validate.run, } diff --git a/metagpt/tools/libs/cr.py b/metagpt/tools/libs/cr.py index e3509591b..150f24bd5 100644 --- a/metagpt/tools/libs/cr.py +++ b/metagpt/tools/libs/cr.py @@ -45,6 +45,7 @@ class CodeReview: """ patch = await self._get_patch_content(patch_path) point_file = point_file if point_file else Path(metagpt.ext.cr.__file__).parent / "points.json" + await EditorReporter().async_report(str(point_file), "path") async with aiofiles.open(point_file, "rb") as f: cr_point_content = await f.read() cr_points = [Point(**i) for i in json.loads(cr_point_content)] From 93b5716e8c6226fa5a585478fced47673efb6fbc Mon Sep 17 00:00:00 2001 From: zhouhangeng Date: Thu, 5 Sep 2024 17:29:56 +0800 Subject: [PATCH 3/7] =?UTF-8?q?update:=20cr=E5=A2=9E=E5=8A=A0=E5=85=9C?= =?UTF-8?q?=E5=BA=95=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/ext/cr/actions/code_review.py | 1 - metagpt/tools/libs/cr.py | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/metagpt/ext/cr/actions/code_review.py b/metagpt/ext/cr/actions/code_review.py index 7ee452194..a9733531e 100644 --- a/metagpt/ext/cr/actions/code_review.py +++ b/metagpt/ext/cr/actions/code_review.py @@ -202,7 +202,6 @@ class CodeReview(Action): comments.extend(comments_batch) if valid_patch_count == 0: - await ThoughtReporter().async_report(value={"type": "limit", "classify": "language"}) raise ValueError("Only code reviews for Python and Java languages are supported.") return comments diff --git a/metagpt/tools/libs/cr.py b/metagpt/tools/libs/cr.py index 150f24bd5..0a53dd194 100644 --- a/metagpt/tools/libs/cr.py +++ b/metagpt/tools/libs/cr.py @@ -49,9 +49,11 @@ class CodeReview: async with aiofiles.open(point_file, "rb") as f: cr_point_content = await f.read() cr_points = [Point(**i) for i in json.loads(cr_point_content)] - - comments = await CodeReview_().run(patch, cr_points, output_file) - return f"The number of defects: {len(comments)} and the comments are stored in {output_file}" + try: + comments = await CodeReview_().run(patch, cr_points, output_file) + except ValueError as e: + return str(e) + return f"The number of defects: {len(comments)}, the comments are stored in {output_file}, and the checkpoints are stored in {str(point_file)}" async def fix( self, From ac44f41fb9a3bd707e3c8d16715d0fe1a1c922ea Mon Sep 17 00:00:00 2001 From: zhouhangeng Date: Thu, 5 Sep 2024 18:44:06 +0800 Subject: [PATCH 4/7] =?UTF-8?q?update:=20cr=E5=A2=9E=E5=8A=A0=E5=85=9C?= =?UTF-8?q?=E5=BA=95=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/ext/cr/actions/code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/ext/cr/actions/code_review.py b/metagpt/ext/cr/actions/code_review.py index a9733531e..0235dc2c6 100644 --- a/metagpt/ext/cr/actions/code_review.py +++ b/metagpt/ext/cr/actions/code_review.py @@ -18,7 +18,7 @@ from metagpt.ext.cr.utils.cleaner import ( from metagpt.ext.cr.utils.schema import Point from metagpt.logs import logger from metagpt.utils.common import parse_json_code_block -from metagpt.utils.report import EditorReporter, ThoughtReporter +from metagpt.utils.report import EditorReporter CODE_REVIEW_PROMPT_TEMPLATE = """ NOTICE From 42544806bd85cbfea1f8d677eb7e2c6e8633dd8e Mon Sep 17 00:00:00 2001 From: garylin2099 Date: Thu, 5 Sep 2024 19:16:39 +0800 Subject: [PATCH 5/7] revert sweagent to use bash --- metagpt/roles/di/swe_agent.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/metagpt/roles/di/swe_agent.py b/metagpt/roles/di/swe_agent.py index f147e80f3..d54c9dd44 100644 --- a/metagpt/roles/di/swe_agent.py +++ b/metagpt/roles/di/swe_agent.py @@ -11,7 +11,7 @@ from metagpt.prompts.di.swe_agent import ( from metagpt.roles.di.role_zero import RoleZero from metagpt.schema import Message from metagpt.tools.libs.git import git_create_pull -from metagpt.tools.libs.terminal import Terminal +from metagpt.tools.libs.terminal import Bash class SWEAgent(RoleZero): @@ -19,8 +19,13 @@ class SWEAgent(RoleZero): profile: str = "Issue Solver" goal: str = "Resolve GitHub issue or bug in any existing codebase" _instruction: str = NEXT_STEP_TEMPLATE - tools: list[str] = ["Browser:goto,scroll", "RoleZero", "git_create_pull", "Editor", "Terminal"] - terminal: Terminal = Field(default_factory=Terminal, exclude=True) + tools: list[str] = [ + "Bash", + "Browser:goto,scroll", + "RoleZero", + "git_create_pull", + ] + terminal: Bash = Field(default_factory=Bash, exclude=True) output_diff: str = "" max_react_loop: int = 40 run_eval: bool = False @@ -33,6 +38,7 @@ class SWEAgent(RoleZero): def _update_tool_execution(self): self.tool_execution_map.update( { + "Bash.run": self.terminal.run, "git_create_pull": git_create_pull, } ) From e9d7556a0e5b2b7f543e1e50d133be3fc8befc0e Mon Sep 17 00:00:00 2001 From: garylin2099 Date: Thu, 5 Sep 2024 19:35:35 +0800 Subject: [PATCH 6/7] add current time for search qa --- metagpt/actions/analyze_requirements.py | 2 +- metagpt/actions/research.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/metagpt/actions/analyze_requirements.py b/metagpt/actions/analyze_requirements.py index d81da3e14..86088d824 100644 --- a/metagpt/actions/analyze_requirements.py +++ b/metagpt/actions/analyze_requirements.py @@ -48,7 +48,7 @@ INSTRUCTIONS = """ You must output in the same language as the Requirements. First, This language should be consistent with the language used in the requirement description. determine the natural language you must respond in. If the requirements specify a special language, follow those instructions. The default language for responses is English. Second, extract the restrictions in the requirements, specifically the steps. Do not include detailed demand descriptions; focus only on the restrictions. -Third, if the requirements is a software development, extract the program language. If If no specific programming language is required, Use HTML (*.html), CSS (*.css), and JavaScript (*.js) +Third, if the requirements is a software development, extract the program language. If no specific programming language is required, Use HTML (*.html), CSS (*.css), and JavaScript (*.js) Note: 1. if there is not restrictions, requirements_restrictions must be "" diff --git a/metagpt/actions/research.py b/metagpt/actions/research.py index 98edfddb0..91a2e7090 100644 --- a/metagpt/actions/research.py +++ b/metagpt/actions/research.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio +from datetime import datetime from typing import Any, Callable, Coroutine, Optional, Union from pydantic import TypeAdapter, model_validator @@ -43,7 +44,9 @@ COLLECT_AND_RANKURLS_PROMPT = """### Topic {results} ### Requirements -Please remove irrelevant search results that are not related to the query or topic. Then, sort the remaining search results \ +Please remove irrelevant search results that are not related to the query or topic. +If the query is time-sensitive or specifies a certain time frame, please also remove search results that are outdated or outside the specified time frame. Notice that the current time is {time_stamp}. +Then, sort the remaining search results based on the link credibility. If two results have equal credibility, prioritize them based on the relevance. Provide the ranked results' indices in JSON format, like [0, 1, 3, 4, ...], without including other words. """ @@ -165,7 +168,8 @@ class CollectLinks(Action): max_results = max_num_results or max(num_results * 2, 6) results = await self._search_urls(query, max_results=max_results) _results = "\n".join(f"{i}: {j}" for i, j in zip(range(max_results), results)) - prompt = COLLECT_AND_RANKURLS_PROMPT.format(topic=topic, query=query, results=_results) + time_stamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + prompt = COLLECT_AND_RANKURLS_PROMPT.format(topic=topic, query=query, results=_results, time_stamp=time_stamp) logger.debug(prompt) indices = await self._aask(prompt) try: From 3f22d9e162d08a5172dbaacf7daa53ec36e82403 Mon Sep 17 00:00:00 2001 From: garylin2099 Date: Thu, 5 Sep 2024 19:37:56 +0800 Subject: [PATCH 7/7] format --- metagpt/actions/research.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/metagpt/actions/research.py b/metagpt/actions/research.py index 91a2e7090..99f72b076 100644 --- a/metagpt/actions/research.py +++ b/metagpt/actions/research.py @@ -46,9 +46,8 @@ COLLECT_AND_RANKURLS_PROMPT = """### Topic ### Requirements Please remove irrelevant search results that are not related to the query or topic. If the query is time-sensitive or specifies a certain time frame, please also remove search results that are outdated or outside the specified time frame. Notice that the current time is {time_stamp}. -Then, sort the remaining search results -based on the link credibility. If two results have equal credibility, prioritize them based on the relevance. Provide the -ranked results' indices in JSON format, like [0, 1, 3, 4, ...], without including other words. +Then, sort the remaining search results based on the link credibility. If two results have equal credibility, prioritize them based on the relevance. +Provide the ranked results' indices in JSON format, like [0, 1, 3, 4, ...], without including other words. """ WEB_BROWSE_AND_SUMMARIZE_PROMPT = """### Requirements