/ examples / build_customized_agent.py
build_customized_agent.py
  1  """
  2  Filename: MetaGPT/examples/build_customized_agent.py
  3  Created Date: Tuesday, September 19th 2023, 6:52:25 pm
  4  Author: garylin2099
  5  """
  6  import asyncio
  7  import re
  8  import subprocess
  9  
 10  import fire
 11  
 12  from metagpt.actions import Action
 13  from metagpt.logs import logger
 14  from metagpt.roles.role import Role, RoleReactMode
 15  from metagpt.schema import Message
 16  
 17  
 18  class SimpleWriteCode(Action):
 19      PROMPT_TEMPLATE: str = """
 20      Write a python function that can {instruction} and provide two runnable test cases.
 21      Return ```python your_code_here ``` with NO other texts,
 22      your code:
 23      """
 24  
 25      name: str = "SimpleWriteCode"
 26  
 27      async def run(self, instruction: str):
 28          prompt = self.PROMPT_TEMPLATE.format(instruction=instruction)
 29  
 30          rsp = await self._aask(prompt)
 31  
 32          code_text = SimpleWriteCode.parse_code(rsp)
 33  
 34          return code_text
 35  
 36      @staticmethod
 37      def parse_code(rsp):
 38          pattern = r"```python(.*)```"
 39          match = re.search(pattern, rsp, re.DOTALL)
 40          code_text = match.group(1) if match else rsp
 41          return code_text
 42  
 43  
 44  class SimpleRunCode(Action):
 45      name: str = "SimpleRunCode"
 46  
 47      async def run(self, code_text: str):
 48          result = subprocess.run(["python3", "-c", code_text], capture_output=True, text=True)
 49          code_result = result.stdout
 50          logger.info(f"{code_result=}")
 51          return code_result
 52  
 53  
 54  class SimpleCoder(Role):
 55      name: str = "Alice"
 56      profile: str = "SimpleCoder"
 57  
 58      def __init__(self, **kwargs):
 59          super().__init__(**kwargs)
 60          self.set_actions([SimpleWriteCode])
 61  
 62      async def _act(self) -> Message:
 63          logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
 64          todo = self.rc.todo  # todo will be SimpleWriteCode()
 65  
 66          msg = self.get_memories(k=1)[0]  # find the most recent messages
 67          code_text = await todo.run(msg.content)
 68          msg = Message(content=code_text, role=self.profile, cause_by=type(todo))
 69  
 70          return msg
 71  
 72  
 73  class RunnableCoder(Role):
 74      name: str = "Alice"
 75      profile: str = "RunnableCoder"
 76  
 77      def __init__(self, **kwargs):
 78          super().__init__(**kwargs)
 79          self.set_actions([SimpleWriteCode, SimpleRunCode])
 80          self._set_react_mode(react_mode=RoleReactMode.BY_ORDER.value)
 81  
 82      async def _act(self) -> Message:
 83          logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
 84          # By choosing the Action by order under the hood
 85          # todo will be first SimpleWriteCode() then SimpleRunCode()
 86          todo = self.rc.todo
 87  
 88          msg = self.get_memories(k=1)[0]  # find the most k recent messages
 89          result = await todo.run(msg.content)
 90  
 91          msg = Message(content=result, role=self.profile, cause_by=type(todo))
 92          self.rc.memory.add(msg)
 93          return msg
 94  
 95  
 96  def main(msg="write a function that calculates the product of a list and run it"):
 97      # role = SimpleCoder()
 98      role = RunnableCoder()
 99      logger.info(msg)
100      result = asyncio.run(role.run(msg))
101      logger.info(result)
102  
103  
104  if __name__ == "__main__":
105      fire.Fire(main)