From 8e2c7c964f82ccb59eab5f0611070917c3a5e34e Mon Sep 17 00:00:00 2001 From: garylin2099 Date: Thu, 6 Jun 2024 10:41:49 +0800 Subject: [PATCH] provide example for running the whole software company; fix editor bug --- metagpt/tools/libs/editor.py | 2 +- .../environment/mgx_env/run_mgx_env.py | 26 ++++++++----- tests/metagpt/roles/di/run_architect.py | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 tests/metagpt/roles/di/run_architect.py diff --git a/metagpt/tools/libs/editor.py b/metagpt/tools/libs/editor.py index 9b36d5eea..23df02edd 100644 --- a/metagpt/tools/libs/editor.py +++ b/metagpt/tools/libs/editor.py @@ -27,7 +27,7 @@ class Editor: def write(self, path: str, content: str): """Write the whole content to a file. When used, make sure content arg contains the full content of the file.""" directory = os.path.dirname(path) - if not os.path.exists(directory): + if directory and not os.path.exists(directory): os.makedirs(directory) with open(path, "w", encoding="utf-8") as f: f.write(content) diff --git a/tests/metagpt/environment/mgx_env/run_mgx_env.py b/tests/metagpt/environment/mgx_env/run_mgx_env.py index 42f550ab6..0d5287412 100644 --- a/tests/metagpt/environment/mgx_env/run_mgx_env.py +++ b/tests/metagpt/environment/mgx_env/run_mgx_env.py @@ -5,19 +5,25 @@ import threading from metagpt.environment.mgx.mgx_env import MGXEnv from metagpt.roles import Architect, Engineer, ProductManager, ProjectManager from metagpt.roles.di.data_analyst import DataAnalyst +from metagpt.roles.di.engineer2 import Engineer2 from metagpt.roles.di.team_leader import TeamLeader from metagpt.schema import Message -async def main(requirement="", enable_human_input=False): - env = MGXEnv() +async def main(requirement="", enable_human_input=False, use_fixed_sop=False): + if use_fixed_sop: + engineer = Engineer(n_borg=5, use_code_review=False) + else: + engineer = Engineer2() + + env = MGXEnv(allow_bypass_team_leader=use_fixed_sop) env.add_roles( [ TeamLeader(), - ProductManager(), - Architect(), - ProjectManager(), - Engineer(n_borg=5, use_code_review=False), + ProductManager(use_fixed_sop=use_fixed_sop), + Architect(use_fixed_sop=use_fixed_sop), + ProjectManager(use_fixed_sop=use_fixed_sop), + engineer, # QaEngineer(), DataAnalyst(tools=[""]), ] @@ -52,8 +58,10 @@ def send_human_input(env): GAME_REQ = "create a 2048 game" +WEB_GAME_REQ = "Write a 2048 game using JavaScript without using any frameworks, user can play with keyboard." +WEB_GAME_REQ_DEPLOY = "Write a 2048 game using JavaScript without using any frameworks, user can play with keyboard. When finished, deploy the game to public at port 8090." SIMPLE_REQ = "print statistic summary of sklearn iris dataset" -WINE_REQ = "Run data analysis on sklearn Wine recognition dataset, include a plot, and train a model to predict wine class (20% as validation), and show validation accuracy." +WINE_REQ = "Run data analysis on sklearn Wine recognition dataset, and train a model to predict wine class (20% as validation), and show validation accuracy." PAPER_LIST_REQ = """ Get data from `paperlist` table in https://papercopilot.com/statistics/iclr-statistics/iclr-2024-statistics/, and save it to a csv file. paper title must include `multiagent` or `large language model`. *notice: print key variables* @@ -67,7 +75,7 @@ data_path = "data/titanic" train_path = f"{data_path}/split_train.csv" eval_path = f"{data_path}/split_eval.csv" TITANIC_REQ = f"This is a titanic passenger survival dataset, your goal is to predict passenger survival outcome. The target column is Survived. Perform data analysis, data preprocessing, feature engineering, and modeling to predict the target. Report accuracy on the eval data. Train data path: '{train_path}', eval data path: '{eval_path}'." -FIX_ISSUE = """ +FIX_ISSUE1 = """ Write a fix for this issue: https://github.com/langchain-ai/langchain/issues/20453, you can fix it on this repo https://github.com/garylin2099/langchain, checkout a branch named test-fix, commit your changes, push, and create a PR to the master branch of https://github.com/iorisa/langchain @@ -98,4 +106,4 @@ if __name__ == "__main__": os.environ["access_token"] = "ghp_xxx" # NOTE: Change the requirement to the one you want to test # Set enable_human_input to True if you want to simulate sending messages in chatbox - asyncio.run(main(requirement=FIX_ISSUE, enable_human_input=False)) + asyncio.run(main(requirement=GAME_REQ, enable_human_input=False, use_fixed_sop=False)) diff --git a/tests/metagpt/roles/di/run_architect.py b/tests/metagpt/roles/di/run_architect.py new file mode 100644 index 000000000..e615af4eb --- /dev/null +++ b/tests/metagpt/roles/di/run_architect.py @@ -0,0 +1,38 @@ +import asyncio +import os + +from metagpt.roles.architect import Architect + +DESIGN_DOC_SNAKE = """ +{ + "Implementation approach": "We will use the Pygame library to create the CLI-based snake game. Pygame is a set of Python modules designed for writing video games, which will help us handle graphics, sound, and input. The game will be structured into different modules to handle the main game loop, snake movement, food generation, collision detection, and user interface. We will ensure the game is engaging and responsive by optimizing the game loop and input handling. The score display and different speed levels will be implemented to enhance the user experience.", + "File list": [ + "main.py", + "game.py", + "snake.py", + "food.py", + "ui.py" + ], + "Data structures and interfaces": "\nclassDiagram\n class Main {\n +main() void\n }\n class Game {\n -Snake snake\n -Food food\n -int score\n -int speed\n +__init__(speed: int)\n +run() void\n +restart() void\n +update_score() void\n }\n class Snake {\n -list body\n -str direction\n +__init__()\n +move() void\n +change_direction(new_direction: str) void\n +check_collision() bool\n +grow() void\n }\n class Food {\n -tuple position\n +__init__()\n +generate_new_position() void\n }\n class UI {\n +display_score(score: int) void\n +display_game_over() void\n +display_game(snake: Snake, food: Food) void\n }\n Main --> Game\n Game --> Snake\n Game --> Food\n Game --> UI\n", + "Program call flow": "\nsequenceDiagram\n participant M as Main\n participant G as Game\n participant S as Snake\n participant F as Food\n participant U as UI\n M->>G: __init__(speed)\n M->>G: run()\n G->>S: __init__()\n G->>F: __init__()\n loop Game Loop\n G->>S: move()\n G->>S: check_collision()\n alt Collision Detected\n G->>G: restart()\n G->>U: display_game_over()\n else No Collision\n G->>F: generate_new_position()\n G->>S: grow()\n G->>G: update_score()\n G->>U: display_score(score)\n end\n G->>U: display_game(snake, food)\n end\n", + "Anything UNCLEAR": "Currently, all aspects of the project are clear." +} +""" + +WRITE_SNAKE = """Write a system design for a cli snake game with pygame""" + +REWRITE_SNAKE = """Rewrite the system design at temp_design.json, add a web UI""" + +CASUAL_CHAT = """What's your name?""" + + +async def main(requirement): + with open("temp_design.json", "w") as f: + f.write(DESIGN_DOC_SNAKE) + architect = Architect() + await architect.run(requirement) + os.remove("temp_design.json") + + +if __name__ == "__main__": + asyncio.run(main(WRITE_SNAKE))