diff --git a/.gitignore b/.gitignore
index 6d0e0cce..18fc175b 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
\ No newline at end of file
diff --git a/main.py b/main.py
index a077a20e..d194e403 100644
--- a/main.py
+++ b/main.py
@@ -30,7 +30,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')
@@ -42,7 +43,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}"
@@ -70,6 +71,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":
@@ -154,14 +156,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)
@@ -233,6 +238,7 @@ def main():
plugin_["Label"] = f"插件[{k}]不需要高级参数。"
return to_cookie_str(plugin_)
+ # 插件的注册(前端代码注册)
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):
@@ -242,19 +248,18 @@ def main():
if plugins[k].get("Class", None) is None:
assert plugins[k].get("Function", None) is not None
click_handle = plugins[k]["Button"].click(None, inputs=[], outputs=None, _js=f"""()=>run_classic_plugin_via_id("{plugins[k]["ButtonElemId"]}")""")
- # 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)
else:
click_handle = plugins[k]["Button"].click(None, inputs=[], outputs=None, _js=f"""()=>run_advanced_plugin_launch_code("{k}")""")
# 函数插件-下拉菜单与随变按钮的互动(新版-更流畅)
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:
@@ -262,9 +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)")
# 随变按钮的回调函数注册
@@ -302,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()
@@ -309,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/themes/common.js b/themes/common.js
index 5b69c0ce..e7a14ce4 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");
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/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);