From 9fa47aff0328bc81a75fb01443a3af461ed625d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Fri, 10 May 2024 11:53:21 +0800 Subject: [PATCH] fixbug: sent_from, send_to --- metagpt/actions/design_api.py | 1 - metagpt/actions/project_management.py | 1 - metagpt/actions/write_prd.py | 2 -- metagpt/const.py | 1 + metagpt/roles/engineer.py | 16 +++------------- metagpt/roles/role.py | 6 ++++++ metagpt/schema.py | 10 +++++++++- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/metagpt/actions/design_api.py b/metagpt/actions/design_api.py index 9b4a6c969..613c4a47b 100644 --- a/metagpt/actions/design_api.py +++ b/metagpt/actions/design_api.py @@ -76,7 +76,6 @@ class WriteDesign(Action): + list(self.repo.resources.seq_flow.changed_files.keys()) ), cause_by=self, - sent_from=self, ) async def _new_system_design(self, context): diff --git a/metagpt/actions/project_management.py b/metagpt/actions/project_management.py index 6e786c6a3..ef0fe6fc6 100644 --- a/metagpt/actions/project_management.py +++ b/metagpt/actions/project_management.py @@ -62,7 +62,6 @@ class WriteTasks(Action): + list(self.repo.resources.api_spec_and_task.changed_files.keys()) ), cause_by=self, - sent_from=self, ) async def _update_tasks(self, filename): diff --git a/metagpt/actions/write_prd.py b/metagpt/actions/write_prd.py index b90e7bf5f..a4f6e1dd1 100644 --- a/metagpt/actions/write_prd.py +++ b/metagpt/actions/write_prd.py @@ -94,7 +94,6 @@ class WritePRD(Action): + list(self.repo.resources.competitive_analysis.changed_files.keys()) ), cause_by=self, - sent_from=self, ) async def _handle_bugfix(self, req: Document) -> Message: @@ -104,7 +103,6 @@ class WritePRD(Action): return AIMessage( content=f"A new issue is received: {BUGFIX_FILENAME}", cause_by=FixBug, - sent_from=self, send_to="Alex", # the name of Engineer ) diff --git a/metagpt/const.py b/metagpt/const.py index eaa22434f..6e823d56c 100644 --- a/metagpt/const.py +++ b/metagpt/const.py @@ -81,6 +81,7 @@ MESSAGE_ROUTE_CAUSE_BY = "cause_by" MESSAGE_META_ROLE = "role" MESSAGE_ROUTE_TO_ALL = "" MESSAGE_ROUTE_TO_NONE = "" +MESSAGE_ROUTE_TO_SELF = "" # Add this tag to replace `ActionOutput` REQUIREMENT_FILENAME = "requirement.txt" BUGFIX_FILENAME = "bugfix.txt" diff --git a/metagpt/roles/engineer.py b/metagpt/roles/engineer.py index 1e51e9db6..3b7ba597a 100644 --- a/metagpt/roles/engineer.py +++ b/metagpt/roles/engineer.py @@ -47,6 +47,7 @@ from metagpt.logs import logger from metagpt.roles import Role from metagpt.schema import ( AIMessage, + AISelfMessage, CodePlanAndChangeContext, CodeSummarizeContext, CodingContext, @@ -172,12 +173,7 @@ class Engineer(Role): async def _act_write_code(self): await self._act_sp_with_cr(review=self.use_code_review) - return AIMessage( - content="", - cause_by=WriteCodeReview if self.use_code_review else WriteCode, - send_to=self, - sent_from=self, - ) + return AISelfMessage(content="", cause_by=WriteCodeReview if self.use_code_review else WriteCode) async def _act_summarize(self): tasks = [] @@ -216,7 +212,6 @@ class Engineer(Role): + list(self.project_repo.srcs.changed_files.keys()) ), cause_by=SummarizeCode, - sent_from=self, send_to="Edward", # The name of QaEngineer ) # The maximum number of times the 'SummarizeCode' action is automatically invoked, with -1 indicating unlimited. @@ -244,12 +239,7 @@ class Engineer(Role): dependencies=dependencies, ) - return AIMessage( - content="", - cause_by=WriteCodePlanAndChange, - send_to=self, - sent_from=self, - ) + return AISelfMessage(content="", cause_by=WriteCodePlanAndChange) async def _is_pass(self, summary) -> (str, str): rsp = await self.llm.aask(msg=IS_PASS_PROMPT.format(context=summary), stream=False) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 7e3c85579..1eaa77fa3 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -30,6 +30,7 @@ from pydantic import BaseModel, ConfigDict, Field, SerializeAsAny, model_validat from metagpt.actions import Action, ActionOutput from metagpt.actions.action_node import ActionNode from metagpt.actions.add_requirement import UserRequirement +from metagpt.const import MESSAGE_ROUTE_TO_SELF from metagpt.context_mixin import ContextMixin from metagpt.logs import logger from metagpt.memory import Memory @@ -443,6 +444,11 @@ class Role(SerializationMixin, ContextMixin, BaseModel): """If the role belongs to env, then the role's messages will be broadcast to env""" if not msg: return + if MESSAGE_ROUTE_TO_SELF in msg.send_to: + msg.send_to.add(any_to_str(self)) + msg.send_to.remove(MESSAGE_ROUTE_TO_SELF) + if not msg.sent_from or msg.sent_from == MESSAGE_ROUTE_TO_SELF: + msg.sent_from = any_to_str(self) if all(to in {any_to_str(self), self.name} for to in msg.send_to): # Message to myself self.put_message(msg) return diff --git a/metagpt/schema.py b/metagpt/schema.py index ba64c0f06..ee8b1ca96 100644 --- a/metagpt/schema.py +++ b/metagpt/schema.py @@ -43,6 +43,7 @@ from metagpt.const import ( MESSAGE_ROUTE_FROM, MESSAGE_ROUTE_TO, MESSAGE_ROUTE_TO_ALL, + MESSAGE_ROUTE_TO_SELF, PRDS_FILE_REPO, SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO, @@ -200,7 +201,7 @@ class Message(BaseModel): """list[: ]""" id: str = Field(default="", validate_default=True) # According to Section 2.2.3.1.1 of RFC 135 - content: str + content: str # natural language for user or agent instruct_content: Optional[BaseModel] = Field(default=None, validate_default=True) role: str = "user" # system / user / assistant cause_by: str = Field(default="", validate_default=True) @@ -399,6 +400,13 @@ class AIMessage(Message): return self.metadata.get(AGENT, "") +class AISelfMessage(AIMessage): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.sent_from = MESSAGE_ROUTE_TO_SELF + self.send_to = MESSAGE_ROUTE_TO_SELF + + class Task(BaseModel): task_id: str = "" dependent_task_ids: list[str] = [] # Tasks prerequisite to this Task