From 33143c4a6dde5959e7c54e8c721143965b193eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Mon, 11 Sep 2023 02:17:59 +0000 Subject: [PATCH 01/16] webui_demo_v1.0.0 --- metagpt/app.py | 129 ++++++++++++++++++++++++++++++++++++ metagpt/environment.py | 7 +- metagpt/software_company.py | 6 +- 3 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 metagpt/app.py diff --git a/metagpt/app.py b/metagpt/app.py new file mode 100644 index 000000000..8f23f627c --- /dev/null +++ b/metagpt/app.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import aiofiles +import gradio as gr +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles.researcher import RESEARCH_PATH, Researcher +import io +import asyncio +import threading +from metagpt.const import PROJECT_ROOT +from time import sleep +from metagpt.schema import Message +import sys + + + +def clear_logs(): + with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: + f.write("") + +async def startup(company : str, + idea : str, + investment : float = 6.0, + n_round : int = 5, + code_review : bool = True, + run_tests : bool = False, + implement : bool = True, + staffs : list = ["ProjectManager", + "ProductManager", + "Architect",] + )->SoftwareCompany: + + if company == "SoftwareCompany": + company = SoftwareCompany() + else: + raise Exception("Company type not supported") + if idea == "": + raise Exception("Please input your idea") + staff_list = [] + for staff in staffs: + if staff == "ProjectManager": + staff_list.append(ProjectManager()) + elif staff == "ProductManager": + staff_list.append(ProductManager()) + elif staff == "Architect": + staff_list.append(Architect()) + else: + raise Exception("Staff type not supported") + company.hire(staff_list) + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + company.invest(investment) + company.start_project(idea) + # report all output to webui + global SoftwareCompany_Company + SoftwareCompany_Company = company + await company.continue_run() + return company.environment.short_term_history.content + +async def __continue(message_content : str): + company = SoftwareCompany_Company + company.environment.short_term_history.content = message_content + print(company.environment.short_term_history.content) + company.environment.memory.add(company.environment.short_term_history) + company.environment.history += f"\n{company.environment.short_term_history}" + await company.continue_run() + return company.environment.short_term_history.content + +async def research_startup(language : str, + topic : str): + if language == "en-us": + language = "en-us" + elif language == "zh-ch": + language = "zh-ch" + else: + raise Exception("Language not supported") + role = Researcher(language="en-us") + await role.run(topic) + return f"save report to {RESEARCH_PATH / f'{topic}.md'}." + +app = gr.Blocks() +SoftwareCompany_Company = SoftwareCompany() +import sys +sys.path.append('/workspaces/CSworks/zknow/proj_meta_gpt_linux/metagpt/metagpt') +with app: + gr.Markdown(""" + # MetaGPT + """) + with gr.Tabs(): + with gr.TabItem("MetaGPT") as generate_tab: + company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") + with gr.Row(): + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) + n_round = gr.Number( label="Round", value = 5) + with gr.Row(): + run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) + with gr.Row(): + implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) + code_review = gr.Checkbox(label = "Whether to use code review", value = False) + staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) + idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") + with gr.Row(): + Start_MetaGPT = gr.Button(label="Start", value = "Start") + with gr.Row(): + clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future + output_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",max_lines=999,show_copy_button = True) + continue_run = gr.Button(label="Continue Run", value = "Continue Run") + Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], [output_metagpt]) + clear_log.click(clear_logs, [],[]) + continue_run.click(__continue, [output_metagpt], [output_metagpt]) + with gr.TabItem("Research") as research_tab: + language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") + topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") + submit_Research = gr.Button(label="Submit", value = "Submit") + output_path_md = gr.Textbox(label="Output") + submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) + + +if __name__ == "__main__": + app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file diff --git a/metagpt/environment.py b/metagpt/environment.py index 24e6ada2f..8877b5c39 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -14,13 +14,12 @@ from metagpt.roles import Role from metagpt.schema import Message - class Environment(BaseModel): """环境,承载一批角色,角色可以向环境发布消息,可以被其他角色观察到 Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles """ - + short_term_history: str = Field(default_factory=Memory) roles: dict[str, Role] = Field(default_factory=dict) memory: Memory = Field(default_factory=Memory) history: str = Field(default='') @@ -43,12 +42,12 @@ def add_roles(self, roles: Iterable[Role]): self.add_role(role) def publish_message(self, message: Message): + """需要修改这里""" """向当前环境发布信息 Post information to the current environment """ # self.message_queue.put(message) - self.memory.add(message) - self.history += f"\n{message}" + self.short_term_history = message async def run(self, k=1): """处理一次所有信息的运行 diff --git a/metagpt/software_company.py b/metagpt/software_company.py index b2bd18c58..70ac47e4f 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -3,7 +3,7 @@ """ @Time : 2023/5/12 00:30 @Author : alexanderwu -@File : software_company.py +@File : software_company_with_human.py """ from pydantic import BaseModel, Field @@ -50,6 +50,10 @@ def start_project(self, idea): def _save(self): logger.info(self.json()) + async def continue_run(self): + await self.environment.run() + return self.environment.history + async def run(self, n_round=3): """Run company until target round or no money""" while n_round > 0: From 922ccf34bf18ad11d6a794d565a09cdce9e56238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Mon, 11 Sep 2023 02:27:10 +0000 Subject: [PATCH 02/16] Webui_v1.0.0 --- metagpt/app.py | 29 ++++++++++++++++------- metagpt/software_company.py | 47 +++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index 8f23f627c..b01a68705 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -3,7 +3,7 @@ import aiofiles import gradio as gr -from metagpt.software_company import SoftwareCompany +from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service from metagpt.roles.researcher import RESEARCH_PATH, Researcher import io @@ -20,7 +20,7 @@ def clear_logs(): with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: f.write("") -async def startup(company : str, +async def startup(company_name : str, idea : str, investment : float = 6.0, n_round : int = 5, @@ -32,8 +32,10 @@ async def startup(company : str, "Architect",] )->SoftwareCompany: - if company == "SoftwareCompany": + if company_name == "SoftwareCompany": company = SoftwareCompany() + elif company_name == "SoftwareCompany_With_Human": + company = SoftwareCompanyWithHuman() else: raise Exception("Company type not supported") if idea == "": @@ -63,7 +65,10 @@ async def startup(company : str, # report all output to webui global SoftwareCompany_Company SoftwareCompany_Company = company - await company.continue_run() + if company_name == "SoftwareCompany": + await company.run(n_round) + elif company_name == "SoftwareCompany_With_Human": + await company.continue_run() return company.environment.short_term_history.content async def __continue(message_content : str): @@ -87,6 +92,7 @@ async def research_startup(language : str, await role.run(topic) return f"save report to {RESEARCH_PATH / f'{topic}.md'}." + app = gr.Blocks() SoftwareCompany_Company = SoftwareCompany() import sys @@ -97,10 +103,10 @@ async def research_startup(language : str, """) with gr.Tabs(): with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") + company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany", "SoftwareCompany_With_Human"], value = "SoftwareCompany_With_Human") with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) - n_round = gr.Number( label="Round", value = 5) + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0, info="The maxmium investment you want to invest") + n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run") with gr.Row(): run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) with gr.Row(): @@ -113,16 +119,23 @@ async def research_startup(language : str, with gr.Row(): clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future output_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",max_lines=999,show_copy_button = True) - continue_run = gr.Button(label="Continue Run", value = "Continue Run") + continue_run = gr.Button(label="Continue Run", value = "Continue Run", visible = True) Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], [output_metagpt]) clear_log.click(clear_logs, [],[]) continue_run.click(__continue, [output_metagpt], [output_metagpt]) + company_choise.change(lambda company_choise : gr.update(visible = True if company_choise == "SoftwareCompany_With_Human" else False), [company_choise], [continue_run]) with gr.TabItem("Research") as research_tab: language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") submit_Research = gr.Button(label="Submit", value = "Submit") output_path_md = gr.Textbox(label="Output") submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) + with gr.TabItem("Markdown Shower") as MarkdownShower_tab: + with gr.Row(): + with gr.Row(): + input_str = gr.Textbox(label="Input",max_lines=999,show_copy_button=True) + output_md = gr.Markdown(label="Output") + input_str.change(lambda x: x,[input_str],[output_md]) if __name__ == "__main__": diff --git a/metagpt/software_company.py b/metagpt/software_company.py index 70ac47e4f..122668f87 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -25,6 +25,50 @@ class SoftwareCompany(BaseModel): investment: float = Field(default=10.0) idea: str = Field(default="") + class Config: + arbitrary_types_allowed = True + + def hire(self, roles: list[Role]): + """Hire roles to cooperate""" + self.environment.add_roles(roles) + + def invest(self, investment: float): + """Invest company. raise NoMoneyException when exceed max_budget.""" + self.investment = investment + CONFIG.max_budget = investment + logger.info(f'Investment: ${investment}.') + + def _check_balance(self): + if CONFIG.total_cost > CONFIG.max_budget: + raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') + + def start_project(self, idea): + """Start a project from publishing boss requirement.""" + self.idea = idea + self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) + + def _save(self): + logger.info(self.json()) + + async def run(self, n_round=3): + """Run company until target round or no money""" + while n_round > 0: + # self._save() + n_round -= 1 + logger.debug(f"{n_round=}") + self._check_balance() + await self.environment.run() + return self.environment.history + +class SoftwareCompanyWithHuman(BaseModel): + """ + Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, + dedicated to writing executable code. + """ + environment: Environment = Field(default_factory=Environment) + investment: float = Field(default=10.0) + idea: str = Field(default="") + class Config: arbitrary_types_allowed = True @@ -62,5 +106,4 @@ async def run(self, n_round=3): logger.debug(f"{n_round=}") self._check_balance() await self.environment.run() - return self.environment.history - \ No newline at end of file + return self.environment.history \ No newline at end of file From cccef5795458cb3d415b9ae220b130a0ccd28ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Mon, 11 Sep 2023 02:30:27 +0000 Subject: [PATCH 03/16] webui_v1.0.0 --- README copy.md | 9 ++ examples/llm_hello_world.py | 2 +- metagpt/software_company_with_human.py | 65 ++++++++++ metagpt/software_company_with_human_copy.py | 62 +++++++++ test_startup/test2.py | 18 +++ test_startup/test3.py | 1 + test_startup/test_v001.py | 90 +++++++++++++ test_startup/webui_v001.py | 93 +++++++++++++ test_startup/webui_v002.py | 137 ++++++++++++++++++++ test_startup/webui_v003.py | 120 +++++++++++++++++ 10 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 README copy.md create mode 100644 metagpt/software_company_with_human.py create mode 100644 metagpt/software_company_with_human_copy.py create mode 100644 test_startup/test2.py create mode 100644 test_startup/test3.py create mode 100644 test_startup/test_v001.py create mode 100644 test_startup/webui_v001.py create mode 100644 test_startup/webui_v002.py create mode 100644 test_startup/webui_v003.py diff --git a/README copy.md b/README copy.md new file mode 100644 index 000000000..30ce307fc --- /dev/null +++ b/README copy.md @@ -0,0 +1,9 @@ +基于metaGPT的交互式控制,人类介入的企业服务流程设计辅助工具开发 + +预期目标: +1.实现各个环节的人类介入,修改文件后再进行输入 +2.实现markdown文件输出位置的引导 +3.实现基于gradio的webui实现 + + +细节:需要修改env等接口,在角色返回信息之前先要向用户进行汇报,用户修改后方可继续进行 \ No newline at end of file diff --git a/examples/llm_hello_world.py b/examples/llm_hello_world.py index 3ba03eea0..091d2065c 100644 --- a/examples/llm_hello_world.py +++ b/examples/llm_hello_world.py @@ -14,7 +14,7 @@ async def main(): llm = LLM() claude = Claude() - logger.info(await claude.aask('你好,请进行自我介绍')) + # logger.info(await claude.aask('你好,请进行自我介绍')) logger.info(await llm.aask('hello world')) logger.info(await llm.aask_batch(['hi', 'write python hello world.'])) diff --git a/metagpt/software_company_with_human.py b/metagpt/software_company_with_human.py new file mode 100644 index 000000000..0a7c20d73 --- /dev/null +++ b/metagpt/software_company_with_human.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/5/12 00:30 +@Author : alexanderwu +@File : software_company_with_human.py +""" +from pydantic import BaseModel, Field + +from metagpt.actions import BossRequirement +from metagpt.config import CONFIG +from metagpt.environment import Environment +from metagpt.logs import logger +from metagpt.roles import Role +from metagpt.schema import Message +from metagpt.utils.common import NoMoneyException + + +class SoftwareCompanyWithHuman(BaseModel): + """ + Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, + dedicated to writing executable code. + """ + environment: Environment = Field(default_factory=Environment) + investment: float = Field(default=10.0) + idea: str = Field(default="") + + class Config: + arbitrary_types_allowed = True + + def hire(self, roles: list[Role]): + """Hire roles to cooperate""" + self.environment.add_roles(roles) + + def invest(self, investment: float): + """Invest company. raise NoMoneyException when exceed max_budget.""" + self.investment = investment + CONFIG.max_budget = investment + logger.info(f'Investment: ${investment}.') + + def _check_balance(self): + if CONFIG.total_cost > CONFIG.max_budget: + raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') + + def start_project(self, idea): + """Start a project from publishing boss requirement.""" + self.idea = idea + self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) + + def _save(self): + logger.info(self.json()) + + async def _continue(self): + await self.environment.run() + return self.environment.history + async def run(self, n_round=3): + """Run company until target round or no money""" + while n_round > 0: + # self._save() + n_round -= 1 + logger.debug(f"{n_round=}") + self._check_balance() + await self.environment.run() + return self.environment.history + \ No newline at end of file diff --git a/metagpt/software_company_with_human_copy.py b/metagpt/software_company_with_human_copy.py new file mode 100644 index 000000000..b2bd18c58 --- /dev/null +++ b/metagpt/software_company_with_human_copy.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/5/12 00:30 +@Author : alexanderwu +@File : software_company.py +""" +from pydantic import BaseModel, Field + +from metagpt.actions import BossRequirement +from metagpt.config import CONFIG +from metagpt.environment import Environment +from metagpt.logs import logger +from metagpt.roles import Role +from metagpt.schema import Message +from metagpt.utils.common import NoMoneyException + + +class SoftwareCompany(BaseModel): + """ + Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, + dedicated to writing executable code. + """ + environment: Environment = Field(default_factory=Environment) + investment: float = Field(default=10.0) + idea: str = Field(default="") + + class Config: + arbitrary_types_allowed = True + + def hire(self, roles: list[Role]): + """Hire roles to cooperate""" + self.environment.add_roles(roles) + + def invest(self, investment: float): + """Invest company. raise NoMoneyException when exceed max_budget.""" + self.investment = investment + CONFIG.max_budget = investment + logger.info(f'Investment: ${investment}.') + + def _check_balance(self): + if CONFIG.total_cost > CONFIG.max_budget: + raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') + + def start_project(self, idea): + """Start a project from publishing boss requirement.""" + self.idea = idea + self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) + + def _save(self): + logger.info(self.json()) + + async def run(self, n_round=3): + """Run company until target round or no money""" + while n_round > 0: + # self._save() + n_round -= 1 + logger.debug(f"{n_round=}") + self._check_balance() + await self.environment.run() + return self.environment.history + \ No newline at end of file diff --git a/test_startup/test2.py b/test_startup/test2.py new file mode 100644 index 000000000..0c02d0862 --- /dev/null +++ b/test_startup/test2.py @@ -0,0 +1,18 @@ +from time import sleep +import aiofiles +import gradio as gr +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, CustomerService +import io +import asyncio +import threading +from metagpt.const import PROJECT_ROOT + +def report_logs(): + while True: + with open(PROJECT_ROOT / 'logs/log.txt', 'r') as f: + + print(f.read()) + sleep(1) + +print(PROJECT_ROOT) \ No newline at end of file diff --git a/test_startup/test3.py b/test_startup/test3.py new file mode 100644 index 000000000..d1a95b94a --- /dev/null +++ b/test_startup/test3.py @@ -0,0 +1 @@ +import metagpt.software_company_with_human_copy diff --git a/test_startup/test_v001.py b/test_startup/test_v001.py new file mode 100644 index 000000000..5154b05a6 --- /dev/null +++ b/test_startup/test_v001.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import asyncio +import platform +import fire + +from metagpt.roles import Architect, Engineer, ProductManager +from metagpt.roles import ProjectManager, QaEngineer +from metagpt.software_company import SoftwareCompany + + +async def startup( + idea: str, + investment: float = 3.0, + n_round: int = 5, + code_review: bool = False, + run_tests: bool = False, + implement: bool = True +): + """Run a startup. Be a boss.""" + company = SoftwareCompany() + company.hire([ + ProductManager(), + Architect(), + ProjectManager(), + ]) + + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + + company.invest(investment) + company.start_project(idea) + await company.run(n_round=n_round) + + +def main( + idea: str, + investment: float = 3.0, + n_round: int = 5, + code_review: bool = True, + run_tests: bool = False, + implement: bool = True +): + """ + We are a software startup comprised of AI. By investing in us, + you are empowering a future filled with limitless possibilities. + :param idea: Your innovative idea, such as "Creating a snake game." + :param investment: As an investor, you have the opportunity to contribute + a certain dollar amount to this AI company. + :param n_round: + :param code_review: Whether to use code review. + :return: + """ + if platform.system() == "Windows": + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + asyncio.run(startup(idea, investment, n_round, + code_review, run_tests, implement)) + + +if __name__ == '__main__': + fire.Fire(main) + + + + +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer + +async def startup(idea: str, investment: float = 3.0, n_round: int = 5): + """运行一个创业公司。做一个老板""" + company = SoftwareCompany() + company.hire([ProductManager(), Architect(), ProjectManager(), Engineer()]) + company.invest(investment) + company.start_project(idea) + await company.run(n_round=n_round) + """ + architect, + customer_service, + engineer, + product_manager, + project_manager, + """ + diff --git a/test_startup/webui_v001.py b/test_startup/webui_v001.py new file mode 100644 index 000000000..9ab358f6b --- /dev/null +++ b/test_startup/webui_v001.py @@ -0,0 +1,93 @@ +import gradio as gr +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, CustomerService +import io +import asyncio +import threading + + +log_stream = io.StringIO() + +async def report_logs(interface: gr.Interface): + """report logs to webui""" + print("report_logs\n\n\n\n\n") + while True: + #if there are new logs, report them + if log_stream.getvalue() != "": + interface.outputs[0].textbox.value = log_stream.getvalue() + log_stream.truncate(0) + log_stream.seek(0) + await asyncio.sleep(0.1) + +async def startup(company : str, + idea : str, + investment : float = 6.0, + n_round : int = 5, + code_review : bool = True, + run_tests : bool = False, + implement : bool = True, + staffs : list = ["ProjectManager", + "ProductManager", + "Architect", + "Engineer"]): + """create a webui with gradio""" + if company == "SoftwareCompany": + company = SoftwareCompany() + else: + raise Exception("Company type not supported") + if idea == "": + raise Exception("Please input your idea") + staff_list = [] + for staff in staffs: + if staff == "ProjectManager": + staff_list.append(ProjectManager()) + elif staff == "ProductManager": + staff_list.append(ProductManager()) + elif staff == "Architect": + staff_list.append(Architect()) + else: + raise Exception("Staff type not supported") + company.hire(staff_list) + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + company.invest(investment) + company.start_project(idea) + # report all output to webui + asyncio.gather( + report_logs(demo), + company.run(n_round = n_round) + ) + + + + + +demo = gr.Interface(fn=startup, + inputs=[ + gr.Dropdown(["SoftwareCompany"],label="Company", info="Choose the company type"), + gr.Textbox(label="Idea", info="Your innovative idea, such as 'Creating a snake game.'"), + gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment", info="The maxmium money($) you would like to spend on generate"), + gr.Number( label="Round", info="The maxmium round you would like to run"), + gr.Checkbox(label="Code Review", info="Whether to use code review"), + gr.Checkbox(label="Run Tests", info="Whether to hire a QaEngineer to run tests"), + gr.Checkbox(label="Implement", info="Whether to hire a Engineer to implement the idea(write code)"), + gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Staff", info="Choose the staff you would like to hire") + ], + outputs=[ + gr.Textbox(label="Output", type="text", default=""), + ], + title="AI Startup", + examples=[ + ["SoftwareCompany", "Creating a snake game.", 6.0, 5, True, False, True, ["ProjectManager", "ProductManager", "Architect"]], + ] +) + +if __name__ == "__main__": + demo.launch() \ No newline at end of file diff --git a/test_startup/webui_v002.py b/test_startup/webui_v002.py new file mode 100644 index 000000000..127215578 --- /dev/null +++ b/test_startup/webui_v002.py @@ -0,0 +1,137 @@ +import aiofiles +import gradio as gr +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles.researcher import RESEARCH_PATH, Researcher +import io +import asyncio +import threading +from metagpt.const import PROJECT_ROOT +from time import sleep +from metagpt.schema import Message + + +class UserInput: + def __init__(self): + self.event = asyncio.Event() + self.data = None + + async def wait_for_input(self): + await self.event.wait() + return self.data + + def set_input(self, data): + self.data = data + self.event.set() + +class AwaitHook: + def __init__(self): + self.event = asyncio.Event() + self.data = None + def set_input(self, data : Message): + self.data = data + self.event.set() + async def wait_for_input(self): + await self.event.wait() + return self.data + + + + +async def await_hook(message : Message): + text = message.content + return text + + +def clear_logs(): + with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: + f.write("") + +async def startup(company : str, + idea : str, + investment : float = 6.0, + n_round : int = 5, + code_review : bool = True, + run_tests : bool = False, + implement : bool = True, + staffs : list = ["ProjectManager", + "ProductManager", + "Architect",]): + """create a webui with gradio""" + if company == "SoftwareCompany": + company = SoftwareCompany() + else: + raise Exception("Company type not supported") + if idea == "": + raise Exception("Please input your idea") + staff_list = [] + for staff in staffs: + if staff == "ProjectManager": + staff_list.append(ProjectManager()) + elif staff == "ProductManager": + staff_list.append(ProductManager()) + elif staff == "Architect": + staff_list.append(Architect()) + else: + raise Exception("Staff type not supported") + company.hire(staff_list) + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + company.invest(investment) + company.start_project(idea) + # report all output to webui + await company.run(n_round = n_round) + +async def research_startup(language : str, + topic : str): + if language == "en-us": + language = "en-us" + elif language == "zh-ch": + language = "zh-ch" + else: + raise Exception("Language not supported") + role = Researcher(language="en-us") + await role.run(topic) + return f"save report to {RESEARCH_PATH / f'{topic}.md'}." + +app = gr.Blocks() +with app: + gr.Markdown(""" + # MetaGPT + """) + with gr.Tabs(): + with gr.TabItem("MetaGPT") as generate_tab: + company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") + with gr.Row(): + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) + n_round = gr.Number( label="Round", value = 5) + with gr.Row(): + code_review = gr.Checkbox(label = "Whether to use code review", value = False) + with gr.Row(): + run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) + implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) + staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) + idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") + submit = gr.Button(label="Submit", value = "Submit") + get_log = gr.Button(label="Get Log", value = "Get Log") + clear_log = gr.Button(label="Clear Log", value = "Clear Log") + output = gr.Textbox(label="Output",max_lines=999) + submit.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], outputs=[]) + clear_log.click(clear_logs, [],[]) + with gr.TabItem("Research") as research_tab: + language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") + topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") + submit_Research = gr.Button(label="Submit", value = "Submit") + output_path_md = gr.Textbox(label="Output") + submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) + + +if __name__ == "__main__": + app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file diff --git a/test_startup/webui_v003.py b/test_startup/webui_v003.py new file mode 100644 index 000000000..0162dc4aa --- /dev/null +++ b/test_startup/webui_v003.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import aiofiles +import gradio as gr +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles.researcher import RESEARCH_PATH, Researcher +import io +import asyncio +import threading +from metagpt.const import PROJECT_ROOT +from time import sleep +from metagpt.schema import Message + +def clear_logs(): + with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: + f.write("") + +async def startup(company : str, + idea : str, + investment : float = 6.0, + n_round : int = 5, + code_review : bool = True, + run_tests : bool = False, + implement : bool = True, + staffs : list = ["ProjectManager", + "ProductManager", + "Architect",] + )->SoftwareCompany: + + if company == "SoftwareCompany": + company = SoftwareCompany() + else: + raise Exception("Company type not supported") + if idea == "": + raise Exception("Please input your idea") + staff_list = [] + for staff in staffs: + if staff == "ProjectManager": + staff_list.append(ProjectManager()) + elif staff == "ProductManager": + staff_list.append(ProductManager()) + elif staff == "Architect": + staff_list.append(Architect()) + else: + raise Exception("Staff type not supported") + company.hire(staff_list) + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + company.invest(investment) + company.start_project(idea) + # report all output to webui + global SoftwareCompany_Company + SoftwareCompany_Company = company + + await company.run() + return company + +async def __continue(): + company = SoftwareCompany_Company + await company.run() + +async def research_startup(language : str, + topic : str): + if language == "en-us": + language = "en-us" + elif language == "zh-ch": + language = "zh-ch" + else: + raise Exception("Language not supported") + role = Researcher(language="en-us") + await role.run(topic) + return f"save report to {RESEARCH_PATH / f'{topic}.md'}." + +app = gr.Blocks() +SoftwareCompany_Company = SoftwareCompany() +with app: + gr.Markdown(""" + # MetaGPT + """) + with gr.Tabs(): + with gr.TabItem("MetaGPT") as generate_tab: + company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") + with gr.Row(): + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) + n_round = gr.Number( label="Round", value = 5) + with gr.Row(): + code_review = gr.Checkbox(label = "Whether to use code review", value = False) + with gr.Row(): + run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) + implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) + staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) + idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") + with gr.Row(): + submit = gr.Button(label="Submit", value = "Submit") + with gr.Row(): + clear_log = gr.Button(label="Clear Log", value = "Clear Log") + continue_run = gr.Button(label="Continue Run", value = "Continue Run") + output_metagpt = gr.Textbox(label="Output",max_lines=999) + submit.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], []) + clear_log.click(clear_logs, [],[]) + continue_run.click(__continue, [], []) + with gr.TabItem("Research") as research_tab: + language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") + topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") + submit_Research = gr.Button(label="Submit", value = "Submit") + output_path_md = gr.Textbox(label="Output") + submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) + + +if __name__ == "__main__": + app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file From a9b6d9b2d992cc80a41d0dc0e3cee188c2d80b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Mon, 11 Sep 2023 08:23:18 +0000 Subject: [PATCH 04/16] webui_v1.0.1 --- metagpt/app_chs.py | 149 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 metagpt/app_chs.py diff --git a/metagpt/app_chs.py b/metagpt/app_chs.py new file mode 100644 index 000000000..4dadc97cf --- /dev/null +++ b/metagpt/app_chs.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import aiofiles +import gradio as gr +from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman +from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles.researcher import RESEARCH_PATH, Researcher +import io +import asyncio +import threading +from metagpt.const import PROJECT_ROOT +from time import sleep +from metagpt.schema import Message +import sys + +def clear_logs(): + with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: + f.write("") + +async def startup(company_name : str, + idea : str, + investment : float = 6.0, + n_round : int = 5, + code_review : bool = True, + run_tests : bool = False, + implement : bool = True, + staffs : list = ["ProjectManager", + "ProductManager", + "Architect",] + )->SoftwareCompany: + + if company_name == "软件公司": + company = SoftwareCompany() + elif company_name == "可以人为干预的软件公司": + company = SoftwareCompanyWithHuman() + else: + return "不支持的公司类型" + if idea == "": + return "请输入你的创意" + staff_list = [] + for staff in staffs: + if staff == "项目经理": + staff_list.append(ProjectManager()) + elif staff == "产品经理": + staff_list.append(ProductManager()) + elif staff == "架构师": + staff_list.append(Architect()) + else: + raise Exception("不支持的员工类型") + company.hire(staff_list) + # if implement or code_review + if implement or code_review: + # developing features: implement the idea + company.hire([Engineer(n_borg=5, use_code_review=code_review)]) + + if run_tests: + # developing features: run tests on the spot and identify bugs + # (bug fixing capability comes soon!) + company.hire([QaEngineer()]) + company.invest(investment) + company.start_project(idea) + # report all output to webui + global SoftwareCompany_Company + SoftwareCompany_Company = company + if company_name == "软件公司": + await company.run(n_round) + elif company_name == "可以人为干预的软件公司": + await company.continue_run() + return "角色: "+company.environment.short_term_history.role, "行为: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + +async def __continue(message_content : str): + company = SoftwareCompany_Company + company.environment.short_term_history.content = message_content + print(company.environment.short_term_history.content) + company.environment.memory.add(company.environment.short_term_history) + company.environment.history += f"\n{company.environment.short_term_history}" + await company.continue_run() + return "角色: "+company.environment.short_term_history.role, "行为: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + +async def research_startup(language : str, + topic : str): + if language == "en-us": + language = "en-us" + elif language == "zh-ch": + language = "zh-ch" + else: + raise Exception("Language not supported") + role = Researcher(language="en-us") + await role.run(topic) + return f"save report to {RESEARCH_PATH / f'{topic}.md'}." + + +app = gr.Blocks() +SoftwareCompany_Company = SoftwareCompany() +import sys +sys.path.append('/workspaces/CSworks/zknow/proj_meta_gpt_linux/metagpt/metagpt') +with app: + gr.Markdown(""" + # MetaGPT + """) + with gr.Tabs(): + with gr.TabItem("MetaGPT") as generate_tab: + company_choise = gr.Dropdown(label = "选择公司类型", choices = ["软件公司", "可以人为干预的软件公司"], value = "可以人为干预的软件公司") + with gr.Row(): + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="投资",value = 6.0, info="The maxmium money you want to spend on the GPT generation") + n_round = gr.Number( label="轮数", value = 5, info="你想要运行的最大轮数",visible = False) + with gr.Row(): + run_tests = gr.Checkbox(label = "是否要雇佣质量保证工程师来进行测试", value = False) + with gr.Row(): + implement = gr.Checkbox(label = "是否要雇佣工程师来实施项目(仅支持python)", value = True) + code_review = gr.Checkbox(label = "是否进行代码检查", value = False) + staffs = gr.CheckboxGroup(["项目经理", "产品经理", "架构师"], label="Choose the staff you would like to hire", value = ["项目经理", "产品经理", "架构师"]) + idea = gr.Textbox(label="你的创新想法,比如:“做一个贪吃蛇游戏”", value = "做一个贪吃蛇游戏") + with gr.Row(): + Start_MetaGPT = gr.Button(label="开始 / 重新开始", value = "开始 / 重新开始") + continue_run = gr.Button(label="继续", value = "继续", visible = True) + with gr.Row(): + show_markdown = gr.Checkbox(label="展示Markdown") + # with gr.Row(): + # clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future + notice_metagpt = gr.Markdown(value = "每轮生成时间大约为45秒,请耐心等待") + with gr.Row(): + output_role_metagpt = gr.Markdown(label="角色") + output_cause_metagpt = gr.Markdown(label="行为") + with gr.Row(): + output_sent_from_metagpt = gr.Markdown(label="发送者") + output_send_to_metagpt = gr.Markdown(label="接收者") + + with gr.Row(): + output_content_metagpt = gr.Textbox(label="MetaGPT的阶段性输出,按照你的意愿进行修改",max_lines=999,show_copy_button = True) + output_content_markdown_metagpt = gr.Markdown(label="Markdown输出", visible = False) + + + Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + # clear_log.click(clear_logs, [],[]) + continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + company_choise.change(lambda company_choise : gr.update(visible = True if company_choise == "可以人为干预的软件公司" else False), [company_choise], [continue_run]) + company_choise.change(lambda company_choise : gr.update(visible = False if company_choise == "可以人为干预的软件公司" else True), [company_choise], [n_round]) + show_markdown.change(lambda x: gr.update(visible = True if x == True else False), [show_markdown], [output_content_markdown_metagpt]) + with gr.TabItem("Research") as research_tab: + language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") + topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") + submit_Research = gr.Button(label="Submit", value = "Submit") + output_path_md = gr.Textbox(label="Output") + submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) + +if __name__ == "__main__": + app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file From 8040782520647b7cfb78d7e8ef6fb85a85c9d7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Mon, 11 Sep 2023 08:31:17 +0000 Subject: [PATCH 05/16] webui_v1.0.2 --- metagpt/software_company_with_human.py | 65 ---------- metagpt/software_company_with_human_copy.py | 62 --------- test_startup/test2.py | 18 --- test_startup/test3.py | 1 - test_startup/test_v001.py | 90 ------------- test_startup/webui_v001.py | 93 ------------- test_startup/webui_v002.py | 137 -------------------- test_startup/webui_v003.py | 120 ----------------- 8 files changed, 586 deletions(-) delete mode 100644 metagpt/software_company_with_human.py delete mode 100644 metagpt/software_company_with_human_copy.py delete mode 100644 test_startup/test2.py delete mode 100644 test_startup/test3.py delete mode 100644 test_startup/test_v001.py delete mode 100644 test_startup/webui_v001.py delete mode 100644 test_startup/webui_v002.py delete mode 100644 test_startup/webui_v003.py diff --git a/metagpt/software_company_with_human.py b/metagpt/software_company_with_human.py deleted file mode 100644 index 0a7c20d73..000000000 --- a/metagpt/software_company_with_human.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/5/12 00:30 -@Author : alexanderwu -@File : software_company_with_human.py -""" -from pydantic import BaseModel, Field - -from metagpt.actions import BossRequirement -from metagpt.config import CONFIG -from metagpt.environment import Environment -from metagpt.logs import logger -from metagpt.roles import Role -from metagpt.schema import Message -from metagpt.utils.common import NoMoneyException - - -class SoftwareCompanyWithHuman(BaseModel): - """ - Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, - dedicated to writing executable code. - """ - environment: Environment = Field(default_factory=Environment) - investment: float = Field(default=10.0) - idea: str = Field(default="") - - class Config: - arbitrary_types_allowed = True - - def hire(self, roles: list[Role]): - """Hire roles to cooperate""" - self.environment.add_roles(roles) - - def invest(self, investment: float): - """Invest company. raise NoMoneyException when exceed max_budget.""" - self.investment = investment - CONFIG.max_budget = investment - logger.info(f'Investment: ${investment}.') - - def _check_balance(self): - if CONFIG.total_cost > CONFIG.max_budget: - raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') - - def start_project(self, idea): - """Start a project from publishing boss requirement.""" - self.idea = idea - self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) - - def _save(self): - logger.info(self.json()) - - async def _continue(self): - await self.environment.run() - return self.environment.history - async def run(self, n_round=3): - """Run company until target round or no money""" - while n_round > 0: - # self._save() - n_round -= 1 - logger.debug(f"{n_round=}") - self._check_balance() - await self.environment.run() - return self.environment.history - \ No newline at end of file diff --git a/metagpt/software_company_with_human_copy.py b/metagpt/software_company_with_human_copy.py deleted file mode 100644 index b2bd18c58..000000000 --- a/metagpt/software_company_with_human_copy.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/5/12 00:30 -@Author : alexanderwu -@File : software_company.py -""" -from pydantic import BaseModel, Field - -from metagpt.actions import BossRequirement -from metagpt.config import CONFIG -from metagpt.environment import Environment -from metagpt.logs import logger -from metagpt.roles import Role -from metagpt.schema import Message -from metagpt.utils.common import NoMoneyException - - -class SoftwareCompany(BaseModel): - """ - Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, - dedicated to writing executable code. - """ - environment: Environment = Field(default_factory=Environment) - investment: float = Field(default=10.0) - idea: str = Field(default="") - - class Config: - arbitrary_types_allowed = True - - def hire(self, roles: list[Role]): - """Hire roles to cooperate""" - self.environment.add_roles(roles) - - def invest(self, investment: float): - """Invest company. raise NoMoneyException when exceed max_budget.""" - self.investment = investment - CONFIG.max_budget = investment - logger.info(f'Investment: ${investment}.') - - def _check_balance(self): - if CONFIG.total_cost > CONFIG.max_budget: - raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') - - def start_project(self, idea): - """Start a project from publishing boss requirement.""" - self.idea = idea - self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) - - def _save(self): - logger.info(self.json()) - - async def run(self, n_round=3): - """Run company until target round or no money""" - while n_round > 0: - # self._save() - n_round -= 1 - logger.debug(f"{n_round=}") - self._check_balance() - await self.environment.run() - return self.environment.history - \ No newline at end of file diff --git a/test_startup/test2.py b/test_startup/test2.py deleted file mode 100644 index 0c02d0862..000000000 --- a/test_startup/test2.py +++ /dev/null @@ -1,18 +0,0 @@ -from time import sleep -import aiofiles -import gradio as gr -from metagpt.software_company import SoftwareCompany -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, CustomerService -import io -import asyncio -import threading -from metagpt.const import PROJECT_ROOT - -def report_logs(): - while True: - with open(PROJECT_ROOT / 'logs/log.txt', 'r') as f: - - print(f.read()) - sleep(1) - -print(PROJECT_ROOT) \ No newline at end of file diff --git a/test_startup/test3.py b/test_startup/test3.py deleted file mode 100644 index d1a95b94a..000000000 --- a/test_startup/test3.py +++ /dev/null @@ -1 +0,0 @@ -import metagpt.software_company_with_human_copy diff --git a/test_startup/test_v001.py b/test_startup/test_v001.py deleted file mode 100644 index 5154b05a6..000000000 --- a/test_startup/test_v001.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import asyncio -import platform -import fire - -from metagpt.roles import Architect, Engineer, ProductManager -from metagpt.roles import ProjectManager, QaEngineer -from metagpt.software_company import SoftwareCompany - - -async def startup( - idea: str, - investment: float = 3.0, - n_round: int = 5, - code_review: bool = False, - run_tests: bool = False, - implement: bool = True -): - """Run a startup. Be a boss.""" - company = SoftwareCompany() - company.hire([ - ProductManager(), - Architect(), - ProjectManager(), - ]) - - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) - - company.invest(investment) - company.start_project(idea) - await company.run(n_round=n_round) - - -def main( - idea: str, - investment: float = 3.0, - n_round: int = 5, - code_review: bool = True, - run_tests: bool = False, - implement: bool = True -): - """ - We are a software startup comprised of AI. By investing in us, - you are empowering a future filled with limitless possibilities. - :param idea: Your innovative idea, such as "Creating a snake game." - :param investment: As an investor, you have the opportunity to contribute - a certain dollar amount to this AI company. - :param n_round: - :param code_review: Whether to use code review. - :return: - """ - if platform.system() == "Windows": - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - asyncio.run(startup(idea, investment, n_round, - code_review, run_tests, implement)) - - -if __name__ == '__main__': - fire.Fire(main) - - - - -from metagpt.software_company import SoftwareCompany -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer - -async def startup(idea: str, investment: float = 3.0, n_round: int = 5): - """运行一个创业公司。做一个老板""" - company = SoftwareCompany() - company.hire([ProductManager(), Architect(), ProjectManager(), Engineer()]) - company.invest(investment) - company.start_project(idea) - await company.run(n_round=n_round) - """ - architect, - customer_service, - engineer, - product_manager, - project_manager, - """ - diff --git a/test_startup/webui_v001.py b/test_startup/webui_v001.py deleted file mode 100644 index 9ab358f6b..000000000 --- a/test_startup/webui_v001.py +++ /dev/null @@ -1,93 +0,0 @@ -import gradio as gr -from metagpt.software_company import SoftwareCompany -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, CustomerService -import io -import asyncio -import threading - - -log_stream = io.StringIO() - -async def report_logs(interface: gr.Interface): - """report logs to webui""" - print("report_logs\n\n\n\n\n") - while True: - #if there are new logs, report them - if log_stream.getvalue() != "": - interface.outputs[0].textbox.value = log_stream.getvalue() - log_stream.truncate(0) - log_stream.seek(0) - await asyncio.sleep(0.1) - -async def startup(company : str, - idea : str, - investment : float = 6.0, - n_round : int = 5, - code_review : bool = True, - run_tests : bool = False, - implement : bool = True, - staffs : list = ["ProjectManager", - "ProductManager", - "Architect", - "Engineer"]): - """create a webui with gradio""" - if company == "SoftwareCompany": - company = SoftwareCompany() - else: - raise Exception("Company type not supported") - if idea == "": - raise Exception("Please input your idea") - staff_list = [] - for staff in staffs: - if staff == "ProjectManager": - staff_list.append(ProjectManager()) - elif staff == "ProductManager": - staff_list.append(ProductManager()) - elif staff == "Architect": - staff_list.append(Architect()) - else: - raise Exception("Staff type not supported") - company.hire(staff_list) - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) - company.invest(investment) - company.start_project(idea) - # report all output to webui - asyncio.gather( - report_logs(demo), - company.run(n_round = n_round) - ) - - - - - -demo = gr.Interface(fn=startup, - inputs=[ - gr.Dropdown(["SoftwareCompany"],label="Company", info="Choose the company type"), - gr.Textbox(label="Idea", info="Your innovative idea, such as 'Creating a snake game.'"), - gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment", info="The maxmium money($) you would like to spend on generate"), - gr.Number( label="Round", info="The maxmium round you would like to run"), - gr.Checkbox(label="Code Review", info="Whether to use code review"), - gr.Checkbox(label="Run Tests", info="Whether to hire a QaEngineer to run tests"), - gr.Checkbox(label="Implement", info="Whether to hire a Engineer to implement the idea(write code)"), - gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Staff", info="Choose the staff you would like to hire") - ], - outputs=[ - gr.Textbox(label="Output", type="text", default=""), - ], - title="AI Startup", - examples=[ - ["SoftwareCompany", "Creating a snake game.", 6.0, 5, True, False, True, ["ProjectManager", "ProductManager", "Architect"]], - ] -) - -if __name__ == "__main__": - demo.launch() \ No newline at end of file diff --git a/test_startup/webui_v002.py b/test_startup/webui_v002.py deleted file mode 100644 index 127215578..000000000 --- a/test_startup/webui_v002.py +++ /dev/null @@ -1,137 +0,0 @@ -import aiofiles -import gradio as gr -from metagpt.software_company import SoftwareCompany -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service -from metagpt.roles.researcher import RESEARCH_PATH, Researcher -import io -import asyncio -import threading -from metagpt.const import PROJECT_ROOT -from time import sleep -from metagpt.schema import Message - - -class UserInput: - def __init__(self): - self.event = asyncio.Event() - self.data = None - - async def wait_for_input(self): - await self.event.wait() - return self.data - - def set_input(self, data): - self.data = data - self.event.set() - -class AwaitHook: - def __init__(self): - self.event = asyncio.Event() - self.data = None - def set_input(self, data : Message): - self.data = data - self.event.set() - async def wait_for_input(self): - await self.event.wait() - return self.data - - - - -async def await_hook(message : Message): - text = message.content - return text - - -def clear_logs(): - with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: - f.write("") - -async def startup(company : str, - idea : str, - investment : float = 6.0, - n_round : int = 5, - code_review : bool = True, - run_tests : bool = False, - implement : bool = True, - staffs : list = ["ProjectManager", - "ProductManager", - "Architect",]): - """create a webui with gradio""" - if company == "SoftwareCompany": - company = SoftwareCompany() - else: - raise Exception("Company type not supported") - if idea == "": - raise Exception("Please input your idea") - staff_list = [] - for staff in staffs: - if staff == "ProjectManager": - staff_list.append(ProjectManager()) - elif staff == "ProductManager": - staff_list.append(ProductManager()) - elif staff == "Architect": - staff_list.append(Architect()) - else: - raise Exception("Staff type not supported") - company.hire(staff_list) - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) - company.invest(investment) - company.start_project(idea) - # report all output to webui - await company.run(n_round = n_round) - -async def research_startup(language : str, - topic : str): - if language == "en-us": - language = "en-us" - elif language == "zh-ch": - language = "zh-ch" - else: - raise Exception("Language not supported") - role = Researcher(language="en-us") - await role.run(topic) - return f"save report to {RESEARCH_PATH / f'{topic}.md'}." - -app = gr.Blocks() -with app: - gr.Markdown(""" - # MetaGPT - """) - with gr.Tabs(): - with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") - with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) - n_round = gr.Number( label="Round", value = 5) - with gr.Row(): - code_review = gr.Checkbox(label = "Whether to use code review", value = False) - with gr.Row(): - run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) - implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) - staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) - idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") - submit = gr.Button(label="Submit", value = "Submit") - get_log = gr.Button(label="Get Log", value = "Get Log") - clear_log = gr.Button(label="Clear Log", value = "Clear Log") - output = gr.Textbox(label="Output",max_lines=999) - submit.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], outputs=[]) - clear_log.click(clear_logs, [],[]) - with gr.TabItem("Research") as research_tab: - language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") - topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") - submit_Research = gr.Button(label="Submit", value = "Submit") - output_path_md = gr.Textbox(label="Output") - submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) - - -if __name__ == "__main__": - app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file diff --git a/test_startup/webui_v003.py b/test_startup/webui_v003.py deleted file mode 100644 index 0162dc4aa..000000000 --- a/test_startup/webui_v003.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import aiofiles -import gradio as gr -from metagpt.software_company import SoftwareCompany -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service -from metagpt.roles.researcher import RESEARCH_PATH, Researcher -import io -import asyncio -import threading -from metagpt.const import PROJECT_ROOT -from time import sleep -from metagpt.schema import Message - -def clear_logs(): - with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: - f.write("") - -async def startup(company : str, - idea : str, - investment : float = 6.0, - n_round : int = 5, - code_review : bool = True, - run_tests : bool = False, - implement : bool = True, - staffs : list = ["ProjectManager", - "ProductManager", - "Architect",] - )->SoftwareCompany: - - if company == "SoftwareCompany": - company = SoftwareCompany() - else: - raise Exception("Company type not supported") - if idea == "": - raise Exception("Please input your idea") - staff_list = [] - for staff in staffs: - if staff == "ProjectManager": - staff_list.append(ProjectManager()) - elif staff == "ProductManager": - staff_list.append(ProductManager()) - elif staff == "Architect": - staff_list.append(Architect()) - else: - raise Exception("Staff type not supported") - company.hire(staff_list) - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) - company.invest(investment) - company.start_project(idea) - # report all output to webui - global SoftwareCompany_Company - SoftwareCompany_Company = company - - await company.run() - return company - -async def __continue(): - company = SoftwareCompany_Company - await company.run() - -async def research_startup(language : str, - topic : str): - if language == "en-us": - language = "en-us" - elif language == "zh-ch": - language = "zh-ch" - else: - raise Exception("Language not supported") - role = Researcher(language="en-us") - await role.run(topic) - return f"save report to {RESEARCH_PATH / f'{topic}.md'}." - -app = gr.Blocks() -SoftwareCompany_Company = SoftwareCompany() -with app: - gr.Markdown(""" - # MetaGPT - """) - with gr.Tabs(): - with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany"], value = "SoftwareCompany") - with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="The maxmium money($) you would like to spend on generate",value = 6.0) - n_round = gr.Number( label="Round", value = 5) - with gr.Row(): - code_review = gr.Checkbox(label = "Whether to use code review", value = False) - with gr.Row(): - run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) - implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) - staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) - idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") - with gr.Row(): - submit = gr.Button(label="Submit", value = "Submit") - with gr.Row(): - clear_log = gr.Button(label="Clear Log", value = "Clear Log") - continue_run = gr.Button(label="Continue Run", value = "Continue Run") - output_metagpt = gr.Textbox(label="Output",max_lines=999) - submit.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], []) - clear_log.click(clear_logs, [],[]) - continue_run.click(__continue, [], []) - with gr.TabItem("Research") as research_tab: - language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") - topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") - submit_Research = gr.Button(label="Submit", value = "Submit") - output_path_md = gr.Textbox(label="Output") - submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) - - -if __name__ == "__main__": - app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file From 78e966a6cf0c010aa2d663625fb8686d6603e307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 13 Sep 2023 06:42:22 +0000 Subject: [PATCH 06/16] webuiv1.0.3 --- metagpt/app.py | 75 ++++++++++++++++++++++-------------------------- requirements.txt | 3 +- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index b01a68705..403685e9f 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -14,8 +14,6 @@ from metagpt.schema import Message import sys - - def clear_logs(): with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: f.write("") @@ -25,11 +23,9 @@ async def startup(company_name : str, investment : float = 6.0, n_round : int = 5, code_review : bool = True, - run_tests : bool = False, - implement : bool = True, staffs : list = ["ProjectManager", "ProductManager", - "Architect",] + "Architect"] )->SoftwareCompany: if company_name == "SoftwareCompany": @@ -37,9 +33,9 @@ async def startup(company_name : str, elif company_name == "SoftwareCompany_With_Human": company = SoftwareCompanyWithHuman() else: - raise Exception("Company type not supported") + return "Company type not supported" if idea == "": - raise Exception("Please input your idea") + return "Please input your idea" staff_list = [] for staff in staffs: if staff == "ProjectManager": @@ -48,18 +44,11 @@ async def startup(company_name : str, staff_list.append(ProductManager()) elif staff == "Architect": staff_list.append(Architect()) - else: - raise Exception("Staff type not supported") + elif staff == "Engineer": + staff_list.append(Engineer()) + elif staff == "QaEngineer": + staff_list.append(QaEngineer(n_borg=5,use_code_review=code_review)) company.hire(staff_list) - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) company.invest(investment) company.start_project(idea) # report all output to webui @@ -69,7 +58,7 @@ async def startup(company_name : str, await company.run(n_round) elif company_name == "SoftwareCompany_With_Human": await company.continue_run() - return company.environment.short_term_history.content + return "Role: "+company.environment.short_term_history.role, "Action: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content async def __continue(message_content : str): company = SoftwareCompany_Company @@ -78,7 +67,7 @@ async def __continue(message_content : str): company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" await company.continue_run() - return company.environment.short_term_history.content + return "Role: "+company.environment.short_term_history.role, "Action: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content async def research_startup(language : str, topic : str): @@ -105,38 +94,42 @@ async def research_startup(language : str, with gr.TabItem("MetaGPT") as generate_tab: company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany", "SoftwareCompany_With_Human"], value = "SoftwareCompany_With_Human") with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0, info="The maxmium investment you want to invest") - n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run") + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0, info="The maxmium money you want to spend on the GPT generation") + n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run",visible = False) with gr.Row(): - run_tests = gr.Checkbox(label = "Whether to hire a QaEngineer to run tests", value = False) - with gr.Row(): - implement = gr.Checkbox(label = "Whether to hire a Engineer to implement the idea(write code)", value = True) - code_review = gr.Checkbox(label = "Whether to use code review", value = False) - staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect"]) + code_review = gr.Checkbox(label = "Whether to use code review", value = False) + staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect", "Engineer", "QaEngineer"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect", "Engineer"]) idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") with gr.Row(): - Start_MetaGPT = gr.Button(label="Start", value = "Start") + Start_MetaGPT = gr.Button(label="Start / ReStart", value = "Start / ReStart") + continue_run = gr.Button(label="Continue Run", value = "Continue Run", visible = True) + with gr.Row(): + show_markdown = gr.Checkbox(label="Show Markdown") + # with gr.Row(): + # clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future with gr.Row(): - clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future - output_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",max_lines=999,show_copy_button = True) - continue_run = gr.Button(label="Continue Run", value = "Continue Run", visible = True) - Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], [output_metagpt]) - clear_log.click(clear_logs, [],[]) - continue_run.click(__continue, [output_metagpt], [output_metagpt]) + output_role_metagpt = gr.Markdown(label="The role of the output of MetaGPT") + output_cause_metagpt = gr.Markdown(label="The cause of the output of MetaGPT") + with gr.Row(): + output_sent_from_metagpt = gr.Markdown(label="The sent_from of the output of MetaGPT") + output_send_to_metagpt = gr.Markdown(label="The send_to of the output of MetaGPT") + with gr.Row(): + output_content_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",max_lines=999,show_copy_button = True) + output_content_markdown_metagpt = gr.Markdown(label="The markdown output of MetaGPT", visible = False) + + + Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, staffs], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + # clear_log.click(clear_logs, [],[]) + continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) company_choise.change(lambda company_choise : gr.update(visible = True if company_choise == "SoftwareCompany_With_Human" else False), [company_choise], [continue_run]) + company_choise.change(lambda company_choise : gr.update(visible = False if company_choise == "SoftwareCompany_With_Human" else True), [company_choise], [n_round]) + show_markdown.change(lambda x: gr.update(visible = True if x == True else False), [show_markdown], [output_content_markdown_metagpt]) with gr.TabItem("Research") as research_tab: language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") submit_Research = gr.Button(label="Submit", value = "Submit") output_path_md = gr.Textbox(label="Output") submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) - with gr.TabItem("Markdown Shower") as MarkdownShower_tab: - with gr.Row(): - with gr.Row(): - input_str = gr.Textbox(label="Input",max_lines=999,show_copy_button=True) - output_md = gr.Markdown(label="Output") - input_str.change(lambda x: x,[input_str],[output_md]) - if __name__ == "__main__": app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 741ae74df..6b1c0044d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -37,4 +37,5 @@ anthropic==0.3.6 typing-inspect==0.8.0 typing_extensions==4.5.0 libcst==1.0.1 -qdrant-client==1.4.0 \ No newline at end of file +qdrant-client==1.4.0 +gradio==2.3.6 \ No newline at end of file From c0d43e7f7dd2c8b7c1366ed57e24fe5a949ee7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 13 Sep 2023 08:16:12 +0000 Subject: [PATCH 07/16] webui_v1.04 --- metagpt/app.py | 4 ++-- metagpt/environment.py | 5 ++++- metagpt/software_company.py | 12 ++---------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index 403685e9f..edd58b770 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -45,9 +45,9 @@ async def startup(company_name : str, elif staff == "Architect": staff_list.append(Architect()) elif staff == "Engineer": - staff_list.append(Engineer()) + staff_list.append(Engineer(n_borg=5,use_code_review=code_review)) elif staff == "QaEngineer": - staff_list.append(QaEngineer(n_borg=5,use_code_review=code_review)) + staff_list.append(QaEngineer()) company.hire(staff_list) company.invest(investment) company.start_project(idea) diff --git a/metagpt/environment.py b/metagpt/environment.py index 8877b5c39..85acec38a 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -19,6 +19,7 @@ class Environment(BaseModel): Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles """ + environment_type: str = Field(default='') short_term_history: str = Field(default_factory=Memory) roles: dict[str, Role] = Field(default_factory=dict) memory: Memory = Field(default_factory=Memory) @@ -46,8 +47,10 @@ def publish_message(self, message: Message): """向当前环境发布信息 Post information to the current environment """ - # self.message_queue.put(message) self.short_term_history = message + if self.environment_type == "SoftwareCompany": + self.memory.add(message) + self.history += f"\n{message}" async def run(self, k=1): """处理一次所有信息的运行 diff --git a/metagpt/software_company.py b/metagpt/software_company.py index 122668f87..50ba39197 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -44,6 +44,7 @@ def _check_balance(self): def start_project(self, idea): """Start a project from publishing boss requirement.""" + self.environment.environment_type = "SoftwareCompany" self.idea = idea self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) @@ -88,6 +89,7 @@ def _check_balance(self): def start_project(self, idea): """Start a project from publishing boss requirement.""" + self.environment.environment_type = "SoftwareCompany_With_Human" self.idea = idea self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) @@ -96,14 +98,4 @@ def _save(self): async def continue_run(self): await self.environment.run() - return self.environment.history - - async def run(self, n_round=3): - """Run company until target round or no money""" - while n_round > 0: - # self._save() - n_round -= 1 - logger.debug(f"{n_round=}") - self._check_balance() - await self.environment.run() return self.environment.history \ No newline at end of file From 24a07131f0f2c0f6de12b6f47438701132f10ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 13 Sep 2023 08:32:39 +0000 Subject: [PATCH 08/16] webui_v1.05 --- README copy.md | 9 --------- examples/llm_hello_world.py | 2 +- metagpt/environment.py | 1 - metagpt/software_company.py | 4 ++-- 4 files changed, 3 insertions(+), 13 deletions(-) delete mode 100644 README copy.md diff --git a/README copy.md b/README copy.md deleted file mode 100644 index 30ce307fc..000000000 --- a/README copy.md +++ /dev/null @@ -1,9 +0,0 @@ -基于metaGPT的交互式控制,人类介入的企业服务流程设计辅助工具开发 - -预期目标: -1.实现各个环节的人类介入,修改文件后再进行输入 -2.实现markdown文件输出位置的引导 -3.实现基于gradio的webui实现 - - -细节:需要修改env等接口,在角色返回信息之前先要向用户进行汇报,用户修改后方可继续进行 \ No newline at end of file diff --git a/examples/llm_hello_world.py b/examples/llm_hello_world.py index 091d2065c..3ba03eea0 100644 --- a/examples/llm_hello_world.py +++ b/examples/llm_hello_world.py @@ -14,7 +14,7 @@ async def main(): llm = LLM() claude = Claude() - # logger.info(await claude.aask('你好,请进行自我介绍')) + logger.info(await claude.aask('你好,请进行自我介绍')) logger.info(await llm.aask('hello world')) logger.info(await llm.aask_batch(['hi', 'write python hello world.'])) diff --git a/metagpt/environment.py b/metagpt/environment.py index 85acec38a..d477722cb 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -43,7 +43,6 @@ def add_roles(self, roles: Iterable[Role]): self.add_role(role) def publish_message(self, message: Message): - """需要修改这里""" """向当前环境发布信息 Post information to the current environment """ diff --git a/metagpt/software_company.py b/metagpt/software_company.py index 50ba39197..5f8a71913 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -3,7 +3,7 @@ """ @Time : 2023/5/12 00:30 @Author : alexanderwu -@File : software_company_with_human.py +@File : software_company.py """ from pydantic import BaseModel, Field @@ -50,7 +50,7 @@ def start_project(self, idea): def _save(self): logger.info(self.json()) - + async def run(self, n_round=3): """Run company until target round or no money""" while n_round > 0: From 9695e8978367e6772ea6962c6e7985ba0eb1362d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Tue, 19 Sep 2023 02:05:16 +0000 Subject: [PATCH 09/16] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- metagpt/environment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/metagpt/environment.py b/metagpt/environment.py index d477722cb..6c67fc269 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -14,6 +14,7 @@ from metagpt.roles import Role from metagpt.schema import Message + class Environment(BaseModel): """环境,承载一批角色,角色可以向环境发布消息,可以被其他角色观察到 Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles From c1a7978c24227589439f1b023b6f6bea425c4321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 20 Sep 2023 06:12:13 +0000 Subject: [PATCH 10/16] Attempt to comply with PEP8 standards --- metagpt/app.py | 60 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index edd58b770..40b07d664 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -1,17 +1,17 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -import aiofiles +""" +@Time : 2023/9/19 17:12 +@Author : ORI_Replication +@File : app.py +""" import gradio as gr from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles import ProjectManager,\ + ProductManager, Architect,\ + Engineer, QaEngineer from metagpt.roles.researcher import RESEARCH_PATH, Researcher -import io -import asyncio -import threading from metagpt.const import PROJECT_ROOT -from time import sleep -from metagpt.schema import Message import sys def clear_logs(): @@ -58,7 +58,12 @@ async def startup(company_name : str, await company.run(n_round) elif company_name == "SoftwareCompany_With_Human": await company.continue_run() - return "Role: "+company.environment.short_term_history.role, "Action: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + return "Role: "+company.environment.short_term_history.role,\ + "Action: "+str(company.environment.short_term_history.cause_by),\ + company.environment.short_term_history.sent_from,\ + company.environment.short_term_history.send_to,\ + company.environment.short_term_history.content,\ + company.environment.short_term_history.content async def __continue(message_content : str): company = SoftwareCompany_Company @@ -67,7 +72,11 @@ async def __continue(message_content : str): company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" await company.continue_run() - return "Role: "+company.environment.short_term_history.role, "Action: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + return "Role: "+company.environment.short_term_history.role,\ + "Action: "+str(company.environment.short_term_history.cause_by),\ + company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to,\ + company.environment.short_term_history.content,\ + company.environment.short_term_history.content async def research_startup(language : str, topic : str): @@ -92,13 +101,18 @@ async def research_startup(language : str, """) with gr.Tabs(): with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "Choose the company type", choices = ["SoftwareCompany", "SoftwareCompany_With_Human"], value = "SoftwareCompany_With_Human") + company_choise = gr.Dropdown(label = "Choose the company type",\ + choices = ["SoftwareCompany", "SoftwareCompany_With_Human"],\ + value = "SoftwareCompany_With_Human") with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0, info="The maxmium money you want to spend on the GPT generation") + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0,\ + info="The maxmium money you want to spend on the GPT generation") n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run",visible = False) with gr.Row(): code_review = gr.Checkbox(label = "Whether to use code review", value = False) - staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect", "Engineer", "QaEngineer"], label="Choose the staff you would like to hire", value = ["ProjectManager", "ProductManager", "Architect", "Engineer"]) + staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect", "Engineer", "QaEngineer"],\ + label="Choose the staff you would like to hire",\ + value = ["ProjectManager", "ProductManager", "Architect", "Engineer"]) idea = gr.Textbox(label="Your innovative idea, such as 'Creating a snake game.'", value = "Creating a snake game.") with gr.Row(): Start_MetaGPT = gr.Button(label="Start / ReStart", value = "Start / ReStart") @@ -114,16 +128,24 @@ async def research_startup(language : str, output_sent_from_metagpt = gr.Markdown(label="The sent_from of the output of MetaGPT") output_send_to_metagpt = gr.Markdown(label="The send_to of the output of MetaGPT") with gr.Row(): - output_content_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",max_lines=999,show_copy_button = True) + output_content_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",\ + max_lines=999,show_copy_button = True) output_content_markdown_metagpt = gr.Markdown(label="The markdown output of MetaGPT", visible = False) - Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, staffs], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, staffs],\ + [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,\ + output_content_metagpt,output_content_markdown_metagpt]) # clear_log.click(clear_logs, [],[]) - continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) - company_choise.change(lambda company_choise : gr.update(visible = True if company_choise == "SoftwareCompany_With_Human" else False), [company_choise], [continue_run]) - company_choise.change(lambda company_choise : gr.update(visible = False if company_choise == "SoftwareCompany_With_Human" else True), [company_choise], [n_round]) - show_markdown.change(lambda x: gr.update(visible = True if x == True else False), [show_markdown], [output_content_markdown_metagpt]) + continue_run.click(__continue, [output_content_metagpt],\ + [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,\ + output_content_metagpt,output_content_markdown_metagpt]) + company_choise.change(lambda company_choise : gr.update(visible = True \ + if company_choise == "SoftwareCompany_With_Human" else False), [company_choise], [continue_run]) + company_choise.change(lambda company_choise : gr.update(visible = False \ + if company_choise == "SoftwareCompany_With_Human" else True), [company_choise], [n_round]) + show_markdown.change(lambda x: gr.update(visible = True if x == True else False),\ + [show_markdown], [output_content_markdown_metagpt]) with gr.TabItem("Research") as research_tab: language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") From b4a34127f0c9545f38fcc8fb7734357ddf9ac75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 20 Sep 2023 06:13:23 +0000 Subject: [PATCH 11/16] Attempt to comply with PEP8 standards --- metagpt/app_chs.py | 59 ++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/metagpt/app_chs.py b/metagpt/app_chs.py index 4dadc97cf..594a05441 100644 --- a/metagpt/app_chs.py +++ b/metagpt/app_chs.py @@ -1,17 +1,17 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -import aiofiles +""" +@Time : 2023/9/19 17:12 +@Author : ORI_Replication +@File : app_chs.py +""" import gradio as gr from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman -from metagpt.roles import ProjectManager, ProductManager, Architect, Engineer, QaEngineer, Searcher, Sales, customer_service +from metagpt.roles import ProjectManager,\ + ProductManager, Architect,\ + Engineer, QaEngineer from metagpt.roles.researcher import RESEARCH_PATH, Researcher -import io -import asyncio -import threading from metagpt.const import PROJECT_ROOT -from time import sleep -from metagpt.schema import Message import sys def clear_logs(): @@ -67,7 +67,12 @@ async def startup(company_name : str, await company.run(n_round) elif company_name == "可以人为干预的软件公司": await company.continue_run() - return "角色: "+company.environment.short_term_history.role, "行为: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + return "角色: "+company.environment.short_term_history.role, \ + "行为: "+str(company.environment.short_term_history.cause_by),\ + company.environment.short_term_history.sent_from,\ + company.environment.short_term_history.send_to,\ + company.environment.short_term_history.content,\ + company.environment.short_term_history.content async def __continue(message_content : str): company = SoftwareCompany_Company @@ -76,7 +81,12 @@ async def __continue(message_content : str): company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" await company.continue_run() - return "角色: "+company.environment.short_term_history.role, "行为: "+str(company.environment.short_term_history.cause_by),company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to, company.environment.short_term_history.content, company.environment.short_term_history.content + return "角色: "+company.environment.short_term_history.role,\ + "行为: "+str(company.environment.short_term_history.cause_by),\ + company.environment.short_term_history.sent_from,\ + company.environment.short_term_history.send_to,\ + company.environment.short_term_history.content,\ + company.environment.short_term_history.content async def research_startup(language : str, topic : str): @@ -101,16 +111,19 @@ async def research_startup(language : str, """) with gr.Tabs(): with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "选择公司类型", choices = ["软件公司", "可以人为干预的软件公司"], value = "可以人为干预的软件公司") + company_choise = gr.Dropdown(label = "选择公司类型",\ + choices = ["软件公司", "可以人为干预的软件公司"], value = "可以人为干预的软件公司") with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="投资",value = 6.0, info="The maxmium money you want to spend on the GPT generation") + investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="投资",\ + value = 6.0, info="The maxmium money you want to spend on the GPT generation") n_round = gr.Number( label="轮数", value = 5, info="你想要运行的最大轮数",visible = False) with gr.Row(): run_tests = gr.Checkbox(label = "是否要雇佣质量保证工程师来进行测试", value = False) with gr.Row(): implement = gr.Checkbox(label = "是否要雇佣工程师来实施项目(仅支持python)", value = True) code_review = gr.Checkbox(label = "是否进行代码检查", value = False) - staffs = gr.CheckboxGroup(["项目经理", "产品经理", "架构师"], label="Choose the staff you would like to hire", value = ["项目经理", "产品经理", "架构师"]) + staffs = gr.CheckboxGroup(["项目经理", "产品经理", "架构师"],\ + label="Choose the staff you would like to hire", value = ["项目经理", "产品经理", "架构师"]) idea = gr.Textbox(label="你的创新想法,比如:“做一个贪吃蛇游戏”", value = "做一个贪吃蛇游戏") with gr.Row(): Start_MetaGPT = gr.Button(label="开始 / 重新开始", value = "开始 / 重新开始") @@ -128,16 +141,22 @@ async def research_startup(language : str, output_send_to_metagpt = gr.Markdown(label="接收者") with gr.Row(): - output_content_metagpt = gr.Textbox(label="MetaGPT的阶段性输出,按照你的意愿进行修改",max_lines=999,show_copy_button = True) + output_content_metagpt = gr.Textbox(label="MetaGPT的阶段性输出,按照你的意愿进行修改",\ + max_lines=999,show_copy_button = True) output_content_markdown_metagpt = gr.Markdown(label="Markdown输出", visible = False) - Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) - # clear_log.click(clear_logs, [],[]) - continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) - company_choise.change(lambda company_choise : gr.update(visible = True if company_choise == "可以人为干预的软件公司" else False), [company_choise], [continue_run]) - company_choise.change(lambda company_choise : gr.update(visible = False if company_choise == "可以人为干预的软件公司" else True), [company_choise], [n_round]) - show_markdown.change(lambda x: gr.update(visible = True if x == True else False), [show_markdown], [output_content_markdown_metagpt]) + Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs],\ + [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,\ + output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,\ + output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) + company_choise.change(lambda company_choise : gr.update(visible = True \ + if company_choise == "可以人为干预的软件公司" else False), [company_choise], [continue_run]) + company_choise.change(lambda company_choise : gr.update(visible = False \ + if company_choise == "可以人为干预的软件公司" else True), [company_choise], [n_round]) + show_markdown.change(lambda x: gr.update(visible = True \ + if x == True else False), [show_markdown], [output_content_markdown_metagpt]) with gr.TabItem("Research") as research_tab: language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") From 1f30a024a5489f2802f6dcff33beb252ef69a881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 20 Sep 2023 06:29:07 +0000 Subject: [PATCH 12/16] Removed some useless codes --- metagpt/app.py | 4 +--- metagpt/app_chs.py | 8 ++++---- metagpt/environment.py | 1 - metagpt/software_company.py | 2 ++ 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index 40b07d664..49ec8b387 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -68,7 +68,6 @@ async def startup(company_name : str, async def __continue(message_content : str): company = SoftwareCompany_Company company.environment.short_term_history.content = message_content - print(company.environment.short_term_history.content) company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" await company.continue_run() @@ -93,8 +92,7 @@ async def research_startup(language : str, app = gr.Blocks() SoftwareCompany_Company = SoftwareCompany() -import sys -sys.path.append('/workspaces/CSworks/zknow/proj_meta_gpt_linux/metagpt/metagpt') + with app: gr.Markdown(""" # MetaGPT diff --git a/metagpt/app_chs.py b/metagpt/app_chs.py index 594a05441..dd694e6a3 100644 --- a/metagpt/app_chs.py +++ b/metagpt/app_chs.py @@ -77,7 +77,6 @@ async def startup(company_name : str, async def __continue(message_content : str): company = SoftwareCompany_Company company.environment.short_term_history.content = message_content - print(company.environment.short_term_history.content) company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" await company.continue_run() @@ -100,11 +99,12 @@ async def research_startup(language : str, await role.run(topic) return f"save report to {RESEARCH_PATH / f'{topic}.md'}." - +#initialize the app app = gr.Blocks() +#initialize the company SoftwareCompany_Company = SoftwareCompany() -import sys -sys.path.append('/workspaces/CSworks/zknow/proj_meta_gpt_linux/metagpt/metagpt') + + with app: gr.Markdown(""" # MetaGPT diff --git a/metagpt/environment.py b/metagpt/environment.py index 6c67fc269..34a29e8db 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -18,7 +18,6 @@ class Environment(BaseModel): """环境,承载一批角色,角色可以向环境发布消息,可以被其他角色观察到 Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles - """ environment_type: str = Field(default='') short_term_history: str = Field(default_factory=Memory) diff --git a/metagpt/software_company.py b/metagpt/software_company.py index 5f8a71913..ac51d74d2 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -65,6 +65,7 @@ class SoftwareCompanyWithHuman(BaseModel): """ Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, dedicated to writing executable code. + The SoftwareCompanyWithHuman can be intervened by human throuth webui. """ environment: Environment = Field(default_factory=Environment) investment: float = Field(default=10.0) @@ -97,5 +98,6 @@ def _save(self): logger.info(self.json()) async def continue_run(self): + """Run one round and report to webui""" await self.environment.run() return self.environment.history \ No newline at end of file From f064acd38c10fc0a8261b4953e82210a639274e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Wed, 20 Sep 2023 06:36:42 +0000 Subject: [PATCH 13/16] fixed a bug --- metagpt/app.py | 2 +- metagpt/environment.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/metagpt/app.py b/metagpt/app.py index 49ec8b387..c4cb35668 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -98,7 +98,7 @@ async def research_startup(language : str, # MetaGPT """) with gr.Tabs(): - with gr.TabItem("MetaGPT") as generate_tab: + with gr.TabItem("MetaGPT") as generate_tab: company_choise = gr.Dropdown(label = "Choose the company type",\ choices = ["SoftwareCompany", "SoftwareCompany_With_Human"],\ value = "SoftwareCompany_With_Human") diff --git a/metagpt/environment.py b/metagpt/environment.py index 34a29e8db..a9e66baee 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -19,7 +19,7 @@ class Environment(BaseModel): """环境,承载一批角色,角色可以向环境发布消息,可以被其他角色观察到 Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles """ - environment_type: str = Field(default='') + environment_type: str = Field(default='SoftwareCompany') short_term_history: str = Field(default_factory=Memory) roles: dict[str, Role] = Field(default_factory=dict) memory: Memory = Field(default_factory=Memory) From e8ddb193fe077ea508d22abd79adc1115adc77ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Thu, 21 Sep 2023 07:36:35 +0000 Subject: [PATCH 14/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6b1c0044d..d37025ebd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,4 +38,6 @@ typing-inspect==0.8.0 typing_extensions==4.5.0 libcst==1.0.1 qdrant-client==1.4.0 -gradio==2.3.6 \ No newline at end of file +gradio==2.3.6 +open-interpreter==0.1.3 +ta==0.10.2 \ No newline at end of file From 4afad9cb665508c86392f21a9fd586a051e271d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Thu, 21 Sep 2023 08:26:30 +0000 Subject: [PATCH 15/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d37025ebd..8e889ac77 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,6 +38,6 @@ typing-inspect==0.8.0 typing_extensions==4.5.0 libcst==1.0.1 qdrant-client==1.4.0 -gradio==2.3.6 open-interpreter==0.1.3 -ta==0.10.2 \ No newline at end of file +ta==0.10.2 +gradio==2.3.6 \ No newline at end of file From 5e80e5b7b12c34cb6ec1a63e22e921090ae9689f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=AA=E6=B2=90=E5=A4=A9?= <1747638932@qq.com> Date: Thu, 28 Sep 2023 16:38:18 +0000 Subject: [PATCH 16/16] attempt to meet all requests --- metagpt/app.py | 113 +++++++++++------------- metagpt/app_chs.py | 168 ------------------------------------ metagpt/environment.py | 6 +- metagpt/software_company.py | 39 +-------- requirements.txt | 4 +- 5 files changed, 56 insertions(+), 274 deletions(-) delete mode 100644 metagpt/app_chs.py diff --git a/metagpt/app.py b/metagpt/app.py index c4cb35668..7b4fadc16 100644 --- a/metagpt/app.py +++ b/metagpt/app.py @@ -6,85 +6,70 @@ @File : app.py """ import gradio as gr -from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman -from metagpt.roles import ProjectManager,\ - ProductManager, Architect,\ - Engineer, QaEngineer +from metagpt.software_company import SoftwareCompany +from metagpt.roles import ProjectManager,ProductManager, Architect,Engineer, QaEngineer from metagpt.roles.researcher import RESEARCH_PATH, Researcher -from metagpt.const import PROJECT_ROOT -import sys -def clear_logs(): - with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: - f.write("") + +class Report: + def __init__(self, role, action, sent_from, send_to, content): + self.role = role + self.action = action + self.sent_from = sent_from + self.send_to = send_to + self.content = content async def startup(company_name : str, idea : str, + staffs : list, investment : float = 6.0, n_round : int = 5, - code_review : bool = True, - staffs : list = ["ProjectManager", - "ProductManager", - "Architect"] - )->SoftwareCompany: - - if company_name == "SoftwareCompany": - company = SoftwareCompany() - elif company_name == "SoftwareCompany_With_Human": - company = SoftwareCompanyWithHuman() - else: - return "Company type not supported" - if idea == "": - return "Please input your idea" + code_review : bool = False, + auto_mode : bool = False, + ): + global SoftwareCompany_Company + + if company_name == "SoftwareCompany": company = SoftwareCompany() + else: return "Company type not supported" + if idea == "": return "Please input your idea" staff_list = [] for staff in staffs: - if staff == "ProjectManager": - staff_list.append(ProjectManager()) - elif staff == "ProductManager": - staff_list.append(ProductManager()) - elif staff == "Architect": - staff_list.append(Architect()) - elif staff == "Engineer": - staff_list.append(Engineer(n_borg=5,use_code_review=code_review)) - elif staff == "QaEngineer": - staff_list.append(QaEngineer()) + if staff == "ProjectManager": staff_list.append(ProjectManager()) + elif staff == "ProductManager": staff_list.append(ProductManager()) + elif staff == "Architect": staff_list.append(Architect()) + elif staff == "Engineer": staff_list.append(Engineer(n_borg=5,use_code_review=code_review)) + elif staff == "QaEngineer": staff_list.append(QaEngineer()) company.hire(staff_list) company.invest(investment) company.start_project(idea) # report all output to webui - global SoftwareCompany_Company SoftwareCompany_Company = company - if company_name == "SoftwareCompany": + if auto_mode: + company.environment.human_interaction = False await company.run(n_round) - elif company_name == "SoftwareCompany_With_Human": - await company.continue_run() - return "Role: "+company.environment.short_term_history.role,\ - "Action: "+str(company.environment.short_term_history.cause_by),\ - company.environment.short_term_history.sent_from,\ - company.environment.short_term_history.send_to,\ - company.environment.short_term_history.content,\ - company.environment.short_term_history.content + else : + company.environment.human_interaction = True + report = Report(company.environment.short_term_history.role, + str(company.environment.short_term_history.cause_by), + company.environment.short_term_history.sent_from, + company.environment.short_term_history.send_to, + company.environment.short_term_history.content) + return report.role, report.action, report.sent_from, report.send_to, report.content, report.content async def __continue(message_content : str): company = SoftwareCompany_Company company.environment.short_term_history.content = message_content company.environment.memory.add(company.environment.short_term_history) company.environment.history += f"\n{company.environment.short_term_history}" - await company.continue_run() - return "Role: "+company.environment.short_term_history.role,\ - "Action: "+str(company.environment.short_term_history.cause_by),\ - company.environment.short_term_history.sent_from,company.environment.short_term_history.send_to,\ - company.environment.short_term_history.content,\ - company.environment.short_term_history.content + await company.run_one_round() + report = Report(company.environment.short_term_history.role, + str(company.environment.short_term_history.cause_by), + company.environment.short_term_history.sent_from, + company.environment.short_term_history.send_to, + company.environment.short_term_history.content) + return report.role, report.action, report.sent_from, report.send_to, report.content, report.content -async def research_startup(language : str, - topic : str): - if language == "en-us": - language = "en-us" - elif language == "zh-ch": - language = "zh-ch" - else: - raise Exception("Language not supported") +async def research_startup(language : str, topic : str): role = Researcher(language="en-us") await role.run(topic) return f"save report to {RESEARCH_PATH / f'{topic}.md'}." @@ -97,17 +82,17 @@ async def research_startup(language : str, gr.Markdown(""" # MetaGPT """) + with gr.Tabs(): with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "Choose the company type",\ - choices = ["SoftwareCompany", "SoftwareCompany_With_Human"],\ - value = "SoftwareCompany_With_Human") + company_choise = gr.Dropdown(label = "Choose the company type",choices = ["SoftwareCompany"],value = "SoftwareCompany") with gr.Row(): investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="Investment",value = 6.0,\ info="The maxmium money you want to spend on the GPT generation") - n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run",visible = False) + n_round = gr.Number( label="Round", value = 5, info="The maxmium round you want to run",visible = True) with gr.Row(): code_review = gr.Checkbox(label = "Whether to use code review", value = False) + auto_mode = gr.Checkbox(label = "Whether to use auto mode", info = "run without human interaction", value = False) staffs = gr.CheckboxGroup(["ProjectManager", "ProductManager", "Architect", "Engineer", "QaEngineer"],\ label="Choose the staff you would like to hire",\ value = ["ProjectManager", "ProductManager", "Architect", "Engineer"]) @@ -129,9 +114,8 @@ async def research_startup(language : str, output_content_metagpt = gr.Textbox(label="The phased output of MetaGPT, modify it as your will",\ max_lines=999,show_copy_button = True) output_content_markdown_metagpt = gr.Markdown(label="The markdown output of MetaGPT", visible = False) - - - Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, staffs],\ + + Start_MetaGPT.click(startup, [company_choise, idea, staffs, investment, n_round, code_review, auto_mode],\ [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,output_send_to_metagpt,\ output_content_metagpt,output_content_markdown_metagpt]) # clear_log.click(clear_logs, [],[]) @@ -144,6 +128,7 @@ async def research_startup(language : str, if company_choise == "SoftwareCompany_With_Human" else True), [company_choise], [n_round]) show_markdown.change(lambda x: gr.update(visible = True if x == True else False),\ [show_markdown], [output_content_markdown_metagpt]) + with gr.TabItem("Research") as research_tab: language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") diff --git a/metagpt/app_chs.py b/metagpt/app_chs.py deleted file mode 100644 index dd694e6a3..000000000 --- a/metagpt/app_chs.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/9/19 17:12 -@Author : ORI_Replication -@File : app_chs.py -""" -import gradio as gr -from metagpt.software_company import SoftwareCompany, SoftwareCompanyWithHuman -from metagpt.roles import ProjectManager,\ - ProductManager, Architect,\ - Engineer, QaEngineer -from metagpt.roles.researcher import RESEARCH_PATH, Researcher -from metagpt.const import PROJECT_ROOT -import sys - -def clear_logs(): - with open(PROJECT_ROOT / 'logs/log.txt', 'w') as f: - f.write("") - -async def startup(company_name : str, - idea : str, - investment : float = 6.0, - n_round : int = 5, - code_review : bool = True, - run_tests : bool = False, - implement : bool = True, - staffs : list = ["ProjectManager", - "ProductManager", - "Architect",] - )->SoftwareCompany: - - if company_name == "软件公司": - company = SoftwareCompany() - elif company_name == "可以人为干预的软件公司": - company = SoftwareCompanyWithHuman() - else: - return "不支持的公司类型" - if idea == "": - return "请输入你的创意" - staff_list = [] - for staff in staffs: - if staff == "项目经理": - staff_list.append(ProjectManager()) - elif staff == "产品经理": - staff_list.append(ProductManager()) - elif staff == "架构师": - staff_list.append(Architect()) - else: - raise Exception("不支持的员工类型") - company.hire(staff_list) - # if implement or code_review - if implement or code_review: - # developing features: implement the idea - company.hire([Engineer(n_borg=5, use_code_review=code_review)]) - - if run_tests: - # developing features: run tests on the spot and identify bugs - # (bug fixing capability comes soon!) - company.hire([QaEngineer()]) - company.invest(investment) - company.start_project(idea) - # report all output to webui - global SoftwareCompany_Company - SoftwareCompany_Company = company - if company_name == "软件公司": - await company.run(n_round) - elif company_name == "可以人为干预的软件公司": - await company.continue_run() - return "角色: "+company.environment.short_term_history.role, \ - "行为: "+str(company.environment.short_term_history.cause_by),\ - company.environment.short_term_history.sent_from,\ - company.environment.short_term_history.send_to,\ - company.environment.short_term_history.content,\ - company.environment.short_term_history.content - -async def __continue(message_content : str): - company = SoftwareCompany_Company - company.environment.short_term_history.content = message_content - company.environment.memory.add(company.environment.short_term_history) - company.environment.history += f"\n{company.environment.short_term_history}" - await company.continue_run() - return "角色: "+company.environment.short_term_history.role,\ - "行为: "+str(company.environment.short_term_history.cause_by),\ - company.environment.short_term_history.sent_from,\ - company.environment.short_term_history.send_to,\ - company.environment.short_term_history.content,\ - company.environment.short_term_history.content - -async def research_startup(language : str, - topic : str): - if language == "en-us": - language = "en-us" - elif language == "zh-ch": - language = "zh-ch" - else: - raise Exception("Language not supported") - role = Researcher(language="en-us") - await role.run(topic) - return f"save report to {RESEARCH_PATH / f'{topic}.md'}." - -#initialize the app -app = gr.Blocks() -#initialize the company -SoftwareCompany_Company = SoftwareCompany() - - -with app: - gr.Markdown(""" - # MetaGPT - """) - with gr.Tabs(): - with gr.TabItem("MetaGPT") as generate_tab: - company_choise = gr.Dropdown(label = "选择公司类型",\ - choices = ["软件公司", "可以人为干预的软件公司"], value = "可以人为干预的软件公司") - with gr.Row(): - investment = gr.Slider(minimum=0.0, maximum=20.0, step=0.1, label="投资",\ - value = 6.0, info="The maxmium money you want to spend on the GPT generation") - n_round = gr.Number( label="轮数", value = 5, info="你想要运行的最大轮数",visible = False) - with gr.Row(): - run_tests = gr.Checkbox(label = "是否要雇佣质量保证工程师来进行测试", value = False) - with gr.Row(): - implement = gr.Checkbox(label = "是否要雇佣工程师来实施项目(仅支持python)", value = True) - code_review = gr.Checkbox(label = "是否进行代码检查", value = False) - staffs = gr.CheckboxGroup(["项目经理", "产品经理", "架构师"],\ - label="Choose the staff you would like to hire", value = ["项目经理", "产品经理", "架构师"]) - idea = gr.Textbox(label="你的创新想法,比如:“做一个贪吃蛇游戏”", value = "做一个贪吃蛇游戏") - with gr.Row(): - Start_MetaGPT = gr.Button(label="开始 / 重新开始", value = "开始 / 重新开始") - continue_run = gr.Button(label="继续", value = "继续", visible = True) - with gr.Row(): - show_markdown = gr.Checkbox(label="展示Markdown") - # with gr.Row(): - # clear_log = gr.Button(label="Clear Log", value = "Clear Log") # temporary, should be removed in the future - notice_metagpt = gr.Markdown(value = "每轮生成时间大约为45秒,请耐心等待") - with gr.Row(): - output_role_metagpt = gr.Markdown(label="角色") - output_cause_metagpt = gr.Markdown(label="行为") - with gr.Row(): - output_sent_from_metagpt = gr.Markdown(label="发送者") - output_send_to_metagpt = gr.Markdown(label="接收者") - - with gr.Row(): - output_content_metagpt = gr.Textbox(label="MetaGPT的阶段性输出,按照你的意愿进行修改",\ - max_lines=999,show_copy_button = True) - output_content_markdown_metagpt = gr.Markdown(label="Markdown输出", visible = False) - - - Start_MetaGPT.click(startup, [company_choise, idea, investment, n_round, code_review, run_tests, implement, staffs],\ - [output_role_metagpt,output_cause_metagpt,output_sent_from_metagpt,\ - output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) - continue_run.click(__continue, [output_content_metagpt], [output_role_metagpt,output_cause_metagpt,\ - output_sent_from_metagpt,output_send_to_metagpt,output_content_metagpt,output_content_markdown_metagpt]) - company_choise.change(lambda company_choise : gr.update(visible = True \ - if company_choise == "可以人为干预的软件公司" else False), [company_choise], [continue_run]) - company_choise.change(lambda company_choise : gr.update(visible = False \ - if company_choise == "可以人为干预的软件公司" else True), [company_choise], [n_round]) - show_markdown.change(lambda x: gr.update(visible = True \ - if x == True else False), [show_markdown], [output_content_markdown_metagpt]) - with gr.TabItem("Research") as research_tab: - language = gr.Dropdown(label = "Choose the language", choices = ["en-us","zh-ch"], value = "en-us") - topic = gr.Textbox(label="Your research topic, such as 'dataiku vs. datarobot'", value = "dataiku vs. datarobot") - submit_Research = gr.Button(label="Submit", value = "Submit") - output_path_md = gr.Textbox(label="Output") - submit_Research.click(research_startup, [language,topic], outputs=[output_path_md]) - -if __name__ == "__main__": - app.queue(concurrency_count=1022, max_size=2044).launch(inbrowser=True) \ No newline at end of file diff --git a/metagpt/environment.py b/metagpt/environment.py index a9e66baee..a59c1f8b0 100644 --- a/metagpt/environment.py +++ b/metagpt/environment.py @@ -19,11 +19,11 @@ class Environment(BaseModel): """环境,承载一批角色,角色可以向环境发布消息,可以被其他角色观察到 Environment, hosting a batch of roles, roles can publish messages to the environment, and can be observed by other roles """ - environment_type: str = Field(default='SoftwareCompany') - short_term_history: str = Field(default_factory=Memory) roles: dict[str, Role] = Field(default_factory=dict) memory: Memory = Field(default_factory=Memory) history: str = Field(default='') + short_term_history : Message = Field(default=Message(content="")) + human_interaction : bool = Field(default=False) class Config: arbitrary_types_allowed = True @@ -47,7 +47,7 @@ def publish_message(self, message: Message): Post information to the current environment """ self.short_term_history = message - if self.environment_type == "SoftwareCompany": + if self.human_interaction == False: self.memory.add(message) self.history += f"\n{message}" diff --git a/metagpt/software_company.py b/metagpt/software_company.py index ac51d74d2..96b0f5f88 100644 --- a/metagpt/software_company.py +++ b/metagpt/software_company.py @@ -44,7 +44,6 @@ def _check_balance(self): def start_project(self, idea): """Start a project from publishing boss requirement.""" - self.environment.environment_type = "SoftwareCompany" self.idea = idea self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) @@ -61,43 +60,7 @@ async def run(self, n_round=3): await self.environment.run() return self.environment.history -class SoftwareCompanyWithHuman(BaseModel): - """ - Software Company: Possesses a team, SOP (Standard Operating Procedures), and a platform for instant messaging, - dedicated to writing executable code. - The SoftwareCompanyWithHuman can be intervened by human throuth webui. - """ - environment: Environment = Field(default_factory=Environment) - investment: float = Field(default=10.0) - idea: str = Field(default="") - - class Config: - arbitrary_types_allowed = True - - def hire(self, roles: list[Role]): - """Hire roles to cooperate""" - self.environment.add_roles(roles) - - def invest(self, investment: float): - """Invest company. raise NoMoneyException when exceed max_budget.""" - self.investment = investment - CONFIG.max_budget = investment - logger.info(f'Investment: ${investment}.') - - def _check_balance(self): - if CONFIG.total_cost > CONFIG.max_budget: - raise NoMoneyException(CONFIG.total_cost, f'Insufficient funds: {CONFIG.max_budget}') - - def start_project(self, idea): - """Start a project from publishing boss requirement.""" - self.environment.environment_type = "SoftwareCompany_With_Human" - self.idea = idea - self.environment.publish_message(Message(role="BOSS", content=idea, cause_by=BossRequirement)) - - def _save(self): - logger.info(self.json()) - - async def continue_run(self): + async def run_one_round(self): """Run one round and report to webui""" await self.environment.run() return self.environment.history \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 8e889ac77..1f5a6264d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,6 +38,8 @@ typing-inspect==0.8.0 typing_extensions==4.5.0 libcst==1.0.1 qdrant-client==1.4.0 -open-interpreter==0.1.3 +pytest-mock==3.11.1 +open-interpreter==0.1.4; python_version>"3.9" ta==0.10.2 +semantic-kernel==0.3.10.dev0 gradio==2.3.6 \ No newline at end of file