mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-17 15:35:21 +02:00
update:更新基础版本,支持多轮,每轮使用每个角色的任务完成情况判断
This commit is contained in:
parent
cbd071a10e
commit
493225f636
10 changed files with 93 additions and 37 deletions
|
|
@ -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__ = [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue