feat: +user requirement to Architect, ProjectManager

This commit is contained in:
莘权 马 2024-04-29 15:07:21 +08:00
parent df36fcc929
commit 125d043464
15 changed files with 264 additions and 911 deletions

View file

@ -11,53 +11,123 @@ from pathlib import Path
import pytest
from metagpt.actions import UserRequirement
from metagpt.actions.prepare_documents import PrepareDocuments
from metagpt.context import Context
from metagpt.environment import Environment
from metagpt.logs import logger
from metagpt.roles import Architect, ProductManager, Role
from metagpt.schema import Message
from metagpt.roles import (
Architect,
Engineer,
ProductManager,
ProjectManager,
QaEngineer,
)
from metagpt.schema import Message, UserMessage
from metagpt.utils.common import any_to_str, is_send_to
serdeser_path = Path(__file__).absolute().parent.joinpath("../data/serdeser_storage")
@pytest.fixture
def env():
return Environment()
# @pytest.fixture
# def env():
# return Environment()
#
#
# def test_add_role(env: Environment):
# role = ProductManager(
# name="Alice", profile="product manager", goal="create a new product", constraints="limited resources"
# )
# env.add_role(role)
# assert env.get_role(role.profile) == role
#
#
# def test_get_roles(env: Environment):
# role1 = Role(name="Alice", profile="product manager", goal="create a new product", constraints="limited resources")
# role2 = Role(name="Bob", profile="engineer", goal="develop the new product", constraints="short deadline")
# env.add_role(role1)
# env.add_role(role2)
# roles = env.get_roles()
# assert roles == {role1.profile: role1, role2.profile: role2}
#
#
# @pytest.mark.asyncio
# async def test_publish_and_process_message(env: Environment):
# if env.context.git_repo:
# env.context.git_repo.delete_repository()
# env.context.git_repo = None
#
# product_manager = ProductManager(name="Alice", profile="Product Manager", goal="做AI Native产品", constraints="资源有限")
# architect = Architect(
# name="Bob", profile="Architect", goal="设计一个可用、高效、较低成本的系统,包括数据结构与接口", constraints="资源有限,需要节省成本"
# )
#
# env.add_roles([product_manager, architect])
#
# env.publish_message(Message(role="User", content="需要一个基于LLM做总结的搜索引擎", cause_by=UserRequirement))
# await env.run(k=2)
# logger.info(f"{env.history}")
# assert len(env.history.storage) > 10
def test_add_role(env: Environment):
role = ProductManager(
name="Alice", profile="product manager", goal="create a new product", constraints="limited resources"
)
env.add_role(role)
assert env.get_role(role.profile) == role
class MockEnv(Environment):
def publish_message(self, message: Message, peekable: bool = True) -> bool:
consumers = []
for role, addrs in self.member_addrs.items():
if is_send_to(message, addrs):
role.put_message(message)
consumers.append(role)
if not consumers:
logger.warning(f"Message no recipients: {message.dump()}")
if message.cause_by in [any_to_str(UserRequirement), any_to_str(PrepareDocuments)]:
assert len(consumers) == 1
def test_get_roles(env: Environment):
role1 = Role(name="Alice", profile="product manager", goal="create a new product", constraints="limited resources")
role2 = Role(name="Bob", profile="engineer", goal="develop the new product", constraints="short deadline")
env.add_role(role1)
env.add_role(role2)
roles = env.get_roles()
assert roles == {role1.profile: role1, role2.profile: role2}
return True
@pytest.mark.asyncio
async def test_publish_and_process_message(env: Environment):
if env.context.git_repo:
env.context.git_repo.delete_repository()
env.context.git_repo = None
product_manager = ProductManager(name="Alice", profile="Product Manager", goal="做AI Native产品", constraints="资源有限")
architect = Architect(
name="Bob", profile="Architect", goal="设计一个可用、高效、较低成本的系统,包括数据结构与接口", constraints="资源有限,需要节省成本"
@pytest.mark.parametrize(
("content", "send_to"),
[
# ("snake game", any_to_str(ProductManager)),
# (
# "Rewrite the PRD file of the project at '/Users/iorishinier/github/MetaGPT/workspace/snake_game', add 'moving enemy' to the original requirement",
# any_to_str(ProductManager),
# ),
# (
# "Add 'random moving enemy, and dispears after 10 seconds' design to the project at '/Users/iorishinier/github/MetaGPT/workspace/snake_game'",
# any_to_str(Architect),
# ),
(
'Rewrite the tasks file of the project at "/Users/iorishinier/github/MetaGPT/workspace/snake_game"',
any_to_str(ProjectManager),
),
# (
# "Rewrite 'main.py' of the project at '/Users/iorishinier/github/MetaGPT/workspace/snake_game'",
# any_to_str(Engineer),
# ),
# (
# "Rewrite the unit test of 'test_main.py' at '/Users/iorishinier/github/MetaGPT/workspace/snake_game'",
# any_to_str(QaEngineer),
# ),
],
)
async def test_env(content, send_to):
context = Context()
env = MockEnv(context=context)
env.add_roles(
[
ProductManager(context=context),
Architect(context=context),
ProjectManager(context=context),
Engineer(n_borg=5, use_code_review=True, context=context),
QaEngineer(context=context),
]
)
env.add_roles([product_manager, architect])
env.publish_message(Message(role="User", content="需要一个基于LLM做总结的搜索引擎", cause_by=UserRequirement))
await env.run(k=2)
logger.info(f"{env.history=}")
assert len(env.history) > 10
msg = UserMessage(content=content, send_to=send_to)
env.publish_message(msg)
while not env.is_idle:
await env.run()
pass
if __name__ == "__main__":