MetaGPT/metagpt/team.py

96 lines
3.4 KiB
Python
Raw Normal View History

2023-06-30 17:10:48 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2023/5/12 00:30
@Author : alexanderwu
@File : software_company.py
"""
2023-11-28 09:29:00 +08:00
from pathlib import Path
2023-07-12 15:46:51 +08:00
from pydantic import BaseModel, Field
2023-06-30 17:10:48 +08:00
from metagpt.actions import BossRequirement
2023-07-22 11:28:22 +08:00
from metagpt.config import CONFIG
2023-06-30 17:10:48 +08:00
from metagpt.environment import Environment
2023-07-22 11:28:22 +08:00
from metagpt.logs import logger
from metagpt.roles import Role
2023-06-30 17:10:48 +08:00
from metagpt.schema import Message
from metagpt.utils.common import NoMoneyException
from metagpt.utils.utils import read_json_file, write_json_file, serialize_decorator
from metagpt.const import SERDESER_PATH
2023-06-30 17:10:48 +08:00
class Team(BaseModel):
2023-06-30 17:10:48 +08:00
"""
Team: Possesses one or more roles (agents), SOP (Standard Operating Procedures), and a platform for instant messaging,
dedicated to perform any multi-agent activity, such as collaboratively writing executable code.
2023-06-30 17:10:48 +08:00
"""
2023-07-12 15:46:51 +08:00
environment: Environment = Field(default_factory=Environment)
investment: float = Field(default=10.0)
idea: str = Field(default="")
2023-07-07 10:30:53 +08:00
class Config:
arbitrary_types_allowed = True
2023-06-30 17:10:48 +08:00
def serialize(self, stg_path: Path = None):
stg_path = SERDESER_PATH.joinpath("team") if stg_path is None else stg_path
2023-11-28 09:29:00 +08:00
team_info_path = stg_path.joinpath("team_info.json")
write_json_file(team_info_path, self.dict(exclude={"environment": True}))
self.environment.serialize(stg_path.joinpath("environment")) # save environment alone
2023-11-28 09:29:00 +08:00
@classmethod
def recover(cls, stg_path: Path) -> "Team":
return cls.deserialize(stg_path)
2023-11-28 09:29:00 +08:00
@classmethod
def deserialize(cls, stg_path: Path) -> "Team":
2023-11-28 09:29:00 +08:00
""" stg_path = ./storage/team """
# recover team_info
team_info_path = stg_path.joinpath("team_info.json")
if not team_info_path.exists():
raise FileNotFoundError("recover storage meta file `team_info.json` not exist, "
"not to recover and please start a new project.")
team_info: dict = read_json_file(team_info_path)
2023-11-28 09:29:00 +08:00
# recover environment
environment = Environment.deserialize(stg_path=stg_path.joinpath("environment"))
team_info.update({"environment": environment})
team = Team(**team_info)
return team
2023-11-28 09:29:00 +08:00
2023-06-30 17:10:48 +08:00
def hire(self, roles: list[Role]):
"""Hire roles to cooperate"""
self.environment.add_roles(roles)
2023-07-03 13:51:59 +08:00
def invest(self, investment: float):
2023-06-30 17:10:48 +08:00
"""Invest company. raise NoMoneyException when exceed max_budget."""
self.investment = investment
2023-07-07 10:30:53 +08:00
CONFIG.max_budget = investment
2023-07-07 10:37:42 +08:00
logger.info(f'Investment: ${investment}.')
2023-06-30 17:10:48 +08:00
def _check_balance(self):
2023-07-07 10:30:53 +08:00
if CONFIG.total_cost > CONFIG.max_budget:
raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}')
2023-06-30 17:10:48 +08:00
def start_project(self, idea, send_to: str = ""):
2023-07-07 10:43:04 +08:00
"""Start a project from publishing boss requirement."""
2023-06-30 17:10:48 +08:00
self.idea = idea
self.environment.publish_message(Message(role="Human", content=idea, cause_by=BossRequirement, send_to=send_to))
2023-06-30 17:10:48 +08:00
2023-07-07 10:30:53 +08:00
def _save(self):
logger.info(self.json())
@serialize_decorator
2023-06-30 17:10:48 +08:00
async def run(self, n_round=3):
2023-07-07 10:43:04 +08:00
"""Run company until target round or no money"""
2023-07-07 10:30:53 +08:00
while n_round > 0:
# self._save()
2023-06-30 17:10:48 +08:00
n_round -= 1
logger.debug(f"{n_round=}")
2023-07-07 10:30:53 +08:00
self._check_balance()
2023-06-30 17:10:48 +08:00
await self.environment.run()
return self.environment.history