diff --git a/metagpt/actions/__init__.py b/metagpt/actions/__init__.py index f2e939e0e..ce5d96edf 100644 --- a/metagpt/actions/__init__.py +++ b/metagpt/actions/__init__.py @@ -10,31 +10,32 @@ from enum import Enum from metagpt.actions.action import Action from metagpt.actions.action_output import ActionOutput from metagpt.actions.add_requirement import BossRequirement +''' from metagpt.actions.debug_error import DebugError from metagpt.actions.design_api import WriteDesign from metagpt.actions.project_management import AssignTasks, WriteTasks from metagpt.actions.run_code import RunCode -from metagpt.actions.search_and_summarize import SearchAndSummarize +#from metagpt.actions.search_and_summarize import SearchAndSummarize from metagpt.actions.write_code import WriteCode from metagpt.actions.write_code_review import WriteCodeReview from metagpt.actions.write_prd import WritePRD from metagpt.actions.write_test import WriteTest - +''' class ActionType(Enum): """All types of Actions, used for indexing.""" ADD_REQUIREMENT = BossRequirement - WRITE_PRD = WritePRD - WRITE_DESIGN = WriteDesign - WRTIE_CODE = WriteCode - WRITE_CODE_REVIEW = WriteCodeReview - WRITE_TEST = WriteTest - RUN_CODE = RunCode - DEBUG_ERROR = DebugError - WRITE_TASKS = WriteTasks - ASSIGN_TASKS = AssignTasks - SEARCH_AND_SUMMARIZE = SearchAndSummarize + #WRITE_PRD = WritePRD + #WRITE_DESIGN = WriteDesign + #WRTIE_CODE = WriteCode + #WRITE_CODE_REVIEW = WriteCodeReview + #WRITE_TEST = WriteTest + #RUN_CODE = RunCode + #DEBUG_ERROR = DebugError + #WRITE_TASKS = WriteTasks + #ASSIGN_TASKS = AssignTasks + # SEARCH_AND_SUMMARIZE = SearchAndSummarize __all__ = [ diff --git a/metagpt/minecraft_team.py b/metagpt/minecraft_team.py index 27a64686f..4f3e701a7 100644 --- a/metagpt/minecraft_team.py +++ b/metagpt/minecraft_team.py @@ -219,24 +219,37 @@ class MinecraftPlayer(SoftwareCompany): self.environment.add_roles(roles) self.game_memory.register_roles(roles) - def start(self, task): + def start(self, task, round=0): """Start a project from publishing boss requirement.""" self.task = task self.environment.publish_message( - Message(role="Player", content=task, cause_by=PlayerActions) + Message(role="Player", content=task, cause_by=PlayerActions, round_id=round) ) logger.info(self.game_info) def _save(self): logger.info(self.json()) + + def _reset(self): + for role_profile, role in self.environment.roles.items(): + role.reset_state() async def run(self, n_round=3): """Run company until target round or no money""" + round_id=0 while n_round > 0: # self._save() - n_round -= 1 - logger.debug(f"{n_round=}") + if self.check_complete_round(): + n_round -= 1 + self.update_round() + round_id+=1 + # add new task into env and continue + #fixme: update self.task + self.start(task=self.task, round=round_id) + + logger.info(f"{n_round=}") self._check_balance() await self.environment.run() - + #self.environment.memory.clear() + #self._reset() return self.environment.history diff --git a/metagpt/roles/__init__.py b/metagpt/roles/__init__.py index 7f0fd2f62..939be094e 100644 --- a/metagpt/roles/__init__.py +++ b/metagpt/roles/__init__.py @@ -7,19 +7,20 @@ """ from metagpt.roles.role import Role +''' from metagpt.roles.architect import Architect from metagpt.roles.project_manager import ProjectManager from metagpt.roles.product_manager import ProductManager from metagpt.roles.engineer import Engineer from metagpt.roles.qa_engineer import QaEngineer - +''' __all__ = [ "Role", - "Architect", - "ProjectManager", - "ProductManager", - "Engineer", - "QaEngineer", + #"Architect", + #"ProjectManager", + #"ProductManager", + #"Engineer", + #"QaEngineer", ] diff --git a/metagpt/roles/minecraft/action_developer.py b/metagpt/roles/minecraft/action_developer.py index 65dd5afa2..a99f10c4f 100644 --- a/metagpt/roles/minecraft/action_developer.py +++ b/metagpt/roles/minecraft/action_developer.py @@ -197,7 +197,7 @@ class ActionDeveloper(Base): async def _act(self) -> Message: todo = self._rc.todo logger.debug(f"Todo is {todo}") - + self.maintain_actions(todo) # 获取最新的游戏周边信息 events = await self._obtain_events() self.perform_game_info_callback(events, self.game_memory.update_event) @@ -225,6 +225,7 @@ class ActionDeveloper(Base): if handler: msg = await handler(**message) msg.cause_by = type(todo) + msg.round_id = self.round_id logger.info(msg.send_to) self._publish_message(msg) return msg diff --git a/metagpt/roles/minecraft/critic_agent.py b/metagpt/roles/minecraft/critic_agent.py index 5f4f59c46..9c490c7ee 100644 --- a/metagpt/roles/minecraft/critic_agent.py +++ b/metagpt/roles/minecraft/critic_agent.py @@ -116,7 +116,7 @@ class CriticReviewer(Base): async def _act(self) -> Message: todo = self._rc.todo logger.debug(f"Todo is {todo}") - + self.maintain_actions(todo) # 获取最新的游戏周边信息 events = await self._obtain_events() context = self.game_memory.context @@ -136,6 +136,7 @@ class CriticReviewer(Base): if handler: msg = await handler(**message) msg.cause_by = type(todo) + msg.round_id = self.round_id logger.info(msg.send_to) self._publish_message(msg) return msg diff --git a/metagpt/roles/minecraft/curriculum_agent.py b/metagpt/roles/minecraft/curriculum_agent.py index 9004f06fa..c9d8e1ce9 100644 --- a/metagpt/roles/minecraft/curriculum_agent.py +++ b/metagpt/roles/minecraft/curriculum_agent.py @@ -357,7 +357,7 @@ class CurriculumDesigner(Base): async def _act(self) -> Message: todo = self._rc.todo logger.debug(f"Todo is {todo}") - + self.maintain_actions(todo) # 获取最新的游戏周边环境信息 events = await self._obtain_events() self.perform_game_info_callback(events, self.game_memory.update_event) @@ -386,6 +386,7 @@ class CurriculumDesigner(Base): else: msg = await handler(**design_curriculum_message) msg.cause_by = type(todo) + msg.round_id = self.round_id self._publish_message(msg) return msg diff --git a/metagpt/roles/minecraft/minecraft_base.py b/metagpt/roles/minecraft/minecraft_base.py index 6834de606..47852b4fb 100644 --- a/metagpt/roles/minecraft/minecraft_base.py +++ b/metagpt/roles/minecraft/minecraft_base.py @@ -11,7 +11,7 @@ from metagpt.schema import HumanMessage, SystemMessage from typing import Dict from pydantic import BaseModel - +from metagpt.roles.role import RoleContext class Registry(BaseModel): """Registry for storing and building classes.""" @@ -47,18 +47,47 @@ class Minecraft(Role): super().__init__(name, profile, goal, constraints) self.game_memory = None self.event = {} + self.round_id = 0 + self.finish_state = len(self._actions) + self.finish_step = False + def maintain_actions(self, todo): + if todo in self._actions: + self.finish_state-=1 + if self.finish_state<=0: + self.finish_step = True + + + async def _observe(self) -> int: + await super()._observe() + for msg in self._rc.news: + logger.info(f"check msg round :{msg.round_id}") + logger.info(msg.round_id == self.round_id) + self._rc.news = [ + msg for msg in self._rc.news if msg.round_id == self.round_id + ] # only relevant msgs count as observed news + logger.info(len(self._rc.news)) + return len(self._rc.news) + async def _think(self) -> None: + logger.info(self._actions) + logger.info(self._rc.state) if len(self._actions) == 1: # If there is only one action, then only this one can be performed self._set_state(0) return True - + if self._rc.todo is None: logger.info("0") self._set_state(0) return True - + ''' + if self._rc.state+1==len(self._states): + logger.info("new run") + self._set_state(0) + return True + ''' + if self._rc.state + 1 < len(self._states): self._set_state(self._rc.state + 1) logger.info("1") @@ -66,9 +95,13 @@ class Minecraft(Role): else: self._rc.todo = None logger.info("2") - + self._set_state(self._rc.state) + logger.info(f"self.finish_step: {self.finish_step}") return False - + + def reset_state(self): + self._rc.todo = None + async def _obtain_events(self): return await self.game_memory.on_event() @@ -83,7 +116,7 @@ class Minecraft(Role): @staticmethod def perform_game_info_callback(info: object, callback: object) -> object: - logger.debug(info) + logger.info(info) callback(info) def encapsule_message(self, msg, *args, **kwargs): diff --git a/metagpt/roles/minecraft/skill_manager.py b/metagpt/roles/minecraft/skill_manager.py index 3a618c2cc..6f06a0f8f 100644 --- a/metagpt/roles/minecraft/skill_manager.py +++ b/metagpt/roles/minecraft/skill_manager.py @@ -23,7 +23,7 @@ class SkillManager(Base): ) -> None: super().__init__(name, profile, goal, constraints) # Initialize actions specific to the SkillManager role - self._init_actions([RetrieveSkills, GenerateSkillDescription, AddNewSkills]) + self._init_actions([RetrieveSkills, GenerateSkillDescription]) #AddNewSkills])#先去掉add # Set events or actions the SkillManager should watch or be aware of self._watch([DesignCurriculum, VerifyTask, RetrieveSkills, GenerateSkillDescription]) @@ -47,7 +47,7 @@ class SkillManager(Base): async def _act(self) -> Message: todo = self._rc.todo logger.debug(f"Todo is {todo}") - + self.maintain_actions(todo) # 获取最新的游戏周边信息 context = self.game_memory.context @@ -65,6 +65,7 @@ class SkillManager(Base): if handler: msg = await handler(**message) msg.cause_by = type(todo) + msg.round_id = self.round_id self._publish_message(msg) return msg diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 405313b29..fc21ef76b 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -127,6 +127,7 @@ class Role: self._rc.state = state logger.debug(self._actions) self._rc.todo = self._actions[self._rc.state] + logger.info(self._rc.todo) def set_env(self, env: 'Environment'): """Set the environment in which the role works. The role can talk to the environment and can also receive messages by observing.""" @@ -184,9 +185,11 @@ class Role: env_msgs = self._rc.env.memory.get() observed = self._rc.env.memory.get_by_actions(self._rc.watch) - logger.info(observed) + #logger.info(observed) + #self._rc.news = observed self._rc.news = self._rc.memory.remember(observed) # remember recent exact or similar memories - logger.info(self._rc.news) + if len(self._rc.news)>0: + logger.info(self._rc.news) for i in env_msgs: self.recv(i) @@ -205,7 +208,7 @@ class Role: async def _react(self) -> Message: """Think first, then act""" await self._think() - logger.debug(f"{self._setting}: {self._rc.state=}, will do {self._rc.todo}") + logger.info(f"{self._setting}: {self._rc.state=}, will do {self._rc.todo}") return await self._act() def recv(self, message: Message) -> None: diff --git a/metagpt/schema.py b/metagpt/schema.py index 9e016059d..9d5fcde0d 100644 --- a/metagpt/schema.py +++ b/metagpt/schema.py @@ -29,6 +29,7 @@ class Message: cause_by: Type["Action"] = field(default="") sent_from: str = field(default="") send_to: str = field(default="") + round_id: int=0 def __str__(self): # prefix = '-'.join([self.role, str(self.cause_by)])