From 31ff6e1e7ad2fdb9a36c259aa5a053c7a7036d4c Mon Sep 17 00:00:00 2001 From: qingxu fu <505030475@qq.com> Date: Tue, 29 Aug 2023 17:37:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E7=84=B6=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE=E6=9C=AC=E8=BA=AB?= =?UTF-8?q?=E7=9A=84=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crazy_functional.py | 67 ++++--- crazy_functions/json_fns/pydantic_io.py | 100 +++++++++++ crazy_functions/vt_fns/vt_modify_config.py | 66 +++++++ crazy_functions/虚空终端.py | 195 ++++++++++----------- tests/test_plugins.py | 4 +- 5 files changed, 294 insertions(+), 138 deletions(-) create mode 100644 crazy_functions/json_fns/pydantic_io.py create mode 100644 crazy_functions/vt_fns/vt_modify_config.py diff --git a/crazy_functional.py b/crazy_functional.py index 4a8c03c..491288e 100644 --- a/crazy_functional.py +++ b/crazy_functional.py @@ -25,7 +25,7 @@ def get_crazy_functions(): from crazy_functions.对话历史存档 import 载入对话历史存档 from crazy_functions.对话历史存档 import 删除所有本地对话历史记录 from crazy_functions.辅助功能 import 清除缓存 - + from crazy_functions.批量Markdown翻译 import Markdown英译中 function_plugins = { "解析整个Python项目": { @@ -34,11 +34,11 @@ def get_crazy_functions(): }, "载入对话历史存档(先上传存档或输入路径)": { "Color": "stop", - "AsButton":False, + "AsButton": False, "Function": HotReload(载入对话历史存档) }, "删除所有本地对话历史记录(请谨慎操作)": { - "AsButton":False, + "AsButton": False, "Function": HotReload(删除所有本地对话历史记录) }, "清除所有缓存文件(请谨慎操作)": { @@ -48,10 +48,10 @@ def get_crazy_functions(): }, "解析Jupyter Notebook文件": { "Color": "stop", - "AsButton":False, + "AsButton": False, "Function": HotReload(解析ipynb文件), - "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) - "ArgsReminder": "若输入0,则不解析notebook中的Markdown块", # 高级参数输入区的显示提示 + "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) + "ArgsReminder": "若输入0,则不解析notebook中的Markdown块", # 高级参数输入区的显示提示 }, "批量总结Word文档": { "Color": "stop", @@ -255,8 +255,8 @@ def get_crazy_functions(): "解析项目源代码(手动指定和筛选源代码文件类型)": { "Color": "stop", "AsButton": False, - "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) - "ArgsReminder": "输入时用逗号隔开, *代表通配符, 加了^代表不匹配; 不输入代表全部匹配。例如: \"*.c, ^*.cpp, config.toml, ^*.toml\"", # 高级参数输入区的显示提示 + "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) + "ArgsReminder": "输入时用逗号隔开, *代表通配符, 加了^代表不匹配; 不输入代表全部匹配。例如: \"*.c, ^*.cpp, config.toml, ^*.toml\"", # 高级参数输入区的显示提示 "Function": HotReload(解析任意code项目) }, }) @@ -269,8 +269,8 @@ def get_crazy_functions(): "询问多个GPT模型(手动指定询问哪些模型)": { "Color": "stop", "AsButton": False, - "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) - "ArgsReminder": "支持任意数量的llm接口,用&符号分隔。例如chatglm&gpt-3.5-turbo&api2d-gpt-4", # 高级参数输入区的显示提示 + "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) + "ArgsReminder": "支持任意数量的llm接口,用&符号分隔。例如chatglm&gpt-3.5-turbo&api2d-gpt-4", # 高级参数输入区的显示提示 "Function": HotReload(同时问询_指定模型) }, }) @@ -283,8 +283,8 @@ def get_crazy_functions(): "图片生成(先切换模型到openai或api2d)": { "Color": "stop", "AsButton": False, - "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) - "ArgsReminder": "在这里输入分辨率, 如256x256(默认)", # 高级参数输入区的显示提示 + "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) + "ArgsReminder": "在这里输入分辨率, 如256x256(默认)", # 高级参数输入区的显示提示 "Function": HotReload(图片生成) }, }) @@ -358,7 +358,7 @@ def get_crazy_functions(): }) except: print('Load function plugin failed') - + try: from crazy_functions.交互功能函数模板 import 交互功能模板函数 function_plugins.update({ @@ -402,9 +402,10 @@ def get_crazy_functions(): "Color": "stop", "AsButton": False, "AdvancedArgs": True, - "ArgsReminder": - "如果有必要, 请在此处给出自定义翻译命令, 解决部分词汇翻译不准确的问题。 "+ - "例如当单词'agent'翻译不准确时, 请尝试把以下指令复制到高级参数区: " + 'If the term "agent" is used in this section, it should be translated to "智能体". ', + "ArgsReminder": + "如果有必要, 请在此处给出自定义翻译命令, 解决部分词汇翻译不准确的问题。 " + + "例如当单词'agent'翻译不准确时, 请尝试把以下指令复制到高级参数区: " + + 'If the term "agent" is used in this section, it should be translated to "智能体". ', "Function": HotReload(Latex翻译中文并重新编译PDF) } }) @@ -413,16 +414,16 @@ def get_crazy_functions(): "Color": "stop", "AsButton": False, "AdvancedArgs": True, - "ArgsReminder": - "如果有必要, 请在此处给出自定义翻译命令, 解决部分词汇翻译不准确的问题。 "+ - "例如当单词'agent'翻译不准确时, 请尝试把以下指令复制到高级参数区: " + 'If the term "agent" is used in this section, it should be translated to "智能体". ', + "ArgsReminder": + "如果有必要, 请在此处给出自定义翻译命令, 解决部分词汇翻译不准确的问题。 " + + "例如当单词'agent'翻译不准确时, 请尝试把以下指令复制到高级参数区: " + + 'If the term "agent" is used in this section, it should be translated to "智能体". ', "Function": HotReload(Latex翻译中文并重新编译PDF) } }) except: print('Load function plugin failed') - try: from toolbox import get_conf ENABLE_AUDIO, = get_conf('ENABLE_AUDIO') @@ -437,19 +438,17 @@ def get_crazy_functions(): }) except: print('Load function plugin failed') - - # try: - # from crazy_functions.虚空终端 import 终端 - # function_plugins.update({ - # "超级终端": { - # "Color": "stop", - # "AsButton": False, - # # "AdvancedArgs": True, - # # "ArgsReminder": "", - # "Function": HotReload(终端) - # } - # }) - # except: - # print('Load function plugin failed') + + try: + from crazy_functions.虚空终端 import 自动终端 + function_plugins.update({ + "自动终端": { + "Color": "stop", + "AsButton": False, + "Function": HotReload(自动终端) + } + }) + except: + print('Load function plugin failed') return function_plugins diff --git a/crazy_functions/json_fns/pydantic_io.py b/crazy_functions/json_fns/pydantic_io.py new file mode 100644 index 0000000..15cfc94 --- /dev/null +++ b/crazy_functions/json_fns/pydantic_io.py @@ -0,0 +1,100 @@ +""" +https://github.com/langchain-ai/langchain/blob/master/docs/extras/modules/model_io/output_parsers/pydantic.ipynb + +Example 1. + +# Define your desired data structure. +class Joke(BaseModel): + setup: str = Field(description="question to set up a joke") + punchline: str = Field(description="answer to resolve the joke") + + # You can add custom validation logic easily with Pydantic. + @validator("setup") + def question_ends_with_question_mark(cls, field): + if field[-1] != "?": + raise ValueError("Badly formed question!") + return field + + +Example 2. + +# Here's another example, but with a compound typed field. +class Actor(BaseModel): + name: str = Field(description="name of an actor") + film_names: List[str] = Field(description="list of names of films they starred in") +""" + +import json, re, logging + + +PYDANTIC_FORMAT_INSTRUCTIONS = """The output should be formatted as a JSON instance that conforms to the JSON schema below. + +As an example, for the schema {{"properties": {{"foo": {{"title": "Foo", "description": "a list of strings", "type": "array", "items": {{"type": "string"}}}}}}, "required": ["foo"]}} +the object {{"foo": ["bar", "baz"]}} is a well-formatted instance of the schema. The object {{"properties": {{"foo": ["bar", "baz"]}}}} is not well-formatted. + +Here is the output schema: +``` +{schema} +```""" + +class GptJsonIO(): + + def __init__(self, schema): + self.pydantic_object = schema + self.format_instructions = self.generate_format_instructions() + + def generate_format_instructions(self): + schema = self.pydantic_object.schema() + + # Remove extraneous fields. + reduced_schema = schema + if "title" in reduced_schema: + del reduced_schema["title"] + if "type" in reduced_schema: + del reduced_schema["type"] + # Ensure json in context is well-formed with double quotes. + schema_str = json.dumps(reduced_schema) + + return PYDANTIC_FORMAT_INSTRUCTIONS.format(schema=schema_str) + + def generate_output(self, text): + # Greedy search for 1st json candidate. + match = re.search( + r"\{.*\}", text.strip(), re.MULTILINE | re.IGNORECASE | re.DOTALL + ) + json_str = "" + if match: json_str = match.group() + json_object = json.loads(json_str, strict=False) + final_object = self.pydantic_object.parse_obj(json_object) + return final_object + + def generate_repair_prompt(self, broken_json, error): + prompt = "Fix a broken json string.\n\n" + \ + "(1) The broken json string need to fix is: \n\n" + \ + "```" + "\n" + \ + broken_json + "\n" + \ + "```" + "\n\n" + \ + "(2) The error message is: \n\n" + \ + error + "\n\n" + \ + "Now, fix this json string. \n\n" + return prompt + + def generate_output_auto_repair(self, response, gpt_gen_fn): + """ + response: string containing canidate json + gpt_gen_fn: gpt_gen_fn(inputs, sys_prompt) + """ + try: + result = self.generate_output(response) + except Exception as e: + try: + logging.info(f'Repairing json:{response}') + repair_prompt = self.generate_repair_prompt(broken_json = response, error=repr(e)) + result = self.generate_output(gpt_gen_fn(repair_prompt, self.generate_format_instructions())) + logging.info('Repaire json success.') + except Exception as e: + # 没辙了,放弃治疗 + logging.info('Repaire json fail.') + raise RuntimeError('Cannot repair json.', str(e)) + return result + diff --git a/crazy_functions/vt_fns/vt_modify_config.py b/crazy_functions/vt_fns/vt_modify_config.py new file mode 100644 index 0000000..cda7402 --- /dev/null +++ b/crazy_functions/vt_fns/vt_modify_config.py @@ -0,0 +1,66 @@ +from pydantic import BaseModel, Field +from typing import List +from toolbox import update_ui_lastest_msg +from request_llm.bridge_all import predict_no_ui_long_connection +from crazy_functions.json_fns.pydantic_io import GptJsonIO +import copy, json, pickle, os, sys + + +def modify_configuration_hot(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention): + import config + + # ⭐ ⭐ ⭐ 读取可配置项目条目 + from enum import Enum + names = {} + for k, v in config.__dict__.items(): + if k.startswith('__'): continue + names.update({k:k}) + # if len(names) > 20: break # 限制最多前10个配置项,如果太多了会导致gpt无法理解 + + ConfigOptions = Enum('ConfigOptions', names) + class ModifyConfigurationIntention(BaseModel): + which_config_to_modify: ConfigOptions = Field(description="the name of the configuration to modify, you must choose from one of the ConfigOptions enum.", default=None) + new_option_value: str = Field(description="the new value of the option", default=None) + + # ⭐ ⭐ ⭐ 分析用户意图 + yield from update_ui_lastest_msg(lastmsg=f"正在执行任务: {txt}\n\n读取新配置中", chatbot=chatbot, history=history, delay=0) + gpt_json_io = GptJsonIO(ModifyConfigurationIntention) + inputs = "Analyze how to change configuration according to following user input, answer me with json: \n\n" + \ + ">>" + txt + '\n\n' + \ + gpt_json_io.format_instructions + + run_gpt_fn = lambda inputs, sys_prompt: predict_no_ui_long_connection( + inputs=inputs, llm_kwargs=llm_kwargs, history=[], sys_prompt=sys_prompt, observe_window=[]) + user_intention = gpt_json_io.generate_output_auto_repair(run_gpt_fn(inputs, ""), run_gpt_fn) + + explicit_conf = user_intention.which_config_to_modify.value + + ok = (explicit_conf in txt) + if ok: + yield from update_ui_lastest_msg( + lastmsg=f"正在执行任务: {txt}\n\n新配置{explicit_conf}={user_intention.new_option_value}", + chatbot=chatbot, history=history, delay=1 + ) + yield from update_ui_lastest_msg( + lastmsg=f"正在执行任务: {txt}\n\n新配置{explicit_conf}={user_intention.new_option_value}\n\n正在修改配置中", + chatbot=chatbot, history=history, delay=2 + ) + + # ⭐ ⭐ ⭐ 立即应用配置 + from toolbox import set_conf + set_conf(explicit_conf, user_intention.new_option_value) + + yield from update_ui_lastest_msg( + lastmsg=f"正在执行任务: {txt}\n\n配置修改完成,重新页面即可生效。", chatbot=chatbot, history=history, delay=1 + ) + else: + yield from update_ui_lastest_msg( + lastmsg=f"失败,如果需要配置{explicit_conf},您需要明确说明并在指令中提到它。", chatbot=chatbot, history=history, delay=5 + ) + +def modify_configuration_reboot(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention): + yield from modify_configuration_hot(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention) + yield from update_ui_lastest_msg( + lastmsg=f"正在执行任务: {txt}\n\n配置修改完成,五秒后即将重启!若出现报错请无视即可。", chatbot=chatbot, history=history, delay=5 + ) + os.execl(sys.executable, sys.executable, *sys.argv) diff --git a/crazy_functions/虚空终端.py b/crazy_functions/虚空终端.py index 36667e9..272bc9a 100644 --- a/crazy_functions/虚空终端.py +++ b/crazy_functions/虚空终端.py @@ -1,119 +1,108 @@ +from pydantic import BaseModel, Field +from typing import List from toolbox import CatchException, update_ui, gen_time_str -from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive -from .crazy_utils import input_clipping -import copy, json +from toolbox import update_ui_lastest_msg +from request_llm.bridge_all import predict_no_ui_long_connection +from crazy_functions.crazy_utils import request_gpt_model_in_new_thread_with_ui_alive +from crazy_functions.crazy_utils import input_clipping +from crazy_functions.json_fns.pydantic_io import GptJsonIO +from crazy_functions.vt_fns.vt_modify_config import modify_configuration_hot +from crazy_functions.vt_fns.vt_modify_config import modify_configuration_reboot +from enum import Enum +import copy, json, pickle, os, sys -def get_fn_lib(): - return { - "BatchTranslatePDFDocuments_MultiThreaded": { - "module": "crazy_functions.批量翻译PDF文档_多线程", - "function": "批量翻译PDF文档", - "description": "Translate PDF Documents", - "arg_1_description": "A path containing pdf files.", - }, - "SummarizingWordDocuments": { - "module": "crazy_functions.总结word文档", - "function": "总结word文档", - "description": "Summarize Word Documents", - "arg_1_description": "A path containing Word files.", - }, - "ImageGeneration": { - "module": "crazy_functions.图片生成", - "function": "图片生成", - "description": "Generate a image that satisfies some description.", - "arg_1_description": "Descriptions about the image to be generated.", - }, - "TranslateMarkdownFromEnglishToChinese": { - "module": "crazy_functions.批量Markdown翻译", - "function": "Markdown中译英", - "description": "Translate Markdown Documents from English to Chinese.", - "arg_1_description": "A path containing Markdown files.", - }, - "SummaryAudioVideo": { - "module": "crazy_functions.总结音视频", - "function": "总结音视频", - "description": "Get text from a piece of audio and summarize this audio.", - "arg_1_description": "A path containing audio files.", - }, - } +class IntentionEnum(str, Enum): + ModifyConfiguration = 'ModifyConfiguration' + ExecutePlugin = 'ExecutePlugin' + Chat = 'Chat' -functions = [ - { - "name": k, - "description": v['description'], - "parameters": { - "type": "object", - "properties": { - "plugin_arg_1": { - "type": "string", - "description": v['arg_1_description'], - }, - }, - "required": ["plugin_arg_1"], - }, - } for k, v in get_fn_lib().items() -] +class UserIntention(BaseModel): + user_prompt: str = Field(description="the content of user input", default="") + intention_type: IntentionEnum = Field(description="the type of user intention", default=IntentionEnum.Chat) + user_provide_file: bool = Field(description="whether the user provides a path to a file", default=False) + user_provide_url: bool = Field(description="whether the user provides a url", default=False) -def inspect_dependency(chatbot, history): - return True +def execute_plugin(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention): + # 没写完 + pass -def eval_code(code, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): - import importlib - try: - tmp = get_fn_lib()[code['name']] - fp, fn = tmp['module'], tmp['function'] - fn_plugin = getattr(importlib.import_module(fp, fn), fn) - arg = json.loads(code['arguments'])['plugin_arg_1'] - yield from fn_plugin(arg, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port) - except: - from toolbox import trimmed_format_exc - chatbot.append(["执行错误", f"\n```\n{trimmed_format_exc()}\n```\n"]) - yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 - -def get_code_block(reply): - import re - pattern = r"```([\s\S]*?)```" # regex pattern to match code blocks - matches = re.findall(pattern, reply) # find all code blocks in text - if len(matches) != 1: - raise RuntimeError("GPT is not generating proper code.") - return matches[0].strip('python') # code block +def chat(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention): + gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( + inputs=txt, inputs_show_user=txt, + llm_kwargs=llm_kwargs, chatbot=chatbot, history=[], + sys_prompt=system_prompt + ) + chatbot[-1] = [txt, gpt_say] + history.extend([txt, gpt_say]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + pass @CatchException -def 终端(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): +def 自动终端(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): """ - txt 输入栏用户输入的文本, 例如需要翻译的一段话, 再例如一个包含了待处理文件的路径 + txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径 llm_kwargs gpt模型参数, 如温度和top_p等, 一般原样传递下去就行 - plugin_kwargs 插件模型的参数, 暂时没有用武之地 - chatbot 聊天显示框的句柄, 用于显示给用户 - history 聊天历史, 前情提要 + plugin_kwargs 插件模型的参数, 如温度和top_p等, 一般原样传递下去就行 + chatbot 聊天显示框的句柄,用于显示给用户 + history 聊天历史,前情提要 system_prompt 给gpt的静默提醒 web_port 当前软件运行的端口号 """ - # 清空历史, 以免输入溢出 - history = [] - - # 基本信息:功能、贡献者 - chatbot.append(["虚空终端插件的功能?", "根据自然语言的描述, 执行任意插件的命令."]) + history = [] # 清空历史,以免输入溢出 + chatbot.append(("自动终端状态: ", f"正在执行任务: {txt}")) yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 - - # 输入 - i_say = txt - # 开始 - llm_kwargs_function_call = copy.deepcopy(llm_kwargs) - llm_kwargs_function_call['llm_model'] = 'gpt-call-fn' # 修改调用函数 - gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( - inputs=i_say, inputs_show_user=txt, - llm_kwargs=llm_kwargs_function_call, chatbot=chatbot, history=[], - sys_prompt=functions - ) - # 将代码转为动画 - res = json.loads(gpt_say)['choices'][0] - if res['finish_reason'] == 'function_call': - code = json.loads(gpt_say)['choices'][0] - yield from eval_code(code['message']['function_call'], llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port) - else: - chatbot.append(["无法调用相关功能", res]) - yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + # 初始化插件状态 + state = chatbot._cookies.get('plugin_state', None) + if state is not None: state = pickle.loads(state) + else: state = {} + + def update_vt_state(): + # 赋予插件锁定 锁定插件回调路径,当下一次用户提交时,会直接转到该函数 + chatbot._cookies['lock_plugin'] = 'crazy_functions.虚空终端->自动终端' + chatbot._cookies['vt_state'] = pickle.dumps(state) + + # ⭐ ⭐ ⭐ 分析用户意图 + yield from update_ui_lastest_msg(lastmsg=f"正在执行任务: {txt}\n\n分析用户意图中", chatbot=chatbot, history=history, delay=0) + gpt_json_io = GptJsonIO(UserIntention) + inputs = "Analyze the intention of the user according to following user input: \n\n" + txt + '\n\n' + gpt_json_io.format_instructions + run_gpt_fn = lambda inputs, sys_prompt: predict_no_ui_long_connection( + inputs=inputs, llm_kwargs=llm_kwargs, history=[], sys_prompt=sys_prompt, observe_window=[]) + user_intention = gpt_json_io.generate_output_auto_repair(run_gpt_fn(inputs, ""), run_gpt_fn) + + # 用户意图: 修改本项目的配置 + if user_intention.intention_type == IntentionEnum.ModifyConfiguration: + yield from modify_configuration_reboot(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention) + + # 用户意图: 调度插件 + if user_intention.intention_type == IntentionEnum.ExecutePlugin: + yield from execute_plugin(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention) + + # 用户意图: 聊天 + if user_intention.intention_type == IntentionEnum.Chat: + yield from chat(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, user_intention) + + # update_vt_state() + + return + + + + # # if state == 'wait_user_keyword': + # # chatbot._cookies['lock_plugin'] = None # 解除插件锁定,避免遗忘导致死锁 + # # chatbot._cookies['plugin_state_0001'] = None # 解除插件状态,避免遗忘导致死锁 + + # # # 解除插件锁定 + # # chatbot.append((f"获取关键词:{txt}", "")) + # # yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + # # inputs=inputs_show_user=f"Extract all image urls in this html page, pick the first 5 images and show them with markdown format: \n\n {page_return}" + # # gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( + # # inputs=inputs, inputs_show_user=inputs_show_user, + # # llm_kwargs=llm_kwargs, chatbot=chatbot, history=[], + # # sys_prompt="When you want to show an image, use markdown format. e.g. ![image_description](image_url). If there are no image url provided, answer 'no image url provided'" + # # ) + # # chatbot[-1] = [chatbot[-1][0], gpt_say] + # yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + # return diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 4913a59..3c31cbb 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -9,6 +9,8 @@ validate_path() # 返回项目根路径 from tests.test_utils import plugin_test if __name__ == "__main__": + plugin_test(plugin='crazy_functions.虚空终端->自动终端', main_input='修改api-key为sk-jhoejriotherjep') + # plugin_test(plugin='crazy_functions.命令行助手->命令行助手', main_input='查看当前的docker容器列表') # plugin_test(plugin='crazy_functions.解析项目源代码->解析一个Python项目', main_input="crazy_functions/test_project/python/dqn") @@ -19,7 +21,7 @@ if __name__ == "__main__": # plugin_test(plugin='crazy_functions.批量Markdown翻译->Markdown中译英', main_input="README.md") - plugin_test(plugin='crazy_functions.批量翻译PDF文档_多线程->批量翻译PDF文档', main_input='crazy_functions/test_project/pdf_and_word/aaai.pdf') + # plugin_test(plugin='crazy_functions.批量翻译PDF文档_多线程->批量翻译PDF文档', main_input='crazy_functions/test_project/pdf_and_word/aaai.pdf') # plugin_test(plugin='crazy_functions.谷歌检索小助手->谷歌检索小助手', main_input="https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=auto+reinforcement+learning&btnG=")