From a0b13c8e0ff4b4647585780f75644aff3b64471e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=A3=92=E6=A3=92?= Date: Thu, 23 Nov 2023 10:45:40 +0800 Subject: [PATCH] chore: change name. --- metagpt/actions/__init__.py | 8 ++++---- .../{code_executor.py => execute_code.py} | 15 ++++++++++----- metagpt/actions/{plan.py => write_plan.py} | 2 +- ...t_code_executor.py => test_execute_code.py} | 11 +++++------ .../actions/test_write_code_function.py | 18 +++++++++--------- .../{test_plan.py => test_write_plan.py} | 6 +++--- 6 files changed, 32 insertions(+), 28 deletions(-) rename metagpt/actions/{code_executor.py => execute_code.py} (92%) rename metagpt/actions/{plan.py => write_plan.py} (97%) rename tests/metagpt/actions/{test_code_executor.py => test_execute_code.py} (87%) rename tests/metagpt/actions/{test_plan.py => test_write_plan.py} (88%) diff --git a/metagpt/actions/__init__.py b/metagpt/actions/__init__.py index d0163c24e..ba2170cbd 100644 --- a/metagpt/actions/__init__.py +++ b/metagpt/actions/__init__.py @@ -23,9 +23,9 @@ from metagpt.actions.write_code_review import WriteCodeReview from metagpt.actions.write_prd import WritePRD from metagpt.actions.write_prd_review import WritePRDReview from metagpt.actions.write_test import WriteTest -from metagpt.actions.code_executor import PyCodeExecutor +from metagpt.actions.execute_code import ExecutePyCode from metagpt.actions.write_code_function import WriteCodeFunction -from metagpt.actions.plan import Plan +from metagpt.actions.write_plan import WritePlan class ActionType(Enum): @@ -48,9 +48,9 @@ class ActionType(Enum): COLLECT_LINKS = CollectLinks WEB_BROWSE_AND_SUMMARIZE = WebBrowseAndSummarize CONDUCT_RESEARCH = ConductResearch - PYCODE_EXECUTOR = PyCodeExecutor + EXECUTE_PYCODE = ExecutePyCode WRITE_CODE_FUNCTION = WriteCodeFunction - PLAN = Plan + WRITE_PLAN = WritePlan __all__ = [ diff --git a/metagpt/actions/code_executor.py b/metagpt/actions/execute_code.py similarity index 92% rename from metagpt/actions/code_executor.py rename to metagpt/actions/execute_code.py index 0b4f5171f..e80886c3e 100644 --- a/metagpt/actions/code_executor.py +++ b/metagpt/actions/execute_code.py @@ -18,7 +18,7 @@ from metagpt.actions import Action from metagpt.schema import Message -class CodeExecutor(ABC): +class ExecuteCode(ABC): @abstractmethod async def build(self): """build code executor""" @@ -40,7 +40,7 @@ class CodeExecutor(ABC): ... -class PyCodeExecutor(CodeExecutor, Action): +class ExecutePyCode(ExecuteCode, Action): """execute code, return result to llm, and display it.""" def __init__(self, name: str = "python_executor", context=None, llm=None): @@ -128,6 +128,7 @@ class PyCodeExecutor(CodeExecutor, Action): return False def _process_code(self, code: Union[str, Dict, Message], language: str = None) -> Tuple: + language = language or 'python' if isinstance(code, str) and Path(code).suffix in (".py", ".txt"): code = Path(code).read_text(encoding="utf-8") return code, language @@ -137,11 +138,15 @@ class PyCodeExecutor(CodeExecutor, Action): if isinstance(code, dict): assert "code" in code - assert "language" in code + if "language" not in code: + code['language'] = 'python' code, language = code["code"], code["language"] elif isinstance(code, Message): - assert "language" in code.content - code, language = code.content["code"], code.content["language"] + if isinstance(code.content, dict) and "language" not in code.content: + code.content["language"] = 'python' + code, language = code.content["code"], code.content["language"] + elif isinstance(code.content, str): + code, language = code.content, language else: raise ValueError(f"Not support code type {type(code).__name__}.") diff --git a/metagpt/actions/plan.py b/metagpt/actions/write_plan.py similarity index 97% rename from metagpt/actions/plan.py rename to metagpt/actions/write_plan.py index 8bc575992..96d15cb84 100644 --- a/metagpt/actions/plan.py +++ b/metagpt/actions/write_plan.py @@ -12,7 +12,7 @@ from metagpt.schema import Message from metagpt.utils.common import CodeParser -class Plan(Action): +class WritePlan(Action): def __init__(self, llm=None): super().__init__("", None, llm) diff --git a/tests/metagpt/actions/test_code_executor.py b/tests/metagpt/actions/test_execute_code.py similarity index 87% rename from tests/metagpt/actions/test_code_executor.py rename to tests/metagpt/actions/test_execute_code.py index d1833b48c..88c5adf18 100644 --- a/tests/metagpt/actions/test_code_executor.py +++ b/tests/metagpt/actions/test_execute_code.py @@ -1,25 +1,24 @@ import pytest -from metagpt.actions import PyCodeExecutor +from metagpt.actions import ExecutePyCode from metagpt.schema import Message @pytest.mark.asyncio async def test_code_running(): - pi = PyCodeExecutor() + pi = ExecutePyCode() output = await pi.run("print('hello world!')") assert output.state == "done" output = await pi.run({"code": "print('hello world!')", "language": "python"}) assert output.state == "done" code_msg = Message("print('hello world!')") - setattr(code_msg, "language", "python") output = await pi.run(code_msg) assert output.state == "done" @pytest.mark.asyncio async def test_split_code_running(): - pi = PyCodeExecutor() + pi = ExecutePyCode() output = await pi.run("x=1\ny=2") output = await pi.run("z=x+y") output = await pi.run("assert z==3") @@ -28,14 +27,14 @@ async def test_split_code_running(): @pytest.mark.asyncio async def test_execute_error(): - pi = PyCodeExecutor() + pi = ExecutePyCode() output = await pi.run("z=1/0") assert output.state == "error" @pytest.mark.asyncio async def test_plotting_code(): - pi = PyCodeExecutor() + pi = ExecutePyCode() code = """ import numpy as np import matplotlib.pyplot as plt diff --git a/tests/metagpt/actions/test_write_code_function.py b/tests/metagpt/actions/test_write_code_function.py index cac459380..4ff1a63c4 100644 --- a/tests/metagpt/actions/test_write_code_function.py +++ b/tests/metagpt/actions/test_write_code_function.py @@ -1,13 +1,13 @@ import pytest from metagpt.actions.write_code_function import WriteCodeFunction -from metagpt.actions.code_executor import PyCodeExecutor +from metagpt.actions.execute_code import ExecutePyCode @pytest.mark.asyncio async def test_write_code(): - coder = WriteCodeFunction() - code = await coder.run("Write a hello world code.") + write_code = WriteCodeFunction() + code = await write_code.run("Write a hello world code.") assert "language" in code.content assert "code" in code.content print(code) @@ -15,9 +15,9 @@ async def test_write_code(): @pytest.mark.asyncio async def test_write_code_by_list_prompt(): - coder = WriteCodeFunction() + write_code = WriteCodeFunction() msg = ["a=[1,2,5,10,-10]", "写出求a中最大值的代码python"] - code = await coder.run(msg) + code = await write_code.run(msg) assert "language" in code.content assert "code" in code.content print(code) @@ -25,17 +25,17 @@ async def test_write_code_by_list_prompt(): @pytest.mark.asyncio async def test_write_code_by_list_plan(): - coder = WriteCodeFunction() - executor = PyCodeExecutor() + write_code = WriteCodeFunction() + execute_code = ExecutePyCode() messages = [] plan = ["随机生成一个pandas DataFrame时间序列", "绘制这个时间序列的直方图", "求均值"] for task in plan: print(f"\n任务: {task}\n\n") messages.append(task) - code = await coder.run(messages) + code = await write_code.run(messages) messages.append(code) assert "language" in code.content assert "code" in code.content - output = await executor.run(code) + output = await execute_code.run(code) print(f"\n[Output]: 任务{task}的执行结果是: \n{output}\n") messages.append(output) diff --git a/tests/metagpt/actions/test_plan.py b/tests/metagpt/actions/test_write_plan.py similarity index 88% rename from tests/metagpt/actions/test_plan.py rename to tests/metagpt/actions/test_write_plan.py index 1b1b90513..2bf200ab3 100644 --- a/tests/metagpt/actions/test_plan.py +++ b/tests/metagpt/actions/test_write_plan.py @@ -1,13 +1,13 @@ import pytest -from metagpt.actions.plan import Plan +from metagpt.actions.write_plan import WritePlan @pytest.mark.asyncio async def test_plan(): - p = Plan() + p = WritePlan() task_desc = """Here’s some background information on Cyclistic, a bike-sharing company designing a marketing strategy aimed at converting casual riders into annual members: So far, Cyclistic’s marketing strategy has relied on building general awareness and engaging a wide range of consumers. group. One way to help achieve these goals is the flexibility of its pricing plans: one-way passes, full-day passes, and annual memberships. Customers who purchase a one-way or full-day pass are known as recreational riders. Customers purchasing an annual membership are Cyclistic members. I will provide you with a data sheet that records user behavior: '/Users/vicis/Downloads/202103-divvy-tripdata.csv""" rsp = await p.run(task_desc, role="data analyst") assert len(rsp.content) > 0 - assert rsp.sent_from == "Plan" + assert rsp.sent_from == "WritePlan" print(rsp)