1. remove INC prompt in some ActionNode

2. replace Code archive from data to tests/data/incremental_dev_project
3. update test case for ActionNode
This commit is contained in:
mannaandpoem 2024-01-16 15:42:48 +08:00
parent f460771978
commit f4e39a462c
19 changed files with 194 additions and 420 deletions

View file

@ -18,14 +18,6 @@ IMPLEMENTATION_APPROACH = ActionNode(
example="We will ...",
)
INCREMENTAL_IMPLEMENTATION_APPROACH = ActionNode(
key="Incremental Implementation approach",
expected_type=str,
instruction="Analyze the challenging aspects of the requirements and select a suitable open-source framework. "
"Outline the incremental steps involved in the implementation process with the detailed strategies.",
example="we will ...",
)
REFINED_IMPLEMENTATION_APPROACH = ActionNode(
key="Refined Implementation Approach",
expected_type=str,
@ -63,16 +55,6 @@ DATA_STRUCTURES_AND_INTERFACES = ActionNode(
example=MMC1,
)
INCREMENTAL_DATA_STRUCTURES_AND_INTERFACES = ActionNode(
key="Incremental Data structures and interfaces",
expected_type=str,
instruction="Extend the existing mermaid classDiagram code syntax to incorporate new classes, "
"methods (including __init__), and functions with precise type annotations. Clearly delineate additional "
"relationships between classes, maintaining adherence to PEP8 standards. Enhance the level of detail in data "
"structures, ensuring a comprehensive API design that seamlessly integrates with the existing structure.",
example=MMC1_REFINE,
)
REFINED_DATA_STRUCTURES_AND_INTERFACES = ActionNode(
key="Refined Data Structures and Interfaces",
expected_type=str,
@ -108,32 +90,6 @@ ANYTHING_UNCLEAR = ActionNode(
example="Clarification needed on third-party API integration, ...",
)
INC_DESIGN_CONTEXT = """
## Legacy Content
{old_design}
## New Requirements
{requirements}
## PRD Increment Content
{prd_increment}
"""
MERGE_DESIGN_CONTEXT = """
Role: You are a professional Architect tasked with overseeing incremental development.
Based on new requirements, review and refine the system design. Integrate existing architecture with incremental design changes, ensuring the refined design encompasses all architectural elements, enhancements, and adjustments. Retain content unrelated to incremental development needs for coherence and clarity.
# Context
## New Requirements
{requirements}
## Legacy Content
{old_design}
## Design Increment Content
{design_increment}
"""
NODES = [
IMPLEMENTATION_APPROACH,
# PROJECT_NAME,
@ -143,8 +99,6 @@ NODES = [
ANYTHING_UNCLEAR,
]
INC_NODES = [INCREMENTAL_IMPLEMENTATION_APPROACH, INCREMENTAL_DATA_STRUCTURES_AND_INTERFACES, REFINED_PROGRAM_CALL_FLOW]
REFINE_NODES = [
REFINED_IMPLEMENTATION_APPROACH,
REFINED_FILE_LIST,
@ -154,7 +108,6 @@ REFINE_NODES = [
]
DESIGN_API_NODE = ActionNode.from_children("DesignAPI", NODES)
INCREMENTAL_DESIGN_NODES = ActionNode.from_children("Incremental_Design_API", INC_NODES)
REFINED_DESIGN_NODES = ActionNode.from_children("Refined_Design_API", REFINE_NODES)

View file

@ -35,24 +35,12 @@ LOGIC_ANALYSIS = ActionNode(
],
)
INCREMENTAL_LOGIC_ANALYSIS = ActionNode(
key="Incremental Logic Analysis",
expected_type=List[List[str]],
instruction="Provide a list of files with the classes/methods/functions to be implemented or modified "
"incrementally. Include thorough dependency analysis, consider potential impacts on existing code, and document"
" necessary imports.",
example=[
["new_feature.py", "Introduces NewFeature class and related functions"],
["utils.py", "Modifies existing utility functions to support incremental changes"],
],
)
REFINED_LOGIC_ANALYSIS = ActionNode(
key="Refined Logic Analysis",
expected_type=List[List[str]],
instruction="Review and refine the logic analysis by merging the Legacy Content and Incremental Content. "
"Provide a comprehensive list of files with classes/methods/functions to be implemented or modified incrementally. "
"Include thorough dependency analysis, consider potential impacts on existing code, and document necessary imports.",
"Include dependency analysis, consider potential impacts on existing code, and document necessary imports.",
example=[
["game.py", "Contains Game class and ... functions"],
["main.py", "Contains main function, from game import Game"],
@ -68,15 +56,6 @@ TASK_LIST = ActionNode(
example=["game.py", "main.py"],
)
INCREMENTAL_TASK_LIST = ActionNode(
key="Incremental Task list",
expected_type=List[str],
instruction="Break down the incremental development tasks into a prioritized list of filenames."
"Organize the tasks based on dependency order, ensuring a systematic and efficient implementation."
"Only output filename! Do not include comments in the list ",
example=["new_feature.py", "main.py"],
)
REFINED_TASK_LIST = ActionNode(
key="Refined Task list",
expected_type=List[str],
@ -101,14 +80,6 @@ SHARED_KNOWLEDGE = ActionNode(
example="`game.py` contains functions shared across the project.",
)
INCREMENTAL_SHARED_KNOWLEDGE = ActionNode(
key="Incremental Shared Knowledge",
expected_type=str,
instruction="Document any new shared knowledge generated during incremental development. This includes common "
"utility functions, configuration variables, or any information vital for team collaboration.",
example="`new_module.py` introduces shared utility functions for improved code reusability.",
)
REFINED_SHARED_KNOWLEDGE = ActionNode(
key="Refined Shared Knowledge",
expected_type=str,
@ -126,32 +97,6 @@ ANYTHING_UNCLEAR_PM = ActionNode(
example="Clarification needed on how to start and initialize third-party libraries.",
)
INC_PM_CONTEXT = """
### Legacy Content
{old_tasks}
### New Requirements
{requirements}
### Design Increment Content
{design_increment}
"""
MERGE_PM_CONTEXT = """
Role: You are a professional Project Manager tasked with overseeing incremental development.
Based on New Requirements, refine the project context to account for incremental development. Ensure the context offers a comprehensive overview of the project's evolving scope, covering both legacy content and incremental content. Retain any content unrelated to incremental development.
# Context
## New Requirements
{requirements}
## Legacy Content
{old_tasks}
## Increment Content
{tasks_increment}
"""
NODES = [
REQUIRED_PYTHON_PACKAGES,
REQUIRED_OTHER_LANGUAGE_PACKAGES,
@ -162,8 +107,6 @@ NODES = [
ANYTHING_UNCLEAR_PM,
]
INC_NODES = [INCREMENTAL_LOGIC_ANALYSIS, INCREMENTAL_TASK_LIST, INCREMENTAL_SHARED_KNOWLEDGE]
REFINE_NODES = [
REQUIRED_PYTHON_PACKAGES,
REQUIRED_OTHER_LANGUAGE_PACKAGES,
@ -175,7 +118,6 @@ REFINE_NODES = [
]
PM_NODE = ActionNode.from_children("PM_NODE", NODES)
INCREMENTAL_PM_NODES = ActionNode.from_children("Incremental_PM_NODES", INC_NODES)
REFINED_PM_NODES = ActionNode.from_children("Refined_PM_NODES", REFINE_NODES)

View file

@ -157,6 +157,24 @@ class WriteCode(Action):
@staticmethod
async def get_codes(task_doc, exclude, mode="normal") -> str:
"""
Get code snippets based on different modes.
Attributes:
task_doc (Document): Document object of the task file.
exclude (str): Specifies the filename to be excluded from the code snippets.
mode (str): Specifies the mode, either "normal" or "guide" (default is "normal").
Returns:
str: Code snippets.
Description:
If mode is set to "normal", it returns code snippets for the regular coding phase,
i.e., all the code generated before writing the current file.
If mode is set to "guide", it returns code snippets for incremental development,
building upon the existing code in the "normal" mode and adding code for the current file's older versions.
"""
if not task_doc:
return ""
if not task_doc.content:
@ -173,6 +191,8 @@ class WriteCode(Action):
union_files_list = list(set(src_files) | set(old_files))
for filename in union_files_list:
if filename == exclude:
# Exclude unnecessary code to maintain a clean and focused main.py file, ensuring only relevant and
# essential functionality is included for the projects requirements
if filename in old_files and filename != "main.py":
# Use legacy code
doc = await old_file_repo.get(filename=filename)

View file

@ -9,6 +9,7 @@ import asyncio
from metagpt.actions.action import Action
from metagpt.actions.action_node import ActionNode
from metagpt.logs import logger
GUIDELINES_AND_INCREMENTAL_CHANGE = ActionNode(
key="Guidelines and Incremental Change",
@ -455,7 +456,7 @@ async def main():
write_code_guideline = WriteCodeGuideline()
node = await write_code_guideline.run(CODE_GUIDELINE_CONTEXT_EXAMPLE)
guideline = node.instruct_content.model_dump_json()
print(guideline)
logger.info(guideline)
if __name__ == "__main__":

View file

@ -130,14 +130,6 @@ REQUIREMENT_ANALYSIS = ActionNode(
example="",
)
INCREMENTAL_REQUIREMENT_ANALYSIS = ActionNode(
key="Incremental Requirement Analysis",
expected_type=List[str],
instruction="Propose the comprehensive incremental development requirement analysis on new features and enhanced "
"features for New Requirements.",
example=["Require add/update/modify ..."],
)
REFINED_REQUIREMENT_ANALYSIS = ActionNode(
key="Refined Requirement Analysis",
expected_type=List[str],
@ -194,22 +186,6 @@ REASON = ActionNode(
key="reason", expected_type=str, instruction="Explain the reasoning process from question to answer", example="..."
)
INCREMENTAL_PRD_CONTEXT = """
Role: You are a professional Product Manager tasked with overseeing incremental development.
Based on New Requirements, output a New PRD that seamlessly integrates both the Legacy Content and the Incremental Content. Ensure the resulting document captures the complete scope of features, enhancements, and retain content unrelated to incremental development needs for coherence and clarity.
# Context
## New Requirements
{requirements}
## Legacy Content
{old_prd}
## PRD Incremental Content
{prd_increment}
"""
REFINE_PRD_TEMPLATE = """
### Project Name
{project_name}
@ -255,11 +231,8 @@ REFINE_NODES = [
ANYTHING_UNCLEAR,
]
INCREMENT_PRD_NODES = [INCREMENTAL_REQUIREMENT_ANALYSIS, REQUIREMENT_POOL]
WRITE_PRD_NODE = ActionNode.from_children("WritePRD", NODES)
REFINE_PRD_NODE = ActionNode.from_children("RefinePRD", REFINE_NODES)
INCREMENTAL_PRD_NODE = ActionNode.from_children("IncrementalPRD", INCREMENT_PRD_NODES)
WP_ISSUE_TYPE_NODE = ActionNode.from_children("WP_ISSUE_TYPE", [ISSUE_TYPE, REASON])
WP_IS_RELATIVE_NODE = ActionNode.from_children("WP_IS_RELATIVE", [IS_RELATIVE, REASON])