diff --git a/metagpt/environment.py b/metagpt/environment.py index 42f7ef5bf..6511647ef 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -33,7 +33,7 @@ class Environment(BaseModel): desc: str = Field(default="") # 环境描述 roles: dict[str, SerializeAsAny[Role]] = Field(default_factory=dict, validate_default=True) - members: dict[Role, Set] = Field(default_factory=dict, exclude=True) + member_addrs: dict[Role, Set] = Field(default_factory=dict, exclude=True) history: str = "" # For debug context: Context = Field(default_factory=Context, exclude=True) @@ -51,7 +51,7 @@ class Environment(BaseModel): "role_class": role.__class__.__name__, "module_name": role.__module__, "role_name": role.name, - "role_sub_tags": list(self.members.get(role)), + "role_sub_tags": list(self.member_addrs.get(role)), } ) role.serialize(stg_path=stg_path.joinpath(f"roles/{role.__class__.__name__}_{role.name}")) diff --git a/metagpt/startup.py b/metagpt/startup.py index e7ae2b09e..cacf68113 100644 --- a/metagpt/startup.py +++ b/metagpt/startup.py @@ -10,31 +10,21 @@ from metagpt.config2 import config app = typer.Typer(add_completion=False) -@app.command() -def startup( - idea: str = typer.Argument(..., help="Your innovative idea, such as 'Create a 2048 game.'"), - investment: float = typer.Option(default=3.0, help="Dollar amount to invest in the AI company."), - n_round: int = typer.Option(default=5, help="Number of rounds for the simulation."), - code_review: bool = typer.Option(default=True, help="Whether to use code review."), - run_tests: bool = typer.Option(default=False, help="Whether to enable QA for adding & running tests."), - implement: bool = typer.Option(default=True, help="Enable or disable code implementation."), - project_name: str = typer.Option(default="", help="Unique project name, such as 'game_2048'."), - inc: bool = typer.Option(default=False, help="Incremental mode. Use it to coop with existing repo."), - project_path: str = typer.Option( - default="", - help="Specify the directory path of the old version project to fulfill the incremental requirements.", - ), - reqa_file: str = typer.Option( - default="", help="Specify the source file name for rewriting the quality assurance code." - ), - max_auto_summarize_code: int = typer.Option( - default=0, - help="The maximum number of times the 'SummarizeCode' action is automatically invoked, with -1 indicating " - "unlimited. This parameter is used for debugging the workflow.", - ), - recover_path: str = typer.Option(default=None, help="recover the project from existing serialized storage"), +def generate_repo( + idea, + investment, + n_round, + code_review, + run_tests, + implement, + project_name, + inc, + project_path, + reqa_file, + max_auto_summarize_code, + recover_path, ): - """Run a startup. Be a boss.""" + """Run the startup logic. Can be called from CLI or other Python scripts.""" from metagpt.roles import ( Architect, Engineer, @@ -62,18 +52,58 @@ def startup( if run_tests: company.hire([QaEngineer()]) else: - # # stg_path = SERDESER_PATH.joinpath("team") stg_path = Path(recover_path) if not stg_path.exists() or not str(stg_path).endswith("team"): raise FileNotFoundError(f"{recover_path} not exists or not endswith `team`") company = Team.deserialize(stg_path=stg_path) - idea = company.idea # use original idea + idea = company.idea company.invest(investment) company.run_project(idea) asyncio.run(company.run(n_round=n_round)) +@app.command() +def startup( + idea: str = typer.Argument(..., help="Your innovative idea, such as 'Create a 2048 game.'"), + investment: float = typer.Option(default=3.0, help="Dollar amount to invest in the AI company."), + n_round: int = typer.Option(default=5, help="Number of rounds for the simulation."), + code_review: bool = typer.Option(default=True, help="Whether to use code review."), + run_tests: bool = typer.Option(default=False, help="Whether to enable QA for adding & running tests."), + implement: bool = typer.Option(default=True, help="Enable or disable code implementation."), + project_name: str = typer.Option(default="", help="Unique project name, such as 'game_2048'."), + inc: bool = typer.Option(default=False, help="Incremental mode. Use it to coop with existing repo."), + project_path: str = typer.Option( + default="", + help="Specify the directory path of the old version project to fulfill the incremental requirements.", + ), + reqa_file: str = typer.Option( + default="", help="Specify the source file name for rewriting the quality assurance code." + ), + max_auto_summarize_code: int = typer.Option( + default=0, + help="The maximum number of times the 'SummarizeCode' action is automatically invoked, with -1 indicating " + "unlimited. This parameter is used for debugging the workflow.", + ), + recover_path: str = typer.Option(default=None, help="recover the project from existing serialized storage"), +): + """Run a startup. Be a boss.""" + return generate_repo( + idea, + investment, + n_round, + code_review, + run_tests, + implement, + project_name, + inc, + project_path, + reqa_file, + max_auto_summarize_code, + recover_path, + ) + + if __name__ == "__main__": app()