mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-05 14:55:18 +02:00
refactor: @cause_by.setter
This commit is contained in:
parent
1febf168e7
commit
d9775037b6
21 changed files with 73 additions and 123 deletions
|
|
@ -66,7 +66,7 @@ class Trump(Role):
|
|||
async def _act(self) -> Message:
|
||||
logger.info(f"{self._setting}: ready to {self._rc.todo}")
|
||||
|
||||
msg_history = self._rc.memory.get_by_actions([ShoutOut.get_class_name()])
|
||||
msg_history = self._rc.memory.get_by_actions([ShoutOut])
|
||||
context = []
|
||||
for m in msg_history:
|
||||
context.append(str(m))
|
||||
|
|
@ -77,7 +77,7 @@ class Trump(Role):
|
|||
msg = Message(
|
||||
content=rsp,
|
||||
role=self.profile,
|
||||
cause_by=ShoutOut.get_class_name(),
|
||||
cause_by=ShoutOut,
|
||||
tx_from=self.name,
|
||||
tx_to=self.opponent_name,
|
||||
)
|
||||
|
|
@ -102,14 +102,14 @@ class Biden(Role):
|
|||
await super()._observe()
|
||||
# accept the very first human instruction (the debate topic) or messages sent (from opponent) to self,
|
||||
# disregard own messages from the last round
|
||||
message_filter = {BossRequirement.get_class_name(), self.name}
|
||||
message_filter = {BossRequirement, self.name}
|
||||
self._rc.news = [msg for msg in self._rc.news if msg.is_recipient(message_filter)]
|
||||
return len(self._rc.news)
|
||||
|
||||
async def _act(self) -> Message:
|
||||
logger.info(f"{self._setting}: ready to {self._rc.todo}")
|
||||
|
||||
msg_history = self._rc.memory.get_by_actions([BossRequirement.get_class_name(), ShoutOut.get_class_name()])
|
||||
msg_history = self._rc.memory.get_by_actions([BossRequirement, ShoutOut])
|
||||
context = []
|
||||
for m in msg_history:
|
||||
context.append(str(m))
|
||||
|
|
@ -120,7 +120,7 @@ class Biden(Role):
|
|||
msg = Message(
|
||||
content=rsp,
|
||||
role=self.profile,
|
||||
cause_by=ShoutOut.get_class_name(),
|
||||
cause_by=ShoutOut,
|
||||
tx_from=self.name,
|
||||
tx_to=self.opponent_name,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ async def basic_planner_example():
|
|||
role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "WriterSkill")
|
||||
role.import_skill(TextSkill(), "TextSkill")
|
||||
# using BasicPlanner
|
||||
await role.run(Message(content=task, cause_by=BossRequirement.get_class_name()))
|
||||
await role.run(Message(content=task, cause_by=BossRequirement))
|
||||
|
||||
|
||||
async def sequential_planner_example():
|
||||
|
|
@ -55,7 +55,7 @@ async def sequential_planner_example():
|
|||
role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "WriterSkill")
|
||||
role.import_skill(TextSkill(), "TextSkill")
|
||||
# using BasicPlanner
|
||||
await role.run(Message(content=task, cause_by=BossRequirement.get_class_name()))
|
||||
await role.run(Message(content=task, cause_by=BossRequirement))
|
||||
|
||||
|
||||
async def basic_planner_web_search_example():
|
||||
|
|
@ -66,7 +66,7 @@ async def basic_planner_web_search_example():
|
|||
role.import_skill(SkSearchEngine(), "WebSearchSkill")
|
||||
# role.import_semantic_skill_from_directory(skills_directory, "QASkill")
|
||||
|
||||
await role.run(Message(content=task, cause_by=BossRequirement.get_class_name()))
|
||||
await role.run(Message(content=task, cause_by=BossRequirement))
|
||||
|
||||
|
||||
async def action_planner_example():
|
||||
|
|
@ -77,7 +77,7 @@ async def action_planner_example():
|
|||
role.import_skill(TimeSkill(), "time")
|
||||
role.import_skill(TextSkill(), "text")
|
||||
task = "What is the sum of 110 and 990?"
|
||||
await role.run(Message(content=task, cause_by=BossRequirement.get_class_name())) # it will choose mathskill.Add
|
||||
await role.run(Message(content=task, cause_by=BossRequirement)) # it will choose mathskill.Add
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@ from metagpt.llm import LLM
|
|||
from metagpt.logs import logger
|
||||
from metagpt.utils.common import OutputParser
|
||||
from metagpt.utils.custom_decoder import CustomDecoder
|
||||
from metagpt.utils.named import Named
|
||||
|
||||
|
||||
class Action(ABC, Named):
|
||||
class Action(ABC):
|
||||
def __init__(self, name: str = "", context=None, llm: LLM = None):
|
||||
self.name: str = name
|
||||
if llm is None:
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class WriteCode(Action):
|
|||
if self._is_invalid(filename):
|
||||
return
|
||||
|
||||
message_filter = {WriteDesign.get_class_name()}
|
||||
message_filter = {WriteDesign}
|
||||
design = [i for i in context if i.is_recipient(message_filter)][0]
|
||||
|
||||
ws_name = CodeParser.parse_str(block="Python package name", text=design.content)
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class Engineer(Role):
|
|||
return CodeParser.parse_str(block="Python package name", text=system_design_msg.content)
|
||||
|
||||
def get_workspace(self) -> Path:
|
||||
msg = self._rc.memory.get_by_action(WriteDesign.get_class_name())[-1]
|
||||
msg = self._rc.memory.get_by_action(WriteDesign)[-1]
|
||||
if not msg:
|
||||
return WORKSPACE_ROOT / "src"
|
||||
workspace = self.parse_workspace(msg)
|
||||
|
|
@ -130,7 +130,7 @@ class Engineer(Role):
|
|||
todo_coros = []
|
||||
for todo in self.todos:
|
||||
todo_coro = WriteCode().run(
|
||||
context=self._rc.memory.get_by_actions([WriteTasks.get_class_name(), WriteDesign.get_class_name()]),
|
||||
context=self._rc.memory.get_by_actions([WriteTasks, WriteDesign]),
|
||||
filename=todo,
|
||||
)
|
||||
todo_coros.append(todo_coro)
|
||||
|
|
@ -185,7 +185,7 @@ class Engineer(Role):
|
|||
TODO: The goal is not to need it. After clear task decomposition, based on the design idea, you should be able to write a single file without needing other codes. If you can't, it means you need a clearer definition. This is the key to writing longer code.
|
||||
"""
|
||||
context = []
|
||||
msg_filters = [WriteDesign.get_class_name(), WriteTasks.get_class_name(), WriteCode.get_class_name()]
|
||||
msg_filters = [WriteDesign, WriteTasks, WriteCode]
|
||||
msg = self._rc.memory.get_by_actions(msg_filters)
|
||||
for m in msg:
|
||||
context.append(m.content)
|
||||
|
|
@ -201,7 +201,7 @@ class Engineer(Role):
|
|||
logger.error("code review failed!", e)
|
||||
pass
|
||||
file_path = self.write_file(todo, code)
|
||||
msg = Message(content=code, role=self.profile, cause_by=WriteCode.get_class_name())
|
||||
msg = Message(content=code, role=self.profile, cause_by=WriteCode)
|
||||
self._rc.memory.add(msg)
|
||||
self.publish_message(msg)
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ class Engineer(Role):
|
|||
return ret
|
||||
|
||||
# Parse task lists
|
||||
message_filter = {WriteTasks.get_class_name()}
|
||||
message_filter = {WriteTasks}
|
||||
for message in self._rc.news:
|
||||
if not message.is_recipient(message_filter):
|
||||
continue
|
||||
|
|
@ -241,7 +241,7 @@ class Engineer(Role):
|
|||
|
||||
async def _think(self) -> None:
|
||||
# In asynchronous scenarios, first check if the required messages are ready.
|
||||
filters = {WriteTasks.get_class_name()}
|
||||
filters = {WriteTasks}
|
||||
msgs = self._rc.memory.get_by_actions(filters)
|
||||
if not msgs:
|
||||
self._rc.todo = None
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class QaEngineer(Role):
|
|||
return CodeParser.parse_str(block="Python package name", text=system_design_msg.content)
|
||||
|
||||
def get_workspace(self, return_proj_dir=True) -> Path:
|
||||
msg = self._rc.memory.get_by_action(WriteDesign.get_class_name())[-1]
|
||||
msg = self._rc.memory.get_by_action(WriteDesign)[-1]
|
||||
if not msg:
|
||||
return WORKSPACE_ROOT / "src"
|
||||
workspace = self.parse_workspace(msg)
|
||||
|
|
@ -99,7 +99,7 @@ class QaEngineer(Role):
|
|||
msg = Message(
|
||||
content=str(file_info),
|
||||
role=self.profile,
|
||||
cause_by=WriteTest.get_class_name(),
|
||||
cause_by=WriteTest,
|
||||
tx_from=self.profile,
|
||||
tx_to=self.profile,
|
||||
)
|
||||
|
|
@ -133,9 +133,7 @@ class QaEngineer(Role):
|
|||
|
||||
recipient = parse_recipient(result_msg) # the recipient might be Engineer or myself
|
||||
content = str(file_info) + FILENAME_CODE_SEP + result_msg
|
||||
msg = Message(
|
||||
content=content, role=self.profile, cause_by=RunCode.get_class_name(), tx_from=self.profile, tx_to=recipient
|
||||
)
|
||||
msg = Message(content=content, role=self.profile, cause_by=RunCode, tx_from=self.profile, tx_to=recipient)
|
||||
self.publish_message(msg)
|
||||
|
||||
async def _debug_error(self, msg):
|
||||
|
|
@ -147,7 +145,7 @@ class QaEngineer(Role):
|
|||
msg = Message(
|
||||
content=file_info,
|
||||
role=self.profile,
|
||||
cause_by=DebugError.get_class_name(),
|
||||
cause_by=DebugError,
|
||||
tx_from=self.profile,
|
||||
tx_to=recipient,
|
||||
)
|
||||
|
|
@ -165,14 +163,14 @@ class QaEngineer(Role):
|
|||
result_msg = Message(
|
||||
content=f"Exceeding {self.test_round_allowed} rounds of tests, skip (writing code counts as a round, too)",
|
||||
role=self.profile,
|
||||
cause_by=WriteTest.get_class_name(),
|
||||
cause_by=WriteTest,
|
||||
tx_from=self.profile,
|
||||
)
|
||||
return result_msg
|
||||
|
||||
code_filters = {WriteCode.get_class_name(), WriteCodeReview.get_class_name()}
|
||||
test_filters = {WriteTest.get_class_name(), DebugError.get_class_name()}
|
||||
run_filters = {RunCode.get_class_name()}
|
||||
code_filters = {WriteCode, WriteCodeReview}
|
||||
test_filters = {WriteTest, DebugError}
|
||||
run_filters = {RunCode}
|
||||
for msg in self._rc.news:
|
||||
# Decide what to do based on observed msg type, currently defined by human,
|
||||
# might potentially be moved to _think, that is, let the agent decides for itself
|
||||
|
|
@ -189,7 +187,7 @@ class QaEngineer(Role):
|
|||
result_msg = Message(
|
||||
content=f"Round {self.test_round} of tests done",
|
||||
role=self.profile,
|
||||
cause_by=WriteTest.get_class_name(),
|
||||
cause_by=WriteTest,
|
||||
tx_from=self.profile,
|
||||
)
|
||||
return result_msg
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ from metagpt.logs import logger
|
|||
from metagpt.memory import LongTermMemory, Memory
|
||||
from metagpt.schema import Message, MessageQueue
|
||||
from metagpt.utils.common import get_class_name, get_object_name
|
||||
from metagpt.utils.named import Named
|
||||
|
||||
PREFIX_TEMPLATE = """You are a {profile}, named {name}, your goal is {goal}, and the constraint is {constraints}. """
|
||||
|
||||
|
|
@ -107,7 +106,7 @@ class RoleContext(BaseModel):
|
|||
return self.memory.get()
|
||||
|
||||
|
||||
class Role(Named):
|
||||
class Role:
|
||||
"""Role/Agent"""
|
||||
|
||||
def __init__(self, name="", profile="", goal="", constraints="", desc=""):
|
||||
|
|
@ -174,10 +173,10 @@ class Role(Named):
|
|||
return self._rc.watch
|
||||
return {
|
||||
self.name,
|
||||
self.get_object_name(),
|
||||
get_object_name(self),
|
||||
self.profile,
|
||||
f"{self.name}({self.profile})",
|
||||
f"{self.name}({self.get_object_name()})",
|
||||
f"{self.name}({get_object_name(self)})",
|
||||
}
|
||||
|
||||
def _get_prefix(self):
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from metagpt.const import (
|
|||
MESSAGE_ROUTE_TO,
|
||||
)
|
||||
from metagpt.logs import logger
|
||||
from metagpt.utils.common import get_class_name, get_object_name
|
||||
from metagpt.utils.common import any_to_str
|
||||
|
||||
|
||||
class RawMessage(TypedDict):
|
||||
|
|
@ -129,11 +129,12 @@ class Message(BaseModel):
|
|||
if k in attribute_names:
|
||||
continue
|
||||
if k == MESSAGE_ROUTE_FROM:
|
||||
self.set_from(v)
|
||||
self.set_from(any_to_str(v))
|
||||
continue
|
||||
if k == MESSAGE_ROUTE_CAUSE_BY:
|
||||
self.meta_info[k] = v
|
||||
if k == MESSAGE_ROUTE_TO or k == MESSAGE_ROUTE_CAUSE_BY:
|
||||
self.set_cause_by(v)
|
||||
continue
|
||||
if k == MESSAGE_ROUTE_TO:
|
||||
self.add_to(v)
|
||||
continue
|
||||
self.meta_info[k] = v
|
||||
|
|
@ -161,18 +162,14 @@ class Message(BaseModel):
|
|||
if key == MESSAGE_ROUTE_CAUSE_BY:
|
||||
self.set_cause_by(val)
|
||||
return
|
||||
if key == MESSAGE_ROUTE_FROM:
|
||||
self.set_from(any_to_str(val))
|
||||
super().__setattr__(key, val)
|
||||
|
||||
def set_cause_by(self, val):
|
||||
"""Update the value of `cause_by` in the `meta_info` and `routes` attributes."""
|
||||
old_value = self.get_meta(MESSAGE_ROUTE_CAUSE_BY)
|
||||
new_value = None
|
||||
if isinstance(val, str):
|
||||
new_value = val
|
||||
elif not callable(val):
|
||||
new_value = get_object_name(val)
|
||||
else:
|
||||
new_value = get_class_name(val)
|
||||
new_value = any_to_str(val)
|
||||
self.set_meta(MESSAGE_ROUTE_CAUSE_BY, new_value)
|
||||
self.route.replace(old_value, new_value)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,9 @@ from metagpt.logs import logger
|
|||
from metagpt.roles import Role
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import NoMoneyException
|
||||
from metagpt.utils.named import Named
|
||||
|
||||
|
||||
class SoftwareCompany(BaseModel, Named):
|
||||
class SoftwareCompany(BaseModel):
|
||||
"""
|
||||
Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging,
|
||||
dedicated to writing executable code.
|
||||
|
|
@ -55,8 +54,8 @@ class SoftwareCompany(BaseModel, Named):
|
|||
Message(
|
||||
role="BOSS",
|
||||
content=idea,
|
||||
cause_by=BossRequirement.get_class_name(),
|
||||
tx_from=SoftwareCompany.get_class_name(),
|
||||
cause_by=BossRequirement,
|
||||
tx_from=SoftwareCompany,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -315,3 +315,13 @@ def get_object_name(obj) -> str:
|
|||
"""Return class name of the object"""
|
||||
cls = type(obj)
|
||||
return f"{cls.__module__}.{cls.__name__}"
|
||||
|
||||
|
||||
def any_to_str(val) -> str:
|
||||
"""Return the class name or the class name of the object, or 'val' if it's a string type."""
|
||||
if isinstance(val, str):
|
||||
return val
|
||||
if not callable(val):
|
||||
return get_object_name(val)
|
||||
|
||||
return get_class_name(val)
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/11/1
|
||||
@Author : mashenquan
|
||||
@File : named.py
|
||||
"""
|
||||
|
||||
|
||||
class Named:
|
||||
"""A base class with functions for converting classes to names and objects to class names."""
|
||||
|
||||
@classmethod
|
||||
def get_class_name(cls):
|
||||
"""Return class name"""
|
||||
return f"{cls.__module__}.{cls.__name__}"
|
||||
|
||||
def get_object_name(self):
|
||||
"""Return class name of the object"""
|
||||
cls = type(self)
|
||||
return f"{cls.__module__}.{cls.__name__}"
|
||||
|
|
@ -19,7 +19,7 @@ from metagpt.schema import Message
|
|||
async def test_write_prd():
|
||||
product_manager = ProductManager()
|
||||
requirements = "开发一个基于大语言模型与私有知识库的搜索引擎,希望可以基于大语言模型进行搜索总结"
|
||||
prd = await product_manager.run(Message(content=requirements, cause_by=BossRequirement.get_class_name()))
|
||||
prd = await product_manager.run(Message(content=requirements, cause_by=BossRequirement))
|
||||
logger.info(requirements)
|
||||
logger.info(prd)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,24 +19,24 @@ def test_ltm_search():
|
|||
assert len(openai_api_key) > 20
|
||||
|
||||
role_id = "UTUserLtm(Product Manager)"
|
||||
rc = RoleContext(watch=[BossRequirement.get_class_name()])
|
||||
rc = RoleContext(watch=[BossRequirement])
|
||||
ltm = LongTermMemory()
|
||||
ltm.recover_memory(role_id, rc)
|
||||
|
||||
idea = "Write a cli snake game"
|
||||
message = Message(role="BOSS", content=idea, cause_by=BossRequirement.get_class_name())
|
||||
message = Message(role="BOSS", content=idea, cause_by=BossRequirement)
|
||||
news = ltm.find_news([message])
|
||||
assert len(news) == 1
|
||||
ltm.add(message)
|
||||
|
||||
sim_idea = "Write a game of cli snake"
|
||||
sim_message = Message(role="BOSS", content=sim_idea, cause_by=BossRequirement.get_class_name())
|
||||
sim_message = Message(role="BOSS", content=sim_idea, cause_by=BossRequirement)
|
||||
news = ltm.find_news([sim_message])
|
||||
assert len(news) == 0
|
||||
ltm.add(sim_message)
|
||||
|
||||
new_idea = "Write a 2048 web game"
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement.get_class_name())
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement)
|
||||
news = ltm.find_news([new_message])
|
||||
assert len(news) == 1
|
||||
ltm.add(new_message)
|
||||
|
|
@ -52,7 +52,7 @@ def test_ltm_search():
|
|||
assert len(news) == 0
|
||||
|
||||
new_idea = "Write a Battle City"
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement.get_class_name())
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement)
|
||||
news = ltm_new.find_news([new_message])
|
||||
assert len(news) == 1
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from metagpt.schema import Message
|
|||
def test_idea_message():
|
||||
idea = "Write a cli snake game"
|
||||
role_id = "UTUser1(Product Manager)"
|
||||
message = Message(role="BOSS", content=idea, cause_by=BossRequirement.get_class_name())
|
||||
message = Message(role="BOSS", content=idea, cause_by=BossRequirement)
|
||||
|
||||
memory_storage: MemoryStorage = MemoryStorage()
|
||||
messages = memory_storage.recover_memory(role_id)
|
||||
|
|
@ -28,12 +28,12 @@ def test_idea_message():
|
|||
assert memory_storage.is_initialized is True
|
||||
|
||||
sim_idea = "Write a game of cli snake"
|
||||
sim_message = Message(role="BOSS", content=sim_idea, cause_by=BossRequirement.get_class_name())
|
||||
sim_message = Message(role="BOSS", content=sim_idea, cause_by=BossRequirement)
|
||||
new_messages = memory_storage.search(sim_message)
|
||||
assert len(new_messages) == 0 # similar, return []
|
||||
|
||||
new_idea = "Write a 2048 web game"
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement.get_class_name())
|
||||
new_message = Message(role="BOSS", content=new_idea, cause_by=BossRequirement)
|
||||
new_messages = memory_storage.search(new_message)
|
||||
assert new_messages[0].content == message.content
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ def test_actionout_message():
|
|||
role_id = "UTUser2(Architect)"
|
||||
content = "The boss has requested the creation of a command-line interface (CLI) snake game"
|
||||
message = Message(
|
||||
content=content, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD.get_class_name()
|
||||
content=content, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD
|
||||
) # WritePRD as test action
|
||||
|
||||
memory_storage: MemoryStorage = MemoryStorage()
|
||||
|
|
@ -60,16 +60,12 @@ def test_actionout_message():
|
|||
assert memory_storage.is_initialized is True
|
||||
|
||||
sim_conent = "The request is command-line interface (CLI) snake game"
|
||||
sim_message = Message(
|
||||
content=sim_conent, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD.get_class_name()
|
||||
)
|
||||
sim_message = Message(content=sim_conent, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD)
|
||||
new_messages = memory_storage.search(sim_message)
|
||||
assert len(new_messages) == 0 # similar, return []
|
||||
|
||||
new_conent = "Incorporate basic features of a snake game such as scoring and increasing difficulty"
|
||||
new_message = Message(
|
||||
content=new_conent, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD.get_class_name()
|
||||
)
|
||||
new_message = Message(content=new_conent, instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD)
|
||||
new_messages = memory_storage.search(new_message)
|
||||
assert new_messages[0].content == message.content
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ async def test_action_planner():
|
|||
role.import_skill(TimeSkill(), "time")
|
||||
role.import_skill(TextSkill(), "text")
|
||||
task = "What is the sum of 110 and 990?"
|
||||
role.put_message(Message(content=task, cause_by=BossRequirement.get_class_name()))
|
||||
role.put_message(Message(content=task, cause_by=BossRequirement))
|
||||
await role._observe()
|
||||
await role._think() # it will choose mathskill.Add
|
||||
assert "1100" == (await role._act()).content
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ async def test_basic_planner():
|
|||
role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "WriterSkill")
|
||||
role.import_skill(TextSkill(), "TextSkill")
|
||||
# using BasicPlanner
|
||||
role.put_message(Message(content=task, cause_by=BossRequirement.get_class_name()))
|
||||
role.put_message(Message(content=task, cause_by=BossRequirement))
|
||||
await role._observe()
|
||||
await role._think()
|
||||
# assuming sk_agent will think he needs WriterSkill.Brainstorm and WriterSkill.Translate
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ a = 'a'
|
|||
|
||||
|
||||
class MockMessages:
|
||||
req = Message(role="Boss", content=BOSS_REQUIREMENT, cause_by=BossRequirement.get_class_name())
|
||||
prd = Message(role="Product Manager", content=PRD, cause_by=WritePRD.get_class_name())
|
||||
system_design = Message(role="Architect", content=SYSTEM_DESIGN, cause_by=WriteDesign.get_class_name())
|
||||
tasks = Message(role="Project Manager", content=TASKS, cause_by=WriteTasks.get_class_name())
|
||||
req = Message(role="Boss", content=BOSS_REQUIREMENT, cause_by=BossRequirement)
|
||||
prd = Message(role="Product Manager", content=PRD, cause_by=WritePRD)
|
||||
system_design = Message(role="Architect", content=SYSTEM_DESIGN, cause_by=WriteDesign)
|
||||
tasks = Message(role="Project Manager", content=TASKS, cause_by=WriteTasks)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ async def test_publish_and_process_message(env: Environment):
|
|||
|
||||
env.add_roles([product_manager, architect])
|
||||
env.set_manager(Manager())
|
||||
env.publish_message(Message(role="BOSS", content="需要一个基于LLM做总结的搜索引擎", cause_by=BossRequirement.get_class_name()))
|
||||
env.publish_message(Message(role="BOSS", content="需要一个基于LLM做总结的搜索引擎", cause_by=BossRequirement))
|
||||
|
||||
await env.run(k=2)
|
||||
logger.info(f"{env.history=}")
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import pytest
|
|||
|
||||
from metagpt.actions import Action
|
||||
from metagpt.schema import AIMessage, Message, Routes, SystemMessage, UserMessage
|
||||
from metagpt.utils.common import get_class_name
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -54,9 +55,9 @@ def test_message():
|
|||
m.cause_by = "Message"
|
||||
assert m.cause_by == "Message"
|
||||
m.cause_by = Action
|
||||
assert m.cause_by == Action.get_class_name()
|
||||
assert m.cause_by == get_class_name(Action)
|
||||
m.cause_by = Action()
|
||||
assert m.cause_by == Action.get_class_name()
|
||||
assert m.cause_by == get_class_name(Action)
|
||||
m.content = "b"
|
||||
assert m.content == "b"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023-11-1
|
||||
@Author : mashenquan
|
||||
@File : test_named.py
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from metagpt.utils.named import Named
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suite():
|
||||
class A(Named):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
pass
|
||||
|
||||
assert A.get_class_name() == "tests.metagpt.utils.test_named.A"
|
||||
assert A().get_object_name() == "tests.metagpt.utils.test_named.A"
|
||||
assert B.get_class_name() == "tests.metagpt.utils.test_named.B"
|
||||
assert B().get_object_name() == "tests.metagpt.utils.test_named.B"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
@ -59,7 +59,7 @@ def test_serialize_and_deserialize_message():
|
|||
ic_obj = ActionOutput.create_model_class("prd", out_mapping)
|
||||
|
||||
message = Message(
|
||||
content="prd demand", instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD.get_class_name()
|
||||
content="prd demand", instruct_content=ic_obj(**out_data), role="user", cause_by=WritePRD
|
||||
) # WritePRD as test action
|
||||
|
||||
message_ser = serialize_message(message)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue