{"repo": "brenchcc/cloudpet", "files": {"toolbox.py": {"851962d055215bda70e04e7d6e894fe9da71317a": {"t": 1785768952.3324454, "n": 16788, "h": "296610eba8f6c9ec", "c": "import markdown\nimport importlib\nimport traceback\nimport inspect\nimport re\nfrom latex2mathml.converter import convert as tex2mathml\nfrom functools import wraps, lru_cache\n############################### 插件输入输出接驳区 #######################################\nclass ChatBotWithCookies(list):\n def __init__(self, cookie):\n self._cookies = cookie\n\n def write_list(self, list):\n for t in list:\n self.append(t)\n\n def get_list(self):\n return [t for t in self]\n\n def get_cookies(self):\n return self._cookies\n\ndef ArgsGeneralWrapper(f):\n \"\"\"\n 装饰器函数,用于重组输入参数,改变输入参数的顺序与结构。\n \"\"\"\n def decorated(cookies, max_length, llm_model, txt, txt2, top_p, temperature, chatbot, history, system_prompt, *args):\n txt_passon = txt\n if txt == \"\" and txt2 != \"\": txt_passon = txt2\n # 引入一个有cookie的chatbot\n cookies.update({\n 'top_p':top_p, \n 'temperature':temperature,\n })\n llm_kwargs = {\n 'api_key': cookies['api_key'],\n 'llm_model': llm_model,\n 'top_p':top_p, \n 'max_length': max_length,\n 'temperature':temperature,\n }\n plugin_kwargs = {\n # 目前还没有\n }\n chatbot_with_cookie = ChatBotWithCookies(cookies)\n chatbot_with_cookie.write_list(chatbot)\n yield from f(txt_passon, llm_kwargs, plugin_kwargs, chatbot_with_cookie, history, system_prompt, *args)\n return decorated\n\ndef update_ui(chatbot, history, msg='正常', **kwargs): # 刷新界面\n \"\"\"\n 刷新用户界面\n \"\"\"\n assert isinstance(chatbot, ChatBotWithCookies), \"在传递chatbot的过程中不要将其丢弃。必要时,可用clear将其清空,然后用for+append循环重新赋值。\"\n yield chatbot.get_cookies(), chatbot, history, msg\n\ndef CatchException(f):\n \"\"\"\n 装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。\n \"\"\"\n @wraps(f)\n def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):\n try:\n yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)\n except Exception as e:\n from check_proxy import check_proxy\n from toolbox import get_conf\n proxies, = get_conf('proxies')\n tb_str = '```\\n' + traceback.format_exc() + '```'\n if chatbot is None or len(chatbot) == 0:\n chatbot = [[\"插件调度异常\", \"异常原因\"]]\n chatbot[-1] = (chatbot[-1][0],\n f\"[Local Message] 实验性函数调用出错: \\n\\n{tb_str} \\n\\n当前代理可用性: \\n\\n{check_proxy(proxies)}\")\n yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面\n return decorated\n\n\ndef HotReload(f):\n \"\"\"\n HotReload的装饰器函数,用于实现Python函数插件的热更新。\n 函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。\n 在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。\n 内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,\n 然后通过getattr函数获取函数名,并在新模块中重新加载函数。\n 最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。\n 最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。\n \"\"\"\n @wraps(f)\n def decorated(*args, **kwargs):\n fn_name = f.__name__\n f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)\n yield from f_hot_reload(*args, **kwargs)\n return decorated\n\n\n####################################### 其他小工具 #####################################\n\ndef get_reduce_token_percent(text):\n \"\"\"\n * 此函数未来将被弃用\n \"\"\"\n try:\n # text = \"maximum context length is 4097 tokens. However, your messages resulted in 4870 tokens\"\n pattern = r\"(\\d+)\\s+tokens\\b\"\n match = re.findall(pattern, text)\n EXCEED_ALLO = 500 # 稍微留一点余地,否则在回复时会因余量太少出问题\n max_limit = float(match[0]) - EXCEED_ALLO\n current_tokens = float(match[1])\n ratio = max_limit/current_tokens\n assert ratio > 0 and ratio < 1\n return ratio, str(int(current_tokens-max_limit))\n except:\n return 0.5, '不详'\n\n\n\ndef write_results_to_file(history, file_name=None):\n \"\"\"\n 将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。\n \"\"\"\n import os\n import time\n if file_name is None:\n # file_name = time.strftime(\"chatGPT分析报告%Y-%m-%d-%H-%M-%S\", time.localtime()) + '.md'\n file_name = 'chatGPT分析报告' + \\\n time.strftime(\"%Y-%m-%d-%H-%M-%S\", time.localtime()) + '.md'\n os.makedirs('./gpt_log/', exist_ok=True)\n with open(f'./gpt_log/{file_name}', 'w', encoding='utf8') as f:\n f.write('# chatGPT 分析报告\\n')\n for i, content in enumerate(history):\n try: # 这个bug没找到触发条件,暂时先这样顶一下\n if type(content) != str:\n content = str(content)\n except:\n continue\n if i % 2 == 0:\n f.write('## ')\n f.write(content)\n f.write('\\n\\n')\n res = '以上材料已经被写入' + os.path.abspath(f'./gpt_log/{file_name}')\n print(res)\n return res\n\n\ndef regular_txt_to_markdown(text):\n \"\"\"\n 将普通文本转换为Markdown格式的文本。\n \"\"\"\n text = text.replace('\\n', '\\n\\n')\n text = text.replace('\\n\\n\\n', '\\n\\n')\n text = text.replace('\\n\\n\\n', '\\n\\n')\n return text\n\n\n\n\ndef report_execption(chatbot, history, a, b):\n \"\"\"\n 向chatbot中添加错误信息\n \"\"\"\n chatbot.append((a, b))\n history.append(a)\n history.append(b)\n\n\ndef text_divide_paragraph(text):\n \"\"\"\n 将文本按照段落分隔符分割开,生成带有段落标签的HTML代码。\n \"\"\"\n if '```' in text:\n # careful input\n return text\n else:\n # wtf input\n lines = text.split(\"\\n\")\n for i, line in enumerate(lines):\n lines[i] = lines[i].replace(\" \", \" \")\n text = \"\".join(lines)\n return text\n\n\ndef markdown_convertion(txt):\n \"\"\"\n 将Markdown格式的文本转换为HTML格式。如果包含数学公式,则先将公式转换为HTML格式。\n \"\"\"\n pre = '