From b187f80f30fa49a3ea10e7526414b2ddcab85c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E8=8C=82=E5=AE=87?= Date: Mon, 24 Jul 2023 14:21:18 +0800 Subject: [PATCH] save code --- metagpt/actions/write_code.py | 28 +++++++++------- metagpt/actions/write_code_review.py | 8 ++--- metagpt/roles/engineer.py | 33 ++++++++++--------- .../metagpt/actions/test_write_code_review.py | 30 ++++++++++------- 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/metagpt/actions/write_code.py b/metagpt/actions/write_code.py index 60d9b5e71..cc122ef7a 100644 --- a/metagpt/actions/write_code.py +++ b/metagpt/actions/write_code.py @@ -14,11 +14,12 @@ from metagpt.utils.common import CodeParser from tenacity import retry, stop_after_attempt, wait_fixed PROMPT_TEMPLATE = """ -# Context -{context} ------ NOTICE -1. Role: You are an 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) +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) +ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example". + +## 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. @@ -26,15 +27,20 @@ NOTICE 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. -## {filename}: Write code with triple quoto. Do your best to implement THIS ONLY ONE FILE. ONLY USE EXISTING API. IF NO API, IMPLEMENT IT. - +----- +# Context +{context} +----- +## Format example +----- +## Code: {filename} +```python +## {filename} +... +``` +----- """ -## {filename}: Please encapsulate your code within triple quotes. Focus your efforts on implementing ONLY WITHIN THIS FILE. Any class or function labeled as MISSING-DESIGN should be implemented IN THIS FILE ALONE. Do NOT make changes to any other files. -OUTPUT_MAPPING = { - "{filename}": (str, ...), -} - class WriteCode(Action): def __init__(self, name="WriteCode", context: list[Message] = None, llm=None): diff --git a/metagpt/actions/write_code_review.py b/metagpt/actions/write_code_review.py index 7d21b546a..1278d6a72 100644 --- a/metagpt/actions/write_code_review.py +++ b/metagpt/actions/write_code_review.py @@ -15,9 +15,9 @@ from tenacity import retry, stop_after_attempt, wait_fixed 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). -ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. AND '## ' SHOULD WRITE BEFORE the code and triple quote. Output format carefully referenced "Format example". +ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example". -## Code Review: Based on the following context and code, and flowing the check list, Provide key, clear, concise, and specific code modification suggestions, up to 5. +## 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? @@ -27,7 +27,7 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. AND '## ' SHOULD W 6. Check 5: Does the code have ? ``` -## Rewrite Code: {filename} Base on Code Review and the source code, rewrite code with triple quotes. Do your utmost to optimize THIS SINGLE FILE.Ensure that the functionality of the rewritten code is consistent with the "Data structures and interface definitions" and ensure the code is complete and do not omit anything. +## 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} @@ -56,12 +56,12 @@ FORMAT_EXAMPLE = """ ## Rewrite Code: {filename} ```python +## {filename} ... ``` """ - class WriteCodeReview(Action): def __init__(self, name="WriteCodeReview", context: list[Message] = None, llm=None): super().__init__(name, context, llm) diff --git a/metagpt/roles/engineer.py b/metagpt/roles/engineer.py index 7d48e7d01..fdbf829fc 100644 --- a/metagpt/roles/engineer.py +++ b/metagpt/roles/engineer.py @@ -150,37 +150,38 @@ class Engineer(Role): 1. Architect全部 2. ProjectManager全部 3. 是否需要其他代码(暂时需要)? - (目标是不需要。在任务拆分清楚后,根据设计思路,不需要其他代码也能够写清楚单个文件, - 如果不能则表示还需要在定义的更清晰,这个是代码能够写长的关键) + TODO:目标是不需要。在任务拆分清楚后,根据设计思路,不需要其他代码也能够写清楚单个文件,如果不能则表示还需要在定义的更清晰,这个是代码能够写长的关键 :return: """ for todo in self.todos: context = [] - msg = self._rc.memory.get_by_actions([WriteDesign, WriteTasks, WriteCodeReview]) + msg = self._rc.memory.get_by_actions([WriteDesign, WriteTasks, WriteCode]) for m in msg: context.append(m.content) context_str = "\n".join(context) - logger.debug(f'context: {context_str}') + # 编写code code_rsp = await WriteCode().run( context=context_str, filename=todo ) - try: - code = await WriteCodeReview().run( - context=context_str, - code=code_rsp, - filename=todo - ) - code_rsp = code - except Exception as e: - logger.error("code review failed!", e) - pass + # code review + if self.use_code_review: + try: + code = await WriteCodeReview().run( + context=context_str, + code=code_rsp, + filename=todo + ) + code_rsp = code + except Exception as e: + logger.error("code review failed!", e) + pass self.write_file(todo, code_rsp) - msg = Message(content=code_rsp, role=self.profile, cause_by=WriteCodeReview) + msg = Message(content=code_rsp, role=self.profile, cause_by=WriteCode) self._rc.memory.add(msg) logger.info(f'Done {self.get_workspace()} generating.') - msg = Message(content="all done.", role=self.profile, cause_by=type(WriteCode)) + msg = Message(content="all done.", role=self.profile, cause_by=WriteCode) return msg async def _act(self) -> Message: diff --git a/tests/metagpt/actions/test_write_code_review.py b/tests/metagpt/actions/test_write_code_review.py index dda33f903..10efa1ed2 100644 --- a/tests/metagpt/actions/test_write_code_review.py +++ b/tests/metagpt/actions/test_write_code_review.py @@ -13,23 +13,29 @@ from tests.metagpt.actions.mock import SEARCH_CODE_SAMPLE @pytest.mark.asyncio -async def test_write_code_review(): +async def test_write_code_review(capfd): code = """ def add(a, b): - return a + b + return a + """ - write_code_review = WriteCodeReview("write_code_review") + # write_code_review = WriteCodeReview("write_code_review") - review = await write_code_review.run(code) + code = await WriteCodeReview().run( + context="编写一个从a加b的函数,返回a+b", + code=code, + filename="math.py" + ) # 我们不能精确地预测生成的代码评审,但我们可以检查返回的是否为字符串 - assert isinstance(review, str) - assert len(review) > 0 + assert isinstance(code, str) + assert len(code) > 0 + captured = capfd.readouterr() + print(f"输出内容: {captured.out}") -@pytest.mark.asyncio -async def test_write_code_review_directly(): - code = SEARCH_CODE_SAMPLE - write_code_review = WriteCodeReview("write_code_review") - review = await write_code_review.run(code) - logger.info(review) +# @pytest.mark.asyncio +# async def test_write_code_review_directly(): +# code = SEARCH_CODE_SAMPLE +# write_code_review = WriteCodeReview("write_code_review") +# review = await write_code_review.run(code) +# logger.info(review)