Skip to content

Commit 480685d

Browse files
justmywywnil.wyw
andauthored
Feat/gradio4 (#229)
* feat: update gradio 4 * feat: chatbot requirement * feat: update app.py to gradio 4 * fix: gradio 4 of process_configuration * fix: typo * fix: mschatbot * feat: chatbot support copy --------- Co-authored-by: nil.wyw <nil.wyw@alibaba-inc.com>
1 parent 19267b2 commit 480685d

File tree

4 files changed

+179
-119
lines changed

4 files changed

+179
-119
lines changed

apps/agentfabric/app.py

Lines changed: 143 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66

77
import gradio as gr
88
import json
9+
import modelscope_gradio_components as mgr
910
import yaml
1011
from builder_core import beauty_output, init_builder_chatbot_agent
1112
from config_utils import (DEFAULT_AGENT_DIR, Config, get_avatar_image,
1213
get_ci_dir, get_user_cfg_file, get_user_dir,
1314
is_valid_plugin_configuration, parse_configuration,
1415
save_avatar_image, save_builder_configuration,
1516
save_plugin_configuration)
16-
from gradio_utils import ChatBot, format_cover_html, format_goto_publish_html
17+
from gradio_utils import format_cover_html, format_goto_publish_html
1718
from i18n import I18n
1819
from modelscope_agent.utils.logger import agent_logger as logger
20+
from modelscope_gradio_components.components.Chatbot.llm_thinking_presets import \
21+
qwen
1922
from publish_util import (pop_user_info_from_config, prepare_agent_zip,
2023
reload_agent_zip)
2124
from user_core import init_user_chatbot_agent
@@ -70,91 +73,6 @@ def check_uuid(uuid_str):
7073
return uuid_str
7174

7275

73-
def process_configuration(uuid_str, bot_avatar, name, description,
74-
instructions, model, agent_language, suggestions,
75-
knowledge_files, capabilities_checkboxes,
76-
openapi_schema, openapi_auth, openapi_auth_apikey,
77-
openapi_auth_apikey_type, openapi_privacy_policy,
78-
state):
79-
uuid_str = check_uuid(uuid_str)
80-
tool_cfg = state['tool_cfg']
81-
capabilities = state['capabilities']
82-
bot_avatar, bot_avatar_path = save_avatar_image(bot_avatar, uuid_str)
83-
suggestions_filtered = [row for row in suggestions if row[0]]
84-
if len(suggestions_filtered) == 0:
85-
suggestions_filtered == [['']]
86-
user_dir = get_user_dir(uuid_str)
87-
if knowledge_files is not None:
88-
new_knowledge_files = [
89-
os.path.join(user_dir, os.path.basename((f.name)))
90-
for f in knowledge_files
91-
]
92-
for src_file, dst_file in zip(knowledge_files, new_knowledge_files):
93-
if not os.path.exists(dst_file):
94-
shutil.copy(src_file.name, dst_file)
95-
else:
96-
new_knowledge_files = []
97-
98-
builder_cfg = {
99-
'name': name,
100-
'avatar': bot_avatar,
101-
'description': description,
102-
'instruction': instructions,
103-
'prompt_recommend': [row[0] for row in suggestions_filtered],
104-
'knowledge': new_knowledge_files,
105-
'tools': {
106-
capability: dict(
107-
name=tool_cfg[capability]['name'],
108-
is_active=tool_cfg[capability]['is_active'],
109-
use=True if capability in capabilities_checkboxes else False)
110-
for capability in map(lambda item: item[1], capabilities)
111-
},
112-
'model': model,
113-
'language': agent_language,
114-
}
115-
116-
try:
117-
try:
118-
schema_dict = json.loads(openapi_schema)
119-
except json.decoder.JSONDecodeError:
120-
schema_dict = yaml.safe_load(openapi_schema)
121-
except Exception as e:
122-
raise gr.Error(
123-
f'OpenAPI schema format error, should be one of json and yaml: {e}'
124-
)
125-
126-
openapi_plugin_cfg = {
127-
'schema': schema_dict,
128-
'auth': {
129-
'type': openapi_auth,
130-
'apikey': openapi_auth_apikey,
131-
'apikey_type': openapi_auth_apikey_type
132-
},
133-
'privacy_policy': openapi_privacy_policy
134-
}
135-
if is_valid_plugin_configuration(openapi_plugin_cfg):
136-
save_plugin_configuration(openapi_plugin_cfg, uuid_str)
137-
except Exception as e:
138-
logger.error(
139-
uuid=uuid_str,
140-
error=str(e),
141-
content={'error_traceback': traceback.format_exc()})
142-
143-
save_builder_configuration(builder_cfg, uuid_str)
144-
update_builder(uuid_str, state)
145-
init_user(uuid_str, state)
146-
return [
147-
gr.HTML.update(
148-
visible=True,
149-
value=format_cover_html(builder_cfg, bot_avatar_path)),
150-
gr.Chatbot.update(
151-
visible=False,
152-
avatar_images=get_avatar_image(bot_avatar, uuid_str)),
153-
gr.Dataset.update(samples=suggestions_filtered),
154-
gr.DataFrame.update(value=suggestions_filtered)
155-
]
156-
157-
15876
# 创建 Gradio 界面
15977
demo = gr.Blocks(css='assets/app.css')
16078
with demo:
@@ -181,8 +99,16 @@ def process_configuration(uuid_str, bot_avatar, name, description,
18199
# "Create" 标签页的 Chatbot 组件
182100
start_text = '欢迎使用agent创建助手。我可以帮助您创建一个定制agent。'\
183101
'您希望您的agent主要用于什么领域或任务?比如,您可以说,我想做一个RPG游戏agent'
184-
create_chatbot = gr.Chatbot(
185-
show_label=False, value=[[None, start_text]])
102+
create_chatbot = mgr.Chatbot(
103+
show_label=False,
104+
value=[[None, start_text]],
105+
flushing=False,
106+
show_copy_button=True,
107+
llm_thinking_presets=[
108+
qwen(
109+
action_input_title='调用 <Action>',
110+
action_output_title='完成调用')
111+
])
186112
create_chat_input = gr.Textbox(
187113
label=i18n.get('message'),
188114
placeholder=i18n.get('message_placeholder'))
@@ -196,8 +122,7 @@ def process_configuration(uuid_str, bot_avatar, name, description,
196122
with gr.Row():
197123
bot_avatar_comp = gr.Image(
198124
label=i18n.get('form_avatar'),
199-
placeholder='Chatbot avatar image',
200-
source='upload',
125+
sources=['upload'],
201126
interactive=True,
202127
type='filepath',
203128
scale=1,
@@ -291,15 +216,21 @@ def process_configuration(uuid_str, bot_avatar, name, description,
291216
f"""<div class="preview_header">{i18n.get('preview')}<div>""")
292217

293218
user_chat_bot_cover = gr.HTML(format_cover_html({}, None))
294-
user_chatbot = ChatBot(
219+
user_chatbot = mgr.Chatbot(
295220
value=[[None, None]],
296221
elem_id='user_chatbot',
297222
elem_classes=['markdown-body'],
298223
avatar_images=get_avatar_image('', uuid_str),
299224
height=650,
300225
latex_delimiters=[],
301226
show_label=False,
302-
visible=False)
227+
visible=False,
228+
show_copy_button=True,
229+
llm_thinking_presets=[
230+
qwen(
231+
action_input_title='调用 <Action>',
232+
action_output_title='完成调用')
233+
])
303234
preview_chat_input = gr.Textbox(
304235
label=i18n.get('message'),
305236
placeholder=i18n.get('message_placeholder'))
@@ -376,15 +307,15 @@ def init_ui_config(uuid_str, _state, builder_cfg, model_cfg, tool_cfg):
376307
state:
377308
_state,
378309
bot_avatar_comp:
379-
gr.Image.update(value=bot_avatar),
310+
gr.Image(value=bot_avatar),
380311
name_input:
381312
builder_cfg.get('name', ''),
382313
description_input:
383314
builder_cfg.get('description'),
384315
instructions_input:
385316
builder_cfg.get('instruction'),
386317
model_selector:
387-
gr.Dropdown.update(
318+
gr.Dropdown(
388319
value=builder_cfg.get('model', models[0]), choices=models),
389320
agent_language_selector:
390321
builder_cfg.get('language') or 'zh',
@@ -394,7 +325,7 @@ def init_ui_config(uuid_str, _state, builder_cfg, model_cfg, tool_cfg):
394325
builder_cfg.get('knowledge', [])
395326
if len(builder_cfg['knowledge']) > 0 else None,
396327
capabilities_checkboxes:
397-
gr.CheckboxGroup.update(
328+
gr.CheckboxGroup(
398329
value=[
399330
tool for tool in builder_cfg.get('tools', {}).keys()
400331
if builder_cfg.get('tools').get(tool).get('use', False)
@@ -404,7 +335,9 @@ def init_ui_config(uuid_str, _state, builder_cfg, model_cfg, tool_cfg):
404335
user_chat_bot_cover:
405336
format_cover_html(builder_cfg, bot_avatar),
406337
user_chat_bot_suggest:
407-
gr.Dataset.update(samples=[[item] for item in suggests]),
338+
gr.Dataset(
339+
components=[preview_chat_input],
340+
samples=[[item] for item in suggests]),
408341
}
409342

410343
# tab 切换的事件处理
@@ -439,15 +372,16 @@ def format_message_with_builder_cfg(_state, chatbot, builder_cfg,
439372
create_chatbot:
440373
chatbot,
441374
user_chat_bot_cover:
442-
gr.HTML.update(
375+
gr.HTML(
443376
visible=True,
444377
value=format_cover_html(builder_cfg, bot_avatar_path)),
445378
user_chatbot:
446-
gr.Chatbot.update(
379+
mgr.Chatbot(
447380
visible=False,
448-
avatar_images=get_avatar_image(bot_avatar, uuid_str)),
381+
avatar_images=get_avatar_image(bot_avatar, uuid_str),
382+
_force_update=True),
449383
user_chat_bot_suggest:
450-
gr.Dataset.update(samples=suggestion)
384+
gr.Dataset(components=[preview_chat_input], samples=suggestion)
451385
}
452386

453387
def create_send_message(chatbot, input, _state, uuid_str):
@@ -457,7 +391,7 @@ def create_send_message(chatbot, input, _state, uuid_str):
457391
chatbot.append((input, ''))
458392
yield {
459393
create_chatbot: chatbot,
460-
create_chat_input: gr.Textbox.update(value=''),
394+
create_chat_input: gr.Textbox(value=''),
461395
}
462396
response = ''
463397
for frame in builder_agent.stream_run(
@@ -498,6 +432,99 @@ def create_send_message(chatbot, input, _state, uuid_str):
498432
user_chat_bot_suggest, create_chat_input
499433
])
500434

435+
def process_configuration(uuid_str, bot_avatar, name, description,
436+
instructions, model, agent_language, suggestions,
437+
knowledge_files, capabilities_checkboxes,
438+
openapi_schema, openapi_auth,
439+
openapi_auth_apikey, openapi_auth_apikey_type,
440+
openapi_privacy_policy, state):
441+
uuid_str = check_uuid(uuid_str)
442+
tool_cfg = state['tool_cfg']
443+
capabilities = state['capabilities']
444+
bot_avatar, bot_avatar_path = save_avatar_image(bot_avatar, uuid_str)
445+
suggestions_filtered = [row for row in suggestions if row[0]]
446+
if len(suggestions_filtered) == 0:
447+
suggestions_filtered == [['']]
448+
user_dir = get_user_dir(uuid_str)
449+
if knowledge_files is not None:
450+
new_knowledge_files = [
451+
os.path.join(user_dir, os.path.basename((f.name)))
452+
for f in knowledge_files
453+
]
454+
for src_file, dst_file in zip(knowledge_files,
455+
new_knowledge_files):
456+
if not os.path.exists(dst_file):
457+
shutil.copy(src_file.name, dst_file)
458+
else:
459+
new_knowledge_files = []
460+
461+
builder_cfg = {
462+
'name': name,
463+
'avatar': bot_avatar,
464+
'description': description,
465+
'instruction': instructions,
466+
'prompt_recommend': [row[0] for row in suggestions_filtered],
467+
'knowledge': new_knowledge_files,
468+
'tools': {
469+
capability: dict(
470+
name=tool_cfg[capability]['name'],
471+
is_active=tool_cfg[capability]['is_active'],
472+
use=True
473+
if capability in capabilities_checkboxes else False)
474+
for capability in map(lambda item: item[1], capabilities)
475+
},
476+
'model': model,
477+
'language': agent_language,
478+
}
479+
480+
try:
481+
try:
482+
schema_dict = json.loads(openapi_schema)
483+
except json.decoder.JSONDecodeError:
484+
schema_dict = yaml.safe_load(openapi_schema)
485+
except Exception as e:
486+
raise gr.Error(
487+
f'OpenAPI schema format error, should be one of json and yaml: {e}'
488+
)
489+
490+
openapi_plugin_cfg = {
491+
'schema': schema_dict,
492+
'auth': {
493+
'type': openapi_auth,
494+
'apikey': openapi_auth_apikey,
495+
'apikey_type': openapi_auth_apikey_type
496+
},
497+
'privacy_policy': openapi_privacy_policy
498+
}
499+
if is_valid_plugin_configuration(openapi_plugin_cfg):
500+
save_plugin_configuration(openapi_plugin_cfg, uuid_str)
501+
except Exception as e:
502+
logger.error(
503+
uuid=uuid_str,
504+
error=str(e),
505+
content={'error_traceback': traceback.format_exc()})
506+
507+
save_builder_configuration(builder_cfg, uuid_str)
508+
update_builder(uuid_str, state)
509+
init_user(uuid_str, state)
510+
return {
511+
user_chat_bot_cover:
512+
gr.HTML(
513+
visible=True,
514+
value=format_cover_html(builder_cfg, bot_avatar_path)),
515+
user_chatbot:
516+
mgr.Chatbot(
517+
visible=False,
518+
avatar_images=get_avatar_image(bot_avatar, uuid_str),
519+
_force_update=True,
520+
),
521+
user_chat_bot_suggest:
522+
gr.Dataset(
523+
components=[preview_chat_input], samples=suggestions_filtered),
524+
suggestion_input:
525+
gr.DataFrame(value=suggestions_filtered)
526+
}
527+
501528
# 配置 "Configure" 标签页的提交按钮功能
502529
configure_button.click(
503530
process_configuration,
@@ -526,9 +553,9 @@ def preview_send_message(chatbot, input, _state, uuid_str):
526553

527554
chatbot.append((input, ''))
528555
yield {
529-
user_chatbot: gr.Chatbot.update(visible=True, value=chatbot),
530-
user_chat_bot_cover: gr.HTML.update(visible=False),
531-
preview_chat_input: gr.Textbox.update(value='')
556+
user_chatbot: mgr.Chatbot(visible=True, value=chatbot),
557+
user_chat_bot_cover: gr.HTML(visible=False),
558+
preview_chat_input: gr.Textbox(value='')
532559
}
533560

534561
response = ''
@@ -594,9 +621,9 @@ def upload_file(chatbot, upload_button, _state, uuid_str):
594621
else:
595622
chatbot.append((None, f'上传文件{file_name},成功'))
596623
yield {
597-
user_chatbot: gr.Chatbot.update(visible=True, value=chatbot),
598-
user_chat_bot_cover: gr.HTML.update(visible=False),
599-
preview_chat_input: gr.Textbox.update(value='')
624+
user_chatbot: mgr.Chatbot(visible=True, value=chatbot),
625+
user_chat_bot_cover: gr.HTML(visible=False),
626+
preview_chat_input: gr.Textbox(value='')
600627
}
601628

602629
_state['file_paths'] = file_paths
@@ -675,15 +702,17 @@ def change_lang(language):
675702
gr.HTML(
676703
f"""<div class="preview_header">{i18n.get('preview')}<div>"""),
677704
preview_send_button:
678-
gr.Button.update(value=i18n.get('send')),
705+
gr.Button(value=i18n.get('send')),
679706
create_chat_input:
680707
gr.Textbox(
681708
label=i18n.get('message'),
682709
placeholder=i18n.get('message_placeholder')),
683710
create_send_button:
684-
gr.Button.update(value=i18n.get('send')),
711+
gr.Button(value=i18n.get('send')),
685712
user_chat_bot_suggest:
686-
gr.Dataset(label=i18n.get('prompt_suggestion')),
713+
gr.Dataset(
714+
components=[preview_chat_input],
715+
label=i18n.get('prompt_suggestion')),
687716
preview_chat_input:
688717
gr.Textbox(
689718
label=i18n.get('message'),
@@ -725,13 +754,13 @@ def init_all(uuid_str, _state):
725754
state:
726755
_state,
727756
preview_send_button:
728-
gr.Button.update(value=i18n.get('send'), interactive=True),
757+
gr.Button(value=i18n.get('send'), interactive=True),
729758
create_send_button:
730-
gr.Button.update(value=i18n.get('send'), interactive=True),
759+
gr.Button(value=i18n.get('send'), interactive=True),
731760
}
732761

733762
demo.load(
734763
init_all, inputs=[uuid_str, state], outputs=configure_updated_outputs)
735764

736-
demo.queue(concurrency_count=10)
737-
demo.launch(show_error=True)
765+
demo.queue()
766+
demo.launch(show_error=True, max_threads=10)

0 commit comments

Comments
 (0)