diff --git a/README.md b/README.md index b3473a12c..b0faf85c7 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,8 @@ # MetaGPT: The Multi-Agent Framework

Software Company Multi-Role Schematic (Gradually Implementing)

- +## News +- Dec 15: v0.5.0 is released! We introduce **incremental development**, facilitating agents to build up larger projects on top of their previous efforts or exisiting human codebase. We also launch a whole collection of important features, including multilingual support (experimental), multiple programming languages support (experimental), incremental development (experimental), CLI support, pip support, enhanced code review, documentation mechanism, and optimized messaging mechanism! ## Install diff --git a/config/config.yaml b/config/config.yaml index 9a7207c1a..f547462ba 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -1,6 +1,9 @@ # DO NOT MODIFY THIS FILE, create a new key.yaml, define OPENAI_API_KEY. # The configuration of key.yaml has a higher priority and will not enter git +#### Project Path Setting +# WORKSPACE_PATH: "Path for placing output files" + #### if OpenAI ## The official OPENAI_API_BASE is https://api.openai.com/v1 ## If the official OPENAI_API_BASE is not available, we recommend using the [openai-forward](https://github.com/beidongjiedeguang/openai-forward). diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index afc9ff445..3cb03f374 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -30,10 +30,10 @@ ### Tasks 4. Complete the design and implementation of module breakdown 5. Support various modes of memory: clearly distinguish between long-term and short-term memory 6. Perfect the test role, and carry out necessary interactions with humans - 7. Allowing natural communication between roles (expected v0.5.0) + 7. ~~Allowing natural communication between roles~~ (v0.5.0) 8. Implement SkillManager and the process of incremental Skill learning (experimentation done with game agents) 9. Automatically get RPM and configure it by calling the corresponding openai page, so that each key does not need to be manually configured - 10. IMPORTANT: Support incremental development (expected v0.5.0) + 10. ~~IMPORTANT: Support incremental development~~ (v0.5.0) 3. Strategies 1. Support ReAct strategy (experimentation done with game agents) 2. Support CoT strategy (experimentation done with game agents) @@ -45,8 +45,8 @@ ### Tasks 2. Implementation: Knowledge search, supporting 10+ data formats 3. Implementation: Data EDA (expected v0.6.0) 4. Implementation: Review - 5. Implementation: Add Document (expected v0.5.0) - 6. Implementation: Delete Document (expected v0.5.0) + 5. ~~Implementation~~: Add Document (v0.5.0) + 6. ~~Implementation~~: Delete Document (v0.5.0) 7. Implementation: Self-training 8. ~~Implementation: DebugError~~ (v0.2.1) 9. Implementation: Generate reliable unit tests based on YAPI diff --git a/metagpt/config.py b/metagpt/config.py index a0d61b39f..d4e85ca7b 100644 --- a/metagpt/config.py +++ b/metagpt/config.py @@ -55,6 +55,8 @@ class Config(metaclass=Singleton): default_yaml_file = METAGPT_ROOT / "config/config.yaml" def __init__(self, yaml_file=default_yaml_file): + + golbal_options = OPTIONS.get() # cli paras self.project_path = "" self.project_name = "" @@ -64,6 +66,7 @@ class Config(metaclass=Singleton): self._init_with_config_files_and_env(yaml_file) self._update() + golbal_options.update(OPTIONS.get()) logger.debug("Config loading done.") logger.info(f"OpenAI API Model: {self.openai_api_model}") diff --git a/metagpt/const.py b/metagpt/const.py index f6f64a27d..10de0ff66 100644 --- a/metagpt/const.py +++ b/metagpt/const.py @@ -17,12 +17,18 @@ from loguru import logger import metagpt -OPTIONS = contextvars.ContextVar("OPTIONS") +OPTIONS = contextvars.ContextVar("OPTIONS", default={}) def get_metagpt_package_root(): """Get the root directory of the installed package.""" package_root = Path(metagpt.__file__).parent.parent + for i in (".git", ".project_root", ".gitignore"): + if (package_root / i).exists(): + break + else: + package_root = Path.cwd() + logger.info(f"Package root set to {str(package_root)}") return package_root diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index b07541b09..48688ad5f 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -25,7 +25,7 @@ from typing import Iterable, Set, Type from pydantic import BaseModel, Field -from metagpt.actions import Action, ActionOutput +from metagpt.actions import Action, ActionOutput, UserRequirement from metagpt.actions.action_node import ActionNode from metagpt.llm import LLM, HumanProvider from metagpt.logs import logger @@ -138,7 +138,7 @@ class Role: self._states = [] self._actions = [] self._role_id = str(self._setting) - self._rc = RoleContext() + self._rc = RoleContext(watch={any_to_str(UserRequirement)}) self._subscription = {any_to_str(self), name} if name else {any_to_str(self)} def _reset(self): @@ -191,8 +191,7 @@ class Role: """Watch Actions of interest. Role will select Messages caused by these Actions from its personal message buffer during _observe. """ - tags = {any_to_str(t) for t in actions} - self._rc.watch.update(tags) + self._rc.watch = {any_to_str(t) for t in actions} # check RoleContext after adding watch actions self._rc.check(self._role_id) @@ -389,6 +388,8 @@ class Role: msg = with_message elif isinstance(with_message, list): msg = Message("\n".join(with_message)) + if not msg.cause_by: + msg.cause_by = UserRequirement self.put_message(msg) if not await self._observe(): diff --git a/metagpt/startup.py b/metagpt/startup.py index 37526dbcc..a89b9c5e9 100644 --- a/metagpt/startup.py +++ b/metagpt/startup.py @@ -25,7 +25,7 @@ def startup( ), reqa_file: str = typer.Option(default="", help="Specify the source file name for rewriting the quality test code."), max_auto_summarize_code: int = typer.Option( - default=-1, + 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.", ), diff --git a/metagpt/team.py b/metagpt/team.py index ddd145269..570be4e6b 100644 --- a/metagpt/team.py +++ b/metagpt/team.py @@ -3,10 +3,11 @@ """ @Time : 2023/5/12 00:30 @Author : alexanderwu -@File : software_company.py +@File : team.py @Modified By: mashenquan, 2023/11/27. Add an archiving operation after completing the project, as specified in Section 2.2.3.3 of RFC 135. """ +import warnings from pydantic import BaseModel, Field from metagpt.actions import UserRequirement @@ -47,7 +48,7 @@ class Team(BaseModel): raise NoMoneyException(CONFIG.total_cost, f"Insufficient funds: {CONFIG.max_budget}") def run_project(self, idea, send_to: str = ""): - """Start a project from publishing user requirement.""" + """Run a project from publishing user requirement.""" self.idea = idea # Human requirement. @@ -55,6 +56,16 @@ class Team(BaseModel): Message(role="Human", content=idea, cause_by=UserRequirement, send_to=send_to or MESSAGE_ROUTE_TO_ALL) ) + def start_project(self, idea, send_to: str = ""): + """ + Deprecated: This method will be removed in the future. + Please use the `run_project` method instead. + """ + warnings.warn("The 'start_project' method is deprecated and will be removed in the future. " + "Please use the 'run_project' method instead.", + DeprecationWarning, stacklevel=2) + return self.run_project(idea=idea, send_to=send_to) + def _save(self): logger.info(self.json(ensure_ascii=False)) diff --git a/setup.py b/setup.py index 320230a7f..8ef2a6946 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ with open(path.join(here, "requirements.txt"), encoding="utf-8") as f: setup( name="metagpt", - version="0.5.1", + version="0.5.2", description="The Multi-Agent Framework", long_description=long_description, long_description_content_type="text/markdown", diff --git a/tests/metagpt/test_role.py b/tests/metagpt/test_role.py index 3328607cf..dbe45130d 100644 --- a/tests/metagpt/test_role.py +++ b/tests/metagpt/test_role.py @@ -14,7 +14,7 @@ import uuid import pytest from pydantic import BaseModel -from metagpt.actions import Action, ActionOutput +from metagpt.actions import Action, ActionOutput, UserRequirement from metagpt.environment import Environment from metagpt.roles import Role from metagpt.schema import Message @@ -60,7 +60,7 @@ async def test_react(): name=seed.name, profile=seed.profile, goal=seed.goal, constraints=seed.constraints, desc=seed.desc ) role.subscribe({seed.subscription}) - assert role._rc.watch == set({}) + assert role._rc.watch == {any_to_str(UserRequirement)} assert role.name == seed.name assert role.profile == seed.profile assert role._setting.goal == seed.goal