mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-08 15:05:17 +02:00
Merge branch 'role_zero_impr' into 'mgx_ops'
bugfix See merge request pub/MetaGPT!168
This commit is contained in:
commit
f95a62b5df
5 changed files with 15 additions and 8 deletions
|
|
@ -18,7 +18,9 @@ Note:
|
|||
1. If the requirement is a pure DATA-RELATED requirement, such as bug fixes, issue reporting, environment setup, terminal operations, pip install, web browsing, web scraping, web searching, web imitation, data science, data analysis, machine learning, deep learning, text-to-image etc. DON'T decompose it, assign a single task with the original user requirement as instruction directly to Data Analyst.
|
||||
2. If the requirement is developing a software, game, app, or website, excluding the above data-related tasks, you should decompose the requirement into multiple tasks and assign them to different team members based on their expertise, usually the sequence of Product Manager -> Architect -> Project Manager -> Engineer -> (optional: QaEngine if present) -> (optional: DataAnalyst if user requests deployment), each assigned ONE task. When publishing message to Product Manager, you should directly copy the full original user requirement.
|
||||
3. If the requirement contains both DATA-RELATED part mentioned in 1 and software development part mentioned in 2, you should decompose the software development part and assign them to different team members based on their expertise, and assign the DATA-RELATED part to Data Analyst David directly.
|
||||
4. It it helpful for Engineer to have both the system design and the project schedule for writing the code, so include paths of both files (if available) when publishing message to Engineer.
|
||||
4. If the requirement is a common-sense, logical, or math problem, you should respond directly without assigning any task to team members.
|
||||
5. If you think the requirement is not clear or ambiguous, you should ask the user for clarification immediately. Assign tasks only after all info is clear.
|
||||
6. It is helpful for Engineer to have both the system design and the project schedule for writing the code, so include paths of both files (if available) when publishing message to Engineer.
|
||||
"""
|
||||
|
||||
FINISH_CURRENT_TASK_CMD = """
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
import inspect
|
||||
import json
|
||||
import traceback
|
||||
from typing import Literal, Tuple
|
||||
from typing import Callable, Literal, Tuple
|
||||
|
||||
from pydantic import model_validator
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ class RoleZero(Role):
|
|||
# Tools
|
||||
tools: list[str] = [] # Use special symbol ["<all>"] to indicate use of all registered tools
|
||||
tool_recommender: ToolRecommender = None
|
||||
tool_execution_map: dict[str, callable] = {}
|
||||
tool_execution_map: dict[str, Callable] = {}
|
||||
special_tool_commands: list[str] = ["Plan.finish_current_task", "end"]
|
||||
# Equipped with three basic tools by default for optional use
|
||||
editor: Editor = Editor()
|
||||
|
|
@ -175,7 +175,7 @@ class RoleZero(Role):
|
|||
actions_taken += 1
|
||||
return rsp # return output from the last action
|
||||
|
||||
async def _run_commands(self, commands) -> list:
|
||||
async def _run_commands(self, commands) -> str:
|
||||
outputs = []
|
||||
for cmd in commands:
|
||||
# handle special command first
|
||||
|
|
@ -247,7 +247,7 @@ class RoleZero(Role):
|
|||
|
||||
if not isinstance(self.rc.env, MGXEnv):
|
||||
return "Not in MGXEnv, command will not be executed."
|
||||
return await self.rc.env.get_human_input(question, sent_from=self)
|
||||
return await self.rc.env.ask_human(question, sent_from=self)
|
||||
|
||||
async def reply_to_human(self, content: str) -> str:
|
||||
"""Reply to human user with the content provided. Use this when you have a clear answer or solution to the user's question."""
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ class TeamLeader(RoleZero):
|
|||
profile: str = "Team Leader"
|
||||
system_msg: list[str] = [SYSTEM_PROMPT]
|
||||
|
||||
max_react_loop: int = 1 # TeamLeader only reacts once each time
|
||||
# TeamLeader only reacts once each time, but may encounter errors or need to ask human, thus allowing 2 more turns
|
||||
max_react_loop: int = 3
|
||||
|
||||
tools: list[str] = ["Plan", "RoleZero", "TeamLeader"]
|
||||
|
||||
|
|
|
|||
|
|
@ -189,8 +189,8 @@ class Browser:
|
|||
|
||||
async def _view(self, keep_len: int = 5000) -> str:
|
||||
"""simulate human viewing the current page, return the visible text with links"""
|
||||
# visible_text_with_links = await self.current_page.evaluate(VIEW_CONTENT_JS)
|
||||
# print("The visible text and their links (if any): ", visible_text_with_links[:keep_len])
|
||||
visible_text_with_links = await self.current_page.evaluate(VIEW_CONTENT_JS)
|
||||
print("The visible text and their links (if any): ", visible_text_with_links[:keep_len])
|
||||
# html_content = await self._view_page_html(keep_len=keep_len)
|
||||
# print("The html content: ", html_content)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
|
@ -26,6 +27,9 @@ class Editor:
|
|||
|
||||
def write(self, path: str, content: str):
|
||||
"""Write the whole content to a file. When used, make sure content arg contains the full content of the file."""
|
||||
if len(re.findall(r"\\n", content)) >= 5:
|
||||
# A very raw rule to correct the content: Many \\n suggests all new line characters are mistaken as \\n whereas the correct one should be \n
|
||||
content = content.replace("\\n", "\n")
|
||||
directory = os.path.dirname(path)
|
||||
if directory and not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue