diff --git a/metagpt/actions/minecraft/__init__.py b/metagpt/actions/minecraft/__init__.py index d375b7439..227bf7eb3 100644 --- a/metagpt/actions/minecraft/__init__.py +++ b/metagpt/actions/minecraft/__init__.py @@ -7,7 +7,7 @@ from enum import Enum from metagpt.actions.action import Action from metagpt.actions.action_output import ActionOutput from metagpt.actions.minecraft.design_curriculumn import DesignTask, DesignCurriculum -from metagpt.actions.minecraft.generate_actions import GenerateActionCode, SummarizeLog +from metagpt.actions.minecraft.generate_actions import GenerateActionCode from metagpt.actions.minecraft.manage_skills import RetrieveSkills, GenerateSkillDescription, AddNewSkills from metagpt.actions.minecraft.review_task import VerifyTask from metagpt.actions.minecraft.player_action import PlayerActions @@ -19,7 +19,6 @@ class ActionType(Enum): Design_Task = DesignTask Design_Curriculum = DesignCurriculum Generate_Action_Code = GenerateActionCode - Summarize_Log = SummarizeLog Retrieve_Skills = RetrieveSkills Generate_Skill_Description = GenerateSkillDescription Add_New_Skills = AddNewSkills diff --git a/metagpt/actions/minecraft/generate_actions.py b/metagpt/actions/minecraft/generate_actions.py index 9a52bb633..8cc32ec08 100644 --- a/metagpt/actions/minecraft/generate_actions.py +++ b/metagpt/actions/minecraft/generate_actions.py @@ -44,28 +44,3 @@ class GenerateActionCode(Action): # Return the generated code. return generated_code, program_name - - -class SummarizeLog(Action): - """ - Action class for parsing and summarizing logs. - Refer to the code in the voyager/agents/action.py for implementation details. - """ - - def __init__(self, name="", context=None, llm=None): - super().__init__(name, context, llm) - - async def summarize_logs(self): - """ - Summarize chatlogs. - - Implement the logic for summarizing chatlogs here. - """ - return "" - - async def run(self, *args, **kwargs): - # Summarize chatlogs. - summary = await self.summarize_logs() - - # Return the summary. - return summary diff --git a/metagpt/minecraft_team.py b/metagpt/minecraft_team.py index 1ff6fdf6e..4233d7fdc 100644 --- a/metagpt/minecraft_team.py +++ b/metagpt/minecraft_team.py @@ -194,6 +194,50 @@ class GameEnvironment(BaseModel, arbitrary_types_allowed=True): chatlog.add(item) return "I also need " + ", ".join(chatlog) + "." if chatlog else "" + def update_exploration_progress(self, success: bool): + """ + Split task into completed_tasks or failed_tasks + Args: info = { + "task": self.task, + "success": success, + "conversations": self.conversations, + } + """ + task = self.current_task + if task.startswith("Deposit useless items into the chest at"): + return + if success: + logger.info(f"Completed task {task}.") + self.game_memory.completed_tasks.append(task) + else: + logger.info(f"Failed to complete task {task}. Skipping to next task.") + self.game_memory.failed_tasks.append(task) + + self.save_sorted_tasks() + + def save_sorted_tasks(self): + updated_completed_tasks = [] + # record repeated failed tasks + updated_failed_tasks = self.game_memory.failed_tasks + # dedup but keep order + for task in self.game_memory.completed_tasks: + if task not in updated_completed_tasks: + updated_completed_tasks.append(task) + + # remove completed tasks from failed tasks + for task in updated_completed_tasks: + while task in updated_failed_tasks: + updated_failed_tasks.remove(task) + + self.game_memory.completed_tasks = updated_completed_tasks + self.game_memory.failed_tasks = updated_failed_tasks + + # dump to json + with open(f"{CKPT_DIR}/curriculum/completed_tasks.json", "w") as f: + json.dump(self.game_memory.completed_tasks, f) + with open(f"{CKPT_DIR}/curriculum/failed_tasks.json", "w") as f: + json.dump(self.game_memory.failed_tasks, f) + async def on_event(self, *args): """ Retrieve Minecraft events. diff --git a/metagpt/roles/minecraft/critic_agent.py b/metagpt/roles/minecraft/critic_agent.py index 505fa82e4..7bb90767a 100644 --- a/metagpt/roles/minecraft/critic_agent.py +++ b/metagpt/roles/minecraft/critic_agent.py @@ -12,17 +12,19 @@ from metagpt.utils.minecraft import load_prompt from metagpt.schema import Message, HumanMessage, SystemMessage from metagpt.logs import logger + @agent_registry.register("critic_agent") class CriticReviewer(Base): """ self-verification """ + def __init__( - self, - name: str = "Simon", - profile: str = "Task Reviewer", - goal: str = "To provide insightful and constructive feedback on a wide range of content types, helping creators improve their work and maintaining high-quality standards.", - constraints: str = "Adherence to ethical reviewing practices, respectful communication, and confidentiality of sensitive information.", + self, + name: str = "Simon", + profile: str = "Task Reviewer", + goal: str = "To provide insightful and constructive feedback on a wide range of content types, helping creators improve their work and maintaining high-quality standards.", + constraints: str = "Adherence to ethical reviewing practices, respectful communication, and confidentiality of sensitive information.", ) -> None: super().__init__(name, profile, goal, constraints) # Initialize actions specific to the CriticReviewer role @@ -30,7 +32,7 @@ class CriticReviewer(Base): # Set events or actions the CriticReviewer should watch or be aware of # 需要获取最新的events来进行评估 - self._watch([GenerateActionCode,AddNewSkills]) + self._watch([GenerateActionCode, AddNewSkills]) def render_system_message(self): system_message = SystemMessage(content=load_prompt("critic")) @@ -50,7 +52,9 @@ class CriticReviewer(Base): for i, (event_type, event) in enumerate(events): if event_type == "onError": - logger.info(f"\033[31mCritic Agent: Error occurs {event['onError']}\033[0m") + logger.info( + f"\033[31mCritic Agent: Error occurs {event['onError']}\033[0m" + ) # return None return HumanMessage(content="") @@ -88,14 +92,15 @@ class CriticReviewer(Base): logger.info(f"****Critic Agent human message****\n: {observation}") return HumanMessage(content=observation) - def encapsule_message(self, - events, - task, - context, - chest_observation, - *args, - **kwargs, - ): + def encapsule_message( + self, + events, + task, + context, + chest_observation, + *args, + **kwargs, + ): system_message = self.render_system_message() human_message = self.render_human_message( events=events, @@ -109,26 +114,38 @@ class CriticReviewer(Base): "human_msg": human_message.content, } - async def verify_task(self,human_msg, system_msg, *args, **kwargs): + async def verify_task(self, human_msg, system_msg, *args, **kwargs): success, critique = await VerifyTask().run(human_msg, system_msg, max_retries=5) - return Message(content=f"{critique}", instruct_content="verify_task", role=self.profile, - send_to=agent_registry.entries["skill_manager"]()._setting.name)#addnewskill - #TODO:if not success + self.perform_game_info_callback( + success, self.game_memory.update_exploration_progress + ) + return Message( + content=f"{critique}", + instruct_content="verify_task", + role=self.profile, + send_to=agent_registry.entries["skill_manager"]()._setting.name, + ) # addnewskill + # TODO:if not success + 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) # update chest_memory / chest observation + self.perform_game_info_callback( + events, self.game_memory.update_event + ) # update chest_memory / chest observation context = self.game_memory.context task = self.game_memory.current_task chest_observation = self.game_memory.chest_observation - message = self.encapsule_message(events=events, - task=task, - context=context, - chest_observation=chest_observation, ) + message = self.encapsule_message( + events=events, + task=task, + context=context, + chest_observation=chest_observation, + ) logger.info(todo) handler_map = { VerifyTask: self.verify_task, diff --git a/metagpt/roles/minecraft/curriculum_agent.py b/metagpt/roles/minecraft/curriculum_agent.py index 1df9bc359..602792d06 100644 --- a/metagpt/roles/minecraft/curriculum_agent.py +++ b/metagpt/roles/minecraft/curriculum_agent.py @@ -308,52 +308,6 @@ class CurriculumDesigner(Base): role=self.profile, ) - # TODO: move to Critic agent - def update_exploration_progress(self, info): - """ - Split task into completed_tasks or failed_tasks - Args: info = { - "task": self.task, - "success": success, - "conversations": self.conversations, - } - """ - task = info["task"] - if task.startswith("Deposit useless items into the chest at"): - return - if info["success"]: - logger.info(f"Completed task {task}.") - self.game_memory.completed_tasks.append(task) - else: - logger.info(f"Failed to complete task {task}. Skipping to next task.") - self.game_memory.failed_tasks.append(task) - - self.save_sorted_tasks() - - # TODO: move to Critic agent - def save_sorted_tasks(self): - updated_completed_tasks = [] - # record repeated failed tasks - updated_failed_tasks = self.game_memory.failed_tasks - # dedup but keep order - for task in self.game_memory.completed_tasks: - if task not in updated_completed_tasks: - updated_completed_tasks.append(task) - - # remove completed tasks from failed tasks - for task in updated_completed_tasks: - while task in updated_failed_tasks: - updated_failed_tasks.remove(task) - - self.game_memory.completed_tasks = updated_completed_tasks - self.game_memory.failed_tasks = updated_failed_tasks - - # dump to json - with open(f"{CKPT_DIR}/curriculum/completed_tasks.json", "w") as f: - json.dump(self.game_memory.completed_tasks, f) - with open(f"{CKPT_DIR}/curriculum/failed_tasks.json", "w") as f: - json.dump(self.game_memory.failed_tasks, f) - async def _act(self) -> Message: todo = self._rc.todo logger.debug(f"Todo is {todo}")