Spaces:
Runtime error
Runtime error
| #!/usr/bin/env python | |
| # -*- coding: utf-8 -*- | |
| """ | |
| @Time : 2023/4/29 16:07 | |
| @Author : alexanderwu | |
| @File : common.py | |
| @From : https://github.com/geekan/MetaGPT/blob/main/metagpt/utils/common.py | |
| """ | |
| import ast | |
| import inspect | |
| import os | |
| import re | |
| from typing import List, Tuple | |
| from autoagents.system.logs import logger | |
| def check_cmd_exists(command) -> int: | |
| """ 检查命令是否存在 | |
| :param command: 待检查的命令 | |
| :return: 如果命令存在,返回0,如果不存在,返回非0 | |
| """ | |
| check_command = 'command -v ' + command + ' >/dev/null 2>&1 || { echo >&2 "no mermaid"; exit 1; }' | |
| result = os.system(check_command) | |
| return result | |
| class OutputParser: | |
| def parse_blocks(cls, text: str): | |
| # 首先根据"##"将文本分割成不同的block | |
| blocks = text.split("##") | |
| # 创建一个字典,用于存储每个block的标题和内容 | |
| block_dict = {} | |
| # 遍历所有的block | |
| for block in blocks: | |
| # 如果block不为空,则继续处理 | |
| if block.strip() != "": | |
| # 将block的标题和内容分开,并分别去掉前后的空白字符 | |
| block_title, block_content = block.split("\n", 1) | |
| # LLM可能出错,在这里做一下修正 | |
| if block_title[-1] == ":": | |
| block_title = block_title[:-1] | |
| block_dict[block_title.strip()] = block_content.strip() | |
| return block_dict | |
| def parse_code(cls, text: str, lang: str = "") -> str: | |
| pattern = rf'```{lang}.*?\s+(.*?)```' | |
| match = re.search(pattern, text, re.DOTALL) | |
| if match: | |
| code = match.group(1) | |
| else: | |
| raise Exception | |
| return code | |
| def parse_str(cls, text: str): | |
| text = text.split("=")[-1] | |
| text = text.strip().strip("'").strip("\"") | |
| return text | |
| def parse_file_list(cls, text: str) -> list[str]: | |
| # Regular expression pattern to find the tasks list. | |
| pattern = r'\s*(.*=.*)?(\[.*\])' | |
| # Extract tasks list string using regex. | |
| match = re.search(pattern, text, re.DOTALL) | |
| if match: | |
| tasks_list_str = match.group(2) | |
| # Convert string representation of list to a Python list using ast.literal_eval. | |
| tasks = ast.literal_eval(tasks_list_str) | |
| else: | |
| tasks = text.split("\n") | |
| return tasks | |
| def parse_data(cls, data): | |
| block_dict = cls.parse_blocks(data) | |
| parsed_data = {} | |
| for block, content in block_dict.items(): | |
| # 尝试去除code标记 | |
| try: | |
| content = cls.parse_code(text=content) | |
| except Exception: | |
| pass | |
| # 尝试解析list | |
| try: | |
| content = cls.parse_file_list(text=content) | |
| except Exception: | |
| pass | |
| parsed_data[block] = content | |
| return parsed_data | |
| def parse_data_with_mapping(cls, data, mapping): | |
| block_dict = cls.parse_blocks(data) | |
| parsed_data = {} | |
| for block, content in block_dict.items(): | |
| # 尝试去除code标记 | |
| try: | |
| content = cls.parse_code(text=content) | |
| except Exception: | |
| pass | |
| typing_define = mapping.get(block, None) | |
| if isinstance(typing_define, tuple): | |
| typing = typing_define[0] | |
| else: | |
| typing = typing_define | |
| if typing == List[str] or typing == List[Tuple[str, str]]: | |
| # 尝试解析list | |
| try: | |
| content = cls.parse_file_list(text=content) | |
| except Exception: | |
| pass | |
| # TODO: 多余的引号去除有风险,后期再解决 | |
| # elif typing == str: | |
| # # 尝试去除多余的引号 | |
| # try: | |
| # content = cls.parse_str(text=content) | |
| # except Exception: | |
| # pass | |
| parsed_data[block] = content | |
| return parsed_data | |
| class CodeParser: | |
| def parse_block(cls, block: str, text: str) -> str: | |
| blocks = cls.parse_blocks(text) | |
| for k, v in blocks.items(): | |
| if block in k: | |
| return v | |
| return "" | |
| def parse_blocks(cls, text: str): | |
| # 首先根据"##"将文本分割成不同的block | |
| blocks = text.split("##") | |
| # 创建一个字典,用于存储每个block的标题和内容 | |
| block_dict = {} | |
| # 遍历所有的block | |
| for block in blocks: | |
| # 如果block不为空,则继续处理 | |
| if block.strip() != "": | |
| # 将block的标题和内容分开,并分别去掉前后的空白字符 | |
| block_title, block_content = block.split("\n", 1) | |
| block_dict[block_title.strip()] = block_content.strip() | |
| return block_dict | |
| def parse_code(cls, block: str, text: str, lang: str = "") -> str: | |
| if block: | |
| text = cls.parse_block(block, text) | |
| pattern = rf'```{lang}.*?\s+(.*?)```' | |
| match = re.search(pattern, text, re.DOTALL) | |
| if match: | |
| code = match.group(1) | |
| else: | |
| logger.error(f"{pattern} not match following text:") | |
| logger.error(text) | |
| raise Exception | |
| return code | |
| def parse_str(cls, block: str, text: str, lang: str = ""): | |
| code = cls.parse_code(block, text, lang) | |
| code = code.split("=")[-1] | |
| code = code.strip().strip("'").strip("\"") | |
| return code | |
| def parse_file_list(cls, block: str, text: str, lang: str = "") -> list[str]: | |
| # Regular expression pattern to find the tasks list. | |
| code = cls.parse_code(block, text, lang) | |
| print(code) | |
| pattern = r'\s*(.*=.*)?(\[.*\])' | |
| # Extract tasks list string using regex. | |
| match = re.search(pattern, code, re.DOTALL) | |
| if match: | |
| tasks_list_str = match.group(2) | |
| # Convert string representation of list to a Python list using ast.literal_eval. | |
| tasks = ast.literal_eval(tasks_list_str) | |
| else: | |
| raise Exception | |
| return tasks | |
| class NoMoneyException(Exception): | |
| """Raised when the operation cannot be completed due to insufficient funds""" | |
| def __init__(self, amount, message="Insufficient funds"): | |
| self.amount = amount | |
| self.message = message | |
| super().__init__(self.message) | |
| def __str__(self): | |
| return f'{self.message} -> Amount required: {self.amount}' | |
| def print_members(module, indent=0): | |
| """ | |
| https://stackoverflow.com/questions/1796180/how-can-i-get-a-list-of-all-classes-within-current-module-in-python | |
| :param module: | |
| :param indent: | |
| :return: | |
| """ | |
| prefix = ' ' * indent | |
| for name, obj in inspect.getmembers(module): | |
| print(name, obj) | |
| if inspect.isclass(obj): | |
| print(f'{prefix}Class: {name}') | |
| # print the methods within the class | |
| if name in ['__class__', '__base__']: | |
| continue | |
| print_members(obj, indent + 2) | |
| elif inspect.isfunction(obj): | |
| print(f'{prefix}Function: {name}') | |
| elif inspect.ismethod(obj): | |
| print(f'{prefix}Method: {name}') | |