diff --git a/examples/exp_pool/init_exp_pool.py b/examples/exp_pool/init_exp_pool.py index 1601abe0b..42edd9637 100644 --- a/examples/exp_pool/init_exp_pool.py +++ b/examples/exp_pool/init_exp_pool.py @@ -8,7 +8,7 @@ import json from pathlib import Path from metagpt.const import EXAMPLE_DATA_PATH -from metagpt.exp_pool import exp_manager +from metagpt.exp_pool import get_exp_manager from metagpt.exp_pool.schema import EntryType, Experience, Metric, Score from metagpt.logs import logger from metagpt.utils.common import aread @@ -45,10 +45,10 @@ async def add_exp(req: str, resp: str, tag: str, metric: Metric = None): tag=tag, metric=metric or Metric(score=Score(val=10, reason="Manual")), ) - + exp_manager = get_exp_manager() exp_manager.config.exp_pool.enable_write = True exp_manager.create_exp(exp) - logger.info(f"New experience created for the request `{req[:10]}`.") + logger.info(f"New experience created for the request `{req[:10] if len(req) > 10 else req}`.") async def add_exps(exps: list, tag: str): @@ -79,7 +79,7 @@ async def add_exps_from_file(tag: str, filepath: Path): def query_exps_count(): """Queries and logs the total count of experiences in the pool.""" - + exp_manager = get_exp_manager() count = exp_manager.get_exps_count() logger.info(f"Experiences Count: {count}") diff --git a/examples/exp_pool/manager.py b/examples/exp_pool/manager.py index ae998214a..c9ec46da5 100644 --- a/examples/exp_pool/manager.py +++ b/examples/exp_pool/manager.py @@ -6,7 +6,7 @@ This script creates a new experience, logs its creation, and then queries for ex import asyncio -from metagpt.exp_pool import exp_manager +from metagpt.exp_pool import get_exp_manager from metagpt.exp_pool.schema import EntryType, Experience from metagpt.logs import logger @@ -18,6 +18,7 @@ async def main(): # Add the new experience exp = Experience(req=req, resp=resp, entry_type=EntryType.MANUAL) + exp_manager = get_exp_manager() exp_manager.create_exp(exp) logger.info(f"New experience created for the request `{req}`.") diff --git a/metagpt/actions/design_api.py b/metagpt/actions/design_api.py index 6ae21ebd9..4476e7c0a 100644 --- a/metagpt/actions/design_api.py +++ b/metagpt/actions/design_api.py @@ -32,6 +32,7 @@ from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import ( aread, awrite, + rectify_pathname, save_json_to_markdown, to_markdown_code_block, ) @@ -262,10 +263,10 @@ class WriteDesign(Action): ) if not output_pathname: - output_pathname = Path(output_pathname) / "docs" / "sytem_design.json" + output_pathname = Path(output_pathname) / "docs" / "system_design.json" elif not Path(output_pathname).is_absolute(): output_pathname = self.config.workspace.path / output_pathname - output_pathname = Path(output_pathname) + output_pathname = rectify_pathname(path=output_pathname, default_filename="system_design.json") await awrite(filename=output_pathname, data=design.content) output_filename = output_pathname.parent / f"{output_pathname.stem}-class-diagram" await self._save_data_api_design(design_doc=design, output_filename=output_filename) diff --git a/metagpt/actions/project_management.py b/metagpt/actions/project_management.py index b9d3bc3ba..2d54ffe08 100644 --- a/metagpt/actions/project_management.py +++ b/metagpt/actions/project_management.py @@ -26,6 +26,7 @@ from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import ( aread, awrite, + rectify_pathname, save_json_to_markdown, to_markdown_code_block, ) @@ -191,7 +192,7 @@ class WriteTasks(Action): output_pathname = Path(output_pathname) / "docs" / "project_schedule.json" elif not Path(output_pathname).is_absolute(): output_pathname = self.config.workspace.path / output_pathname - output_pathname = Path(output_pathname) + output_pathname = rectify_pathname(path=output_pathname, default_filename="project_schedule.json") await awrite(filename=output_pathname, data=file_content) md_output_filename = output_pathname.with_suffix(".md") await save_json_to_markdown(content=file_content, output_filename=md_output_filename) diff --git a/metagpt/actions/write_prd.py b/metagpt/actions/write_prd.py index e10e7333a..4b2015145 100644 --- a/metagpt/actions/write_prd.py +++ b/metagpt/actions/write_prd.py @@ -43,6 +43,7 @@ from metagpt.utils.common import ( CodeParser, aread, awrite, + rectify_pathname, save_json_to_markdown, to_markdown_code_block, ) @@ -314,7 +315,7 @@ class WritePRD(Action): output_pathname = self.config.workspace.path / "docs" / "prd.json" elif not Path(output_pathname).is_absolute(): output_pathname = self.config.workspace.path / output_pathname - output_pathname = Path(output_pathname) + output_pathname = rectify_pathname(path=output_pathname, default_filename="prd.json") await awrite(filename=output_pathname, data=new_prd.content) competitive_analysis_filename = output_pathname.parent / f"{output_pathname.stem}-competitive-analysis" await self._save_competitive_analysis(prd_doc=new_prd, output_filename=Path(competitive_analysis_filename)) diff --git a/metagpt/roles/di/team_leader.py b/metagpt/roles/di/team_leader.py index 4a39193a2..97100f295 100644 --- a/metagpt/roles/di/team_leader.py +++ b/metagpt/roles/di/team_leader.py @@ -47,12 +47,12 @@ class TeamLeader(RoleZero): # continue team_info += f"{role.name}: {role.profile}, {role.goal}\n" return team_info - + def _get_prefix(self) -> str: role_info = super()._get_prefix() team_info = self._get_team_info() return TL_INFO.format(role_info=role_info, team_info=team_info) - + async def _think(self) -> bool: self.instruction = TL_INSTRUCTION.format(team_info=self._get_team_info()) return await super()._think() diff --git a/metagpt/utils/common.py b/metagpt/utils/common.py index fa2f3cbbc..def127fc9 100644 --- a/metagpt/utils/common.py +++ b/metagpt/utils/common.py @@ -1118,3 +1118,25 @@ def log_time(method): return result return timeit_wrapper_async if iscoroutinefunction(method) else timeit_wrapper + + +def rectify_pathname(path: Union[str, Path], default_filename: str) -> Path: + """ + Rectifies the given path to ensure a valid output file path. + + If the given `path` is a directory, it creates the directory (if it doesn't exist) and appends the `default_filename` to it. If the `path` is a file path, it creates the parent directory (if it doesn't exist) and returns the `path`. + + Args: + path (Union[str, Path]): The input path, which can be a string or a `Path` object. + default_filename (str): The default filename to use if the `path` is a directory. + + Returns: + Path: The rectified output path. + """ + output_pathname = Path(path) + if output_pathname.is_dir(): + output_pathname.mkdir(parents=True, exist_ok=True) + output_pathname = output_pathname / default_filename + else: + output_pathname.parent.mkdir(parents=True, exist_ok=True) + return output_pathname