serdeser rebase from main

This commit is contained in:
better629 2023-12-18 18:13:42 +08:00
commit dd640991b7
15 changed files with 91 additions and 11 deletions

View file

@ -64,11 +64,10 @@ class Action(BaseModel):
"""Set prefix for later usage"""
self.prefix = prefix
self.profile = profile
return self
def __str__(self):
return self.__class__.__name__
def __repr__(self):
return self.__str__()

View file

@ -16,6 +16,11 @@ from pydantic import Field
from metagpt.actions import Action, ActionOutput
from metagpt.actions.design_api_an import DESIGN_API_NODE
from typing import List, Optional, Any
from pydantic import Field
from metagpt.actions import Action, ActionOutput
from metagpt.llm import LLM
from metagpt.provider.base_gpt_api import BaseGPTAPI
from metagpt.config import CONFIG

View file

@ -7,6 +7,9 @@
@Modified By: mashenquan, 2023/11/27. Following the think-act principle, solidify the task parameters when creating the
WriteCode object, rather than passing them in when calling the run function.
"""
from typing import List, Optional, Any
from pydantic import Field
from tenacity import retry, stop_after_attempt, wait_fixed
from typing import List, Optional, Any
from pydantic import Field

View file

@ -55,6 +55,7 @@ DATA_PATH = METAGPT_ROOT / "data"
RESEARCH_PATH = DATA_PATH / "research"
TUTORIAL_PATH = DATA_PATH / "tutorial_docx"
INVOICE_OCR_TABLE_PATH = DATA_PATH / "invoice_table"
UT_PATH = DATA_PATH / "ut"
SWAGGER_PATH = UT_PATH / "files/api/"
UT_PY_PATH = UT_PATH / "files/ut/"

View file

@ -7,6 +7,9 @@
from typing import Optional
from pydantic import Field
from typing import Optional
from pydantic import Field
from metagpt.logs import logger
from metagpt.memory import Memory
from metagpt.memory.memory_storage import MemoryStorage

View file

@ -8,6 +8,7 @@
"""
import copy
from collections import defaultdict
from typing import Iterable, Type, Union, Optional, Set
from pathlib import Path
from pydantic import BaseModel, Field

View file

@ -22,6 +22,7 @@ class Architect(Role):
goal (str): Primary goal or responsibility of the architect.
constraints (str): Constraints or guidelines for the architect.
"""
name: str = "Bob"
profile: str = Field(default="Architect", alias='profile')
goal: str = "design a concise, usable, complete software system"

View file

@ -49,7 +49,6 @@ from metagpt.utils.common import any_to_str, any_to_str_set
IS_PASS_PROMPT = """
{context}
<<<<<<< HEAD
----
Does the above log indicate anything that needs to be done?
If there are any tasks to be completed, please answer 'NO' along with the to-do list in JSON format;

View file

@ -25,6 +25,7 @@ class ProjectManager(Role):
name: str = Field(default="Eve")
profile: str = Field(default="Project Manager")
goal: str = "reak down tasks according to PRD/technical design, generate a task list, and analyze task " \
"dependencies to start with the prerequisite modules"
constraints: str = "use same language as user requirement"

View file

@ -124,7 +124,7 @@ class RoleContext(BaseModel):
news: list[Type[Message]] = Field(default=[], exclude=True) # TODO not used
react_mode: RoleReactMode = RoleReactMode.REACT # see `Role._set_react_mode` for definitions of the following two attributes
max_react_loop: int = 1
class Config:
arbitrary_types_allowed = True
@ -175,7 +175,7 @@ class _RoleInjector(type):
role_subclass_registry = {}
class Role(BaseModel):
class Role(BaseModel, metaclass=_RoleInjector):
"""Role/Agent"""
name: str = ""
profile: str = ""
@ -248,6 +248,62 @@ class Role(BaseModel):
super().__init_subclass__(**kwargs)
role_subclass_registry[cls.__name__] = cls
# builtin variables
recovered: bool = False # to tag if a recovered role
builtin_class_name: str = ""
_private_attributes = {
"_llm": LLM() if not is_human else HumanProvider(),
"_role_id": _role_id,
"_states": [],
"_actions": [],
"_rc": RoleContext()
}
class Config:
arbitrary_types_allowed = True
exclude = ["_llm"]
def __init__(self, **kwargs: Any):
for index in range(len(kwargs.get("_actions", []))):
current_action = kwargs["_actions"][index]
if isinstance(current_action, dict):
item_class_name = current_action.get("builtin_class_name", None)
for name, subclass in action_subclass_registry.items():
registery_class_name = subclass.__fields__["builtin_class_name"].default
if item_class_name == registery_class_name:
current_action = subclass(**current_action)
break
kwargs["_actions"][index] = current_action
super().__init__(**kwargs)
# 关于私有变量的初始化 https://github.com/pydantic/pydantic/issues/655
self._private_attributes["_llm"] = LLM() if not self.is_human else HumanProvider()
self._private_attributes["_role_id"] = str(self._setting)
for key in self._private_attributes.keys():
if key in kwargs:
object.__setattr__(self, key, kwargs[key])
if key == "_rc":
_rc = RoleContext(**kwargs["_rc"])
object.__setattr__(self, "_rc", _rc)
else:
if key == "_rc":
# # Warning, if use self._private_attributes["_rc"],
# # self._rc will be a shared object between roles, so init one or reset it inside `_reset`
object.__setattr__(self, key, RoleContext())
else:
object.__setattr__(self, key, self._private_attributes[key])
# deserialize child classes dynamically for inherited `role`
object.__setattr__(self, "builtin_class_name", self.__class__.__name__)
self.__fields__["builtin_class_name"].default = self.__class__.__name__
def __init_subclass__(cls, **kwargs: Any) -> None:
super().__init_subclass__(**kwargs)
role_subclass_registry[cls.__name__] = cls
def _reset(self):
object.__setattr__(self, "_states", [])
object.__setattr__(self, "_actions", [])
@ -442,7 +498,7 @@ class Role(BaseModel):
if next_state == -1:
logger.info(f"End actions with {next_state=}")
self._set_state(next_state)
async def _act(self) -> Message:
logger.info(f"{self._setting}: ready to {self._rc.todo}")
response = await self._rc.todo.run(self._rc.important_memory)
@ -574,7 +630,7 @@ class Role(BaseModel):
# If there is no new information, suspend and wait
logger.debug(f"{self._setting}: no news. waiting.")
return
rsp = await self.react()
# Reset the next action to be taken.

View file

@ -39,6 +39,9 @@ from metagpt.const import (
TASK_FILE_REPO,
)
from metagpt.logs import logger
from metagpt.utils.serialize import actionoutout_schema_to_mapping, actionoutput_mapping_to_str, \
actionoutput_str_to_mapping
from metagpt.utils.utils import import_class
from metagpt.utils.common import any_to_str, any_to_str_set
# from metagpt.utils.serialize import actionoutout_schema_to_mapping
@ -55,6 +58,7 @@ class RawMessage(TypedDict):
role: str
class Document(BaseModel):
"""
Represents a document.

View file

@ -99,6 +99,7 @@ class Team(BaseModel):
n_round -= 1
logger.debug(f"max {n_round=} left.")
self._check_balance()
await self.env.run()
if CONFIG.git_repo:
CONFIG.git_repo.archive()

View file

@ -8,6 +8,9 @@ import json
from pathlib import Path
import importlib
from tenacity import _utils
import traceback
from metagpt.logs import logger
def general_after_log(logger: "loguru.Logger", sec_format: str = "%0.3f") -> typing.Callable[["RetryCallState"], None]:

View file

@ -61,6 +61,7 @@ async def test_publish_and_process_message(env: Environment):
constraints="资源有限,需要节省成本")
env.add_roles([product_manager, architect])
env.set_manager(Manager())
env.publish_message(Message(role="User", content="需要一个基于LLM做总结的搜索引擎", cause_by=UserRequirement))

View file

@ -8,16 +8,22 @@
the utilization of the new feature of `Message` class.
"""
<<<<<<< HEAD
import json
import pytest
from metagpt.actions import Action
=======
>>>>>>> a69be36abf7beef1a989a707d1aa027948c07fee
from metagpt.schema import AIMessage, Message, SystemMessage, UserMessage
from metagpt.actions.action_output import ActionOutput
from metagpt.actions.write_code import WriteCode
from metagpt.utils.serialize import serialize_general_message, deserialize_general_message
<<<<<<< HEAD
from metagpt.utils.common import get_class_name
=======
>>>>>>> a69be36abf7beef1a989a707d1aa027948c07fee
@pytest.mark.asyncio
@ -110,7 +116,3 @@ def test_message_serdeser():
new_message = deserialize_general_message(message_dict)
assert new_message.instruct_content is None
assert new_message.cause_by == ""
if __name__ == "__main__":
pytest.main([__file__, "-s"])