feat: + DI args error

feat: + test case
This commit is contained in:
莘权 马 2024-03-31 11:49:16 +08:00
parent d9f70730f7
commit dd9b573eb4
6 changed files with 45 additions and 30 deletions

View file

@ -43,7 +43,7 @@ SOP_CONFIG = [
"Writes a PRD based on software requirements.",
"Writes a design to the project repository, based on the PRD of the project.",
"Writes a project plan to the project repository, based on the design of the project.",
"Writes codes to the project repository, based on the project plan of the project.",
"Writes code to implement designed features according to the project plan and adds them to the project repository.",
# "Run QA test on the project repository.",
"Stage and commit changes for the project repository using Git.",
],

View file

@ -8,6 +8,7 @@
from __future__ import annotations
import json
import sys
from datetime import datetime
from functools import partial
@ -17,7 +18,6 @@ from loguru import logger as _logger
from pydantic import BaseModel, Field
from metagpt.const import METAGPT_ROOT
from metagpt.schema import BaseEnum
class ToolOutputItem(BaseModel):
@ -26,21 +26,6 @@ class ToolOutputItem(BaseModel):
value: str
class ToolName(str, BaseEnum):
Terminal = "Terminal"
Plan = "Plan"
Browser = "Browser"
Files = "Files"
WritePRD = "WritePRD"
WriteDesign = "WriteDesign"
WriteProjectPlan = "WriteProjectPlan"
WriteCode = "WriteCode"
WriteUntTest = "WriteUntTest"
FixBug = "FixBug"
GitArchive = "GitArchive"
ImportRepo = "ImportRepo"
def define_log_level(print_level="INFO", logfile_level="DEBUG", name: str = None):
"""Adjust the log level to above level"""
current_date = datetime.now()
@ -66,7 +51,7 @@ def log_tool_output(output: ToolOutputItem | List[ToolOutputItem], tool_name: st
return
outputs = output if isinstance(output, list) else [output]
_tool_output_log(output=[i.model_dump() for i in outputs], tool_name=tool_name)
_tool_output_log(output=json.dumps([i.model_dump() for i in outputs]), tool_name=tool_name)
def set_llm_stream_logfunc(func):
@ -82,4 +67,8 @@ def set_tool_output_logfunc(func):
_llm_stream_log = partial(print, end="")
_tool_output_log = partial(print, end="")
def _default_tool_output_log(*args, **kwargs):
print(*args, str(kwargs), end="")
_tool_output_log = _default_tool_output_log

View file

@ -32,8 +32,8 @@ class MGX(DataInterpreter):
sop_str = "\n".join([f"- {i}" for i in i.sop.sop])
markdown = (
f"### User Requirement Detail\n```text\n{intention_ref}\n````\n"
f"### Knowledge\nTo meet user requirements, the following standard operating procedure(SOP)"
f" must be used:\n"
f"### Knowledge\nTo meet user requirements, the following standard operating procedure(SOP) must be"
f" used. SOP descriptions cannot be modified; user requirements can only be appended to the end of corresponding steps.\n"
f"{sop_str}"
)
return markdown

View file

@ -46,7 +46,6 @@ from metagpt.const import (
SYSTEM_DESIGN_FILE_REPO,
TASK_FILE_REPO,
)
from metagpt.logs import log_tool_output, logger
from metagpt.repo_parser import DotClassInfo
from metagpt.utils.common import any_to_str, any_to_str_set, import_class
from metagpt.utils.exceptions import handle_exception
@ -434,8 +433,12 @@ class Plan(BaseModel):
final_tasks = self.tasks[:prefix_length] + new_tasks[prefix_length:]
self.tasks = final_tasks
from metagpt.logs import ToolOutputItem, log_tool_output
log_tool_output(
{"output": "\n\n".join([f"Task {task.task_id}: {task.instruction}" for task in self.tasks])},
ToolOutputItem(
name="output", value="\n\n".join([f"Task {task.task_id}: {task.instruction}" for task in self.tasks])
),
tool_name="Plan",
)
@ -814,3 +817,18 @@ class BaseEnum(Enum):
obj._value_ = value
obj.desc = desc
return obj
class ToolName(str, BaseEnum):
Terminal = "Terminal"
Plan = "Plan"
Browser = "Browser"
Files = "Files"
WritePRD = "WritePRD"
WriteDesign = "WriteDesign"
WriteProjectPlan = "WriteProjectPlan"
WriteCode = "WriteCode"
WriteUntTest = "WriteUntTest"
FixBug = "FixBug"
GitArchive = "GitArchive"
ImportRepo = "ImportRepo"

View file

@ -6,8 +6,8 @@ from pathlib import Path
from typing import Optional
from metagpt.const import BUGFIX_FILENAME, REQUIREMENT_FILENAME
from metagpt.logs import ToolName, ToolOutputItem, log_tool_output
from metagpt.schema import BugFixContext, Message
from metagpt.logs import ToolOutputItem, log_tool_output
from metagpt.schema import BugFixContext, Message, ToolName
from metagpt.tools.tool_registry import register_tool
from metagpt.utils.common import any_to_str
@ -86,7 +86,8 @@ async def write_design(prd_path: str | Path) -> Path:
from metagpt.roles import Architect
ctx = Context()
project_path = Path(prd_path).parent.parent
prd_path = Path(prd_path)
project_path = (Path(prd_path) if not prd_path.is_file() else prd_path.parent) / "../.."
ctx.set_repo_dir(project_path)
role = Architect(context=ctx)
@ -132,7 +133,8 @@ async def write_project_plan(system_design_path: str | Path) -> Path:
from metagpt.roles import ProjectManager
ctx = Context()
project_path = Path(system_design_path).parent.parent
system_design_path = Path(system_design_path)
project_path = (system_design_path if not system_design_path.is_file() else system_design_path.parent) / "../.."
ctx.set_repo_dir(project_path)
role = ProjectManager(context=ctx)
@ -149,7 +151,7 @@ async def write_project_plan(system_design_path: str | Path) -> Path:
@register_tool(tags=["software development", "Engineer"])
async def write_codes(task_path: str | Path, inc: bool = False) -> Path:
"""Writes codes to the project repository, based on the project plan of the project.
"""Writes code to implement designed features according to the project plan and adds them to the project repository.
Args:
task_path (str|Path): The path to task files under the project directory.
@ -179,7 +181,8 @@ async def write_codes(task_path: str | Path, inc: bool = False) -> Path:
ctx = Context()
ctx.config.inc = inc
project_path = Path(task_path).parent.parent
task_path = Path(task_path)
project_path = (task_path if not task_path.is_file() else task_path.parent) / "../.."
ctx.set_repo_dir(project_path)
role = Engineer(context=ctx)
@ -220,7 +223,8 @@ async def run_qa_test(src_path: str | Path) -> Path:
from metagpt.roles import QaEngineer
ctx = Context()
project_path = Path(src_path).parent
src_path = Path(src_path)
project_path = (src_path if not src_path.is_file() else src_path.parent) / ".."
ctx.set_repo_dir(project_path)
ctx.src_workspace = ctx.git_repo.workdir / ctx.git_repo.workdir.name

View file

@ -16,6 +16,10 @@ from tests.metagpt.actions.test_intent_detect import DEMO1_CONTENT, DEMO_CONTENT
[
[Message.model_validate(i) for i in DEMO_CONTENT if i["role"] == "user"],
[Message.model_validate(i) for i in DEMO1_CONTENT if i["role"] == "user"],
[
Message(role="user", content='Create a "2048 game"'),
Message(role="user", content='"IndentationError: expected an indented block"'),
],
],
)
async def test_mgx(user_messages: List[Message]):