""" Filename: MetaGPT/examples/build_customized_agent.py Created Date: Tuesday, September 19th 2023, 6:52:25 pm Author: garylin2099 """ import asyncio import re import subprocess import fire from metagpt.actions import Action from metagpt.logs import logger from metagpt.roles.role import Role, RoleReactMode from metagpt.schema import Message class SimpleWriteCode(Action): PROMPT_TEMPLATE: str = """ Write a python function that can {instruction} and provide two runnable test cases. Return ```python your_code_here ``` with NO other texts, your code: """ name: str = "SimpleWriteCode" async def run(self, instruction: str): prompt = self.PROMPT_TEMPLATE.format(instruction=instruction) rsp = await self._aask(prompt) code_text = SimpleWriteCode.parse_code(rsp) return code_text @staticmethod def parse_code(rsp): pattern = r"```python(.*)```" match = re.search(pattern, rsp, re.DOTALL) code_text = match.group(1) if match else rsp return code_text class SimpleRunCode(Action): name: str = "SimpleRunCode" async def run(self, code_text: str): result = subprocess.run(["python3", "-c", code_text], capture_output=True, text=True) code_result = result.stdout logger.info(f"{code_result=}") return code_result class SimpleCoder(Role): name: str = "Alice" profile: str = "SimpleCoder" def __init__(self, **kwargs): super().__init__(**kwargs) self.set_actions([SimpleWriteCode]) async def _act(self) -> Message: logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})") todo = self.rc.todo # todo will be SimpleWriteCode() msg = self.get_memories(k=1)[0] # find the most recent messages code_text = await todo.run(msg.content) msg = Message(content=code_text, role=self.profile, cause_by=type(todo)) return msg class RunnableCoder(Role): name: str = "Alice" profile: str = "RunnableCoder" def __init__(self, **kwargs): super().__init__(**kwargs) self.set_actions([SimpleWriteCode, SimpleRunCode]) self._set_react_mode(react_mode=RoleReactMode.BY_ORDER.value) async def _act(self) -> Message: logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})") # By choosing the Action by order under the hood # todo will be first SimpleWriteCode() then SimpleRunCode() todo = self.rc.todo msg = self.get_memories(k=1)[0] # find the most k recent messages result = await todo.run(msg.content) msg = Message(content=result, role=self.profile, cause_by=type(todo)) self.rc.memory.add(msg) return msg def main(msg="write a function that calculates the product of a list and run it"): # role = SimpleCoder() role = RunnableCoder() logger.info(msg) result = asyncio.run(role.run(msg)) logger.info(result) if __name__ == "__main__": fire.Fire(main)