每个插件可以归属多个Group
This commit is contained in:
parent
2d5a1fbc12
commit
b31abbcad3
@ -168,7 +168,7 @@ def get_crazy_functions():
|
|||||||
"Function": HotReload(对话历史存档)
|
"Function": HotReload(对话历史存档)
|
||||||
},
|
},
|
||||||
"[多线程Demo]解析此项目本身(源码自译解)": {
|
"[多线程Demo]解析此项目本身(源码自译解)": {
|
||||||
"Group": "对话",
|
"Group": "对话|编程",
|
||||||
"AsButton": False, # 加入下拉菜单中
|
"AsButton": False, # 加入下拉菜单中
|
||||||
"Function": HotReload(解析项目本身)
|
"Function": HotReload(解析项目本身)
|
||||||
},
|
},
|
||||||
@ -499,13 +499,23 @@ def get_crazy_functions():
|
|||||||
# except:
|
# except:
|
||||||
# print('Load function plugin failed')
|
# print('Load function plugin failed')
|
||||||
|
|
||||||
regroupped_functions = {}
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
设置默认值:
|
||||||
|
- 默认 Group = 对话
|
||||||
|
- 默认 AsButton = True
|
||||||
|
- 默认 AdvancedArgs = False
|
||||||
|
- 默认 Color = secondary
|
||||||
|
"""
|
||||||
for name, function_meta in function_plugins.items():
|
for name, function_meta in function_plugins.items():
|
||||||
if "Group" in function_meta:
|
if "Group" not in function_meta:
|
||||||
groups = function_meta["Group"].split('|')
|
function_plugins[name]["Group"] = '对话'
|
||||||
else:
|
if "AsButton" not in function_meta:
|
||||||
groups = ['对话']
|
function_plugins[name]["AsButton"] = True
|
||||||
for gruop in groups:
|
if "AdvancedArgs" not in function_meta:
|
||||||
regroupped_functions[gruop] = regroupped_functions.get(gruop, {})
|
function_plugins[name]["AdvancedArgs"] = False
|
||||||
regroupped_functions[gruop].update({name: function_meta})
|
if "Color" not in function_meta:
|
||||||
return regroupped_functions
|
function_plugins[name]["Color"] = 'secondary'
|
||||||
|
|
||||||
|
return function_plugins
|
||||||
|
110
main.py
110
main.py
@ -5,19 +5,20 @@ def main():
|
|||||||
# if gr.__version__ not in ['3.28.3','3.32.2']: assert False, "需要特殊依赖,请务必用 pip install -r requirements.txt 指令安装依赖,详情信息见requirements.txt"
|
# if gr.__version__ not in ['3.28.3','3.32.2']: assert False, "需要特殊依赖,请务必用 pip install -r requirements.txt 指令安装依赖,详情信息见requirements.txt"
|
||||||
from request_llm.bridge_all import predict
|
from request_llm.bridge_all import predict
|
||||||
from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, load_chat_cookies, DummyWith
|
from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, load_chat_cookies, DummyWith
|
||||||
|
|
||||||
# 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
|
# 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
|
||||||
proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT, AVAIL_LLM_MODELS, AUTO_CLEAR_TXT = \
|
proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = get_conf('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')
|
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 = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT')
|
ENABLE_AUDIO, AUTO_CLEAR_TXT = get_conf('ENABLE_AUDIO', 'AUTO_CLEAR_TXT')
|
||||||
|
|
||||||
# 如果WEB_PORT是-1, 则随机选取WEB端口
|
# 如果WEB_PORT是-1, 则随机选取WEB端口
|
||||||
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
|
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
|
||||||
if not AUTHENTICATION: AUTHENTICATION = None
|
|
||||||
|
|
||||||
from check_proxy import get_current_version
|
from check_proxy import get_current_version
|
||||||
from themes.theme import adjust_theme, advanced_css, theme_declaration
|
from themes.theme import adjust_theme, advanced_css, theme_declaration
|
||||||
initial_prompt = "Serve me as a writing and programming assistant."
|
initial_prompt = "Serve me as a writing and programming assistant."
|
||||||
title_html = f"<h1 align=\"center\">GPT 学术优化 {get_current_version()}</h1>{theme_declaration}"
|
title_html = f"<h1 align=\"center\">GPT 学术优化 {get_current_version()}</h1>{theme_declaration}"
|
||||||
description = """代码开源和更新[地址🚀](https://github.com/binary-husky/chatgpt_academic),感谢热情的[开发者们❤️](https://github.com/binary-husky/chatgpt_academic/graphs/contributors)"""
|
description = "代码开源和更新[地址🚀](https://github.com/binary-husky/gpt_academic),"
|
||||||
|
description += "感谢热情的[开发者们❤️](https://github.com/binary-husky/gpt_academic/graphs/contributors)"
|
||||||
|
|
||||||
# 问询记录, python 版本建议3.9+(越新越好)
|
# 问询记录, python 版本建议3.9+(越新越好)
|
||||||
import logging, uuid
|
import logging, uuid
|
||||||
@ -35,12 +36,9 @@ def main():
|
|||||||
# 高级函数插件
|
# 高级函数插件
|
||||||
from crazy_functional import get_crazy_functions
|
from crazy_functional import get_crazy_functions
|
||||||
DEFAULT_FN_GROUPS, = get_conf('DEFAULT_FN_GROUPS')
|
DEFAULT_FN_GROUPS, = get_conf('DEFAULT_FN_GROUPS')
|
||||||
crazy_fns_role = get_crazy_functions()
|
plugins = get_crazy_functions()
|
||||||
crazy_classification = [i for i in crazy_fns_role]
|
all_plugin_groups = list(set([g for _, plugin in plugins.items() for g in plugin['Group'].split('|')]))
|
||||||
crazy_fns = {}
|
match_group = lambda tags, groups: any([g in groups for g in tags.split('|')])
|
||||||
for role in crazy_fns_role:
|
|
||||||
for k in crazy_fns_role[role]:
|
|
||||||
crazy_fns[k] = crazy_fns_role[role][k]
|
|
||||||
|
|
||||||
# 处理markdown文本格式的转变
|
# 处理markdown文本格式的转变
|
||||||
gr.Chatbot.postprocess = format_io
|
gr.Chatbot.postprocess = format_io
|
||||||
@ -94,35 +92,21 @@ def main():
|
|||||||
with gr.Row():
|
with gr.Row():
|
||||||
gr.Markdown("插件可读取“输入区”文本/路径作为参数(上传文件自动修正路径)")
|
gr.Markdown("插件可读取“输入区”文本/路径作为参数(上传文件自动修正路径)")
|
||||||
with gr.Row(elem_id="input-plugin-group"):
|
with gr.Row(elem_id="input-plugin-group"):
|
||||||
plugin_dropdown = gr.Dropdown(choices=crazy_classification, label='',
|
plugin_group_sel = gr.Dropdown(choices=all_plugin_groups, label='', show_label=False, value=DEFAULT_FN_GROUPS,
|
||||||
value=DEFAULT_FN_GROUPS,
|
multiselect=True, interactive=True, elem_classes='normal_mut_select').style(container=False)
|
||||||
multiselect=True, interactive=True,
|
|
||||||
elem_classes='normal_mut_select',
|
|
||||||
).style(container=False)
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
for role in crazy_fns_role:
|
for k, plugin in plugins.items():
|
||||||
for k in crazy_fns_role[role]:
|
if not plugin.get("AsButton", True): continue
|
||||||
if not crazy_fns_role[role][k].get("AsButton", True): continue
|
visible = True if match_group(plugin['Group'], DEFAULT_FN_GROUPS) else False
|
||||||
if role not in DEFAULT_FN_GROUPS:
|
variant = plugins[k]["Color"] if "Color" in plugin else "secondary"
|
||||||
variant = crazy_fns_role[role][k]["Color"] if "Color" in crazy_fns_role[role][
|
plugin['Button'] = plugins[k]['Button'] = gr.Button(k, variant=variant, visible=visible).style(size="sm")
|
||||||
k] else "secondary"
|
|
||||||
crazy_fns_role[role][k]['Button'] = gr.Button(k, variant=variant,
|
|
||||||
visible=False).style(size="sm")
|
|
||||||
else:
|
|
||||||
variant = crazy_fns[k]["Color"] if "Color" in crazy_fns_role[role][
|
|
||||||
k] else "secondary"
|
|
||||||
crazy_fns_role[role][k]['Button'] = gr.Button(k, variant=variant,
|
|
||||||
visible=True).style(size="sm")
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
with gr.Accordion("更多函数插件", open=True):
|
with gr.Accordion("更多函数插件", open=True):
|
||||||
dropdown_fn_list = []
|
dropdown_fn_list = []
|
||||||
for role in crazy_fns_role:
|
for k, plugin in plugins.items():
|
||||||
if role in DEFAULT_FN_GROUPS:
|
if not match_group(plugin['Group'], DEFAULT_FN_GROUPS): continue
|
||||||
for k in crazy_fns_role[role]:
|
if not plugin.get("AsButton", True): dropdown_fn_list.append(k) # 排除已经是按钮的插件
|
||||||
if not crazy_fns_role[role][k].get("AsButton", True):
|
elif plugin.get('AdvancedArgs', False): dropdown_fn_list.append(k) # 对于需要高级参数的插件,亦在下拉菜单中显示
|
||||||
dropdown_fn_list.append(k)
|
|
||||||
elif crazy_fns_role[role][k].get('AdvancedArgs', False):
|
|
||||||
dropdown_fn_list.append(k)
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="", show_label=False).style(container=False)
|
dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="", show_label=False).style(container=False)
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
@ -150,6 +134,7 @@ def main():
|
|||||||
resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn2.style(size="sm")
|
resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn2.style(size="sm")
|
||||||
stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
|
stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
|
||||||
clearBtn2 = gr.Button("清除", variant="secondary", visible=False); clearBtn2.style(size="sm")
|
clearBtn2 = gr.Button("清除", variant="secondary", visible=False); clearBtn2.style(size="sm")
|
||||||
|
|
||||||
# 功能区显示开关与功能区的互动
|
# 功能区显示开关与功能区的互动
|
||||||
def fn_area_visibility(a):
|
def fn_area_visibility(a):
|
||||||
ret = {}
|
ret = {}
|
||||||
@ -189,17 +174,17 @@ def main():
|
|||||||
# 文件上传区,接收文件后与chatbot的互动
|
# 文件上传区,接收文件后与chatbot的互动
|
||||||
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes], [chatbot, txt, txt2])
|
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes], [chatbot, txt, txt2])
|
||||||
# 函数插件-固定按钮区
|
# 函数插件-固定按钮区
|
||||||
for k in crazy_fns:
|
for k in plugins:
|
||||||
if not crazy_fns[k].get("AsButton", True): continue
|
if not plugins[k].get("AsButton", True): continue
|
||||||
click_handle = crazy_fns[k]["Button"].click(ArgsGeneralWrapper(crazy_fns[k]["Function"]), [*input_combo, gr.State(PORT)], output_combo)
|
click_handle = plugins[k]["Button"].click(ArgsGeneralWrapper(plugins[k]["Function"]), [*input_combo, gr.State(PORT)], output_combo)
|
||||||
click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
|
click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
|
||||||
cancel_handles.append(click_handle)
|
cancel_handles.append(click_handle)
|
||||||
# 函数插件-下拉菜单与随变按钮的互动
|
# 函数插件-下拉菜单与随变按钮的互动
|
||||||
def on_dropdown_changed(k):
|
def on_dropdown_changed(k):
|
||||||
variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
|
variant = plugins[k]["Color"] if "Color" in plugins[k] else "secondary"
|
||||||
ret = {switchy_bt: gr.update(value=k, variant=variant)}
|
ret = {switchy_bt: gr.update(value=k, variant=variant)}
|
||||||
if crazy_fns[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区
|
if plugins[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区
|
||||||
ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + crazy_fns[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))})
|
ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + plugins[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))})
|
||||||
else:
|
else:
|
||||||
ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")})
|
ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")})
|
||||||
return ret
|
return ret
|
||||||
@ -210,35 +195,26 @@ def main():
|
|||||||
# 随变按钮的回调函数注册
|
# 随变按钮的回调函数注册
|
||||||
def route(request: gr.Request, k, *args, **kwargs):
|
def route(request: gr.Request, k, *args, **kwargs):
|
||||||
if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
|
if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
|
||||||
yield from ArgsGeneralWrapper(crazy_fns[k]["Function"])(request, *args, **kwargs)
|
yield from ArgsGeneralWrapper(plugins[k]["Function"])(request, *args, **kwargs)
|
||||||
click_handle = switchy_bt.click(route,[switchy_bt, *input_combo, gr.State(PORT)], output_combo)
|
click_handle = switchy_bt.click(route,[switchy_bt, *input_combo, gr.State(PORT)], output_combo)
|
||||||
click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
|
click_handle.then(on_report_generated, [cookies, file_upload, chatbot], [cookies, file_upload, chatbot])
|
||||||
cancel_handles.append(click_handle)
|
cancel_handles.append(click_handle)
|
||||||
# 终止按钮的回调函数注册
|
# 终止按钮的回调函数注册
|
||||||
stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
||||||
stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
|
||||||
fn_btn_dict = {crazy_fns_role[role][k]['Button']: {role: k} for role in crazy_fns_role for k in crazy_fns_role[role] if crazy_fns_role[role][k].get('Button')}
|
plugins_as_btn = {name:plugin for name, plugin in plugins.items() if plugin.get('Button', None)}
|
||||||
def show_plugin_btn(plu_list):
|
def on_group_change(group_list):
|
||||||
new_btn_list = []
|
btn_list = []
|
||||||
fns_list = []
|
fns_list = []
|
||||||
if not plu_list:
|
if not group_list: # 处理特殊情况:没有选择任何插件组
|
||||||
return [*[fns.update(visible=False) for fns in fn_btn_dict], gr.Dropdown.update(choices=[])]
|
return [*[plugin['Button'].update(visible=False) for _, plugin in plugins_as_btn.items()], gr.Dropdown.update(choices=[])]
|
||||||
else:
|
for k, plugin in plugins.items():
|
||||||
for fns in fn_btn_dict:
|
if plugin.get("AsButton", True):
|
||||||
if list(fn_btn_dict[fns].keys())[0] in plu_list:
|
btn_list.append(plugin['Button'].update(visible=match_group(plugin['Group'], group_list))) # 刷新按钮
|
||||||
new_btn_list.append(fns.update(visible=True))
|
if plugin.get('AdvancedArgs', False): dropdown_fn_list.append(k) # 对于需要高级参数的插件,亦在下拉菜单中显示
|
||||||
else:
|
elif match_group(plugin['Group'], group_list): fns_list.append(k) # 刷新下拉列表
|
||||||
new_btn_list.append(fns.update(visible=False))
|
return [*btn_list, gr.Dropdown.update(choices=fns_list)]
|
||||||
for role in crazy_fns_role:
|
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 role in plu_list:
|
|
||||||
for k in crazy_fns_role[role]:
|
|
||||||
if not crazy_fns_role[role][k].get("AsButton", True):
|
|
||||||
fns_list.append(k)
|
|
||||||
elif crazy_fns_role[role][k].get('AdvancedArgs', False):
|
|
||||||
fns_list.append(k)
|
|
||||||
return [*new_btn_list, gr.Dropdown.update(choices=fns_list)]
|
|
||||||
plugin_dropdown.select(fn=show_plugin_btn, inputs=[plugin_dropdown],
|
|
||||||
outputs=[*fn_btn_dict.keys(), dropdown])
|
|
||||||
if ENABLE_AUDIO:
|
if ENABLE_AUDIO:
|
||||||
from crazy_functions.live_audio.audio_io import RealtimeAudioDistribution
|
from crazy_functions.live_audio.audio_io import RealtimeAudioDistribution
|
||||||
rad = RealtimeAudioDistribution()
|
rad = RealtimeAudioDistribution()
|
||||||
@ -270,8 +246,10 @@ def main():
|
|||||||
|
|
||||||
auto_opentab_delay()
|
auto_opentab_delay()
|
||||||
demo.queue(concurrency_count=CONCURRENT_COUNT).launch(
|
demo.queue(concurrency_count=CONCURRENT_COUNT).launch(
|
||||||
server_name="0.0.0.0", server_port=PORT,
|
server_name="0.0.0.0",
|
||||||
favicon_path="docs/logo.png", auth=AUTHENTICATION,
|
server_port=PORT,
|
||||||
|
favicon_path="docs/logo.png",
|
||||||
|
auth=AUTHENTICATION if len(AUTHENTICATION) != 0 else None,
|
||||||
blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile"])
|
blocked_paths=["config.py","config_private.py","docker-compose.yml","Dockerfile"])
|
||||||
|
|
||||||
# 如果需要在二级路径下运行
|
# 如果需要在二级路径下运行
|
||||||
|
Loading…
x
Reference in New Issue
Block a user