Merge branch 'dev' into dev

This commit is contained in:
better629 2023-12-29 02:48:39 +08:00 committed by GitHub
commit 539e1c7dce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 1402 additions and 649 deletions

View file

@ -13,7 +13,7 @@ from metagpt.actions.add_requirement import UserRequirement
from metagpt.actions.debug_error import DebugError
from metagpt.actions.design_api import WriteDesign
from metagpt.actions.design_api_review import DesignReview
from metagpt.actions.project_management import AssignTasks, WriteTasks
from metagpt.actions.project_management import WriteTasks
from metagpt.actions.research import CollectLinks, WebBrowseAndSummarize, ConductResearch
from metagpt.actions.run_code import RunCode
from metagpt.actions.search_and_summarize import SearchAndSummarize
@ -38,7 +38,6 @@ class ActionType(Enum):
RUN_CODE = RunCode
DEBUG_ERROR = DebugError
WRITE_TASKS = WriteTasks
ASSIGN_TASKS = AssignTasks
SEARCH_AND_SUMMARIZE = SearchAndSummarize
COLLECT_LINKS = CollectLinks
WEB_BROWSE_AND_SUMMARIZE = WebBrowseAndSummarize

View file

@ -352,17 +352,3 @@ class ActionNode:
cls = self.create_children_class()
self.instruct_content = cls(**tmp)
return self
def action_node_example():
node = ActionNode(key="key-0", expected_type=str, instruction="instruction-a", example="example-b")
logger.info(node.compile(context="123", schema="raw", mode="auto"))
logger.info(node.compile(context="123", schema="json", mode="auto"))
logger.info(node.compile(context="123", schema="markdown", mode="auto"))
logger.info(node.to_dict())
logger.info(node)
if __name__ == "__main__":
action_node_example()

View file

@ -10,6 +10,3 @@ from metagpt.actions import Action
class UserRequirement(Action):
"""User Requirement without any implementation details"""
async def run(self, *args, **kwargs):
raise NotImplementedError

View file

@ -8,7 +8,6 @@
from typing import List
from metagpt.actions.action_node import ActionNode
from metagpt.logs import logger
from metagpt.utils.mermaid import MMC1, MMC2
IMPLEMENTATION_APPROACH = ActionNode(
@ -63,12 +62,3 @@ NODES = [
]
DESIGN_API_NODE = ActionNode.from_children("DesignAPI", NODES)
def main():
prompt = DESIGN_API_NODE.compile(context="")
logger.info(prompt)
if __name__ == "__main__":
main()

View file

@ -39,6 +39,8 @@ class PrepareDocuments(Action):
path = Path(CONFIG.project_path)
if path.exists() and not CONFIG.inc:
shutil.rmtree(path)
CONFIG.project_path = path
CONFIG.project_name = path.name
CONFIG.git_repo = GitRepository(local_path=path, auto_init=True)
async def run(self, with_messages, **kwargs):

View file

@ -123,9 +123,3 @@ class WriteTasks(Action):
@staticmethod
async def _save_pdf(task_doc):
await FileRepository.save_as(doc=task_doc, with_suffix=".md", relative_path=TASK_PDF_FILE_REPO)
class AssignTasks(Action):
async def run(self, *args, **kwargs):
# Here you should implement the actual action
pass

View file

@ -86,7 +86,7 @@ class CollectLinks(Action):
desc: str = "Collect links from a search engine."
search_engine: SearchEngine = Field(default_factory=SearchEngine)
rank_func: Union[Callable[[list[str]], None], None] = None
rank_func: Optional[Callable[[list[str]], None]] = None
async def run(
self,
@ -130,7 +130,8 @@ class CollectLinks(Action):
if len(remove) == 0:
break
prompt = reduce_message_length(gen_msg(), self.llm.model, system_text, CONFIG.max_tokens_rsp)
model_name = CONFIG.get_model_name(CONFIG.get_default_llm_provider_enum())
prompt = reduce_message_length(gen_msg(), model_name, system_text, CONFIG.max_tokens_rsp)
logger.debug(prompt)
queries = await self._aask(prompt, [system_text])
try:
@ -181,18 +182,18 @@ class WebBrowseAndSummarize(Action):
llm: BaseLLM = Field(default_factory=LLM)
desc: str = "Explore the web and provide summaries of articles and webpages."
browse_func: Union[Callable[[list[str]], None], None] = None
web_browser_engine: WebBrowserEngine = Field(
default_factory=lambda: WebBrowserEngine(
engine=WebBrowserEngineType.CUSTOM if WebBrowseAndSummarize.browse_func else None,
run_func=WebBrowseAndSummarize.browse_func,
)
)
web_browser_engine: Optional[WebBrowserEngine] = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
if CONFIG.model_for_researcher_summary:
self.llm.model = CONFIG.model_for_researcher_summary
self.web_browser_engine = WebBrowserEngine(
engine=WebBrowserEngineType.CUSTOM if self.browse_func else None,
run_func=self.browse_func,
)
async def run(
self,
url: str,

View file

@ -82,11 +82,13 @@ class RunCode(Action):
llm: BaseLLM = Field(default_factory=LLM)
@classmethod
@handle_exception
async def run_text(cls, code) -> Tuple[str, str]:
# We will document_store the result in this dictionary
namespace = {}
exec(code, namespace)
try:
# We will document_store the result in this dictionary
namespace = {}
exec(code, namespace)
except Exception as e:
return "", str(e)
return namespace.get("result", ""), ""
@classmethod

View file

@ -21,7 +21,10 @@ Example:
This script uses the 'fire' library to create a command-line interface. It generates docstrings for the given Python code using
the specified docstring style and adds them to the code.
"""
from __future__ import annotations
import ast
from pathlib import Path
from typing import Literal, Optional
from pydantic import Field
@ -29,7 +32,7 @@ from pydantic import Field
from metagpt.actions.action import Action
from metagpt.llm import LLM
from metagpt.provider.base_llm import BaseLLM
from metagpt.utils.common import OutputParser
from metagpt.utils.common import OutputParser, aread, awrite
from metagpt.utils.pycst import merge_docstring
PYTHON_DOCSTRING_SYSTEM = """### Requirements
@ -187,6 +190,16 @@ class WriteDocstring(Action):
documented_code = OutputParser.parse_python_code(documented_code)
return merge_docstring(code, documented_code)
@staticmethod
async def write_docstring(
filename: str | Path, overwrite: bool = False, style: Literal["google", "numpy", "sphinx"] = "google"
) -> str:
data = await aread(str(filename))
code = await WriteDocstring().run(data, style=style)
if overwrite:
await awrite(filename, code)
return code
def _simplify_python_code(code: str) -> None:
"""Simplifies the given Python code by removing expressions and the last if statement.
@ -207,13 +220,4 @@ def _simplify_python_code(code: str) -> None:
if __name__ == "__main__":
import fire
async def run(filename: str, overwrite: bool = False, style: Literal["google", "numpy", "sphinx"] = "google"):
with open(filename) as f:
code = f.read()
code = await WriteDocstring().run(code, style=style)
if overwrite:
with open(filename, "w") as f:
f.write(code)
return code
fire.Fire(run)
fire.Fire(WriteDocstring.write_docstring)

View file

@ -66,7 +66,7 @@ NEW_REQ_TEMPLATE = """
class WritePRD(Action):
name: str = ""
name: str = "WritePRD"
content: Optional[str] = None
llm: BaseLLM = Field(default_factory=LLM)
@ -181,18 +181,13 @@ class WritePRD(Action):
@staticmethod
async def _rename_workspace(prd):
if CONFIG.project_path: # Updating on the old version has already been specified if it's valid. According to
# Section 2.2.3.10 of RFC 135
if not CONFIG.project_name:
CONFIG.project_name = Path(CONFIG.project_path).name
return
if not CONFIG.project_name:
if isinstance(prd, (ActionOutput, ActionNode)):
ws_name = prd.instruct_content.model_dump()["Project Name"]
else:
ws_name = CodeParser.parse_str(block="Project Name", text=prd)
CONFIG.project_name = ws_name
if ws_name:
CONFIG.project_name = ws_name
CONFIG.git_repo.rename_root(CONFIG.project_name)
async def _is_bugfix(self, context) -> bool: