From 2ec2e71c4d3013635574785072aa69ba7ac7cd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 8 Jan 2024 17:38:53 +0800 Subject: [PATCH 01/15] fixbug: rename folder does not work in windows os --- metagpt/roles/engineer.py | 3 ++- metagpt/utils/git_repository.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/metagpt/roles/engineer.py b/metagpt/roles/engineer.py index e05e69cbb..b2a909400 100644 --- a/metagpt/roles/engineer.py +++ b/metagpt/roles/engineer.py @@ -204,7 +204,8 @@ class Engineer(Role): async def _think(self) -> Action | None: if not CONFIG.src_workspace: - CONFIG.src_workspace = CONFIG.git_repo.workdir / CONFIG.git_repo.workdir.name + project_name = CONFIG.project_name or CONFIG.git_repo.workdir.name + CONFIG.src_workspace = CONFIG.git_repo.workdir / project_name write_code_filters = any_to_str_set([WriteTasks, SummarizeCode, FixBug]) summarize_code_filters = any_to_str_set([WriteCode, WriteCodeReview]) if not self.rc.news: diff --git a/metagpt/utils/git_repository.py b/metagpt/utils/git_repository.py index e9855df05..4feed89d5 100644 --- a/metagpt/utils/git_repository.py +++ b/metagpt/utils/git_repository.py @@ -199,10 +199,17 @@ class GitRepository: if new_path.exists(): logger.info(f"Delete directory {str(new_path)}") shutil.rmtree(new_path) + if new_path.exists(): # Recheck for windows os + logger.warning(f"Failed to delete directory {str(new_path)}") + return try: shutil.move(src=str(self.workdir), dst=str(new_path)) except Exception as e: logger.warning(f"Move {str(self.workdir)} to {str(new_path)} error: {e}") + finally: + if not new_path.exists(): # Recheck for windows os + logger.warning(f"Failed to move {str(self.workdir)} to {str(new_path)}") + return logger.info(f"Rename directory {str(self.workdir)} to {str(new_path)}") self._repository = Repo(new_path) self._gitignore_rules = parse_gitignore(full_path=str(new_path / ".gitignore")) From 12ac57af4c66bfb0e92e36120d65eccc9af77e2d Mon Sep 17 00:00:00 2001 From: shenchucheng Date: Mon, 8 Jan 2024 20:54:52 +0800 Subject: [PATCH 02/15] release 0.6.3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 10938c769..d997b5f62 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ extras_require["dev"] = (["pylint~=3.0.3", "black~=23.3.0", "isort~=5.12.0", "pr setup( name="metagpt", - version="0.6.2", + version="0.6.3", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", From 0788080e205a5437f1974f77b4a203f0b57d1f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Wed, 10 Jan 2024 19:51:38 +0800 Subject: [PATCH 03/15] fixbug: fix todo_description --- metagpt/roles/role.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 3bcd600fc..3d5e55057 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -504,7 +504,13 @@ class Role(SerializationMixin, is_polymorphic_base=True): @property def todo(self) -> str: - """AgentStore uses this attribute to display to the user what actions the current role should take.""" + """ + AgentStore uses this attribute to display to the user what actions the current role should take. + """ + if self.rc.todo: + if self.rc.todo.desc: + return self.rc.todo.desc + return any_to_name(self.rc.todo) if self.actions: return any_to_name(self.actions[0]) return "" From cf2366b72ce2f5fcc8f5a283733eb48f35cf1c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Wed, 10 Jan 2024 21:13:36 +0800 Subject: [PATCH 04/15] feat: +ver --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d997b5f62..ea84fe299 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ extras_require["dev"] = (["pylint~=3.0.3", "black~=23.3.0", "isort~=5.12.0", "pr setup( name="metagpt", - version="0.6.3", + version="0.6.4", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", From 29d8326c06899535bb2d8953246aa30466b8f72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Wed, 10 Jan 2024 21:13:36 +0800 Subject: [PATCH 05/15] feat: +ver feat: Moderation + llm arg feat: +log --- metagpt/document_store/faiss_store.py | 6 +++++- metagpt/tools/moderation.py | 4 ++-- requirements.txt | 2 +- setup.py | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/metagpt/document_store/faiss_store.py b/metagpt/document_store/faiss_store.py index 1271f1c23..6f97141c2 100644 --- a/metagpt/document_store/faiss_store.py +++ b/metagpt/document_store/faiss_store.py @@ -40,7 +40,11 @@ class FaissStore(LocalStore): return FAISS.load_local(self.raw_data_path.parent, self.embedding, self.fname) def _write(self, docs, metadatas): - store = FAISS.from_texts(docs, self.embedding, metadatas=metadatas) + try: + store = FAISS.from_texts(docs, self.embedding, metadatas=metadatas) + except Exception as e: + logger.error(f"Failed to write. error: {e}") + raise e return store def persist(self): diff --git a/metagpt/tools/moderation.py b/metagpt/tools/moderation.py index cda164ec5..8effc0e8b 100644 --- a/metagpt/tools/moderation.py +++ b/metagpt/tools/moderation.py @@ -11,8 +11,8 @@ from metagpt.llm import LLM class Moderation: - def __init__(self): - self.llm = LLM() + def __init__(self, llm=None): + self.llm = llm or LLM() def handle_moderation_results(self, results): resp = [] diff --git a/requirements.txt b/requirements.txt index 0a54236f0..f8e4d2585 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ lancedb==0.4.0 langchain==0.0.352 loguru==0.6.0 meilisearch==0.21.0 -numpy==1.24.3 +numpy>=1.24.3 openai==1.6.0 openpyxl beautifulsoup4==4.12.2 diff --git a/setup.py b/setup.py index d997b5f62..ea84fe299 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ extras_require["dev"] = (["pylint~=3.0.3", "black~=23.3.0", "isort~=5.12.0", "pr setup( name="metagpt", - version="0.6.3", + version="0.6.4", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", From b275f1a3f8c33ea5832d1656e26e9e4b8831b631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Tue, 16 Jan 2024 10:45:01 +0800 Subject: [PATCH 06/15] feat: +ver fixbug: RPC think --- metagpt/roles/role.py | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 3d5e55057..36d007f3b 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -494,6 +494,7 @@ class Role(SerializationMixin, is_polymorphic_base=True): async def think(self) -> Action: """The exported `think` function""" + await self._observe() await self._think() return self.rc.todo diff --git a/setup.py b/setup.py index ea84fe299..ca8bb3980 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ extras_require["dev"] = (["pylint~=3.0.3", "black~=23.3.0", "isort~=5.12.0", "pr setup( name="metagpt", - version="0.6.4", + version="0.6.5", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", From 2b522ffccbf48a8f9295793960e1ea02bdbcd927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Wed, 17 Jan 2024 11:55:09 +0800 Subject: [PATCH 07/15] fixbug: engineer action_description --- metagpt/roles/engineer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/roles/engineer.py b/metagpt/roles/engineer.py index c83a776c2..7c91ec6f9 100644 --- a/metagpt/roles/engineer.py +++ b/metagpt/roles/engineer.py @@ -297,6 +297,6 @@ class Engineer(Role): self.set_todo(self.summarize_todos[0]) @property - def todo(self) -> str: + def action_description(self) -> str: """AgentStore uses this attribute to display to the user what actions the current role should take.""" return self.next_todo_action From 3486b9d1d3e248bda33fee0a73629d4e92f1476c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Fri, 19 Jan 2024 11:20:05 +0800 Subject: [PATCH 08/15] feat: Maintain the original exceptions of OpenAI and HTTPX during exception handling. --- metagpt/utils/common.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/metagpt/utils/common.py b/metagpt/utils/common.py index c7751c2af..3295603b4 100644 --- a/metagpt/utils/common.py +++ b/metagpt/utils/common.py @@ -501,7 +501,7 @@ def role_raise_decorator(func): self.rc.memory.delete(self.latest_observed_msg) # raise again to make it captured outside raise Exception(format_trackback_info(limit=None)) - except Exception: + except Exception as e: if self.latest_observed_msg: logger.warning( "There is a exception in role's execution, in order to resume, " @@ -510,6 +510,11 @@ def role_raise_decorator(func): # remove role newest observed msg to make it observed again self.rc.memory.delete(self.latest_observed_msg) # raise again to make it captured outside + last_error = e.last_attempt._exception + name = any_to_str(last_error) + if re.match(r"^openai\.", name) or re.match(r"^httpx\.", name): + raise last_error + raise Exception(format_trackback_info(limit=None)) return wrapper From b78cc3c1cab491a81bc59ddeff2f2ba96d3bc650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Fri, 19 Jan 2024 11:49:35 +0800 Subject: [PATCH 09/15] feat: Maintain the original exceptions of OpenAI and HTTPX during exception handling. --- metagpt/utils/common.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/metagpt/utils/common.py b/metagpt/utils/common.py index 3295603b4..3102158c2 100644 --- a/metagpt/utils/common.py +++ b/metagpt/utils/common.py @@ -28,7 +28,7 @@ from typing import Any, List, Tuple, Union import aiofiles import loguru from pydantic_core import to_jsonable_python -from tenacity import RetryCallState, _utils +from tenacity import RetryCallState, RetryError, _utils from metagpt.const import MESSAGE_ROUTE_TO_ALL from metagpt.logs import logger @@ -510,10 +510,11 @@ def role_raise_decorator(func): # remove role newest observed msg to make it observed again self.rc.memory.delete(self.latest_observed_msg) # raise again to make it captured outside - last_error = e.last_attempt._exception - name = any_to_str(last_error) - if re.match(r"^openai\.", name) or re.match(r"^httpx\.", name): - raise last_error + if isinstance(e, RetryError): + last_error = e.last_attempt._exception + name = any_to_str(last_error) + if re.match(r"^openai\.", name) or re.match(r"^httpx\.", name): + raise last_error raise Exception(format_trackback_info(limit=None)) From cd919aa71bf9e1305edd9515025931acef6a9dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Fri, 19 Jan 2024 11:51:02 +0800 Subject: [PATCH 10/15] feat: +ver --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ca8bb3980..cc8112ba9 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ extras_require["dev"] = (["pylint~=3.0.3", "black~=23.3.0", "isort~=5.12.0", "pr setup( name="metagpt", - version="0.6.5", + version="0.6.6", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", From 8b84e269a1e803b852e7d8e319f8579e6b10de4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 22 Jan 2024 10:30:38 +0800 Subject: [PATCH 11/15] feat: remove error print --- metagpt/document_store/faiss_store.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/metagpt/document_store/faiss_store.py b/metagpt/document_store/faiss_store.py index 54585dcfc..2359917d5 100644 --- a/metagpt/document_store/faiss_store.py +++ b/metagpt/document_store/faiss_store.py @@ -37,11 +37,7 @@ class FaissStore(LocalStore): return FAISS.load_local(self.raw_data_path.parent, self.embedding, self.fname) def _write(self, docs, metadatas): - try: - store = FAISS.from_texts(docs, self.embedding, metadatas=metadatas) - except Exception as e: - logger.error(f"Failed to write. error: {e}") - raise e + store = FAISS.from_texts(docs, self.embedding, metadatas=metadatas) return store def persist(self): From bda2e06d368e1c80306d441a7ce80da57d5d62f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 22 Jan 2024 10:50:32 +0800 Subject: [PATCH 12/15] feat: +note --- metagpt/roles/role.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index c363d332c..28d2fe693 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -523,19 +523,26 @@ class Role(SerializationMixin, ContextMixin, BaseModel): return not self.rc.news and not self.rc.todo and self.rc.msg_buffer.empty() async def think(self) -> Action: - """The exported `think` function""" - await self._observe() + """ + Export SDK API, used by AgentStore RPC. + The exported `think` function + """ + await self._observe() # For compatibility with the old version of the Agent. await self._think() return self.rc.todo async def act(self) -> ActionOutput: - """The exported `act` function""" + """ + Export SDK API, used by AgentStore RPC. + The exported `act` function + """ msg = await self._act() return ActionOutput(content=msg.content, instruct_content=msg.instruct_content) @property def action_description(self) -> str: """ + Export SDK API, used by AgentStore RPC. AgentStore uses this attribute to display to the user what actions the current role should take. """ if self.rc.todo: From 525d94317cdcfb191280b2ac8485edc500e2b8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 22 Jan 2024 10:52:36 +0800 Subject: [PATCH 13/15] feat: +note --- metagpt/roles/role.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 28d2fe693..53798f385 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -524,7 +524,7 @@ class Role(SerializationMixin, ContextMixin, BaseModel): async def think(self) -> Action: """ - Export SDK API, used by AgentStore RPC. + Export SDK API, used by AgentStore RPC and Agent. The exported `think` function """ await self._observe() # For compatibility with the old version of the Agent. @@ -533,7 +533,7 @@ class Role(SerializationMixin, ContextMixin, BaseModel): async def act(self) -> ActionOutput: """ - Export SDK API, used by AgentStore RPC. + Export SDK API, used by AgentStore RPC and Agent. The exported `act` function """ msg = await self._act() @@ -542,7 +542,7 @@ class Role(SerializationMixin, ContextMixin, BaseModel): @property def action_description(self) -> str: """ - Export SDK API, used by AgentStore RPC. + Export SDK API, used by AgentStore RPC and Agent. AgentStore uses this attribute to display to the user what actions the current role should take. """ if self.rc.todo: From f15b772d77d76a92a8214cf2b5d4f071de9d8a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 22 Jan 2024 10:54:15 +0800 Subject: [PATCH 14/15] feat: +note --- metagpt/roles/role.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 53798f385..dba14bb72 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -524,7 +524,7 @@ class Role(SerializationMixin, ContextMixin, BaseModel): async def think(self) -> Action: """ - Export SDK API, used by AgentStore RPC and Agent. + Export SDK API, used by AgentStore RPC. The exported `think` function """ await self._observe() # For compatibility with the old version of the Agent. @@ -533,7 +533,7 @@ class Role(SerializationMixin, ContextMixin, BaseModel): async def act(self) -> ActionOutput: """ - Export SDK API, used by AgentStore RPC and Agent. + Export SDK API, used by AgentStore RPC. The exported `act` function """ msg = await self._act() From 85465fe500121f65b9c38312034926b7754a0a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 22 Jan 2024 11:04:03 +0800 Subject: [PATCH 15/15] feat: +note --- metagpt/roles/role.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index dba14bb72..3747072f1 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -544,6 +544,8 @@ class Role(SerializationMixin, ContextMixin, BaseModel): """ Export SDK API, used by AgentStore RPC and Agent. AgentStore uses this attribute to display to the user what actions the current role should take. + `Role` provides the default property, and this property should be overridden by children classes if necessary, + as demonstrated by the `Engineer` class. """ if self.rc.todo: if self.rc.todo.desc: