mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-04-28 10:26:32 +02:00
Merge pull request #728 from better629/feat_simple_ser
Feat simpler serialization in one file
This commit is contained in:
commit
9a42a14c91
29 changed files with 232 additions and 316 deletions
|
|
@ -8,25 +8,20 @@ from metagpt.actions import Action
|
|||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
def test_action_serialize():
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_serdeser():
|
||||
action = Action()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
assert "__module_class_name" not in ser_action_dict
|
||||
assert "__module_class_name" in ser_action_dict
|
||||
|
||||
action = Action(name="test")
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "test" in ser_action_dict["name"]
|
||||
|
||||
new_action = Action(**ser_action_dict)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize():
|
||||
action = Action()
|
||||
serialized_data = action.model_dump()
|
||||
|
||||
new_action = Action(**serialized_data)
|
||||
|
||||
assert new_action.name == "Action"
|
||||
assert new_action.name == "test"
|
||||
assert isinstance(new_action.llm, type(LLM()))
|
||||
assert len(await new_action._aask("who are you")) > 0
|
||||
|
|
|
|||
|
|
@ -8,20 +8,15 @@ from metagpt.actions.action import Action
|
|||
from metagpt.roles.architect import Architect
|
||||
|
||||
|
||||
def test_architect_serialize():
|
||||
@pytest.mark.asyncio
|
||||
async def test_architect_serdeser():
|
||||
role = Architect()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
assert "name" in ser_role_dict
|
||||
assert "states" in ser_role_dict
|
||||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_architect_deserialize():
|
||||
role = Architect()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
new_role = Architect(**ser_role_dict)
|
||||
# new_role = Architect.deserialize(ser_role_dict)
|
||||
assert new_role.name == "Bob"
|
||||
assert len(new_role.actions) == 1
|
||||
assert isinstance(new_role.actions[0], Action)
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @Desc :
|
||||
|
||||
import shutil
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.add_requirement import UserRequirement
|
||||
|
|
@ -10,7 +9,7 @@ from metagpt.actions.project_management import WriteTasks
|
|||
from metagpt.environment import Environment
|
||||
from metagpt.roles.project_manager import ProjectManager
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str
|
||||
from metagpt.utils.common import any_to_str, read_json_file, write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
||||
ActionOK,
|
||||
ActionRaise,
|
||||
|
|
@ -19,17 +18,14 @@ from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
|||
)
|
||||
|
||||
|
||||
def test_env_serialize():
|
||||
def test_env_serdeser():
|
||||
env = Environment()
|
||||
env.publish_message(message=Message(content="test env serialize"))
|
||||
|
||||
ser_env_dict = env.model_dump()
|
||||
assert "roles" in ser_env_dict
|
||||
assert len(ser_env_dict["roles"]) == 0
|
||||
|
||||
|
||||
def test_env_deserialize():
|
||||
env = Environment()
|
||||
env.publish_message(message=Message(content="test env serialize"))
|
||||
ser_env_dict = env.model_dump()
|
||||
new_env = Environment(**ser_env_dict)
|
||||
assert len(new_env.roles) == 0
|
||||
assert len(new_env.history) == 25
|
||||
|
|
@ -79,12 +75,13 @@ def test_environment_serdeser_save():
|
|||
environment = Environment()
|
||||
role_c = RoleC()
|
||||
|
||||
shutil.rmtree(serdeser_path.joinpath("team"), ignore_errors=True)
|
||||
|
||||
stg_path = serdeser_path.joinpath("team", "environment")
|
||||
env_path = stg_path.joinpath("env.json")
|
||||
environment.add_role(role_c)
|
||||
environment.serialize(stg_path)
|
||||
|
||||
new_env: Environment = Environment.deserialize(stg_path)
|
||||
write_json_file(env_path, environment.model_dump())
|
||||
|
||||
env_dict = read_json_file(env_path)
|
||||
new_env: Environment = Environment(**env_dict)
|
||||
assert len(new_env.roles) == 1
|
||||
assert type(list(new_env.roles.values())[0].actions[0]) == ActionOK
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from metagpt.actions.add_requirement import UserRequirement
|
|||
from metagpt.actions.design_api import WriteDesign
|
||||
from metagpt.memory.memory import Memory
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str
|
||||
from metagpt.utils.common import any_to_str, read_json_file, write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import serdeser_path
|
||||
|
||||
|
||||
|
|
@ -53,14 +53,14 @@ def test_memory_serdeser_save():
|
|||
memory.add_batch([msg1, msg2])
|
||||
|
||||
stg_path = serdeser_path.joinpath("team", "environment")
|
||||
memory.serialize(stg_path)
|
||||
assert stg_path.joinpath("memory.json").exists()
|
||||
memory_path = stg_path.joinpath("memory.json")
|
||||
write_json_file(memory_path, memory.model_dump())
|
||||
assert memory_path.exists()
|
||||
|
||||
new_memory = Memory.deserialize(stg_path)
|
||||
memory_dict = read_json_file(memory_path)
|
||||
new_memory = Memory(**memory_dict)
|
||||
assert new_memory.count() == 2
|
||||
new_msg2 = new_memory.get(1)[0]
|
||||
assert new_msg2.instruct_content.field1 == ["field1 value1", "field1 value2"]
|
||||
assert new_msg2.cause_by == any_to_str(WriteDesign)
|
||||
assert len(new_memory.index) == 2
|
||||
|
||||
stg_path.joinpath("memory.json").unlink()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : unittest of polymorphic conditions
|
||||
import copy
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, SerializeAsAny
|
||||
|
||||
|
|
@ -12,6 +13,8 @@ from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
|||
|
||||
|
||||
class ActionSubClasses(BaseModel):
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
actions: list[SerializeAsAny[Action]] = []
|
||||
|
||||
|
||||
|
|
@ -40,19 +43,21 @@ def test_no_serialize_as_any():
|
|||
|
||||
|
||||
def test_polymorphic():
|
||||
_ = ActionOKV2(
|
||||
ok_v2 = ActionOKV2(
|
||||
**{"name": "ActionOKV2", "context": "", "prefix": "", "desc": "", "extra_field": "ActionOKV2 Extra Info"}
|
||||
)
|
||||
|
||||
action_subcls = ActionSubClasses(actions=[ActionOKV2(), ActionPass()])
|
||||
action_subcls_dict = action_subcls.model_dump()
|
||||
action_subcls_dict2 = copy.deepcopy(action_subcls_dict)
|
||||
|
||||
assert "__module_class_name" in action_subcls_dict["actions"][0]
|
||||
|
||||
new_action_subcls = ActionSubClasses(**action_subcls_dict)
|
||||
assert isinstance(new_action_subcls.actions[0], ActionOKV2)
|
||||
assert new_action_subcls.actions[0].extra_field == ok_v2.extra_field
|
||||
assert isinstance(new_action_subcls.actions[1], ActionPass)
|
||||
|
||||
new_action_subcls = ActionSubClasses.model_validate(action_subcls_dict)
|
||||
new_action_subcls = ActionSubClasses.model_validate(action_subcls_dict2)
|
||||
assert isinstance(new_action_subcls.actions[0], ActionOKV2)
|
||||
assert isinstance(new_action_subcls.actions[1], ActionPass)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from metagpt.actions.prepare_interview import PrepareInterview
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize():
|
||||
async def test_action_serdeser():
|
||||
action = PrepareInterview()
|
||||
serialized_data = action.model_dump()
|
||||
assert serialized_data["name"] == "PrepareInterview"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from metagpt.schema import Message
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_product_manager_deserialize(new_filename):
|
||||
async def test_product_manager_serdeser(new_filename):
|
||||
role = ProductManager()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
new_role = ProductManager(**ser_role_dict)
|
||||
|
|
|
|||
|
|
@ -9,19 +9,14 @@ from metagpt.actions.project_management import WriteTasks
|
|||
from metagpt.roles.project_manager import ProjectManager
|
||||
|
||||
|
||||
def test_project_manager_serialize():
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_manager_serdeser():
|
||||
role = ProjectManager()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
assert "name" in ser_role_dict
|
||||
assert "states" in ser_role_dict
|
||||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_manager_deserialize():
|
||||
role = ProjectManager()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
|
||||
new_role = ProjectManager(**ser_role_dict)
|
||||
assert new_role.name == "Eve"
|
||||
assert len(new_role.actions) == 1
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from metagpt.roles.researcher import Researcher
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tutorial_assistant_deserialize():
|
||||
async def test_tutorial_assistant_serdeser():
|
||||
role = Researcher()
|
||||
ser_role_dict = role.model_dump()
|
||||
assert "name" in ser_role_dict
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ from pydantic import BaseModel, SerializeAsAny
|
|||
|
||||
from metagpt.actions import WriteCode
|
||||
from metagpt.actions.add_requirement import UserRequirement
|
||||
from metagpt.const import SERDESER_PATH
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles.engineer import Engineer
|
||||
from metagpt.roles.product_manager import ProductManager
|
||||
from metagpt.roles.role import Role
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import format_trackback_info
|
||||
from metagpt.utils.common import format_trackback_info, read_json_file, write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
||||
ActionOK,
|
||||
RoleA,
|
||||
|
|
@ -60,37 +59,31 @@ def test_role_serialize():
|
|||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
def test_engineer_serialize():
|
||||
def test_engineer_serdeser():
|
||||
role = Engineer()
|
||||
ser_role_dict = role.model_dump()
|
||||
assert "name" in ser_role_dict
|
||||
assert "states" in ser_role_dict
|
||||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_engineer_deserialize():
|
||||
role = Engineer(use_code_review=True)
|
||||
ser_role_dict = role.model_dump()
|
||||
|
||||
new_role = Engineer(**ser_role_dict)
|
||||
assert new_role.name == "Alex"
|
||||
assert new_role.use_code_review is True
|
||||
assert new_role.use_code_review is False
|
||||
assert len(new_role.actions) == 1
|
||||
assert isinstance(new_role.actions[0], WriteCode)
|
||||
# await new_role.actions[0].run(context="write a cli snake game", filename="test_code")
|
||||
|
||||
|
||||
def test_role_serdeser_save():
|
||||
stg_path_prefix = serdeser_path.joinpath("team", "environment", "roles")
|
||||
shutil.rmtree(serdeser_path.joinpath("team"), ignore_errors=True)
|
||||
|
||||
pm = ProductManager()
|
||||
role_tag = f"{pm.__class__.__name__}_{pm.name}"
|
||||
stg_path = stg_path_prefix.joinpath(role_tag)
|
||||
pm.serialize(stg_path)
|
||||
|
||||
new_pm = Role.deserialize(stg_path)
|
||||
stg_path = serdeser_path.joinpath("team", "environment", "roles", f"{pm.__class__.__name__}_{pm.name}")
|
||||
role_path = stg_path.joinpath("role.json")
|
||||
write_json_file(role_path, pm.model_dump())
|
||||
|
||||
role_dict = read_json_file(role_path)
|
||||
new_pm = ProductManager(**role_dict)
|
||||
assert new_pm.name == pm.name
|
||||
assert len(new_pm.get_memories(1)) == 0
|
||||
|
||||
|
|
@ -98,22 +91,24 @@ def test_role_serdeser_save():
|
|||
@pytest.mark.asyncio
|
||||
async def test_role_serdeser_interrupt():
|
||||
role_c = RoleC()
|
||||
shutil.rmtree(SERDESER_PATH.joinpath("team"), ignore_errors=True)
|
||||
shutil.rmtree(serdeser_path.joinpath("team"), ignore_errors=True)
|
||||
|
||||
stg_path = SERDESER_PATH.joinpath("team", "environment", "roles", f"{role_c.__class__.__name__}_{role_c.name}")
|
||||
stg_path = serdeser_path.joinpath("team", "environment", "roles", f"{role_c.__class__.__name__}_{role_c.name}")
|
||||
role_path = stg_path.joinpath("role.json")
|
||||
try:
|
||||
await role_c.run(with_message=Message(content="demo", cause_by=UserRequirement))
|
||||
except Exception:
|
||||
logger.error(f"Exception in `role_a.run`, detail: {format_trackback_info()}")
|
||||
role_c.serialize(stg_path)
|
||||
logger.error(f"Exception in `role_c.run`, detail: {format_trackback_info()}")
|
||||
write_json_file(role_path, role_c.model_dump())
|
||||
|
||||
assert role_c.rc.memory.count() == 1
|
||||
|
||||
new_role_a: Role = Role.deserialize(stg_path)
|
||||
assert new_role_a.rc.state == 1
|
||||
role_dict = read_json_file(role_path)
|
||||
new_role_c: Role = RoleC(**role_dict)
|
||||
assert new_role_c.rc.state == 1
|
||||
|
||||
with pytest.raises(Exception):
|
||||
await new_role_a.run(with_message=Message(content="demo", cause_by=UserRequirement))
|
||||
await new_role_c.run(with_message=Message(content="demo", cause_by=UserRequirement))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : unittest of schema ser&deser
|
||||
import pytest
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.write_code import WriteCode
|
||||
from metagpt.schema import Document, Documents, Message
|
||||
from metagpt.schema import CodingContext, Document, Documents, Message, TestingContext
|
||||
from metagpt.utils.common import any_to_str
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
||||
MockICMessage,
|
||||
|
|
@ -12,12 +13,16 @@ from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
|||
)
|
||||
|
||||
|
||||
def test_message_serdeser():
|
||||
def test_message_serdeser_from_create_model():
|
||||
with pytest.raises(KeyError):
|
||||
_ = Message(content="code", instruct_content={"class": "test", "key": "value"})
|
||||
|
||||
out_mapping = {"field3": (str, ...), "field4": (list[str], ...)}
|
||||
out_data = {"field3": "field3 value3", "field4": ["field4 value1", "field4 value2"]}
|
||||
ic_obj = ActionNode.create_model_class("code", out_mapping)
|
||||
ic_inst = ic_obj(**out_data)
|
||||
|
||||
message = Message(content="code", instruct_content=ic_obj(**out_data), role="engineer", cause_by=WriteCode)
|
||||
message = Message(content="code", instruct_content=ic_inst, role="engineer", cause_by=WriteCode)
|
||||
ser_data = message.model_dump()
|
||||
assert ser_data["cause_by"] == "metagpt.actions.write_code.WriteCode"
|
||||
assert ser_data["instruct_content"]["class"] == "code"
|
||||
|
|
@ -25,28 +30,67 @@ def test_message_serdeser():
|
|||
new_message = Message(**ser_data)
|
||||
assert new_message.cause_by == any_to_str(WriteCode)
|
||||
assert new_message.cause_by in [any_to_str(WriteCode)]
|
||||
|
||||
assert new_message.instruct_content != ic_obj(**out_data) # TODO find why `!=`
|
||||
assert new_message.instruct_content != ic_inst
|
||||
assert new_message.instruct_content.model_dump() == ic_obj(**out_data).model_dump()
|
||||
|
||||
message = Message(content="test_ic", instruct_content=MockICMessage())
|
||||
mock_msg = MockMessage()
|
||||
message = Message(content="test_ic", instruct_content=mock_msg)
|
||||
ser_data = message.model_dump()
|
||||
new_message = Message(**ser_data)
|
||||
assert new_message.instruct_content != MockICMessage() # TODO
|
||||
|
||||
message = Message(content="test_documents", instruct_content=Documents(docs={"doc1": Document(content="test doc")}))
|
||||
ser_data = message.model_dump()
|
||||
assert "class" in ser_data["instruct_content"]
|
||||
assert new_message.instruct_content == mock_msg
|
||||
|
||||
|
||||
def test_message_without_postprocess():
|
||||
"""to explain `instruct_content` should be postprocessed"""
|
||||
"""to explain `instruct_content` from `create_model_class` should be postprocessed"""
|
||||
out_mapping = {"field1": (list[str], ...)}
|
||||
out_data = {"field1": ["field1 value1", "field1 value2"]}
|
||||
ic_obj = ActionNode.create_model_class("code", out_mapping)
|
||||
message = MockMessage(content="code", instruct_content=ic_obj(**out_data))
|
||||
message = MockICMessage(content="code", instruct_content=ic_obj(**out_data))
|
||||
ser_data = message.model_dump()
|
||||
assert ser_data["instruct_content"] == {}
|
||||
|
||||
ser_data["instruct_content"] = None
|
||||
new_message = MockMessage(**ser_data)
|
||||
new_message = MockICMessage(**ser_data)
|
||||
assert new_message.instruct_content != ic_obj(**out_data)
|
||||
|
||||
|
||||
def test_message_serdeser_from_basecontext():
|
||||
doc_msg = Message(content="test_document", instruct_content=Document(content="test doc"))
|
||||
ser_data = doc_msg.model_dump()
|
||||
assert ser_data["instruct_content"]["value"]["content"] == "test doc"
|
||||
assert ser_data["instruct_content"]["value"]["filename"] == ""
|
||||
|
||||
docs_msg = Message(
|
||||
content="test_documents", instruct_content=Documents(docs={"doc1": Document(content="test doc")})
|
||||
)
|
||||
ser_data = docs_msg.model_dump()
|
||||
assert ser_data["instruct_content"]["class"] == "Documents"
|
||||
assert ser_data["instruct_content"]["value"]["docs"]["doc1"]["content"] == "test doc"
|
||||
assert ser_data["instruct_content"]["value"]["docs"]["doc1"]["filename"] == ""
|
||||
|
||||
code_ctxt = CodingContext(
|
||||
filename="game.py",
|
||||
design_doc=Document(root_path="docs/system_design", filename="xx.json", content="xxx"),
|
||||
task_doc=Document(root_path="docs/tasks", filename="xx.json", content="xxx"),
|
||||
code_doc=Document(root_path="xxx", filename="game.py", content="xxx"),
|
||||
)
|
||||
code_ctxt_msg = Message(content="coding_context", instruct_content=code_ctxt)
|
||||
ser_data = code_ctxt_msg.model_dump()
|
||||
assert ser_data["instruct_content"]["class"] == "CodingContext"
|
||||
|
||||
new_code_ctxt_msg = Message(**ser_data)
|
||||
assert new_code_ctxt_msg.instruct_content == code_ctxt
|
||||
assert new_code_ctxt_msg.instruct_content.code_doc.filename == "game.py"
|
||||
|
||||
testing_ctxt = TestingContext(
|
||||
filename="test.py",
|
||||
code_doc=Document(root_path="xxx", filename="game.py", content="xxx"),
|
||||
test_doc=Document(root_path="docs/tests", filename="test.py", content="xxx"),
|
||||
)
|
||||
testing_ctxt_msg = Message(content="testing_context", instruct_content=testing_ctxt)
|
||||
ser_data = testing_ctxt_msg.model_dump()
|
||||
new_testing_ctxt_msg = Message(**ser_data)
|
||||
assert new_testing_ctxt_msg.instruct_content == testing_ctxt
|
||||
assert new_testing_ctxt_msg.instruct_content.test_doc.filename == "test.py"
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ from metagpt.roles.role import Role, RoleReactMode
|
|||
serdeser_path = Path(__file__).absolute().parent.joinpath("..", "..", "data", "serdeser_storage")
|
||||
|
||||
|
||||
class MockICMessage(BaseModel):
|
||||
content: str = "test_ic"
|
||||
|
||||
|
||||
class MockMessage(BaseModel):
|
||||
content: str = "test_msg"
|
||||
|
||||
|
||||
class MockICMessage(BaseModel):
|
||||
"""to test normal dict without postprocess"""
|
||||
|
||||
content: str = ""
|
||||
content: str = "test_ic_msg"
|
||||
instruct_content: Optional[BaseModel] = Field(default=None)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,8 @@ import pytest
|
|||
from metagpt.roles.sk_agent import SkAgent
|
||||
|
||||
|
||||
def test_sk_agent_serialize():
|
||||
role = SkAgent()
|
||||
ser_role_dict = role.model_dump(exclude={"import_semantic_skill_from_directory", "import_skill"})
|
||||
assert "name" in ser_role_dict
|
||||
assert "planner" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_sk_agent_deserialize():
|
||||
async def test_sk_agent_serdeser():
|
||||
role = SkAgent()
|
||||
ser_role_dict = role.model_dump(exclude={"import_semantic_skill_from_directory", "import_skill"})
|
||||
assert "name" in ser_role_dict
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
# @Desc :
|
||||
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.const import SERDESER_PATH
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles import Architect, ProductManager, ProjectManager
|
||||
from metagpt.team import Team
|
||||
from metagpt.utils.common import write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
||||
ActionOK,
|
||||
RoleA,
|
||||
|
|
@ -45,9 +46,16 @@ def test_team_deserialize():
|
|||
assert new_company.env.get_role(arch.profile) is not None
|
||||
|
||||
|
||||
def test_team_serdeser_save():
|
||||
company = Team()
|
||||
def mock_team_serialize(self, stg_path: Path = serdeser_path.joinpath("team")):
|
||||
team_info_path = stg_path.joinpath("team.json")
|
||||
|
||||
write_json_file(team_info_path, self.model_dump())
|
||||
|
||||
|
||||
def test_team_serdeser_save(mocker):
|
||||
mocker.patch("metagpt.team.Team.serialize", mock_team_serialize)
|
||||
|
||||
company = Team()
|
||||
company.hire([RoleC()])
|
||||
|
||||
stg_path = serdeser_path.joinpath("team")
|
||||
|
|
@ -61,9 +69,11 @@ def test_team_serdeser_save():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_team_recover():
|
||||
async def test_team_recover(mocker):
|
||||
mocker.patch("metagpt.team.Team.serialize", mock_team_serialize)
|
||||
|
||||
idea = "write a snake game"
|
||||
stg_path = SERDESER_PATH.joinpath("team")
|
||||
stg_path = serdeser_path.joinpath("team")
|
||||
shutil.rmtree(stg_path, ignore_errors=True)
|
||||
|
||||
company = Team()
|
||||
|
|
@ -75,9 +85,9 @@ async def test_team_recover():
|
|||
ser_data = company.model_dump()
|
||||
new_company = Team(**ser_data)
|
||||
|
||||
new_company.env.get_role(role_c.profile)
|
||||
# assert new_role_c.rc.memory == role_c.rc.memory # TODO
|
||||
# assert new_role_c.rc.env != role_c.rc.env # TODO
|
||||
new_role_c = new_company.env.get_role(role_c.profile)
|
||||
assert new_role_c.rc.memory == role_c.rc.memory
|
||||
assert new_role_c.rc.env != role_c.rc.env
|
||||
assert type(list(new_company.env.roles.values())[0].actions[0]) == ActionOK
|
||||
|
||||
new_company.run_project(idea)
|
||||
|
|
@ -85,9 +95,11 @@ async def test_team_recover():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_team_recover_save():
|
||||
async def test_team_recover_save(mocker):
|
||||
mocker.patch("metagpt.team.Team.serialize", mock_team_serialize)
|
||||
|
||||
idea = "write a 2048 web game"
|
||||
stg_path = SERDESER_PATH.joinpath("team")
|
||||
stg_path = serdeser_path.joinpath("team")
|
||||
shutil.rmtree(stg_path, ignore_errors=True)
|
||||
|
||||
company = Team()
|
||||
|
|
@ -98,8 +110,8 @@ async def test_team_recover_save():
|
|||
|
||||
new_company = Team.deserialize(stg_path)
|
||||
new_role_c = new_company.env.get_role(role_c.profile)
|
||||
# assert new_role_c.rc.memory == role_c.rc.memory
|
||||
# assert new_role_c.rc.env != role_c.rc.env
|
||||
assert new_role_c.rc.memory == role_c.rc.memory
|
||||
assert new_role_c.rc.env != role_c.rc.env
|
||||
assert new_role_c.recovered != role_c.recovered # here cause previous ut is `!=`
|
||||
assert new_role_c.rc.todo != role_c.rc.todo # serialize exclude `rc.todo`
|
||||
assert new_role_c.rc.news != role_c.rc.news # serialize exclude `rc.news`
|
||||
|
|
@ -109,9 +121,11 @@ async def test_team_recover_save():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_team_recover_multi_roles_save():
|
||||
async def test_team_recover_multi_roles_save(mocker):
|
||||
mocker.patch("metagpt.team.Team.serialize", mock_team_serialize)
|
||||
|
||||
idea = "write a snake game"
|
||||
stg_path = SERDESER_PATH.joinpath("team")
|
||||
stg_path = serdeser_path.joinpath("team")
|
||||
shutil.rmtree(stg_path, ignore_errors=True)
|
||||
|
||||
role_a = RoleA()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from metagpt.roles.tutorial_assistant import TutorialAssistant
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tutorial_assistant_deserialize():
|
||||
async def test_tutorial_assistant_serdeser():
|
||||
role = TutorialAssistant()
|
||||
ser_role_dict = role.model_dump()
|
||||
assert "name" in ser_role_dict
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from metagpt.actions import WriteCode
|
|||
from metagpt.schema import CodingContext, Document
|
||||
|
||||
|
||||
def test_write_design_serialize():
|
||||
def test_write_design_serdeser():
|
||||
action = WriteCode()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert ser_action_dict["name"] == "WriteCode"
|
||||
|
|
@ -17,7 +17,7 @@ def test_write_design_serialize():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_deserialize():
|
||||
async def test_write_code_serdeser():
|
||||
context = CodingContext(
|
||||
filename="test_code.py", design_doc=Document(content="write add function to calculate two numbers")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from metagpt.schema import CodingContext, Document
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_review_deserialize():
|
||||
async def test_write_code_review_serdeser():
|
||||
code_content = """
|
||||
def div(a: int, b: int = 0):
|
||||
return a / b
|
||||
|
|
|
|||
|
|
@ -7,33 +7,25 @@ import pytest
|
|||
from metagpt.actions import WriteDesign, WriteTasks
|
||||
|
||||
|
||||
def test_write_design_serialize():
|
||||
action = WriteDesign()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
|
||||
|
||||
def test_write_task_serialize():
|
||||
action = WriteTasks()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_design_deserialize():
|
||||
async def test_write_design_serialize():
|
||||
action = WriteDesign()
|
||||
serialized_data = action.model_dump()
|
||||
new_action = WriteDesign(**serialized_data)
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
|
||||
new_action = WriteDesign(**ser_action_dict)
|
||||
assert new_action.name == "WriteDesign"
|
||||
await new_action.run(with_messages="write a cli snake game")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_task_deserialize():
|
||||
async def test_write_task_serialize():
|
||||
action = WriteTasks()
|
||||
serialized_data = action.model_dump()
|
||||
new_action = WriteTasks(**serialized_data)
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
|
||||
new_action = WriteTasks(**ser_action_dict)
|
||||
assert new_action.name == "WriteTasks"
|
||||
await new_action.run(with_messages="write a cli snake game")
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Person:
|
|||
],
|
||||
ids=["google", "numpy", "sphinx"],
|
||||
)
|
||||
async def test_action_deserialize(style: str, part: str):
|
||||
async def test_action_serdeser(style: str, part: str):
|
||||
action = WriteDocstring()
|
||||
serialized_data = action.model_dump()
|
||||
|
||||
|
|
|
|||
|
|
@ -9,18 +9,14 @@ from metagpt.actions import WritePRD
|
|||
from metagpt.schema import Message
|
||||
|
||||
|
||||
def test_action_serialize(new_filename):
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_serdeser(new_filename):
|
||||
action = WritePRD()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize(new_filename):
|
||||
action = WritePRD()
|
||||
serialized_data = action.model_dump()
|
||||
new_action = WritePRD(**serialized_data)
|
||||
new_action = WritePRD(**ser_action_dict)
|
||||
assert new_action.name == "WritePRD"
|
||||
action_output = await new_action.run(with_messages=Message(content="write a cli snake game"))
|
||||
assert len(action_output.content) > 0
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ CONTEXT = """
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize():
|
||||
async def test_action_serdeser():
|
||||
action = WriteReview()
|
||||
serialized_data = action.model_dump()
|
||||
assert serialized_data["name"] == "WriteReview"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from metagpt.actions.write_tutorial import WriteContent, WriteDirectory
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(("language", "topic"), [("English", "Write a tutorial about Python")])
|
||||
async def test_write_directory_deserialize(language: str, topic: str):
|
||||
async def test_write_directory_serdeser(language: str, topic: str):
|
||||
action = WriteDirectory()
|
||||
serialized_data = action.model_dump()
|
||||
assert serialized_data["name"] == "WriteDirectory"
|
||||
|
|
@ -30,7 +30,7 @@ async def test_write_directory_deserialize(language: str, topic: str):
|
|||
("language", "topic", "directory"),
|
||||
[("English", "Write a tutorial about Python", {"Introduction": ["What is Python?", "Why learn Python?"]})],
|
||||
)
|
||||
async def test_write_content_deserialize(language: str, topic: str, directory: Dict):
|
||||
async def test_write_content_serdeser(language: str, topic: str, directory: Dict):
|
||||
action = WriteContent(language=language, directory=directory)
|
||||
serialized_data = action.model_dump()
|
||||
assert serialized_data["name"] == "WriteContent"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue