diff --git a/.gitignore b/.gitignore index 6d0e0cce..c353e4f2 100644 --- a/.gitignore +++ b/.gitignore @@ -153,6 +153,6 @@ media flagged request_llms/ChatGLM-6b-onnx-u8s8 .pre-commit-config.yaml -themes/common.js.min.*.js test.html -objdump* \ No newline at end of file +objdump* +*.min.*.js diff --git a/crazy_functional.py b/crazy_functional.py index bf435be0..2a45f433 100644 --- a/crazy_functional.py +++ b/crazy_functional.py @@ -439,7 +439,7 @@ def get_crazy_functions(): "询问多个GPT模型(手动指定询问哪些模型)": { "Group": "对话", "Color": "stop", - "AsButton": False, + "AsButton": True, "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False) "ArgsReminder": "支持任意数量的llm接口,用&符号分隔。例如chatglm&gpt-3.5-turbo&gpt-4", # 高级参数输入区的显示提示 "Function": HotReload(同时问询_指定模型), diff --git a/main.py b/main.py index b4c424b0..0ad79b78 100644 --- a/main.py +++ b/main.py @@ -44,7 +44,8 @@ def main(): raise ModuleNotFoundError("使用项目内置Gradio获取最优体验! 请运行 `pip install -r requirements.txt` 指令安装内置Gradio及其他依赖, 详情信息见requirements.txt.") from request_llms.bridge_all import predict from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, DummyWith - # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址 + + # 读取配置 proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION') CHATBOT_HEIGHT, LAYOUT, AVAIL_LLM_MODELS, AUTO_CLEAR_TXT = get_conf('CHATBOT_HEIGHT', 'LAYOUT', 'AVAIL_LLM_MODELS', 'AUTO_CLEAR_TXT') ENABLE_AUDIO, AUTO_CLEAR_TXT, PATH_LOGGING, AVAIL_THEMES, THEME, ADD_WAIFU = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT', 'PATH_LOGGING', 'AVAIL_THEMES', 'THEME', 'ADD_WAIFU') @@ -56,7 +57,7 @@ def main(): PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT from check_proxy import get_current_version from themes.theme import adjust_theme, advanced_css, theme_declaration, js_code_clear, js_code_reset, js_code_show_or_hide, js_code_show_or_hide_group2 - from themes.theme import js_code_for_css_changing, js_code_for_toggle_darkmode, js_code_for_persistent_cookie_init + from themes.theme import js_code_for_toggle_darkmode, js_code_for_persistent_cookie_init from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, assign_user_uuid title_html = f"

GPT 学术优化 {get_current_version()}

{theme_declaration}" @@ -84,6 +85,7 @@ def main(): from check_proxy import check_proxy, auto_update, warm_up_modules proxy_info = check_proxy(proxies) + # 切换布局 gr_L1 = lambda: gr.Row().style() gr_L2 = lambda scale, elem_id: gr.Column(scale=scale, elem_id=elem_id, min_width=400) if LAYOUT == "TOP-DOWN": @@ -141,13 +143,15 @@ def main(): plugin_group_sel = gr.Dropdown(choices=all_plugin_groups, label='', show_label=False, value=DEFAULT_FN_GROUPS, multiselect=True, interactive=True, elem_classes='normal_mut_select').style(container=False) with gr.Row(): - for k, plugin in plugins.items(): + for index, (k, plugin) in enumerate(plugins.items()): if not plugin.get("AsButton", True): continue visible = True if match_group(plugin['Group'], DEFAULT_FN_GROUPS) else False variant = plugins[k]["Color"] if "Color" in plugin else "secondary" info = plugins[k].get("Info", k) + btn_elem_id = f"plugin_btn_{index}" plugin['Button'] = plugins[k]['Button'] = gr.Button(k, variant=variant, - visible=visible, info_str=f'函数插件区: {info}').style(size="sm") + visible=visible, info_str=f'函数插件区: {info}', elem_id=btn_elem_id).style(size="sm") + plugin['ButtonElemId'] = btn_elem_id with gr.Row(): with gr.Accordion("更多函数插件", open=True): dropdown_fn_list = [] @@ -166,14 +170,17 @@ def main(): with gr.Accordion("点击展开“文件下载区”。", open=False) as area_file_up: file_upload = gr.Files(label="任何文件, 推荐上传压缩文件(zip, tar)", file_count="multiple", elem_id="elem_upload") + # 左上角工具栏定义 from themes.gui_toolbar import define_gui_toolbar checkboxes, checkboxes_2, max_length_sl, theme_dropdown, system_prompt, file_upload_2, md_dropdown, top_p, temperature = \ define_gui_toolbar(AVAIL_LLM_MODELS, LLM_MODEL, INIT_SYS_PROMPT, THEME, AVAIL_THEMES, ADD_WAIFU, help_menu_description, js_code_for_toggle_darkmode) + # 浮动菜单定义 from themes.gui_floating_menu import define_gui_floating_menu area_input_secondary, txt2, area_customize, submitBtn2, resetBtn2, clearBtn2, stopBtn2 = \ define_gui_floating_menu(customize_btns, functional, predefined_btns, cookies, web_cookie_cache) + # 插件二级菜单的实现 from themes.gui_advanced_plugin_class import define_gui_advanced_plugin_class new_plugin_callback, route_switchy_bt_with_arg, usr_confirmed_arg = \ define_gui_advanced_plugin_class(plugins) @@ -231,6 +238,7 @@ def main(): file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies]).then(None, None, None, _js=r"()=>{toast_push('上传完毕 ...'); cancel_loading_status();}") file_upload_2.upload(on_file_uploaded, [file_upload_2, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies]).then(None, None, None, _js=r"()=>{toast_push('上传完毕 ...'); cancel_loading_status();}") # 函数插件-固定按钮区 + for k in plugins: register_advanced_plugin_init_arr += f"""register_plugin_init("{k}","{encode_plugin_info(k, plugins[k])}");""" if plugins[k].get("Class", None): @@ -239,30 +247,19 @@ def main(): if not plugins[k].get("AsButton", True): continue if plugins[k].get("Class", None) is None: assert plugins[k].get("Function", None) is not None - click_handle = plugins[k]["Button"].click(ArgsGeneralWrapper(plugins[k]["Function"]), [*input_combo], output_combo) - click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot]).then(None, [plugins[k]["Button"]], None, _js=r"(fn)=>on_plugin_exe_complete(fn)") - cancel_handles.append(click_handle) + click_handle = plugins[k]["Button"].click(None, inputs=[], outputs=None, _js=f"""()=>run_classic_plugin_via_id("{plugins[k]["ButtonElemId"]}")""") else: click_handle = plugins[k]["Button"].click(None, inputs=[], outputs=None, _js=f"""()=>run_advanced_plugin_launch_code("{k}")""") - # 函数插件-下拉菜单与随变按钮的互动(旧版) - # def on_dropdown_changed(k): - # variant = plugins[k]["Color"] if "Color" in plugins[k] else "secondary" # 选择颜色 - # info = plugins[k].get("Info", k) # 获取info - # ret = {switchy_bt: gr.update(value=k, variant=variant, info_str=f'函数插件区: {info}')} - # if plugins[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区 - # ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + plugins[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))}) - # else: - # ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")}) - # return ret - # dropdown.select(on_dropdown_changed, [dropdown], [switchy_bt, plugin_advanced_arg] ) # 函数插件-下拉菜单与随变按钮的互动(新版-更流畅) dropdown.select(None, [dropdown], None, _js=f"""(dropdown)=>run_dropdown_shift(dropdown)""") + # 模型切换时的回调 def on_md_dropdown_changed(k): return {chatbot: gr.update(label="当前模型:"+k)} md_dropdown.select(on_md_dropdown_changed, [md_dropdown], [chatbot]) + # 主题修改 def on_theme_dropdown_changed(theme, secret_css): adjust_theme, css_part1, _, adjust_dynamic_theme = load_dynamic_theme(theme) if adjust_dynamic_theme: @@ -270,15 +267,8 @@ def main(): else: css_part2 = adjust_theme()._get_theme_css() return css_part2 + css_part1 - - theme_handle = theme_dropdown.select(on_theme_dropdown_changed, [theme_dropdown, secret_css], [secret_css]) - theme_handle.then( - None, - [secret_css], - None, - _js=js_code_for_css_changing - ) - + theme_handle = theme_dropdown.select(on_theme_dropdown_changed, [theme_dropdown, secret_css], [secret_css]) # , _js="""change_theme_prepare""") + theme_handle.then(None, [theme_dropdown, secret_css], None, _js="""change_theme""") switchy_bt.click(None, [switchy_bt], None, _js="(switchy_bt)=>on_flex_button_click(switchy_bt)") # 随变按钮的回调函数注册 @@ -293,9 +283,10 @@ def main(): click_handle_ng.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot]).then(None, [switchy_bt], None, _js=r"(fn)=>on_plugin_exe_complete(fn)") cancel_handles.append(click_handle_ng) # 新一代插件的高级参数区确认按钮(隐藏) - click_handle_ng = new_plugin_callback.click(route_switchy_bt_with_arg, [ - gr.State(["new_plugin_callback", "usr_confirmed_arg"] + input_combo_order), - new_plugin_callback, usr_confirmed_arg, *input_combo + click_handle_ng = new_plugin_callback.click(route_switchy_bt_with_arg, + [ + gr.State(["new_plugin_callback", "usr_confirmed_arg"] + input_combo_order), # 第一个参数: 指定了后续参数的名称 + new_plugin_callback, usr_confirmed_arg, *input_combo # 后续参数: 真正的参数 ], output_combo) click_handle_ng.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot]).then(None, [switchy_bt], None, _js=r"(fn)=>on_plugin_exe_complete(fn)") cancel_handles.append(click_handle_ng) @@ -315,6 +306,8 @@ def main(): elif match_group(plugin['Group'], group_list): fns_list.append(k) # 刷新下拉列表 return [*btn_list, gr.Dropdown.update(choices=fns_list)] plugin_group_sel.select(fn=on_group_change, inputs=[plugin_group_sel], outputs=[*[plugin['Button'] for name, plugin in plugins_as_btn.items()], dropdown]) + + # 是否启动语音输入功能 if ENABLE_AUDIO: from crazy_functions.live_audio.audio_io import RealtimeAudioDistribution rad = RealtimeAudioDistribution() @@ -322,18 +315,18 @@ def main(): rad.feed(cookies['uuid'].hex, audio) audio_mic.stream(deal_audio, inputs=[audio_mic, cookies]) - + # 生成当前浏览器窗口的uuid(刷新失效) app_block.load(assign_user_uuid, inputs=[cookies], outputs=[cookies]) + # 初始化(前端) from shared_utils.cookie_manager import load_web_cookie_cache__fn_builder load_web_cookie_cache = load_web_cookie_cache__fn_builder(customize_btns, cookies, predefined_btns) app_block.load(load_web_cookie_cache, inputs = [web_cookie_cache, cookies], outputs = [web_cookie_cache, cookies, *customize_btns.values(), *predefined_btns.values()], _js=js_code_for_persistent_cookie_init) - app_block.load(None, inputs=[], outputs=None, _js=f"""()=>GptAcademicJavaScriptInit("{DARK_MODE}","{INIT_SYS_PROMPT}","{ADD_WAIFU}","{LAYOUT}","{TTS_TYPE}")""") # 配置暗色主题或亮色主题 app_block.load(None, inputs=[], outputs=None, _js="""()=>{REP}""".replace("REP", register_advanced_plugin_init_arr)) - # gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数 + # Gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数 def run_delayed_tasks(): import threading, webbrowser, time print(f"如果浏览器没有自动打开,请复制并转到以下URL:") diff --git a/request_llms/bridge_qwen.py b/request_llms/bridge_qwen.py index 2b1eeed2..0a06545b 100644 --- a/request_llms/bridge_qwen.py +++ b/request_llms/bridge_qwen.py @@ -1,7 +1,7 @@ import time import os from toolbox import update_ui, get_conf, update_ui_lastest_msg -from toolbox import check_packages, report_exception +from toolbox import check_packages, report_exception, log_chat model_name = 'Qwen' @@ -59,6 +59,7 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp chatbot[-1] = (inputs, response) yield from update_ui(chatbot=chatbot, history=history) + log_chat(llm_model=llm_kwargs["llm_model"], input_str=inputs, output_str=response) # 总结输出 if response == f"[Local Message] 等待{model_name}响应中 ...": response = f"[Local Message] {model_name}响应异常 ..." diff --git a/request_llms/com_qwenapi.py b/request_llms/com_qwenapi.py index 2cde52c1..a3adad0b 100644 --- a/request_llms/com_qwenapi.py +++ b/request_llms/com_qwenapi.py @@ -65,8 +65,12 @@ class QwenRequestInstance(): self.result_buf += f"[Local Message] 请求错误:状态码:{response.status_code},错误码:{response.code},消息:{response.message}" yield self.result_buf break - logging.info(f'[raw_input] {inputs}') - logging.info(f'[response] {self.result_buf}') + + # 耗尽generator避免报错 + while True: + try: next(responses) + except: break + return self.result_buf diff --git a/themes/common.js b/themes/common.js index ccdc2aed..34351f08 100644 --- a/themes/common.js +++ b/themes/common.js @@ -1,3 +1,6 @@ +// 标志位 +enable_tts = false; + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // 第 1 部分: 工具函数 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -914,131 +917,6 @@ function gpt_academic_gradio_saveload( } } -enable_tts = false; -async function GptAcademicJavaScriptInit(dark, prompt, live2d, layout, tts) { - // 第一部分,布局初始化 - audio_fn_init(); - minor_ui_adjustment(); - chatbotIndicator = gradioApp().querySelector('#gpt-chatbot > div.wrap'); - var chatbotObserver = new MutationObserver(() => { - chatbotContentChanged(1); - }); - chatbotObserver.observe(chatbotIndicator, { attributes: true, childList: true, subtree: true }); - if (layout === "LEFT-RIGHT") { chatbotAutoHeight(); } - if (layout === "LEFT-RIGHT") { limit_scroll_position(); } - - // 第二部分,读取Cookie,初始话界面 - let searchString = ""; - let bool_value = ""; - // darkmode 深色模式 - if (getCookie("js_darkmode_cookie")) { - dark = getCookie("js_darkmode_cookie") - } - dark = dark == "True"; - if (document.querySelectorAll('.dark').length) { - if (!dark) { - document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark')); - } - } else { - if (dark) { - document.querySelector('body').classList.add('dark'); - } - } - - // 自动朗读 - if (tts != "DISABLE"){ - enable_tts = true; - if (getCookie("js_auto_read_cookie")) { - auto_read_tts = getCookie("js_auto_read_cookie") - auto_read_tts = auto_read_tts == "True"; - if (auto_read_tts) { - allow_auto_read_tts_flag = true; - } - } - } - - // SysPrompt 系统静默提示词 - gpt_academic_gradio_saveload("load", "elem_prompt", "js_system_prompt_cookie", null, "str"); - // Temperature 大模型温度参数 - gpt_academic_gradio_saveload("load", "elem_temperature", "js_temperature_cookie", null, "float"); - // md_dropdown 大模型类型选择 - if (getCookie("js_md_dropdown_cookie")) { - const cached_model = getCookie("js_md_dropdown_cookie"); - var model_sel = await get_gradio_component("elem_model_sel"); - // determine whether the cached model is in the choices - if (model_sel.props.choices.includes(cached_model)){ - // change dropdown - gpt_academic_gradio_saveload("load", "elem_model_sel", "js_md_dropdown_cookie", null, "str"); - // 连锁修改chatbot的label - push_data_to_gradio_component({ - label: '当前模型:' + getCookie("js_md_dropdown_cookie"), - __type__: 'update' - }, "gpt-chatbot", "obj") - } - } - - - - // clearButton 自动清除按钮 - if (getCookie("js_clearbtn_show_cookie")) { - // have cookie - bool_value = getCookie("js_clearbtn_show_cookie") - bool_value = bool_value == "True"; - searchString = "输入清除键"; - - if (bool_value) { - // make btns appear - let clearButton = document.getElementById("elem_clear"); clearButton.style.display = "block"; - let clearButton2 = document.getElementById("elem_clear2"); clearButton2.style.display = "block"; - // deal with checkboxes - let arr_with_clear_btn = update_array( - await get_data_from_gradio_component('cbs'), "输入清除键", "add" - ) - push_data_to_gradio_component(arr_with_clear_btn, "cbs", "no_conversion"); - } else { - // make btns disappear - let clearButton = document.getElementById("elem_clear"); clearButton.style.display = "none"; - let clearButton2 = document.getElementById("elem_clear2"); clearButton2.style.display = "none"; - // deal with checkboxes - let arr_without_clear_btn = update_array( - await get_data_from_gradio_component('cbs'), "输入清除键", "remove" - ) - push_data_to_gradio_component(arr_without_clear_btn, "cbs", "no_conversion"); - } - } - - // live2d 显示 - if (getCookie("js_live2d_show_cookie")) { - // have cookie - searchString = "添加Live2D形象"; - bool_value = getCookie("js_live2d_show_cookie"); - bool_value = bool_value == "True"; - if (bool_value) { - loadLive2D(); - let arr_with_live2d = update_array( - await get_data_from_gradio_component('cbsc'), "添加Live2D形象", "add" - ) - push_data_to_gradio_component(arr_with_live2d, "cbsc", "no_conversion"); - } else { - try { - $('.waifu').hide(); - let arr_without_live2d = update_array( - await get_data_from_gradio_component('cbsc'), "添加Live2D形象", "remove" - ) - push_data_to_gradio_component(arr_without_live2d, "cbsc", "no_conversion"); - } catch (error) { - } - } - } else { - // do not have cookie - if (live2d) { - loadLive2D(); - } else { - } - } - -} - function reset_conversation(a, b) { // console.log("js_code_reset"); @@ -1706,6 +1584,7 @@ function register_plugin_init(key, base64String){ } plugin_init_info_lib[key].info = guiJsonData.Info; plugin_init_info_lib[key].color = guiJsonData.Color; + plugin_init_info_lib[key].elem_id = guiJsonData.ButtonElemId; plugin_init_info_lib[key].label = guiJsonData.Label plugin_init_info_lib[key].enable_advanced_arg = guiJsonData.AdvancedArgs; plugin_init_info_lib[key].arg_reminder = guiJsonData.ArgsReminder; @@ -1760,4 +1639,35 @@ async function duplicate_in_new_window() { var url = window.location.href; // 在新标签页中打开这个URL window.open(url, '_blank'); -} \ No newline at end of file +} + +async function run_classic_plugin_via_id(plugin_elem_id){ + // find elementid + for (key in plugin_init_info_lib){ + if (plugin_init_info_lib[key].elem_id == plugin_elem_id){ + let current_btn_name = await get_data_from_gradio_component(plugin_elem_id); + console.log(current_btn_name); + + gui_args = {} + // 关闭菜单 (如果处于开启状态) + push_data_to_gradio_component({ + visible: false, + __type__: 'update' + }, "plugin_arg_menu", "obj"); + hide_all_elem(); + // 为了与旧插件兼容,生成菜单时,自动加载旧高级参数输入区的值 + let advance_arg_input_legacy = await get_data_from_gradio_component('advance_arg_input_legacy'); + if (advance_arg_input_legacy.length != 0){ + gui_args["advanced_arg"] = {}; + gui_args["advanced_arg"].user_confirmed_value = advance_arg_input_legacy; + } + // execute the plugin + push_data_to_gradio_component(JSON.stringify(gui_args), "invisible_current_pop_up_plugin_arg_final", "string"); + push_data_to_gradio_component(current_btn_name, "invisible_callback_btn_for_plugin_exe", "string"); + document.getElementById("invisible_callback_btn_for_plugin_exe").click(); + return; + } + } + // console.log('unable to find function'); + return; +} diff --git a/themes/common.py b/themes/common.py index 50a9e6e4..9b5e8e48 100644 --- a/themes/common.py +++ b/themes/common.py @@ -1,3 +1,4 @@ +from functools import cache from toolbox import get_conf CODE_HIGHLIGHT, ADD_WAIFU, LAYOUT = get_conf("CODE_HIGHLIGHT", "ADD_WAIFU", "LAYOUT") @@ -23,22 +24,30 @@ def minimize_js(common_js_path): except: return common_js_path +@cache def get_common_html_javascript_code(): js = "\n" - common_js_path = "themes/common.js" - minimized_js_path = minimize_js(common_js_path) - for jsf in [ - f"file={minimized_js_path}", - ]: - js += f"""\n""" + common_js_path_list = [ + "themes/common.js", + "themes/theme.js", + "themes/init.js", + ] - # 添加Live2D - if ADD_WAIFU: + if ADD_WAIFU: # 添加Live2D + common_js_path_list += [ + "themes/waifu_plugin/jquery.min.js", + "themes/waifu_plugin/jquery-ui.min.js", + ] + + for common_js_path in common_js_path_list: + if '.min.' not in common_js_path: + minimized_js_path = minimize_js(common_js_path) for jsf in [ - "file=themes/waifu_plugin/jquery.min.js", - "file=themes/waifu_plugin/jquery-ui.min.js", + f"file={minimized_js_path}", ]: js += f"""\n""" - else: + + if not ADD_WAIFU: js += """\n""" + return js diff --git a/themes/gui_advanced_plugin_class.py b/themes/gui_advanced_plugin_class.py index 65332e10..48951874 100644 --- a/themes/gui_advanced_plugin_class.py +++ b/themes/gui_advanced_plugin_class.py @@ -31,18 +31,27 @@ def define_gui_advanced_plugin_class(plugins): invisible_callback_btn_for_plugin_exe = gr.Button(r"未选定任何插件", variant="secondary", visible=False, elem_id="invisible_callback_btn_for_plugin_exe").style(size="sm") # 随变按钮的回调函数注册 def route_switchy_bt_with_arg(request: gr.Request, input_order, *arg): - arguments = {k:v for k,v in zip(input_order, arg)} - which_plugin = arguments.pop('new_plugin_callback') + arguments = {k:v for k,v in zip(input_order, arg)} # 重新梳理输入参数,转化为kwargs字典 + which_plugin = arguments.pop('new_plugin_callback') # 获取需要执行的插件名称 if which_plugin in [r"未选定任何插件"]: return - usr_confirmed_arg = arguments.pop('usr_confirmed_arg') + usr_confirmed_arg = arguments.pop('usr_confirmed_arg') # 获取插件参数 arg_confirm: dict = {} - usr_confirmed_arg_dict = json.loads(usr_confirmed_arg) + usr_confirmed_arg_dict = json.loads(usr_confirmed_arg) # 读取插件参数 for arg_name in usr_confirmed_arg_dict: arg_confirm.update({arg_name: str(usr_confirmed_arg_dict[arg_name]['user_confirmed_value'])}) - plugin_obj = plugins[which_plugin]["Class"] - arguments['plugin_advanced_arg'] = arg_confirm - if arg_confirm.get('main_input', None) is not None: + + if plugins[which_plugin].get("Class", None) is not None: # 获取插件执行函数 + plugin_obj = plugins[which_plugin]["Class"] + plugin_exe = plugin_obj.execute + else: + plugin_exe = plugins[which_plugin]["Function"] + + arguments['plugin_advanced_arg'] = arg_confirm # 更新高级参数输入区的参数 + if arg_confirm.get('main_input', None) is not None: # 更新主输入区的参数 arguments['txt'] = arg_confirm['main_input'] - yield from ArgsGeneralWrapper(plugin_obj.execute)(request, *arguments.values()) + + # 万事俱备,开始执行 + yield from ArgsGeneralWrapper(plugin_exe)(request, *arguments.values()) + return invisible_callback_btn_for_plugin_exe, route_switchy_bt_with_arg, usr_confirmed_arg diff --git a/themes/init.js b/themes/init.js new file mode 100644 index 00000000..0f5711bb --- /dev/null +++ b/themes/init.js @@ -0,0 +1,125 @@ +async function GptAcademicJavaScriptInit(dark, prompt, live2d, layout, tts) { + // 第一部分,布局初始化 + audio_fn_init(); + minor_ui_adjustment(); + chatbotIndicator = gradioApp().querySelector('#gpt-chatbot > div.wrap'); + var chatbotObserver = new MutationObserver(() => { + chatbotContentChanged(1); + }); + chatbotObserver.observe(chatbotIndicator, { attributes: true, childList: true, subtree: true }); + if (layout === "LEFT-RIGHT") { chatbotAutoHeight(); } + if (layout === "LEFT-RIGHT") { limit_scroll_position(); } + + // 第二部分,读取Cookie,初始话界面 + let searchString = ""; + let bool_value = ""; + // darkmode 深色模式 + if (getCookie("js_darkmode_cookie")) { + dark = getCookie("js_darkmode_cookie") + } + dark = dark == "True"; + if (document.querySelectorAll('.dark').length) { + if (!dark) { + document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark')); + } + } else { + if (dark) { + document.querySelector('body').classList.add('dark'); + } + } + + // 自动朗读 + if (tts != "DISABLE"){ + enable_tts = true; + if (getCookie("js_auto_read_cookie")) { + auto_read_tts = getCookie("js_auto_read_cookie") + auto_read_tts = auto_read_tts == "True"; + if (auto_read_tts) { + allow_auto_read_tts_flag = true; + } + } + } + + // SysPrompt 系统静默提示词 + gpt_academic_gradio_saveload("load", "elem_prompt", "js_system_prompt_cookie", null, "str"); + // Temperature 大模型温度参数 + gpt_academic_gradio_saveload("load", "elem_temperature", "js_temperature_cookie", null, "float"); + // md_dropdown 大模型类型选择 + if (getCookie("js_md_dropdown_cookie")) { + const cached_model = getCookie("js_md_dropdown_cookie"); + var model_sel = await get_gradio_component("elem_model_sel"); + // determine whether the cached model is in the choices + if (model_sel.props.choices.includes(cached_model)){ + // change dropdown + gpt_academic_gradio_saveload("load", "elem_model_sel", "js_md_dropdown_cookie", null, "str"); + // 连锁修改chatbot的label + push_data_to_gradio_component({ + label: '当前模型:' + getCookie("js_md_dropdown_cookie"), + __type__: 'update' + }, "gpt-chatbot", "obj") + } + } + + + + // clearButton 自动清除按钮 + if (getCookie("js_clearbtn_show_cookie")) { + // have cookie + bool_value = getCookie("js_clearbtn_show_cookie") + bool_value = bool_value == "True"; + searchString = "输入清除键"; + + if (bool_value) { + // make btns appear + let clearButton = document.getElementById("elem_clear"); clearButton.style.display = "block"; + let clearButton2 = document.getElementById("elem_clear2"); clearButton2.style.display = "block"; + // deal with checkboxes + let arr_with_clear_btn = update_array( + await get_data_from_gradio_component('cbs'), "输入清除键", "add" + ) + push_data_to_gradio_component(arr_with_clear_btn, "cbs", "no_conversion"); + } else { + // make btns disappear + let clearButton = document.getElementById("elem_clear"); clearButton.style.display = "none"; + let clearButton2 = document.getElementById("elem_clear2"); clearButton2.style.display = "none"; + // deal with checkboxes + let arr_without_clear_btn = update_array( + await get_data_from_gradio_component('cbs'), "输入清除键", "remove" + ) + push_data_to_gradio_component(arr_without_clear_btn, "cbs", "no_conversion"); + } + } + + // live2d 显示 + if (getCookie("js_live2d_show_cookie")) { + // have cookie + searchString = "添加Live2D形象"; + bool_value = getCookie("js_live2d_show_cookie"); + bool_value = bool_value == "True"; + if (bool_value) { + loadLive2D(); + let arr_with_live2d = update_array( + await get_data_from_gradio_component('cbsc'), "添加Live2D形象", "add" + ) + push_data_to_gradio_component(arr_with_live2d, "cbsc", "no_conversion"); + } else { + try { + $('.waifu').hide(); + let arr_without_live2d = update_array( + await get_data_from_gradio_component('cbsc'), "添加Live2D形象", "remove" + ) + push_data_to_gradio_component(arr_without_live2d, "cbsc", "no_conversion"); + } catch (error) { + } + } + } else { + // do not have cookie + if (live2d) { + loadLive2D(); + } else { + } + } + + // 主题加载(恢复到上次) + change_theme("", "") +} diff --git a/themes/theme.js b/themes/theme.js new file mode 100644 index 00000000..a0cd5278 --- /dev/null +++ b/themes/theme.js @@ -0,0 +1,41 @@ +async function try_load_previous_theme(){ + if (getCookie("js_theme_selection_cookie")) { + theme_selection = getCookie("js_theme_selection_cookie"); + let css = localStorage.getItem('theme-' + theme_selection); + if (css) { + change_theme(theme_selection, css); + } + } +} + +async function change_theme(theme_selection, css) { + if (theme_selection.length==0) { + try_load_previous_theme(); + return; + } + + var existingStyles = document.querySelectorAll("body > gradio-app > div > style") + for (var i = 0; i < existingStyles.length; i++) { + var style = existingStyles[i]; + style.parentNode.removeChild(style); + } + var existingStyles = document.querySelectorAll("style[data-loaded-css]"); + for (var i = 0; i < existingStyles.length; i++) { + var style = existingStyles[i]; + style.parentNode.removeChild(style); + } + + setCookie("js_theme_selection_cookie", theme_selection, 3); + localStorage.setItem('theme-' + theme_selection, css); + + var styleElement = document.createElement('style'); + styleElement.setAttribute('data-loaded-css', 'placeholder'); + styleElement.innerHTML = css; + document.body.appendChild(styleElement); +} + + +// // 记录本次的主题切换 +// async function change_theme_prepare(theme_selection, secret_css) { +// setCookie("js_theme_selection_cookie", theme_selection, 3); +// } \ No newline at end of file diff --git a/themes/theme.py b/themes/theme.py index e0417871..28195774 100644 --- a/themes/theme.py +++ b/themes/theme.py @@ -71,29 +71,10 @@ def from_cookie_str(c): """ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 第 3 部分 -内嵌的javascript代码 +内嵌的javascript代码(这部分代码会逐渐移动到common.js中) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- """ -js_code_for_css_changing = """(css) => { - var existingStyles = document.querySelectorAll("body > gradio-app > div > style") - for (var i = 0; i < existingStyles.length; i++) { - var style = existingStyles[i]; - style.parentNode.removeChild(style); - } - var existingStyles = document.querySelectorAll("style[data-loaded-css]"); - for (var i = 0; i < existingStyles.length; i++) { - var style = existingStyles[i]; - style.parentNode.removeChild(style); - } - var styleElement = document.createElement('style'); - styleElement.setAttribute('data-loaded-css', 'placeholder'); - styleElement.innerHTML = css; - document.body.appendChild(styleElement); -} -""" - - js_code_for_toggle_darkmode = """() => { if (document.querySelectorAll('.dark').length) { setCookie("js_darkmode_cookie", "False", 365);