Delete files with 'refine'

This commit is contained in:
mannaandpoem 2023-12-27 15:17:21 +08:00
parent 1ee35c930e
commit 8952deaa8b
4 changed files with 0 additions and 469 deletions

View file

@ -1,10 +0,0 @@
from metagpt.actions import Action
# 增量开发动作的基类
class Refine(Action):
def __init__(self, name="Refine", context=None, llm=None):
super().__init__(name, context, llm)
def run(self, *args, **kwargs):
raise NotImplementedError

View file

@ -1,221 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import shutil
from pathlib import Path
from typing import List, Union
from metagpt.actions import Action, ActionOutput
from metagpt.config import CONFIG
from metagpt.logs import logger
from metagpt.utils.common import CodeParser
from metagpt.utils.get_template import get_template
from metagpt.utils.json_to_markdown import json_to_markdown
from metagpt.utils.mermaid import mermaid_to_file
templates = {
"json": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Format example
{format_example}
-----
Role: You are an architect; the goal is to perform incremental development and design a state-of-the-art (SOTA) PEP8-compliant Python system based on the context and legacy design. Make the best use of good open source tools.
Requirement: Fill in the following missing information based on the context, each section name is a key in json. Output exactly as shown in the example, including single and double quotes.
Max Output: 8192 chars or 2048 tokens. Try to use them up.
## Incremental implementation approach: Provide as Python list[str]. Analyze the difficult points of the requirements, select the appropriate open-source framework. Up to 5.
## Python package name: Provide as Python str with python triple quoto, concise and clear, characters only use a combination of all lowercase and underscores
## Data structures and interface definitions: Use single quotes to wrap content. 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 single quotes to wrap content. 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.
output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example.
Output exactly as shown in the example, including single and double quotes, and only output the json inside this tag, nothing else
""",
"FORMAT_EXAMPLE": """
[CONTENT]
{
"Incremental implementation approach": ["We will ...",],
"Python package name": "new_name",
"Data structures and interface definitions": '
classDiagram
class Game{
+int score
}
...
Game "1" -- "1" Food: has
',
"Program call flow": '
sequenceDiagram
participant M as Main
...
G->>M: end game
'
}
[/CONTENT]
""",
},
"markdown": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Format example
{format_example}
-----
Role: You are an architect; the goal is to perform incremental development and design a state-of-the-art (SOTA) PEP8-compliant Python system based on the context and legacy design. Make the best use of good open source tools.
Requirement: Fill in the following missing information based on the context, note that all sections are response with code form separately. Output exactly as shown in the example, including single and double quotes.
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.
## Incremental implementation approach: Provide as Python list[str]. Analyze the difficult points of the requirements, select the appropriate open-source framework. Up to 5.
## Python package name: Provide as Python str with python triple quoto, concise and clear, characters only use a combination of all lowercase and underscores
## Data structures and interface definitions: Use single quotes to wrap content. 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 single quotes to wrap content. 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.
""",
"FORMAT_EXAMPLE": """
---
## Incremental implementation approach
```python
[
"We will ...",
]
```
## Python package name
```python
"new_name"
```
## Data structures and interface definitions
```mermaid
classDiagram
class Game{
+int score
}
...
Game "1" -- "1" Food: has
```
## Program call flow
```mermaid
sequenceDiagram
participant M as Main
...
G->>M: end game
```
---
""",
},
}
OUTPUT_MAPPING = {
# "Incremental Requirements": (str, ...),
# "Difference Description": (Union[List[str], str], ...),
"Incremental implementation approach": (Union[List[str], str], ...),
"Python package name": (str, ...),
# "File list": (List[str], ...),
"Data structures and interface definitions": (str, ...),
"Program call flow": (str, ...),
}
class RefineDesign(Action):
def __init__(self, name, context=None, llm=None):
super().__init__(name, context, llm)
self.desc = (
"Based on the PRD, think about the system design, and design the corresponding APIs, "
"data structures, library tables, processes, and paths. Please provide your design, feedback "
"clearly and in detail."
)
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)
def create_or_increment_workspace(self, workspace: Path):
# 如果工作空间已存在,添加数字以区分
original_workspace = workspace
index = 1
while workspace.exists():
ws_name_match = re.match(r"^(.*)_([\d]+)$", original_workspace.name)
if ws_name_match:
base_name, existing_index = ws_name_match.groups()
index = int(existing_index)
index += 1
workspace = original_workspace.parent / f"{base_name}_{index}"
else:
workspace = original_workspace.parent / f"{original_workspace.name}_{index}"
index += 1
# 创建工作空间,包括所有必要的父文件夹
workspace.mkdir(parents=True, exist_ok=True)
return workspace
async def _save_prd(self, docs_path, resources_path, context):
prd_file = docs_path / "prd.md"
if context[-1].instruct_content:
logger.info(f"Saving PRD to {prd_file}")
prd_file.write_text(json_to_markdown(context[-1].instruct_content.dict()))
async def _save_system_design(self, docs_path, resources_path, system_design):
data_api_design = system_design.instruct_content.dict()[
"Data structures and interface definitions"
] # CodeParser.parse_code(block="Data structures and interface definitions", 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((json_to_markdown(system_design.instruct_content.dict())))
async def _save(self, context, system_design, WORKSPACE_ROOT=None):
if isinstance(system_design, ActionOutput):
ws_name = system_design.instruct_content.dict()["Python package name"]
else:
ws_name = CodeParser.parse_str(block="Python package name", text=system_design)
workspace = WORKSPACE_ROOT / ws_name
# workspace = self.create_or_increment_workspace(workspace)
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, legacy, format=CONFIG.prompt_format):
prompt_template, format_example = get_template(templates, format)
prompt = prompt_template.format(context=context, legacy=legacy, 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
setattr(
system_design.instruct_content,
"Python package name",
system_design.instruct_content.dict()["Python package name"].strip().strip("'").strip('"'),
)
await self._save(context, system_design)
return system_design

View file

@ -1,94 +0,0 @@
from typing import List
from metagpt.actions import SearchAndSummarize
from metagpt.actions.refine import Refine
from metagpt.config import CONFIG
from metagpt.logs import logger
from metagpt.utils.get_template import get_template
increment_template = {
"json": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Search Information
{search_information}
## Format example
{format_example}
-----
Role: You are a professional Product Manager tasked with overseeing incremental development and crafting Product Requirements Documents (PRDs) for a concise, usable, and 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. Only output one json, nothing else.
## Incremental Development Analysis: Provide as Python list[str], up to 5. incremental development analysis and plans based on the context and the legacy. If the requirement itself is simple, the Incremental Development Analysis should also be simple.
output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example,
and only output the json inside this tag, nothing else
""",
"FORMAT_EXAMPLE": """
[CONTENT]
{
"Incremental Development Analysis": [],
}
[/CONTENT]
""",
},
"markdown": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Search Information
{search_information}
## Format example
{format_example}
-----
Role: You are a professional Product Manager tasked with overseeing incremental development and crafting Product Requirements Documents (PRDs) for a concise, usable, and 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
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. AND '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote. Output carefully referenced "Format example" in format.Only output one json, nothing else.
## Incremental Development Analysis: Provide as Python list[str], up to 5. Incremental development analysis and plans based on the context and the legacy. If the requirement itself is simple, the Incremental Development Analysis should also be simple.
""",
"FORMAT_EXAMPLE": """
---
## Incremental Development Analysis
[
"We will ...",
]
""",
},
}
INCREMENT_OUTPUT_MAPPING = {
"Incremental Development Analysis": (List[str], ...),
}
class RefinePRD(Refine):
def __init__(self, name="RefinePRD", context=None, llm=None):
super().__init__(name, context, llm)
async def run(self, context, legacy, format=CONFIG.prompt_format, *args, **kwargs):
sas = SearchAndSummarize()
rsp = ""
info = f"### Search Results\n{sas.result}\n\n### Search Summary\n{rsp}"
if sas.result:
logger.info(sas.result)
logger.info(rsp)
prompt_template, format_example = get_template(increment_template, format)
prompt = prompt_template.format(
context=context, legacy=legacy, search_information=info, format_example=format_example
)
logger.debug(prompt)
prd = await self._aask_v1(prompt, "prd", INCREMENT_OUTPUT_MAPPING, format=format)
return prd

View file

@ -1,144 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import List, Union
from metagpt.actions.action import Action
from metagpt.config import CONFIG
from metagpt.const import WORKSPACE_ROOT
from metagpt.utils.common import CodeParser
from metagpt.utils.get_template import get_template
from metagpt.utils.json_to_markdown import json_to_markdown
templates = {
"json": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Format example
{format_example}
-----
Role: You are a project manager; the goal is to perform incremental development based on the context and the legacy. Break down tasks according to PRD/technical design, provide a Task list, and analyze task dependencies to start with the prerequisite modules.
Requirements: Based on the context and the Legacy Project Management and Legacy Code, fill in the following missing information. Note that Please try your best to reuse legacy code, and all sections are returned in Python code triple quote form seperatedly. Here the granularity of the task is a file that need to modified.
Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote.
Output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT]. The following is the attribute description of the JSON object.
## Required Python third-party packages: Provided as a python list, the requirements.txt format
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend based on the previous.
## 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.
Output a properly formatted JSON, wrapped inside [CONTENT][/CONTENT] like format example,
and only output the json inside this tag, nothing else
""",
"FORMAT_EXAMPLE": '''
{
"Required Python third-party packages": [
"flask==1.1.2",
"bcrypt==3.2.0"
],
"Full API spec": """
openapi: 3.0.0
...
description: A JSON object ...
""",
"Task list": [
"game.py"
]
}
''',
},
"markdown": {
"PROMPT_TEMPLATE": """
# Context
{context}
## Legacy
{legacy}
## Format example
{format_example}
-----
Role: You are a project manager; the goal is to perform incremental development based on the context and the legacy. Break down tasks according to PRD/technical design, provide a Task list need to modified files, and analyze task dependencies to start with the prerequisite modules.
Requirements: Based on the context and the Legacy Project Management and Legacy Code, fill in the following missing information. Note that Please try your best to reuse legacy code, and all sections are returned in Python code triple quote form seperatedly. Here the granularity of the task is a file that need to modified.
Attention: Use '##' to split sections, not '#', and '## <SECTION_NAME>' SHOULD WRITE BEFORE the code and triple quote.
## Required Python third-party packages: Provided as a python list, the requirements.txt format
## Full API spec: Use OpenAPI 3.0. Describe all APIs that may be used by both frontend and backend based on the previous.
## 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.
""",
"FORMAT_EXAMPLE": '''
---
## Required Python third-party packages
```python
[
"flask==1.1.2",
"bcrypt==3.2.0"
]
```
## Full API spec
```python
"""
openapi: 3.0.0
...
description: A JSON object ...
"""
```
## Task list
```python
[
"game.py",
]
```
---
''',
},
}
OUTPUT_MAPPING = {
# "Incremental Requirements": (str, ...),
# ## Incremental Requirements: Provided as a str, the foremost incremental requirements for project management here based on the previous.
# "Difference Analysis": (Union[List[str], str], ...),
"Required Python third-party packages": (Union[List[str], str], ...),
"Full API spec": (str, ...),
# "Logic Analysis": (List[List[str]], ...),
"Task list": (List[str], ...),
}
class RefineTasks(Action):
def __init__(self, name="RefineTasks", context=None, llm=None):
super().__init__(name, context, llm)
def _save(self, context, rsp):
if context[-1].instruct_content:
ws_name = context[-1].instruct_content.dict()["Python package name"]
else:
ws_name = CodeParser.parse_str(block="Python package name", text=context[-1].content)
file_path = WORKSPACE_ROOT / ws_name / "docs/api_spec_and_tasks.md"
file_path.write_text(json_to_markdown(rsp.instruct_content.dict()))
# Write requirements.txt
requirements_path = WORKSPACE_ROOT / 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, legacy, format=CONFIG.prompt_format):
prompt_template, format_example = get_template(templates, format)
prompt = prompt_template.format(context=context, legacy=legacy, format_example=format_example)
rsp = await self._aask_v1(prompt, "task", OUTPUT_MAPPING, format=format)
self._save(context, rsp)
return rsp
class AssignTasks(Action):
async def run(self, *args, **kwargs):
# Here you should implement the actual action
pass