Merge pull request #948 from mannaandpoem/update_plan_and_improve_coverage

Update code plan and change and Improve test coverage
This commit is contained in:
Alexander Wu 2024-03-05 15:37:13 +08:00 committed by GitHub
commit 1e5656df97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 336 additions and 86 deletions

View file

@ -8,7 +8,6 @@
from typing import List
from metagpt.actions.action_node import ActionNode
from metagpt.logs import logger
from metagpt.utils.mermaid import MMC1, MMC2
IMPLEMENTATION_APPROACH = ActionNode(
@ -109,14 +108,3 @@ REFINED_NODES = [
DESIGN_API_NODE = ActionNode.from_children("DesignAPI", NODES)
REFINED_DESIGN_NODE = ActionNode.from_children("RefinedDesignAPI", REFINED_NODES)
def main():
prompt = DESIGN_API_NODE.compile(context="")
logger.info(prompt)
prompt = REFINED_DESIGN_NODE.compile(context="")
logger.info(prompt)
if __name__ == "__main__":
main()

View file

@ -8,7 +8,6 @@
from typing import List
from metagpt.actions.action_node import ActionNode
from metagpt.logs import logger
REQUIRED_PYTHON_PACKAGES = ActionNode(
key="Required Python packages",
@ -119,14 +118,3 @@ REFINED_NODES = [
PM_NODE = ActionNode.from_children("PM_NODE", NODES)
REFINED_PM_NODE = ActionNode.from_children("REFINED_PM_NODE", REFINED_NODES)
def main():
prompt = PM_NODE.compile(context="")
logger.info(prompt)
prompt = REFINED_PM_NODE.compile(context="")
logger.info(prompt)
if __name__ == "__main__":
main()

View file

@ -6,30 +6,44 @@
@File : write_code_plan_and_change_an.py
"""
import os
from typing import List
from pydantic import Field
from metagpt.actions.action import Action
from metagpt.actions.action_node import ActionNode
from metagpt.logs import logger
from metagpt.schema import CodePlanAndChangeContext
CODE_PLAN_AND_CHANGE = ActionNode(
key="Code Plan And Change",
expected_type=str,
instruction="Developing comprehensive and step-by-step incremental development plan, and write Incremental "
"Change by making a code draft that how to implement incremental development including detailed steps based on the "
"context. Note: Track incremental changes using mark of '+' or '-' for add/modify/delete code, and conforms to the "
"output format of git diff",
example="""
1. Plan for calculator.py: Enhance the functionality of `calculator.py` by extending it to incorporate methods for subtraction, multiplication, and division. Additionally, implement robust error handling for the division operation to mitigate potential issues related to division by zero.
```python
DEVELOPMENT_PLAN = ActionNode(
key="Development Plan",
expected_type=List[str],
instruction="Develop a comprehensive and step-by-step incremental development plan, providing the detail "
"changes to be implemented at each step based on the order of 'Task List'",
example=[
"Enhance the functionality of `calculator.py` by extending it to incorporate methods for subtraction, ...",
"Update the existing codebase in main.py to incorporate new API endpoints for subtraction, ...",
],
)
INCREMENTAL_CHANGE = ActionNode(
key="Incremental Change",
expected_type=List[str],
instruction="Write Incremental Change by making a code draft that how to implement incremental development "
"including detailed steps based on the context. Note: Track incremental changes using the marks `+` and `-` to "
"indicate additions and deletions, and ensure compliance with the output format of `git diff`",
example=[
'''```diff
--- Old/calculator.py
+++ New/calculator.py
class Calculator:
self.result = number1 + number2
return self.result
- def sub(self, number1, number2) -> float:
+ def subtract(self, number1: float, number2: float) -> float:
+ '''
+ """
+ Subtracts the second number from the first and returns the result.
+
+ Args:
@ -38,13 +52,13 @@ class Calculator:
+
+ Returns:
+ float: The difference of number1 and number2.
+ '''
+ """
+ self.result = number1 - number2
+ return self.result
+
def multiply(self, number1: float, number2: float) -> float:
- pass
+ '''
+ """
+ Multiplies two numbers and returns the result.
+
+ Args:
@ -53,15 +67,15 @@ class Calculator:
+
+ Returns:
+ float: The product of number1 and number2.
+ '''
+ """
+ self.result = number1 * number2
+ return self.result
+
def divide(self, number1: float, number2: float) -> float:
- pass
+ '''
+ """
+ ValueError: If the second number is zero.
+ '''
+ """
+ if number2 == 0:
+ raise ValueError('Cannot divide by zero')
+ self.result = number1 / number2
@ -75,10 +89,11 @@ class Calculator:
+ print("Result is already zero, no need to clear.")
+
self.result = 0.0
```
```''',
"""```diff
--- Old/main.py
+++ New/main.py
2. Plan for main.py: Integrate new API endpoints for subtraction, multiplication, and division into the existing codebase of `main.py`. Then, ensure seamless integration with the overall application architecture and maintain consistency with coding standards.
```python
def add_numbers():
result = calculator.add_numbers(num1, num2)
return jsonify({'result': result}), 200
@ -106,6 +121,7 @@ def add_numbers():
if __name__ == '__main__':
app.run()
```""",
],
)
CODE_PLAN_AND_CHANGE_CONTEXT = """
@ -172,14 +188,16 @@ Role: You are a professional engineer; The main goal is to complete incremental
2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.
3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.
4. Follow design: YOU MUST FOLLOW "Data structures and interfaces". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.
5. Follow Code Plan And Change: If there is any Incremental Change that is marked by the git diff format using '+' and '-' for add/modify/delete code, or Legacy Code files contain "{filename} to be rewritten", you must merge it into the code file according to the plan.
5. Follow Code Plan And Change: If there is any "Incremental Change" that is marked by the git diff format with '+' and '-' symbols, or Legacy Code files contain "{filename} to be rewritten", you must merge it into the code file according to the "Development Plan".
6. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.
7. Before using a external variable/module, make sure you import it first.
8. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.
9. Attention: Retain details that are not related to incremental development but are important for maintaining the consistency and clarity of the old code.
"""
WRITE_CODE_PLAN_AND_CHANGE_NODE = ActionNode.from_children("WriteCodePlanAndChange", [CODE_PLAN_AND_CHANGE])
CODE_PLAN_AND_CHANGE = [DEVELOPMENT_PLAN, INCREMENTAL_CHANGE]
WRITE_CODE_PLAN_AND_CHANGE_NODE = ActionNode.from_children("WriteCodePlanAndChange", CODE_PLAN_AND_CHANGE)
class WriteCodePlanAndChange(Action):
@ -192,14 +210,14 @@ class WriteCodePlanAndChange(Action):
prd_doc = await self.repo.docs.prd.get(filename=self.i_context.prd_filename)
design_doc = await self.repo.docs.system_design.get(filename=self.i_context.design_filename)
task_doc = await self.repo.docs.task.get(filename=self.i_context.task_filename)
code_text = await self.get_old_codes()
context = CODE_PLAN_AND_CHANGE_CONTEXT.format(
requirement=self.i_context.requirement,
prd=prd_doc.content,
design=design_doc.content,
task=task_doc.content,
code=code_text,
code=await self.get_old_codes(),
)
logger.info("Writing code plan and change..")
return await WRITE_CODE_PLAN_AND_CHANGE_NODE.fill(context=context, llm=self.llm, schema="json")
async def get_old_codes(self) -> str:

View file

@ -56,7 +56,7 @@ REFINED_PRODUCT_GOALS = ActionNode(
key="Refined Product Goals",
expected_type=List[str],
instruction="Update and expand the original product goals to reflect the evolving needs due to incremental "
"development.Ensure that the refined goals align with the current project direction and contribute to its success.",
"development. Ensure that the refined goals align with the current project direction and contribute to its success.",
example=[
"Enhance user engagement through new features",
"Optimize performance for scalability",

View file

@ -204,7 +204,6 @@ class Engineer(Role):
async def _act_code_plan_and_change(self):
"""Write code plan and change that guides subsequent WriteCode and WriteCodeReview"""
logger.info("Writing code plan and change..")
node = await self.rc.todo.run()
code_plan_and_change = node.instruct_content.model_dump_json()
dependencies = {

View file

@ -133,6 +133,7 @@ class ProjectRepo(FileRepository):
code_files = self.with_src_path(path=git_workdir / git_workdir.name).srcs.all_files
if not code_files:
return False
return bool(code_files)
def with_src_path(self, path: str | Path) -> ProjectRepo:
try: