use context instead of FileRepo...

This commit is contained in:
geekan 2024-01-05 00:41:00 +08:00
parent 5c1f3a4b91
commit 3cd881de56
19 changed files with 78 additions and 93 deletions

View file

@ -12,6 +12,7 @@ from typing import Optional, Union
from pydantic import ConfigDict, Field, model_validator
import metagpt
from metagpt.actions.action_node import ActionNode
from metagpt.context import Context
from metagpt.llm import LLM
@ -35,7 +36,7 @@ class Action(SerializationMixin, is_polymorphic_base=True):
prefix: str = "" # aask*时会加上prefix作为system_message
desc: str = "" # for skill manager
node: ActionNode = Field(default=None, exclude=True)
g_context: Optional[Context] = Field(default=None, exclude=True)
g_context: Optional[Context] = Field(default=metagpt.context.context, exclude=True)
@property
def git_repo(self):

View file

@ -9,17 +9,14 @@
2. According to Section 2.2.3.1 of RFC 135, replace file data in the message with the file name.
"""
import re
from typing import Optional
from pydantic import Field
from metagpt.actions.action import Action
from metagpt.const import TEST_CODES_FILE_REPO, TEST_OUTPUTS_FILE_REPO
from metagpt.context import Context
from metagpt.logs import logger
from metagpt.schema import RunCodeContext, RunCodeResult
from metagpt.utils.common import CodeParser
from metagpt.utils.file_repository import FileRepository
PROMPT_TEMPLATE = """
NOTICE
@ -51,10 +48,9 @@ Now you should start rewriting the code:
class DebugError(Action):
context: RunCodeContext = Field(default_factory=RunCodeContext)
g_context: Optional[Context] = None
async def run(self, *args, **kwargs) -> str:
output_doc = await FileRepository.get_file(
output_doc = await self.file_repo.get_file(
filename=self.context.output_filename, relative_path=TEST_OUTPUTS_FILE_REPO
)
if not output_doc:
@ -66,12 +62,12 @@ class DebugError(Action):
return ""
logger.info(f"Debug and rewrite {self.context.test_filename}")
code_doc = await FileRepository.get_file(
code_doc = await self.file_repo.get_file(
filename=self.context.code_filename, relative_path=self.g_context.src_workspace
)
if not code_doc:
return ""
test_doc = await FileRepository.get_file(
test_doc = await self.file_repo.get_file(
filename=self.context.test_filename, relative_path=TEST_CODES_FILE_REPO
)
if not test_doc:

View file

@ -24,7 +24,6 @@ from metagpt.const import (
)
from metagpt.logs import logger
from metagpt.schema import Document, Documents, Message
from metagpt.utils.file_repository import FileRepository
from metagpt.utils.mermaid import mermaid_to_file
NEW_REQ_TEMPLATE = """
@ -75,13 +74,13 @@ class WriteDesign(Action):
# leaving room for global optimization in subsequent steps.
return ActionOutput(content=changed_files.model_dump_json(), instruct_content=changed_files)
async def _new_system_design(self, context, schema=None):
node = await DESIGN_API_NODE.fill(context=context, llm=self.llm, schema=schema)
async def _new_system_design(self, context):
node = await DESIGN_API_NODE.fill(context=context, llm=self.llm)
return node
async def _merge(self, prd_doc, system_design_doc, schema=None):
async def _merge(self, prd_doc, system_design_doc):
context = NEW_REQ_TEMPLATE.format(old_design=system_design_doc.content, context=prd_doc.content)
node = await DESIGN_API_NODE.fill(context=context, llm=self.llm, schema=schema)
node = await DESIGN_API_NODE.fill(context=context, llm=self.llm)
system_design_doc.content = node.instruct_content.model_dump_json()
return system_design_doc
@ -123,9 +122,8 @@ class WriteDesign(Action):
await WriteDesign._save_mermaid_file(seq_flow, pathname)
logger.info(f"Saving sequence flow to {str(pathname)}")
@staticmethod
async def _save_pdf(design_doc):
await FileRepository.save_as(doc=design_doc, with_suffix=".md", relative_path=SYSTEM_DESIGN_PDF_FILE_REPO)
async def _save_pdf(self, design_doc):
await self.file_repo.save_as(doc=design_doc, with_suffix=".md", relative_path=SYSTEM_DESIGN_PDF_FILE_REPO)
@staticmethod
async def _save_mermaid_file(data: str, pathname: Path):

View file

@ -24,7 +24,6 @@ from metagpt.const import (
)
from metagpt.logs import logger
from metagpt.schema import Document, Documents
from metagpt.utils.file_repository import FileRepository
NEW_REQ_TEMPLATE = """
### Legacy Content
@ -39,11 +38,7 @@ class WriteTasks(Action):
name: str = "CreateTasks"
context: Optional[str] = None
@property
def prompt_schema(self):
return self.g_context.config.prompt_schema
async def run(self, with_messages, schema=None):
async def run(self, with_messages):
system_design_file_repo = self.git_repo.new_file_repository(SYSTEM_DESIGN_FILE_REPO)
changed_system_designs = system_design_file_repo.changed_files
@ -114,6 +109,5 @@ class WriteTasks(Action):
packages.add(pkg)
await file_repo.save(PACKAGE_REQUIREMENTS_FILENAME, content="\n".join(packages))
@staticmethod
async def _save_pdf(task_doc):
await FileRepository.save_as(doc=task_doc, with_suffix=".md", relative_path=TASK_PDF_FILE_REPO)
async def _save_pdf(self, task_doc):
await self.file_repo.save_as(doc=task_doc, with_suffix=".md", relative_path=TASK_PDF_FILE_REPO)

View file

@ -14,7 +14,6 @@ from metagpt.actions.action import Action
from metagpt.const import SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO
from metagpt.logs import logger
from metagpt.schema import CodeSummarizeContext
from metagpt.utils.file_repository import FileRepository
PROMPT_TEMPLATE = """
NOTICE
@ -89,7 +88,6 @@ flowchart TB
"""
# TOTEST
class SummarizeCode(Action):
name: str = "SummarizeCode"
context: CodeSummarizeContext = Field(default_factory=CodeSummarizeContext)
@ -101,9 +99,10 @@ class SummarizeCode(Action):
async def run(self):
design_pathname = Path(self.context.design_filename)
design_doc = await FileRepository.get_file(filename=design_pathname.name, relative_path=SYSTEM_DESIGN_FILE_REPO)
repo = self.file_repo
design_doc = await repo.get_file(filename=design_pathname.name, relative_path=SYSTEM_DESIGN_FILE_REPO)
task_pathname = Path(self.context.task_filename)
task_doc = await FileRepository.get_file(filename=task_pathname.name, relative_path=TASK_FILE_REPO)
task_doc = await repo.get_file(filename=task_pathname.name, relative_path=TASK_FILE_REPO)
src_file_repo = self.git_repo.new_file_repository(relative_path=self.g_context.src_workspace)
code_blocks = []
for filename in self.context.codes_filenames:

View file

@ -31,7 +31,6 @@ from metagpt.const import (
from metagpt.logs import logger
from metagpt.schema import CodingContext, Document, RunCodeResult
from metagpt.utils.common import CodeParser
from metagpt.utils.file_repository import FileRepository
PROMPT_TEMPLATE = """
NOTICE
@ -138,12 +137,11 @@ class WriteCode(Action):
coding_context.code_doc.content = code
return coding_context
@staticmethod
async def get_codes(task_doc, exclude, git_repo, src_workspace) -> str:
async def get_codes(self, task_doc, exclude, git_repo, src_workspace) -> str:
if not task_doc:
return ""
if not task_doc.content:
task_doc.content = FileRepository.get_file(filename=task_doc.filename, relative_path=TASK_FILE_REPO)
task_doc.content = self.file_repo.get_file(filename=task_doc.filename, relative_path=TASK_FILE_REPO)
m = json.loads(task_doc.content)
code_filenames = m.get("Task list", [])
codes = []

View file

@ -166,9 +166,8 @@ class WritePRD(Action):
pathname.parent.mkdir(parents=True, exist_ok=True)
await mermaid_to_file(quadrant_chart, pathname)
@staticmethod
async def _save_pdf(prd_doc):
await FileRepository.save_as(doc=prd_doc, with_suffix=".md", relative_path=PRD_PDF_FILE_REPO)
async def _save_pdf(self, prd_doc):
await self.file_repo.save_as(doc=prd_doc, with_suffix=".md", relative_path=PRD_PDF_FILE_REPO)
async def _rename_workspace(self, prd):
if not self.project_name:

View file

@ -24,6 +24,10 @@ class Context:
src_workspace: Optional[Path] = None
cost_manager: CostManager = CostManager()
@property
def file_repo(self):
return self.git_repo.new_file_repository()
@property
def options(self):
"""Return all key-values"""

View file

@ -27,7 +27,6 @@ from metagpt.logs import logger
from metagpt.roles import Role
from metagpt.schema import Document, Message, RunCodeContext, TestingContext
from metagpt.utils.common import any_to_str_set, parse_recipient
from metagpt.utils.file_repository import FileRepository
class QaEngineer(Role):
@ -138,7 +137,7 @@ class QaEngineer(Role):
async def _debug_error(self, msg):
run_code_context = RunCodeContext.loads(msg.content)
code = await DebugError(context=run_code_context, g_context=self.context, llm=self.llm).run()
await FileRepository.save_file(
await self.context.file_repo.save_file(
filename=run_code_context.test_filename, content=code, relative_path=TEST_CODES_FILE_REPO
)
run_code_context.output = None

View file

@ -32,7 +32,7 @@ from metagpt.actions import Action, ActionOutput
from metagpt.actions.action_node import ActionNode
from metagpt.actions.add_requirement import UserRequirement
from metagpt.const import SERDESER_PATH
from metagpt.context import Context
from metagpt.context import Context, context
from metagpt.llm import LLM
from metagpt.logs import logger
from metagpt.memory import Memory
@ -150,7 +150,7 @@ class Role(SerializationMixin, is_polymorphic_base=True):
# builtin variables
recovered: bool = False # to tag if a recovered role
latest_observed_msg: Optional[Message] = None # record the latest observed message when interrupted
context: Optional[Context] = Field(default=None, exclude=True)
context: Optional[Context] = Field(default=context, exclude=True)
__hash__ = object.__hash__ # support Role as hashable type in `Environment.members`