import importlib import os import random import shutil import traceback import gradio as gr import json import yaml from builder_core import beauty_output, init_builder_chatbot_agent from config_utils import (DEFAULT_AGENT_DIR, Config, get_avatar_image, get_ci_dir, get_user_cfg_file, get_user_dir, is_valid_plugin_configuration, parse_configuration, save_avatar_image, save_builder_configuration, save_plugin_configuration) from gradio_utils import ChatBot, format_cover_html, format_goto_publish_html from i18n import I18n from modelscope_agent.utils.logger import agent_logger as logger from publish_util import (pop_user_info_from_config, prepare_agent_zip, reload_agent_zip) from user_core import init_user_chatbot_agent def init_user(uuid_str, state): try: seed = state.get('session_seed', random.randint(0, 1000000000)) user_agent = init_user_chatbot_agent(uuid_str) user_agent.seed = seed state['user_agent'] = user_agent except Exception as e: logger.error( uuid=uuid_str, error=str(e), content={'error_traceback': traceback.format_exc()}) return state def init_builder(uuid_str, state): try: builder_agent = init_builder_chatbot_agent(uuid_str) state['builder_agent'] = builder_agent except Exception as e: logger.error( uuid=uuid_str, error=str(e), content={'error_traceback': traceback.format_exc()}) return state def update_builder(uuid_str, state): try: builder_agent = init_builder_chatbot_agent(uuid_str) state['builder_agent'] = builder_agent except Exception as e: logger.error( uuid=uuid_str, error=str(e), content={'error_traceback': traceback.format_exc()}) return state def check_uuid(uuid_str): if not uuid_str or uuid_str == '': if os.getenv('MODELSCOPE_ENVIRONMENT') == 'studio': raise gr.Error('请登陆后使用! (Please login first)') else: uuid_str = 'local_user' return uuid_str def process_configuration(uuid_str, bot_avatar, name, description, instructions, model, agent_language, suggestions, knowledge_files, capabilities_checkboxes, openapi_schema, openapi_auth, openapi_auth_apikey, openapi_auth_apikey_type, openapi_privacy_policy, state): uuid_str = check_uuid(uuid_str) tool_cfg = state['tool_cfg'] capabilities = state['capabilities'] bot_avatar, bot_avatar_path = save_avatar_image(bot_avatar, uuid_str) suggestions_filtered = [row for row in suggestions if row[0]] if len(suggestions_filtered) == 0: suggestions_filtered == [['']] user_dir = get_user_dir(uuid_str) if knowledge_files is not None: new_knowledge_files = [ os.path.join(user_dir, os.path.basename((f.name))) for f in knowledge_files ] for src_file, dst_file in zip(knowledge_files, new_knowledge_files): if not os.path.exists(dst_file): shutil.copy(src_file.name, dst_file) else: new_knowledge_files = [] builder_cfg = { 'name': name, 'avatar': bot_avatar, 'description': description, 'instruction': instructions, 'prompt_recommend': [row[0] for row in suggestions_filtered], 'knowledge': new_knowledge_files, 'tools': { capability: dict( name=tool_cfg[capability]['name'], is_active=tool_cfg[capability]['is_active'], use=True if capability in capabilities_checkboxes else False) for capability in map(lambda item: item[1], capabilities) }, 'model': model, 'language': agent_language, } try: try: schema_dict = json.loads(openapi_schema) except json.decoder.JSONDecodeError: schema_dict = yaml.safe_load(openapi_schema) except Exception as e: raise gr.Error( f'OpenAPI schema format error, should be one of json and yaml: {e}' ) openapi_plugin_cfg = { 'schema': schema_dict, 'auth': { 'type': openapi_auth, 'apikey': openapi_auth_apikey, 'apikey_type': openapi_auth_apikey_type }, 'privacy_policy': openapi_privacy_policy } if is_valid_plugin_configuration(openapi_plugin_cfg): save_plugin_configuration(openapi_plugin_cfg, uuid_str) except Exception as e: logger.error( uuid=uuid_str, error=str(e), content={'error_traceback': traceback.format_exc()}) save_builder_configuration(builder_cfg, uuid_str) update_builder(uuid_str, state) init_user(uuid_str, state) return [ gr.HTML.update( visible=True, value=format_cover_html(builder_cfg, bot_avatar_path)), gr.Chatbot.update( visible=False, avatar_images=get_avatar_image(bot_avatar, uuid_str)), gr.Dataset.update(samples=suggestions_filtered), gr.DataFrame.update(value=suggestions_filtered) ] # 创建 Gradio 界面 demo = gr.Blocks(css='assets/app.css') with demo: uuid_str = gr.Textbox(label='modelscope_uuid', visible=False) draw_seed = random.randint(0, 1000000000) state = gr.State({'session_seed': draw_seed}) i18n = I18n('zh-cn') with gr.Row(): with gr.Column(scale=5): header = gr.Markdown(i18n.get('header')) with gr.Column(scale=1): language = gr.Dropdown( choices=[('中文', 'zh-cn'), ('English', 'en')], show_label=False, container=False, value='zh-cn', interactive=True) with gr.Row(): with gr.Column(): with gr.Tabs() as tabs: with gr.Tab(i18n.get_whole('create'), id=0) as create_tab: with gr.Column(): # "Create" 标签页的 Chatbot 组件 start_text = '欢迎使用agent创建助手。我可以帮助您创建一个定制agent。'\ '您希望您的agent主要用于什么领域或任务?比如,您可以说,我想做一个RPG游戏agent' create_chatbot = gr.Chatbot( show_label=False, value=[[None, start_text]]) create_chat_input = gr.Textbox( label=i18n.get('message'), placeholder=i18n.get('message_placeholder')) create_send_button = gr.Button( i18n.get('sendOnLoading'), interactive=False) configure_tab = gr.Tab(i18n.get_whole('configure'), id=1) with configure_tab: with gr.Column(): # "Configure" 标签页的配置输入字段 with gr.Row(): bot_avatar_comp = gr.Image( label=i18n.get('form_avatar'), placeholder='Chatbot avatar image', source='upload', interactive=True, type='filepath', scale=1, width=182, height=182, ) with gr.Column(scale=4): name_input = gr.Textbox( label=i18n.get('form_name'), placeholder=i18n.get( 'form_name_placeholder')) description_input = gr.Textbox( label=i18n.get('form_description'), placeholder=i18n.get( 'form_description_placeholder')) instructions_input = gr.Textbox( label=i18n.get('form_instructions'), placeholder=i18n.get( 'form_instructions_placeholder'), lines=3) model_selector = gr.Dropdown( label=i18n.get('form_model')) agent_language_selector = gr.Dropdown( label=i18n.get('form_agent_language'), choices=['zh', 'en'], value='zh') suggestion_input = gr.Dataframe( show_label=False, value=[['']], datatype=['str'], headers=[i18n.get_whole('form_prompt_suggestion')], type='array', col_count=(1, 'fixed'), interactive=True) gr.Markdown( '*注意:知识库上传的文本文档默认按照\\n\\n切分,pdf默认按照页切分。如果片段' '对应的字符大于[配置文件](https://github.com/modelscope/modelscope-agent/' 'blob/master/apps/agentfabric/config/model_config.json)中指定模型的' 'knowledge限制,则在被召回时有可能会被截断。*') knowledge_input = gr.File( label=i18n.get('form_knowledge'), file_count='multiple', file_types=[ 'text', '.json', '.csv', '.pdf', '.md' ]) capabilities_checkboxes = gr.CheckboxGroup( label=i18n.get('form_capabilities')) with gr.Accordion( i18n.get('open_api_accordion'), open=False) as open_api_accordion: openapi_schema = gr.Textbox( label='Schema', placeholder= 'Enter your OpenAPI schema here, JSON or YAML format only' ) with gr.Group(): openapi_auth_type = gr.Radio( label='Authentication Type', choices=['None', 'API Key'], value='None') openapi_auth_apikey = gr.Textbox( label='API Key', placeholder='Enter your API Key here') openapi_auth_apikey_type = gr.Radio( label='API Key type', choices=['Bearer']) openapi_privacy_policy = gr.Textbox( label='Privacy Policy', placeholder='Enter privacy policy URL') configure_button = gr.Button( i18n.get('form_update_button')) with gr.Accordion( label=i18n.get('import_config'), open=False) as update_accordion: with gr.Column(): update_space = gr.Textbox( label=i18n.get('space_addr'), placeholder=i18n.get('input_space_addr')) import_button = gr.Button( i18n.get_whole('import_space')) gr.Markdown( f'#### {i18n.get_whole("import_hint")}') with gr.Column(): # Preview preview_header = gr.HTML( f"""