mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-07-05 16:02:14 +02:00
feat: merge geekan:cli-etc
This commit is contained in:
commit
78548c2ddc
84 changed files with 2982 additions and 1000 deletions
|
|
@ -9,7 +9,7 @@ from enum import Enum
|
|||
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.actions.action_output import ActionOutput
|
||||
from metagpt.actions.add_requirement import BossRequirement
|
||||
from metagpt.actions.add_requirement import UserRequirement
|
||||
from metagpt.actions.debug_error import DebugError
|
||||
from metagpt.actions.design_api import WriteDesign
|
||||
from metagpt.actions.design_api_review import DesignReview
|
||||
|
|
@ -28,7 +28,7 @@ from metagpt.actions.write_test import WriteTest
|
|||
class ActionType(Enum):
|
||||
"""All types of Actions, used for indexing."""
|
||||
|
||||
ADD_REQUIREMENT = BossRequirement
|
||||
ADD_REQUIREMENT = UserRequirement
|
||||
WRITE_PRD = WritePRD
|
||||
WRITE_PRD_REVIEW = WritePRDReview
|
||||
WRITE_DESIGN = WriteDesign
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ class Action(ABC):
|
|||
self.desc = ""
|
||||
self.content = ""
|
||||
self.instruct_content = None
|
||||
self.env = None
|
||||
|
||||
def set_env(self, env):
|
||||
self.env = env
|
||||
|
||||
def set_prefix(self, prefix, profile):
|
||||
"""Set prefix for later usage"""
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
from metagpt.actions import Action
|
||||
|
||||
|
||||
class BossRequirement(Action):
|
||||
"""Boss Requirement without any implementation details"""
|
||||
class UserRequirement(Action):
|
||||
"""User Requirement without any implementation details"""
|
||||
|
||||
async def run(self, *args, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ class DebugError(Action):
|
|||
super().__init__(name, context, llm)
|
||||
|
||||
async def run(self, *args, **kwargs) -> str:
|
||||
output_doc = await FileRepository.get_file(filename=self.context.output_filename, relative_path=TEST_OUTPUTS_FILE_REPO)
|
||||
output_doc = await FileRepository.get_file(
|
||||
filename=self.context.output_filename, relative_path=TEST_OUTPUTS_FILE_REPO
|
||||
)
|
||||
if not output_doc:
|
||||
return ""
|
||||
output_detail = RunCodeResult.loads(output_doc.content)
|
||||
|
|
@ -61,10 +63,14 @@ class DebugError(Action):
|
|||
return ""
|
||||
|
||||
logger.info(f"Debug and rewrite {self.context.code_filename}")
|
||||
code_doc = await FileRepository.get_file(filename=self.context.code_filename, relative_path=CONFIG.src_workspace)
|
||||
code_doc = await FileRepository.get_file(
|
||||
filename=self.context.code_filename, relative_path=CONFIG.src_workspace
|
||||
)
|
||||
if not code_doc:
|
||||
return ""
|
||||
test_doc = await FileRepository.get_file(filename=self.context.test_filename, relative_path=TEST_CODES_FILE_REPO)
|
||||
test_doc = await FileRepository.get_file(
|
||||
filename=self.context.test_filename, relative_path=TEST_CODES_FILE_REPO
|
||||
)
|
||||
if not test_doc:
|
||||
return ""
|
||||
prompt = PROMPT_TEMPLATE.format(code=code_doc.content, test_code=test_doc.content, logs=output_detail.stderr)
|
||||
|
|
|
|||
|
|
@ -37,21 +37,21 @@ templates = {
|
|||
## Format example
|
||||
{format_example}
|
||||
-----
|
||||
Role: You are an architect; the goal is to design a SOTA PEP8-compliant python system; make the best use of good open source tools
|
||||
Role: You are an architect; the goal is to design a SOTA PEP8-compliant python system
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
Requirement: Fill in the following missing information based on the context, each section name is a key in json
|
||||
Max Output: 8192 chars or 2048 tokens. Try to use them up.
|
||||
|
||||
## Implementation approach: Provide as Plain text. Analyze the difficult points of the requirements, select the appropriate open-source framework.
|
||||
## Implementation approach: Provide as Plain text. Analyze the difficult points of the requirements, select appropriate open-source frameworks.
|
||||
|
||||
## Python package name: Provide as Python str with python triple quoto, concise and clear, characters only use a combination of all lowercase and underscores
|
||||
## project_name: Provide as Plain text, concise and clear, characters only use a combination of all lowercase and underscores
|
||||
|
||||
## File list: Provided as Python list[str], the list of ONLY REQUIRED files needed to write the program(LESS IS MORE!). Only need relative paths, comply with PEP8 standards. ALWAYS write a main.py or app.py here
|
||||
## File list: Provided as Python list[str], the list of files needed (including HTML & CSS IF NEEDED) to write the program. Only need relative paths. ALWAYS write a main.py or app.py here
|
||||
|
||||
## Data structures and interface definitions: Use mermaid classDiagram code syntax, including classes (INCLUDING __init__ method) and functions (with type annotations), CLEARLY MARK the RELATIONSHIPS between classes, and comply with PEP8 standards. The data structures SHOULD BE VERY DETAILED and the API should be comprehensive with a complete design.
|
||||
## Data structures and interfaces: Use mermaid classDiagram code syntax, including classes (INCLUDING __init__ method) and functions (with type annotations), CLEARLY MARK the RELATIONSHIPS between classes, and comply with PEP8 standards. The data structures SHOULD BE VERY DETAILED and the API should be comprehensive with a complete design.
|
||||
|
||||
## Program call flow: Use sequenceDiagram code syntax, COMPLETE and VERY DETAILED, using CLASSES AND API DEFINED ABOVE accurately, covering the CRUD AND INIT of each object, SYNTAX MUST BE CORRECT.
|
||||
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here.
|
||||
## Anything UNCLEAR: Provide as Plain text. Try to clarify it.
|
||||
|
||||
output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example,
|
||||
and only output the json inside this tag, nothing else
|
||||
|
|
@ -60,9 +60,9 @@ and only output the json inside this tag, nothing else
|
|||
[CONTENT]
|
||||
{
|
||||
"Implementation approach": "We will ...",
|
||||
"Python package name": "snake_game",
|
||||
"project_name": "snake_game",
|
||||
"File list": ["main.py"],
|
||||
"Data structures and interface definitions": '
|
||||
"Data structures and interfaces": '
|
||||
classDiagram
|
||||
class Game{
|
||||
+int score
|
||||
|
|
@ -90,21 +90,21 @@ and only output the json inside this tag, nothing else
|
|||
{format_example}
|
||||
-----
|
||||
Role: You are an architect; the goal is to design a SOTA PEP8-compliant python system; make the best use of good open source tools
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
Requirement: Fill in the following missing information based on the context, note that all sections are response with code form separately
|
||||
Max Output: 8192 chars or 2048 tokens. Try to use them up.
|
||||
Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote.
|
||||
ATTENTION: Output carefully referenced "Format example" in format.
|
||||
|
||||
## Implementation approach: Provide as Plain text. Analyze the difficult points of the requirements, select the appropriate open-source framework.
|
||||
|
||||
## Python package name: Provide as Python str with python triple quoto, concise and clear, characters only use a combination of all lowercase and underscores
|
||||
## project_name: Provide as Plain text, concise and clear, characters only use a combination of all lowercase and underscores
|
||||
|
||||
## File list: Provided as Python list[str], the list of ONLY REQUIRED files needed to write the program(LESS IS MORE!). Only need relative paths, comply with PEP8 standards. ALWAYS write a main.py or app.py here
|
||||
## File list: Provided as Python list[str], the list of code files (including HTML & CSS IF NEEDED) to write the program. Only need relative paths. ALWAYS write a main.py or app.py here
|
||||
|
||||
## Data structures and interface definitions: Use mermaid classDiagram code syntax, including classes (INCLUDING __init__ method) and functions (with type annotations), CLEARLY MARK the RELATIONSHIPS between classes, and comply with PEP8 standards. The data structures SHOULD BE VERY DETAILED and the API should be comprehensive with a complete design.
|
||||
## Data structures and interfaces: Use mermaid classDiagram code syntax, including classes (INCLUDING __init__ method) and functions (with type annotations), CLEARLY MARK the RELATIONSHIPS between classes, and comply with PEP8 standards. The data structures SHOULD BE VERY DETAILED and the API should be comprehensive with a complete design.
|
||||
|
||||
## Program call flow: Use sequenceDiagram code syntax, COMPLETE and VERY DETAILED, using CLASSES AND API DEFINED ABOVE accurately, covering the CRUD AND INIT of each object, SYNTAX MUST BE CORRECT.
|
||||
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here.
|
||||
## Anything UNCLEAR: Provide as Plain text. Try to clarify it.
|
||||
|
||||
""",
|
||||
"FORMAT_EXAMPLE": """
|
||||
|
|
@ -112,7 +112,7 @@ Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD W
|
|||
## Implementation approach
|
||||
We will ...
|
||||
|
||||
## Python package name
|
||||
## project_name
|
||||
```python
|
||||
"snake_game"
|
||||
```
|
||||
|
|
@ -124,7 +124,7 @@ We will ...
|
|||
]
|
||||
```
|
||||
|
||||
## Data structures and interface definitions
|
||||
## Data structures and interfaces
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Game{
|
||||
|
|
@ -151,9 +151,9 @@ The requirement is clear to me.
|
|||
|
||||
OUTPUT_MAPPING = {
|
||||
"Implementation approach": (str, ...),
|
||||
"Python package name": (str, ...),
|
||||
"project_name": (str, ...),
|
||||
"File list": (List[str], ...),
|
||||
"Data structures and interface definitions": (str, ...),
|
||||
"Data structures and interfaces": (str, ...),
|
||||
"Program call flow": (str, ...),
|
||||
"Anything UNCLEAR": (str, ...),
|
||||
}
|
||||
|
|
@ -226,19 +226,76 @@ class WriteDesign(Action):
|
|||
# leaving room for global optimization in subsequent steps.
|
||||
return ActionOutput(content=changed_files.json(), instruct_content=changed_files)
|
||||
|
||||
# =======
|
||||
# def recreate_workspace(self, workspace: Path):
|
||||
# try:
|
||||
# shutil.rmtree(workspace)
|
||||
# except FileNotFoundError:
|
||||
# pass # Folder does not exist, but we don't care
|
||||
# workspace.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# async def _save_prd(self, docs_path, resources_path, context):
|
||||
# prd_file = docs_path / "prd.md"
|
||||
# if context[-1].instruct_content and context[-1].instruct_content.dict()["Competitive Quadrant Chart"]:
|
||||
# quadrant_chart = context[-1].instruct_content.dict()["Competitive Quadrant Chart"]
|
||||
# await mermaid_to_file(quadrant_chart, resources_path / "competitive_analysis")
|
||||
#
|
||||
# if context[-1].instruct_content:
|
||||
# logger.info(f"Saving PRD to {prd_file}")
|
||||
# prd_file.write_text(context[-1].instruct_content.json(ensure_ascii=False), encoding='utf-8')
|
||||
|
||||
# async def _save_system_design(self, docs_path, resources_path, system_design):
|
||||
# data_api_design = system_design.instruct_content.dict()[
|
||||
# "Data structures and interfaces"
|
||||
# ] # CodeParser.parse_code(block="Data structures and interfaces", text=content)
|
||||
# seq_flow = system_design.instruct_content.dict()[
|
||||
# "Program call flow"
|
||||
# ] # CodeParser.parse_code(block="Program call flow", text=content)
|
||||
# await mermaid_to_file(data_api_design, resources_path / "data_api_design")
|
||||
# await mermaid_to_file(seq_flow, resources_path / "seq_flow")
|
||||
# system_design_file = docs_path / "system_design.md"
|
||||
# logger.info(f"Saving System Designs to {system_design_file}")
|
||||
# system_design_file.write_text(system_design.instruct_content.json(ensure_ascii=False), encoding='utf-8')
|
||||
|
||||
# async def _save(self, context, system_design):
|
||||
# if isinstance(system_design, ActionOutput):
|
||||
# project_name = system_design.instruct_content.dict()["project_name"]
|
||||
# else:
|
||||
# project_name = CodeParser.parse_str(block="project_name", text=system_design)
|
||||
# workspace = CONFIG.workspace_path / project_name
|
||||
# self.recreate_workspace(workspace)
|
||||
# docs_path = workspace / "docs"
|
||||
# resources_path = workspace / "resources"
|
||||
# docs_path.mkdir(parents=True, exist_ok=True)
|
||||
# resources_path.mkdir(parents=True, exist_ok=True)
|
||||
# await self._save_prd(docs_path, resources_path, context)
|
||||
# await self._save_system_design(docs_path, resources_path, system_design)
|
||||
|
||||
# async def run(self, context, format=CONFIG.prompt_format):
|
||||
|
||||
async def _new_system_design(self, context, format=CONFIG.prompt_format):
|
||||
prompt_template, format_example = get_template(templates, format)
|
||||
prompt = prompt_template.format(context=context, format_example=format_example)
|
||||
# system_design = await self._aask(prompt)
|
||||
system_design = await self._aask_v1(prompt, "system_design", OUTPUT_MAPPING, format=format)
|
||||
# fix Python package name, we can't system_design.instruct_content.python_package_name = "xxx" since "Python
|
||||
# package name" contain space, have to use setattr
|
||||
|
||||
# fix project_name, we can't system_design.instruct_content.python_package_name = "xxx" since "project_name"
|
||||
# contain space, have to use setattr
|
||||
setattr(
|
||||
system_design.instruct_content,
|
||||
"Python package name",
|
||||
system_design.instruct_content.dict()["Python package name"].strip().strip("'").strip('"'),
|
||||
"project_name",
|
||||
system_design.instruct_content.dict()["project_name"].strip().strip("'").strip('"'),
|
||||
)
|
||||
await self._rename_workspace(system_design)
|
||||
# =======
|
||||
# # fix project_name, we can't system_design.instruct_content.python_package_name = "xxx" since "project_name" contain space, have to use setattr
|
||||
# # setattr(
|
||||
# # system_design.instruct_content,
|
||||
# # "project_name",
|
||||
# # system_design.instruct_content.dict()["project_name"].strip().strip("'").strip('"'),
|
||||
# # )
|
||||
# await self._save(context, system_design)
|
||||
# >>>>>>> feature/geekan_cli_etc
|
||||
return system_design
|
||||
|
||||
async def _merge(self, prd_doc, system_design_doc, format=CONFIG.prompt_format):
|
||||
|
|
@ -248,10 +305,10 @@ class WriteDesign(Action):
|
|||
# package name" contain space, have to use setattr
|
||||
setattr(
|
||||
system_design.instruct_content,
|
||||
"Python package name",
|
||||
system_design.instruct_content.dict()["Python package name"].strip().strip("'").strip('"'),
|
||||
"project_name",
|
||||
system_design.instruct_content.dict()["project_name"].strip().strip("'").strip('"'),
|
||||
)
|
||||
system_design_doc.content = system_design.instruct_content.json()
|
||||
system_design_doc.content = system_design.instruct_content.json(ensure_ascii=False)
|
||||
return system_design_doc
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -260,9 +317,9 @@ class WriteDesign(Action):
|
|||
return
|
||||
|
||||
if isinstance(system_design, ActionOutput):
|
||||
ws_name = system_design.instruct_content.dict()["Python package name"]
|
||||
ws_name = system_design.instruct_content.dict()["project_name"]
|
||||
else:
|
||||
ws_name = CodeParser.parse_str(block="Python package name", text=system_design)
|
||||
ws_name = CodeParser.parse_str(block="project_name", text=system_design)
|
||||
CONFIG.git_repo.rename_root(ws_name)
|
||||
|
||||
async def _update_system_design(self, filename, prds_file_repo, system_design_file_repo) -> Document:
|
||||
|
|
@ -271,7 +328,9 @@ class WriteDesign(Action):
|
|||
if not old_system_design_doc:
|
||||
system_design = await self._new_system_design(context=prd.content)
|
||||
doc = Document(
|
||||
root_path=SYSTEM_DESIGN_FILE_REPO, filename=filename, content=system_design.instruct_content.json()
|
||||
root_path=SYSTEM_DESIGN_FILE_REPO,
|
||||
filename=filename,
|
||||
content=system_design.instruct_content.json(ensure_ascii=False),
|
||||
)
|
||||
else:
|
||||
doc = await self._merge(prd_doc=prd, system_design_doc=old_system_design_doc)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@ from typing import List
|
|||
from metagpt.actions import ActionOutput
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO, TASK_PDF_FILE_REPO, PACKAGE_REQUIREMENTS_FILENAME
|
||||
from metagpt.const import (
|
||||
PACKAGE_REQUIREMENTS_FILENAME,
|
||||
SYSTEM_DESIGN_FILE_REPO,
|
||||
TASK_FILE_REPO,
|
||||
TASK_PDF_FILE_REPO,
|
||||
)
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import Document, Documents
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
|
@ -31,22 +36,23 @@ templates = {
|
|||
{format_example}
|
||||
-----
|
||||
Role: You are a project manager; the goal is to break down tasks according to PRD/technical design, give a task list, and analyze task dependencies to start with the prerequisite modules
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
Requirements: Based on the context, fill in the following missing information, each section name is a key in json. Here the granularity of the task is a file, if there are any missing files, you can supplement them
|
||||
Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote.
|
||||
ATTENTION: Output carefully referenced "Format example" in format.
|
||||
|
||||
## Required Python third-party packages: Provided in requirements.txt format
|
||||
## Required Python third-party packages: Provide Python list[str] in requirements.txt format
|
||||
|
||||
## Required Other language third-party packages: Provided in requirements.txt format
|
||||
|
||||
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend.
|
||||
## Required Other language third-party packages: Provide Python list[str] in requirements.txt format
|
||||
|
||||
## Logic Analysis: Provided as a Python list[list[str]. the first is filename, the second is class/method/function should be implemented in this file. Analyze the dependencies between the files, which work should be done first
|
||||
|
||||
## Task list: Provided as Python list[str]. Each str is a filename, the more at the beginning, the more it is a prerequisite dependency, should be done first
|
||||
|
||||
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend.
|
||||
|
||||
## Shared Knowledge: Anything that should be public like utils' functions, config's variables details that should make clear first.
|
||||
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here. For example, don't forget a main entry. don't forget to init 3rd party libs.
|
||||
## Anything UNCLEAR: Provide as Plain text. Try to clarify it. For example, don't forget a main entry. don't forget to init 3rd party libs.
|
||||
|
||||
output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example,
|
||||
and only output the json inside this tag, nothing else
|
||||
|
|
@ -60,17 +66,17 @@ and only output the json inside this tag, nothing else
|
|||
"Required Other language third-party packages": [
|
||||
"No third-party ..."
|
||||
],
|
||||
"Logic Analysis": [
|
||||
["game.py", "Contains..."]
|
||||
],
|
||||
"Task list": [
|
||||
"game.py"
|
||||
],
|
||||
"Full API spec": """
|
||||
openapi: 3.0.0
|
||||
...
|
||||
description: A JSON object ...
|
||||
""",
|
||||
"Logic Analysis": [
|
||||
["game.py","Contains..."]
|
||||
],
|
||||
"Task list": [
|
||||
"game.py"
|
||||
],
|
||||
"Shared Knowledge": """
|
||||
'game.py' contains ...
|
||||
""",
|
||||
|
|
@ -94,15 +100,15 @@ Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD W
|
|||
|
||||
## Required Other language third-party packages: Provided in requirements.txt format
|
||||
|
||||
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend.
|
||||
|
||||
## Logic Analysis: Provided as a Python list[list[str]. the first is filename, the second is class/method/function should be implemented in this file. Analyze the dependencies between the files, which work should be done first
|
||||
|
||||
## Task list: Provided as Python list[str]. Each str is a filename, the more at the beginning, the more it is a prerequisite dependency, should be done first
|
||||
|
||||
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend.
|
||||
|
||||
## Shared Knowledge: Anything that should be public like utils' functions, config's variables details that should make clear first.
|
||||
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here. For example, don't forget a main entry. don't forget to init 3rd party libs.
|
||||
## Anything UNCLEAR: Provide as Plain text. Try to clarify it. For example, don't forget a main entry. don't forget to init 3rd party libs.
|
||||
|
||||
""",
|
||||
"FORMAT_EXAMPLE": '''
|
||||
|
|
@ -134,14 +140,16 @@ description: A JSON object ...
|
|||
## Logic Analysis
|
||||
```python
|
||||
[
|
||||
["game.py", "Contains ..."],
|
||||
["index.js", "Contains ..."],
|
||||
["main.py", "Contains ..."],
|
||||
]
|
||||
```
|
||||
|
||||
## Task list
|
||||
```python
|
||||
[
|
||||
"game.py",
|
||||
"index.js",
|
||||
"main.py",
|
||||
]
|
||||
```
|
||||
|
||||
|
|
@ -239,7 +247,9 @@ class WriteTasks(Action):
|
|||
task_doc = await self._merge(system_design_doc=system_design_doc, task_doc=task_doc)
|
||||
else:
|
||||
rsp = await self._run_new_tasks(context=system_design_doc.content)
|
||||
task_doc = Document(root_path=TASK_FILE_REPO, filename=filename, content=rsp.instruct_content.json())
|
||||
task_doc = Document(
|
||||
root_path=TASK_FILE_REPO, filename=filename, content=rsp.instruct_content.json(ensure_ascii=False)
|
||||
)
|
||||
await tasks_file_repo.save(
|
||||
filename=filename, content=task_doc.content, dependencies={system_design_doc.root_relative_path}
|
||||
)
|
||||
|
|
@ -248,6 +258,21 @@ class WriteTasks(Action):
|
|||
return task_doc
|
||||
|
||||
async def _run_new_tasks(self, context, format=CONFIG.prompt_format):
|
||||
# =======
|
||||
# def _save(self, context, rsp):
|
||||
# if context[-1].instruct_content:
|
||||
# ws_name = context[-1].instruct_content.dict()["project_name"]
|
||||
# else:
|
||||
# ws_name = CodeParser.parse_str(block="project_name", text=context[-1].content)
|
||||
# file_path = CONFIG.workspace_path / ws_name / "docs/api_spec_and_tasks.md"
|
||||
# file_path.write_text(rsp.instruct_content.json(ensure_ascii=False))
|
||||
#
|
||||
# # Write requirements.txt
|
||||
# requirements_path = CONFIG.workspace_path / ws_name / "requirements.txt"
|
||||
# requirements_path.write_text("\n".join(rsp.instruct_content.dict().get("Required Python third-party packages")))
|
||||
#
|
||||
# async def run(self, context, format=CONFIG.prompt_format):
|
||||
# >>>>>>> feature/geekan_cli_etc
|
||||
prompt_template, format_example = get_template(templates, format)
|
||||
prompt = prompt_template.format(context=context, format_example=format_example)
|
||||
rsp = await self._aask_v1(prompt, "task", OUTPUT_MAPPING, format=format)
|
||||
|
|
@ -256,7 +281,7 @@ class WriteTasks(Action):
|
|||
async def _merge(self, system_design_doc, task_doc, format=CONFIG.prompt_format) -> Document:
|
||||
prompt = MERGE_PROMPT.format(context=system_design_doc.content, old_tasks=task_doc.content)
|
||||
rsp = await self._aask_v1(prompt, "task", OUTPUT_MAPPING, format=format)
|
||||
task_doc.content = rsp.instruct_content.json()
|
||||
task_doc.content = rsp.instruct_content.json(ensure_ascii=False)
|
||||
return task_doc
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
115
metagpt/actions/summarize_code.py
Normal file
115
metagpt/actions/summarize_code.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Author : alexanderwu
|
||||
@File : summarize_code.py
|
||||
"""
|
||||
|
||||
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.logs import logger
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
||||
PROMPT_TEMPLATE = """
|
||||
NOTICE
|
||||
Role: You are a professional software engineer, and your main task is to review the code.
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
|
||||
|
||||
-----
|
||||
# System Design
|
||||
```text
|
||||
{system_design}
|
||||
```
|
||||
-----
|
||||
# Tasks
|
||||
```text
|
||||
{tasks}
|
||||
```
|
||||
-----
|
||||
{code_blocks}
|
||||
|
||||
## Code Review All: 请你对历史所有文件进行阅读,在文件中找到可能的bug,如函数未实现、调用错误、未引用等
|
||||
|
||||
## Call flow: mermaid代码,根据实现的函数,使用mermaid绘制完整的调用链
|
||||
|
||||
## Summary: 根据历史文件的实现情况进行总结
|
||||
|
||||
## TODOs: Python dict[str, str],这里写出需要修改的文件列表与理由,我们会在之后进行修改
|
||||
|
||||
"""
|
||||
|
||||
FORMAT_EXAMPLE = """
|
||||
|
||||
## Code Review All
|
||||
|
||||
### a.py
|
||||
- 它少实现了xxx需求...
|
||||
- 字段yyy没有给出...
|
||||
- ...
|
||||
|
||||
### b.py
|
||||
...
|
||||
|
||||
### c.py
|
||||
...
|
||||
|
||||
## Call flow
|
||||
```mermaid
|
||||
flowchart TB
|
||||
c1-->a2
|
||||
subgraph one
|
||||
a1-->a2
|
||||
end
|
||||
subgraph two
|
||||
b1-->b2
|
||||
end
|
||||
subgraph three
|
||||
c1-->c2
|
||||
end
|
||||
```
|
||||
|
||||
## Summary
|
||||
- a.py:...
|
||||
- b.py:...
|
||||
- c.py:...
|
||||
- ...
|
||||
|
||||
## TODOs
|
||||
{
|
||||
"a.py": "implement requirement xxx...",
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class SummarizeCode(Action):
|
||||
def __init__(self, name="SummarizeCode", context=None, llm=None):
|
||||
super().__init__(name, context, llm)
|
||||
|
||||
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
|
||||
async def summarize_code(self, prompt):
|
||||
code_rsp = await self._aask(prompt)
|
||||
return code_rsp
|
||||
|
||||
async def run(self):
|
||||
design_doc = await FileRepository.get_file(self.context.design_filename)
|
||||
task_doc = await FileRepository.get_file(self.context.task_filename)
|
||||
src_file_repo = CONFIG.git_repo.new_file_repository(relative_path=CONFIG.src_workspace)
|
||||
code_blocks = []
|
||||
for filename in self.context.codes_filenames:
|
||||
code_doc = await src_file_repo.get(filename)
|
||||
code_block = f"```python\n{code_doc.content}\n```\n-----"
|
||||
code_blocks.append(code_block)
|
||||
format_example = FORMAT_EXAMPLE
|
||||
prompt = PROMPT_TEMPLATE.format(
|
||||
system_design=design_doc.content,
|
||||
tasks=task_doc.content,
|
||||
code_blocks="\n".join(code_blocks),
|
||||
format_example=format_example,
|
||||
)
|
||||
logger.info("Summarize code..")
|
||||
rsp = await self.summarize_code(prompt)
|
||||
return rsp
|
||||
|
|
@ -15,10 +15,10 @@
|
|||
RunCodeResult to standardize and unify parameter passing between WriteCode, RunCode, and DebugError.
|
||||
"""
|
||||
|
||||
|
||||
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import TEST_OUTPUTS_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import CodingContext, RunCodeResult
|
||||
|
|
@ -28,16 +28,24 @@ from metagpt.utils.file_repository import FileRepository
|
|||
PROMPT_TEMPLATE = """
|
||||
NOTICE
|
||||
Role: You are a professional engineer; the main goal is to write PEP8 compliant, elegant, modular, easy to read and maintain Python 3.9 code (but you can also use other programming language)
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
|
||||
|
||||
-----
|
||||
# Context
|
||||
{context}
|
||||
-----
|
||||
|
||||
## Code: {filename} Write code with triple quoto, based on the following list and context.
|
||||
1. Do your best to implement THIS ONLY ONE FILE. ONLY USE EXISTING API. IF NO API, IMPLEMENT IT.
|
||||
2. Requirement: Based on the context, implement one following code file, note to return only in code form, your code will be part of the entire project, so please implement complete, reliable, reusable code snippets
|
||||
3. Attention1: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE.
|
||||
4. Attention2: YOU MUST FOLLOW "Data structures and interface definitions". DONT CHANGE ANY DESIGN.
|
||||
3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE.
|
||||
4. Follow design: YOU MUST FOLLOW "Data structures and interfaces". DONT CHANGE ANY DESIGN.
|
||||
5. Think before writing: What should be implemented and provided in this document?
|
||||
6. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.
|
||||
7. Do not use public member functions that do not exist in your design.
|
||||
8. Before using a variable, make sure you reference it first
|
||||
9. Write out EVERY DETAIL, DON'T LEAVE TODO.
|
||||
|
||||
-----
|
||||
# Design
|
||||
|
|
@ -75,6 +83,29 @@ class WriteCode(Action):
|
|||
def __init__(self, name="WriteCode", context=None, llm=None):
|
||||
super().__init__(name, context, llm)
|
||||
|
||||
# <<<<<<< HEAD
|
||||
# =======
|
||||
# def _is_invalid(self, filename):
|
||||
# return any(i in filename for i in ["mp3", "wav"])
|
||||
#
|
||||
# def _save(self, context, filename, code):
|
||||
# # logger.info(filename)
|
||||
# # logger.info(code_rsp)
|
||||
# if self._is_invalid(filename):
|
||||
# return
|
||||
#
|
||||
# design = [i for i in context if i.cause_by == WriteDesign][0]
|
||||
#
|
||||
# ws_name = CodeParser.parse_str(block="project_name", text=design.content)
|
||||
# ws_path = CONFIG.workspace_path / ws_name
|
||||
# if f"{ws_name}/" not in filename and all(i not in filename for i in ["requirements.txt", ".md"]):
|
||||
# ws_path = ws_path / ws_name
|
||||
# code_path = ws_path / filename
|
||||
# code_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
# code_path.write_text(code)
|
||||
# logger.info(f"Saving Code to {code_path}")
|
||||
#
|
||||
# >>>>>>> feature/geekan_cli_etc
|
||||
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
|
||||
async def write_code(self, prompt) -> str:
|
||||
code_rsp = await self._aask(prompt)
|
||||
|
|
@ -83,8 +114,9 @@ class WriteCode(Action):
|
|||
|
||||
async def run(self, *args, **kwargs) -> CodingContext:
|
||||
coding_context = CodingContext.loads(self.context.content)
|
||||
test_doc = await FileRepository.get_file(filename="test_" + coding_context.filename + ".json",
|
||||
relative_path=TEST_OUTPUTS_FILE_REPO)
|
||||
test_doc = await FileRepository.get_file(
|
||||
filename="test_" + coding_context.filename + ".json", relative_path=TEST_OUTPUTS_FILE_REPO
|
||||
)
|
||||
logs = ""
|
||||
if test_doc:
|
||||
test_detail = RunCodeResult.loads(test_doc.content)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import CodingContext
|
||||
from metagpt.utils.common import CodeParser
|
||||
|
|
@ -18,49 +19,74 @@ from metagpt.utils.common import CodeParser
|
|||
PROMPT_TEMPLATE = """
|
||||
NOTICE
|
||||
Role: You are a professional software engineer, and your main task is to review the code. You need to ensure that the code conforms to the PEP8 standards, is elegantly designed and modularized, easy to read and maintain, and is written in Python 3.9 (or in another programming language).
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
|
||||
|
||||
## Code Review: Based on the following context and code, and following the check list, Provide key, clear, concise, and specific code modification suggestions, up to 5.
|
||||
```
|
||||
1. Check 0: Is the code implemented as per the requirements?
|
||||
2. Check 1: Are there any issues with the code logic?
|
||||
3. Check 2: Does the existing code follow the "Data structures and interface definitions"?
|
||||
4. Check 3: Is there a function in the code that is omitted or not fully implemented that needs to be implemented?
|
||||
5. Check 4: Does the code have unnecessary or lack dependencies?
|
||||
```
|
||||
|
||||
## Rewrite Code: {filename} Base on "Code Review" and the source code, rewrite code with triple quotes. Do your utmost to optimize THIS SINGLE FILE.
|
||||
-----
|
||||
# Context
|
||||
{context}
|
||||
|
||||
## Code: {filename}
|
||||
## Code to be Reviewed: {filename}
|
||||
```
|
||||
{code}
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Code Review: Based on the "Code to be Reviewed", provide key, clear, concise, and specific code modification suggestions, up to 5.
|
||||
1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.
|
||||
2. Is the code logic completely correct? If there are errors, please indicate how to correct them.
|
||||
3. Does the existing code follow the "Data structures and interfaces"?
|
||||
4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.
|
||||
5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported
|
||||
6. Is the code implemented concisely enough? Are methods from other files being reused correctly?
|
||||
|
||||
## Code Review Result: If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.
|
||||
LGTM/LBTM
|
||||
|
||||
## Rewrite Code: if it still has some bugs, rewrite {filename} based on "Code Review" with triple quotes, try to get LGTM. Do your utmost to optimize THIS SINGLE FILE. Implement ALL TODO. RETURN ALL CODE, NEVER OMIT ANYTHING. 以任何方式省略代码都是不允许的。
|
||||
```
|
||||
```
|
||||
|
||||
## Format example
|
||||
-----
|
||||
{format_example}
|
||||
-----
|
||||
|
||||
"""
|
||||
|
||||
FORMAT_EXAMPLE = """
|
||||
|
||||
## Code Review
|
||||
1. The code ...
|
||||
-----
|
||||
# EXAMPLE 1
|
||||
## Code Review: {filename}
|
||||
1. No, we should add the logic of ...
|
||||
2. ...
|
||||
3. ...
|
||||
4. ...
|
||||
5. ...
|
||||
6. ...
|
||||
|
||||
## Code Review Result: {filename}
|
||||
LBTM
|
||||
|
||||
## Rewrite Code: {filename}
|
||||
```python
|
||||
## {filename}
|
||||
...
|
||||
```
|
||||
-----
|
||||
# EXAMPLE 2
|
||||
## Code Review: {filename}
|
||||
1. Yes.
|
||||
2. Yes.
|
||||
3. Yes.
|
||||
4. Yes.
|
||||
5. Yes.
|
||||
6. Yes.
|
||||
|
||||
## Code Review Result: {filename}
|
||||
LGTM
|
||||
|
||||
## Rewrite Code: {filename}
|
||||
pass
|
||||
-----
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -69,23 +95,60 @@ class WriteCodeReview(Action):
|
|||
super().__init__(name, context, llm)
|
||||
|
||||
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
|
||||
async def write_code(self, prompt):
|
||||
async def write_code_review_and_rewrite(self, prompt):
|
||||
code_rsp = await self._aask(prompt)
|
||||
result = CodeParser.parse_block("Code Review Result", code_rsp)
|
||||
if "LGTM" in result:
|
||||
return result, None
|
||||
code = CodeParser.parse_code(block="", text=code_rsp)
|
||||
return code
|
||||
return result, code
|
||||
|
||||
# <<<<<<< HEAD
|
||||
# async def run(self, *args, **kwargs) -> CodingContext:
|
||||
# format_example = FORMAT_EXAMPLE.format(filename=self.context.code_doc.filename)
|
||||
# context = "\n----------\n".join(
|
||||
# [self.context.design_doc.content, self.context.task_doc.content, self.context.code_doc.content]
|
||||
# )
|
||||
# prompt = PROMPT_TEMPLATE.format(
|
||||
# context=context,
|
||||
# code=self.context.code_doc.content,
|
||||
# filename=self.context.code_doc.filename,
|
||||
# format_example=format_example,
|
||||
# )
|
||||
# logger.info(f"Code review {self.context.code_doc.filename}..")
|
||||
# code = await self.write_code(prompt)
|
||||
# self.context.code_doc.content = code
|
||||
# return self.context
|
||||
# =======
|
||||
async def run(self, *args, **kwargs) -> CodingContext:
|
||||
format_example = FORMAT_EXAMPLE.format(filename=self.context.code_doc.filename)
|
||||
context = "\n".join(
|
||||
[self.context.design_doc.content, self.context.task_doc.content, self.context.code_doc.content]
|
||||
)
|
||||
prompt = PROMPT_TEMPLATE.format(
|
||||
context=context,
|
||||
code=self.context.code_doc.content,
|
||||
filename=self.context.code_doc.filename,
|
||||
format_example=format_example,
|
||||
)
|
||||
logger.info(f"Code review {self.context.code_doc.filename}..")
|
||||
code = await self.write_code(prompt)
|
||||
self.context.code_doc.content = code
|
||||
iterative_code = self.context.code_doc.content
|
||||
k = CONFIG.code_review_k_times or 1
|
||||
for i in range(k):
|
||||
format_example = FORMAT_EXAMPLE.format(filename=self.context.code_doc.filename)
|
||||
context = "\n----------\n".join(
|
||||
[
|
||||
"```text\n" + self.context.design_doc.content + "```\n",
|
||||
"```text\n" + self.context.task_doc.content + "```\n",
|
||||
"```python\n" + self.context.code_doc.content + "```\n",
|
||||
]
|
||||
)
|
||||
prompt = PROMPT_TEMPLATE.format(
|
||||
context=context,
|
||||
code=iterative_code,
|
||||
filename=self.context.code_doc.filename,
|
||||
format_example=format_example,
|
||||
)
|
||||
logger.info(
|
||||
f"Code review and rewrite {self.context.code_doc.filename,}: {i+1}/{k} | {len(iterative_code)=}, {len(self.context.code_doc.content)=}"
|
||||
)
|
||||
result, rewrited_code = await self.write_code_review_and_rewrite(prompt)
|
||||
if "LBTM" in result:
|
||||
iterative_code = rewrited_code
|
||||
elif "LGTM" in result:
|
||||
self.context.code_doc.content = iterative_code
|
||||
return self.context
|
||||
# code_rsp = await self._aask_v1(prompt, "code_rsp", OUTPUT_MAPPING)
|
||||
# self._save(context, filename, code)
|
||||
# 如果rewrited_code是None(原code perfect),那么直接返回code
|
||||
self.context.code_doc.content = iterative_code
|
||||
return self.context
|
||||
|
|
|
|||
|
|
@ -35,53 +35,50 @@ templates = {
|
|||
"json": {
|
||||
"PROMPT_TEMPLATE": """
|
||||
# Context
|
||||
## Original Requirements
|
||||
{requirements}
|
||||
|
||||
## Search Information
|
||||
{search_information}
|
||||
|
||||
## mermaid quadrantChart code syntax example. DONT USE QUOTO IN CODE DUE TO INVALID SYNTAX. Replace the <Campain X> with REAL COMPETITOR NAME
|
||||
```mermaid
|
||||
quadrantChart
|
||||
title Reach and engagement of campaigns
|
||||
x-axis Low Reach --> High Reach
|
||||
y-axis Low Engagement --> High Engagement
|
||||
quadrant-1 We should expand
|
||||
quadrant-2 Need to promote
|
||||
quadrant-3 Re-evaluate
|
||||
quadrant-4 May be improved
|
||||
"Campaign: A": [0.3, 0.6]
|
||||
"Campaign B": [0.45, 0.23]
|
||||
"Campaign C": [0.57, 0.69]
|
||||
"Campaign D": [0.78, 0.34]
|
||||
"Campaign E": [0.40, 0.34]
|
||||
"Campaign F": [0.35, 0.78]
|
||||
"Our Target Product": [0.5, 0.6]
|
||||
```
|
||||
{{
|
||||
"Original Requirements": "{requirements}",
|
||||
"Search Information": ""
|
||||
}}
|
||||
|
||||
## Format example
|
||||
{format_example}
|
||||
-----
|
||||
Role: You are a professional product manager; the goal is to design a concise, usable, efficient product
|
||||
Requirements: According to the context, fill in the following missing information, each section name is a key in json ,If the requirements are unclear, ensure minimum viability and avoid excessive design
|
||||
Language: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
Requirements: According to the context, fill in the following missing information, note that each sections are returned in Python code triple quote form seperatedly.
|
||||
ATTENTION: Output carefully referenced "Format example" in format.
|
||||
|
||||
## Original Requirements: Provide as Plain text, place the polished complete original requirements here
|
||||
## YOU NEED TO FULFILL THE BELOW JSON DOC
|
||||
|
||||
## Product Goals: Provided as Python list[str], up to 3 clear, orthogonal product goals. If the requirement itself is simple, the goal should also be simple
|
||||
|
||||
## User Stories: Provided as Python list[str], up to 5 scenario-based user stories, If the requirement itself is simple, the user stories should also be less
|
||||
|
||||
## Competitive Analysis: Provided as Python list[str], up to 7 competitive product analyses, consider as similar competitors as possible
|
||||
|
||||
## Competitive Quadrant Chart: Use mermaid quadrantChart code syntax. up to 14 competitive products. Translation: Distribute these competitor scores evenly between 0 and 1, trying to conform to a normal distribution centered around 0.5 as much as possible.
|
||||
|
||||
## Requirement Analysis: Provide as Plain text. Be simple. LESS IS MORE. Make your requirements less dumb. Delete the parts unnessasery.
|
||||
|
||||
## Requirement Pool: Provided as Python list[list[str], the parameters are requirement description, priority(P0/P1/P2), respectively, comply with PEP standards; no more than 5 requirements and consider to make its difficulty lower
|
||||
|
||||
## UI Design draft: Provide as Plain text. Be simple. Describe the elements and functions, also provide a simple style description and layout description.
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here.
|
||||
{{
|
||||
"Language": "", # str, use the same language as the user requirement. en_us / zh_cn etc.
|
||||
"Original Requirements": "", # str, place the polished complete original requirements here
|
||||
"project_name": "", # str, name it like game_2048 / web_2048 / simple_crm etc.
|
||||
"Search Information": "",
|
||||
"Requirements": "",
|
||||
"Product Goals": [], # Provided as Python list[str], up to 3 clear, orthogonal product goals.
|
||||
"User Stories": [], # Provided as Python list[str], up to 5 scenario-based user stories
|
||||
"Competitive Analysis": [], # Provided as Python list[str], up to 8 competitive product analyses
|
||||
# Use mermaid quadrantChart code syntax. up to 14 competitive products. Translation: Distribute these competitor scores evenly between 0 and 1, trying to conform to a normal distribution centered around 0.5 as much as possible.
|
||||
"Competitive Quadrant Chart": "quadrantChart
|
||||
title Reach and engagement of campaigns
|
||||
x-axis Low Reach --> High Reach
|
||||
y-axis Low Engagement --> High Engagement
|
||||
quadrant-1 We should expand
|
||||
quadrant-2 Need to promote
|
||||
quadrant-3 Re-evaluate
|
||||
quadrant-4 May be improved
|
||||
Campaign A: [0.3, 0.6]
|
||||
Campaign B: [0.45, 0.23]
|
||||
Campaign C: [0.57, 0.69]
|
||||
Campaign D: [0.78, 0.34]
|
||||
Campaign E: [0.40, 0.34]
|
||||
Campaign F: [0.35, 0.78]",
|
||||
"Requirement Analysis": "", # Provide as Plain text.
|
||||
"Requirement Pool": [["P0","P0 requirement"],["P1","P1 requirement"]], # Provided as Python list[list[str], the parameters are requirement description, priority(P0/P1/P2), respectively, comply with PEP standards
|
||||
"UI Design draft": "", # Provide as Plain text. Be simple. Describe the elements and functions, also provide a simple style description and layout description.
|
||||
"Anything UNCLEAR": "", # Provide as Plain text. Try to clarify it.
|
||||
}}
|
||||
|
||||
output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example,
|
||||
and only output the json inside this tag, nothing else
|
||||
|
|
@ -89,6 +86,7 @@ and only output the json inside this tag, nothing else
|
|||
"FORMAT_EXAMPLE": """
|
||||
[CONTENT]
|
||||
{
|
||||
"Language": "",
|
||||
"Original Requirements": "",
|
||||
"Search Information": "",
|
||||
"Requirements": "",
|
||||
|
|
@ -149,30 +147,33 @@ quadrantChart
|
|||
{format_example}
|
||||
-----
|
||||
Role: You are a professional product manager; the goal is to design a concise, usable, efficient product
|
||||
Requirements: According to the context, fill in the following missing information, note that each sections are returned in Python code triple quote form seperatedly. If the requirements are unclear, ensure minimum viability and avoid excessive design
|
||||
Language: Please use the same language as the user requirement to answer, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
||||
Requirements: According to the context, fill in the following missing information, note that each sections are returned in Python code triple quote form seperatedly.
|
||||
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. AND '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote. Output carefully referenced "Format example" in format.
|
||||
|
||||
## Language: Provide as Plain text, use the same language as the user requirement.
|
||||
|
||||
## Original Requirements: Provide as Plain text, place the polished complete original requirements here
|
||||
|
||||
## Product Goals: Provided as Python list[str], up to 3 clear, orthogonal product goals. If the requirement itself is simple, the goal should also be simple
|
||||
## Product Goals: Provided as Python list[str], up to 3 clear, orthogonal product goals.
|
||||
|
||||
## User Stories: Provided as Python list[str], up to 5 scenario-based user stories, If the requirement itself is simple, the user stories should also be less
|
||||
## User Stories: Provided as Python list[str], up to 5 scenario-based user stories
|
||||
|
||||
## Competitive Analysis: Provided as Python list[str], up to 7 competitive product analyses, consider as similar competitors as possible
|
||||
|
||||
## Competitive Quadrant Chart: Use mermaid quadrantChart code syntax. up to 14 competitive products. Translation: Distribute these competitor scores evenly between 0 and 1, trying to conform to a normal distribution centered around 0.5 as much as possible.
|
||||
|
||||
## Requirement Analysis: Provide as Plain text. Be simple. LESS IS MORE. Make your requirements less dumb. Delete the parts unnessasery.
|
||||
## Requirement Analysis: Provide as Plain text.
|
||||
|
||||
## Requirement Pool: Provided as Python list[list[str], the parameters are requirement description, priority(P0/P1/P2), respectively, comply with PEP standards; no more than 5 requirements and consider to make its difficulty lower
|
||||
## Requirement Pool: Provided as Python list[list[str], the parameters are requirement description, priority(P0/P1/P2), respectively, comply with PEP standards
|
||||
|
||||
## UI Design draft: Provide as Plain text. Be simple. Describe the elements and functions, also provide a simple style description and layout description.
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here.
|
||||
## Anything UNCLEAR: Provide as Plain text. Try to clarify it.
|
||||
""",
|
||||
"FORMAT_EXAMPLE": """
|
||||
---
|
||||
## Original Requirements
|
||||
The boss ...
|
||||
The user ...
|
||||
|
||||
## Product Goals
|
||||
```python
|
||||
|
|
@ -225,6 +226,7 @@ There are no unclear points.
|
|||
|
||||
|
||||
OUTPUT_MAPPING = {
|
||||
"Language": (str, ...),
|
||||
"Original Requirements": (str, ...),
|
||||
"Product Goals": (List[str], ...),
|
||||
"User Stories": (List[str], ...),
|
||||
|
|
@ -322,11 +324,14 @@ class WritePRD(Action):
|
|||
logger.info(sas.result)
|
||||
logger.info(rsp)
|
||||
|
||||
# logger.info(format)
|
||||
prompt_template, format_example = get_template(templates, format)
|
||||
# logger.info(prompt_template)
|
||||
# logger.info(format_example)
|
||||
prompt = prompt_template.format(
|
||||
requirements=requirements, search_information=info, format_example=format_example
|
||||
)
|
||||
logger.debug(prompt)
|
||||
# logger.info(prompt)
|
||||
# prd = await self._aask_v1(prompt, "prd", OUTPUT_MAPPING)
|
||||
prd = await self._aask_v1(prompt, "prd", OUTPUT_MAPPING, format=format)
|
||||
return prd
|
||||
|
|
@ -346,7 +351,7 @@ class WritePRD(Action):
|
|||
async def _merge(self, new_requirement_doc, prd_doc, format=CONFIG.prompt_format) -> Document:
|
||||
prompt = MERGE_PROMPT.format(requirements=new_requirement_doc.content, old_prd=prd_doc.content)
|
||||
prd = await self._aask_v1(prompt, "prd", OUTPUT_MAPPING, format=format)
|
||||
prd_doc.content = prd.instruct_content.json()
|
||||
prd_doc.content = prd.instruct_content.json(ensure_ascii=False)
|
||||
return prd_doc
|
||||
|
||||
async def _update_prd(self, requirement_doc, prd_doc, prds_file_repo, *args, **kwargs) -> Document | None:
|
||||
|
|
@ -355,7 +360,7 @@ class WritePRD(Action):
|
|||
new_prd_doc = Document(
|
||||
root_path=PRDS_FILE_REPO,
|
||||
filename=FileRepository.new_filename() + ".json",
|
||||
content=prd.instruct_content.json(),
|
||||
content=prd.instruct_content.json(ensure_ascii=False),
|
||||
)
|
||||
elif await self._is_relative_to(requirement_doc, prd_doc):
|
||||
new_prd_doc = await self._merge(requirement_doc, prd_doc)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"""
|
||||
@Time : 2023/5/11 22:12
|
||||
@Author : alexanderwu
|
||||
@File : environment.py
|
||||
@File : write_test.py
|
||||
@Modified By: mashenquan, 2023-11-27. Following the think-act principle, solidify the task parameters when creating the
|
||||
WriteTest object, rather than passing them in when calling the run function.
|
||||
"""
|
||||
|
|
@ -19,7 +19,7 @@ NOTICE
|
|||
2. Requirement: Based on the context, develop a comprehensive test suite that adequately covers all relevant aspects of the code file under review. Your test suite will be part of the overall project QA, so please develop complete, robust, and reusable test cases.
|
||||
3. Attention1: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the test case or script.
|
||||
4. Attention2: If there are any settings in your tests, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE.
|
||||
5. Attention3: YOU MUST FOLLOW "Data structures and interface definitions". DO NOT CHANGE ANY DESIGN. Make sure your tests respect the existing design and ensure its validity.
|
||||
5. Attention3: YOU MUST FOLLOW "Data structures and interfaces". DO NOT CHANGE ANY DESIGN. Make sure your tests respect the existing design and ensure its validity.
|
||||
6. Think before writing: What should be tested and validated in this document? What edge cases could exist? What might fail?
|
||||
7. CAREFULLY CHECK THAT YOU DON'T MISS ANY NECESSARY TEST CASES/SCRIPTS IN THIS FILE.
|
||||
Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the test case or script and triple quotes.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue