mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-05 14:55:18 +02:00
fix di bug, small enhancement for tl
This commit is contained in:
parent
531fe12e3f
commit
ede3e36944
4 changed files with 26 additions and 21 deletions
|
|
@ -33,7 +33,7 @@ class MGXEnv(Environment):
|
|||
if user_defined_recipient:
|
||||
self._publish_message(message)
|
||||
# bypass team leader, team leader only needs to know but not to react
|
||||
tl.rc.memory.add(message)
|
||||
tl.rc.memory.add(self.move_message_info_to_content(message))
|
||||
|
||||
elif self.message_within_software_sop(message) and not self.has_user_requirement():
|
||||
# Quick routing for messages within software SOP, bypassing TL.
|
||||
|
|
@ -43,7 +43,7 @@ class MGXEnv(Environment):
|
|||
# Consider replacing this in the future.
|
||||
self._publish_message(message)
|
||||
if self.is_software_task_finished(message):
|
||||
tl.rc.memory.add(message)
|
||||
tl.rc.memory.add(self.move_message_info_to_content(message))
|
||||
tl.finish_current_task()
|
||||
|
||||
elif publicer == tl.profile:
|
||||
|
|
@ -52,6 +52,7 @@ class MGXEnv(Environment):
|
|||
|
||||
else:
|
||||
# every regular message goes through team leader
|
||||
message = self.move_message_info_to_content(message)
|
||||
message.send_to.add(tl.name)
|
||||
tl.put_message(message)
|
||||
|
||||
|
|
@ -70,7 +71,7 @@ class MGXEnv(Environment):
|
|||
def message_within_software_sop(self, message: Message) -> bool:
|
||||
return message.sent_from in any_to_str_set([ProductManager, Architect, ProjectManager, Engineer, QaEngineer])
|
||||
|
||||
def has_user_requirement(self, k=3) -> bool:
|
||||
def has_user_requirement(self, k=2) -> bool:
|
||||
"""A heuristics to check if there is a recent user intervention"""
|
||||
return any_to_str(UserRequirement) in [msg.cause_by for msg in self.history.get(k)]
|
||||
|
||||
|
|
@ -79,3 +80,16 @@ class MGXEnv(Environment):
|
|||
return message.cause_by in any_to_str_set([WritePRD, WriteDesign, WriteTasks, SummarizeCode]) or (
|
||||
message.cause_by == any_to_str(WriteTest) and "Exceeding" in message.content
|
||||
)
|
||||
|
||||
def move_message_info_to_content(self, message: Message) -> Message:
|
||||
"""Two things here:
|
||||
1. Convert role, since role field must be reserved for LLM API, and is limited to, for example, one of ["user", "assistant", "system"]
|
||||
2. Add sender and recipient info to content, making TL aware, since LLM API only takes content as input
|
||||
"""
|
||||
if message.role in ["system", "user", "assistant"]:
|
||||
sent_from = message.sent_from
|
||||
else:
|
||||
sent_from = message.role
|
||||
message.role = "assistant"
|
||||
message.content = f"from {sent_from} to {message.send_to}: {message.content}"
|
||||
return message
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from metagpt.roles import Role
|
|||
from metagpt.schema import Message, Task, TaskResult
|
||||
from metagpt.strategy.task_type import TaskType
|
||||
from metagpt.tools.tool_recommend import BM25ToolRecommender, ToolRecommender
|
||||
from metagpt.utils.common import CodeParser, role_raise_decorator
|
||||
from metagpt.utils.common import CodeParser
|
||||
|
||||
REACT_THINK_PROMPT = """
|
||||
# User Requirement
|
||||
|
|
@ -62,7 +62,7 @@ class DataInterpreter(Role):
|
|||
|
||||
async def _think(self) -> bool:
|
||||
"""Useful in 'react' mode. Use LLM to decide whether and what to do next."""
|
||||
user_requirement = self.get_memories()[0].content
|
||||
user_requirement = self.get_memories()[-1].content
|
||||
context = self.working_memory.get()
|
||||
|
||||
if not context:
|
||||
|
|
@ -86,6 +86,7 @@ class DataInterpreter(Role):
|
|||
return Message(content=code, role="assistant", cause_by=WriteAnalysisCode)
|
||||
|
||||
async def _plan_and_act(self) -> Message:
|
||||
self._set_state(0)
|
||||
try:
|
||||
rsp = await super()._plan_and_act()
|
||||
await self.execute_code.terminate()
|
||||
|
|
@ -153,7 +154,7 @@ class DataInterpreter(Role):
|
|||
logger.info(f"ready to {todo.name}")
|
||||
use_reflection = counter > 0 and self.use_reflection # only use reflection after the first trial
|
||||
|
||||
user_requirement = self.get_memories()[0].content # issue: 1)多次用户交互时,永远只读用户的第1次request;2)prerequisite没处理
|
||||
user_requirement = self.get_memories()[-1].content
|
||||
|
||||
code = await todo.run(
|
||||
user_requirement=user_requirement,
|
||||
|
|
@ -186,11 +187,3 @@ class DataInterpreter(Role):
|
|||
print(result)
|
||||
data_info = DATA_INFO.format(info=result)
|
||||
self.working_memory.add(Message(content=data_info, role="user", cause_by=CheckData))
|
||||
|
||||
@role_raise_decorator
|
||||
async def run(self, with_message=None) -> Message | None:
|
||||
if not self.rc.todo:
|
||||
self.set_actions([WriteAnalysisCode])
|
||||
self._set_state(0)
|
||||
|
||||
return await super().run(with_message)
|
||||
|
|
|
|||
|
|
@ -70,12 +70,8 @@ class TeamLeader(Role):
|
|||
self._set_state(-1)
|
||||
|
||||
def get_memory(self, k=10) -> list[Message]:
|
||||
mem = self.rc.memory.get(k=k)
|
||||
for m in mem:
|
||||
if m.role not in ["system", "user", "assistant"]:
|
||||
m.content = f"from {m.role} to {m.send_to}: {m.content}"
|
||||
m.role = "assistant"
|
||||
return mem
|
||||
"""A wrapper with default value"""
|
||||
return self.rc.memory.get(k=k)
|
||||
|
||||
async def _think(self) -> bool:
|
||||
"""Useful in 'react' mode. Use LLM to decide whether and what to do next."""
|
||||
|
|
@ -115,7 +111,7 @@ class TeamLeader(Role):
|
|||
"""Useful in 'react' mode. Return a Message conforming to Role._act interface."""
|
||||
self.run_commands(self.commands)
|
||||
self.task_result = TaskResult(result="Success", is_success=True)
|
||||
msg = Message(content="Commands executed", role="user", send_to=self)
|
||||
msg = Message(content="Commands executed", send_to="no one") # a dummy message to conform to the interface
|
||||
self.rc.memory.add(msg)
|
||||
return msg
|
||||
|
||||
|
|
|
|||
|
|
@ -492,6 +492,8 @@ class Role(SerializationMixin, ContextMixin, BaseModel):
|
|||
await self.planner.process_task_result(task_result)
|
||||
|
||||
rsp = self.planner.get_useful_memories()[0] # return the completed plan as a response
|
||||
rsp.role = "assistant"
|
||||
rsp.sent_from = self._setting
|
||||
|
||||
self.rc.memory.add(rsp) # add to persistent memory
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue