refactor WriteTRD.run

This commit is contained in:
莘权 马 2024-06-14 14:48:58 +08:00
parent 92dbf76079
commit ff2c54777c
3 changed files with 202 additions and 6 deletions

View file

@ -0,0 +1,135 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2024/6/13
@Author : mashenquan
@File : write_project_framework.py
@Desc : The implementation of RFC243. https://deepwisdom.feishu.cn/wiki/QobGwPkImijoyukBUKHcrYetnBb
"""
import asyncio
import json
import uuid
from pathlib import Path
from typing import Dict, List
import typer
from pydantic import BaseModel
from metagpt.config2 import Config
from metagpt.const import DEFAULT_WORKSPACE_ROOT
from metagpt.context import Context
from metagpt.environment import Environment
from metagpt.logs import logger
from metagpt.roles import Architect
from metagpt.roles.di.team_leader import TeamLeader
from metagpt.schema import AIMessage, UserMessage
from metagpt.utils.common import any_to_str, aread, to_markdown_code_block
app = typer.Typer(add_completion=False)
class EnvBuilder(BaseModel):
context: Context
user_requirements: List[str]
actors: Dict[str, str]
acknowledge: str
technical_constraint: str
output_dir: Path
def build(self) -> Environment:
env = Environment(context=self.context)
team_leader = TeamLeader()
architect = Architect()
# Prepare context
use_case_actors = "".join([f"- {v}: {k}\n" for k, v in self.actors.items()])
msg = """
The content of "Actor, System, External System" provides an explanation of actors and systems that appear in UML Use Case diagram.
## Actor, System, External System
{use_case_actors}
"""
architect.rc.memory.add(AIMessage(content=msg.format(use_case_actors=use_case_actors)))
# Prepare acknowledge
msg = """
The descriptions of the interfaces used in TRD can be found in the "Acknowledge" section.
## Acknowledge
{acknowledge}
"""
architect.rc.memory.add(AIMessage(content=msg.format(acknowledge=to_markdown_code_block(val=self.acknowledge))))
# Prepare technical requirements
msg = """
"Additional Technical Requirements" specifies the additional technical requirements that the generated software framework code must meet.
## Additional Technical Requirements
{technical_requirements}
"""
architect.rc.memory.add(AIMessage(content=msg.format(technical_requirements=self.technical_constraint)))
env.add_roles([team_leader, architect])
return env
async def develop(
context: Context,
user_requirement_filename: str,
actors_filename: str,
acknowledge_filename: str,
constraint_filename: str,
output_dir: str,
):
output_dir = Path(output_dir) if output_dir else DEFAULT_WORKSPACE_ROOT / uuid.uuid4().hex
v = await aread(filename=user_requirement_filename)
user_requirements = json.loads(v)
v = await aread(filename=actors_filename)
actors = json.loads(v)
acknowledge = await aread(filename=acknowledge_filename)
technical_constraint = await aread(filename=constraint_filename)
env_builder = EnvBuilder(
context=context,
user_requirements=user_requirements,
actors=actors,
acknowledge=acknowledge,
technical_constraint=technical_constraint,
output_dir=output_dir,
)
env = env_builder.build()
msg = """
根据"User Requirements"中的用户需求写TRD
## User Requirements
```json
{user_requirements}
```
"""
env.publish_message(
UserMessage(content=msg.format(user_requirements=f"{user_requirements}"), send_to=any_to_str(TeamLeader))
)
while not env.is_idle:
await env.run()
@app.command()
def startup(
user_requirement_filename: str = typer.Argument(..., help="The filename of the user requirements."),
actors_filename: str = typer.Argument(..., help="The filename of UML use case actors description."),
acknowledge_filename: str = typer.Argument(..., help="External interfaces declarations."),
llm_config: str = typer.Option(default="", help="Low-cost LLM config"),
constraint_filename: str = typer.Option(default="", help="What technical dependency constraints are."),
output_dir: str = typer.Option(default="", help="Output directory."),
):
if llm_config and Path(llm_config).exists():
config = Config.from_yaml_file(Path(llm_config))
else:
logger.info("GPT 4 turbo is recommended")
config = Config.default()
ctx = Context(config=config)
asyncio.run(
develop(ctx, user_requirement_filename, actors_filename, acknowledge_filename, constraint_filename, output_dir)
)
if __name__ == "__main__":
app()

View file

@ -5,9 +5,6 @@
@Author : mashenquan
@File : write_project_framework.py
@Desc : The implementation of RFC243. https://deepwisdom.feishu.cn/wiki/QobGwPkImijoyukBUKHcrYetnBb
Usage Example:
"""
import asyncio
import json
@ -64,7 +61,7 @@ async def _write_trd(
user_requirements=r,
use_case_actors=use_case_actors,
available_external_interfaces=available_external_interfaces,
legacy_trd=trd,
previous_version_trd=trd,
evaluation_conclusion=evaluation_conclusion,
interaction_events=interaction_events,
)