From ced9b581fc5f324841db90c824beb451d5022e1c Mon Sep 17 00:00:00 2001 From: yhjun1026 <460342015@qq.com> Date: Wed, 31 May 2023 18:09:20 +0800 Subject: [PATCH] chat with plugin bug fix --- pilot/scene/base_chat.py | 37 +++++++----------- .../chat_db/professional_qa/out_parser.py | 3 -- pilot/scene/chat_execution/chat.py | 2 +- pilot/scene/chat_execution/out_parser.py | 7 +++- .../scene/chat_knowledge/custom/out_parser.py | 3 -- .../chat_knowledge/default/out_parser.py | 3 -- pilot/scene/chat_knowledge/url/out_parser.py | 3 -- pilot/server/webserver.py | 17 ++++---- plugins/DB-GPT-Plugin-ByteBase.zip | Bin 0 -> 30614 bytes 9 files changed, 27 insertions(+), 48 deletions(-) create mode 100644 plugins/DB-GPT-Plugin-ByteBase.zip diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index dce25bec4..650235d63 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -179,31 +179,22 @@ class BaseChat(ABC): result = self.do_with_prompt_response(prompt_define_response) if hasattr(prompt_define_response, "thoughts"): - if hasattr(prompt_define_response.thoughts, "speak"): - self.current_message.add_view_message( - self.prompt_template.output_parser.parse_view_response( - prompt_define_response.thoughts.get("speak"), result - ) - ) - elif hasattr(prompt_define_response.thoughts, "reasoning"): - self.current_message.add_view_message( - self.prompt_template.output_parser.parse_view_response( - prompt_define_response.thoughts.get("reasoning"), result - ) - ) + if isinstance(prompt_define_response.thoughts, dict): + if "speak" in prompt_define_response.thoughts: + speak_to_user = prompt_define_response.thoughts.get("speak") + else: + speak_to_user = str(prompt_define_response.thoughts) else: - self.current_message.add_view_message( - self.prompt_template.output_parser.parse_view_response( - prompt_define_response.thoughts, result - ) - ) + if hasattr(prompt_define_response.thoughts, "speak"): + speak_to_user = prompt_define_response.thoughts.get("speak") + elif hasattr(prompt_define_response.thoughts, "reasoning"): + speak_to_user = prompt_define_response.thoughts.get("reasoning") + else: + speak_to_user = prompt_define_response.thoughts else: - self.current_message.add_view_message( - self.prompt_template.output_parser.parse_view_response( - prompt_define_response, result - ) - ) - + speak_to_user = prompt_define_response + view_message = self.prompt_template.output_parser.parse_view_response(speak_to_user, result) + self.current_message.add_view_message(view_message) except Exception as e: print(traceback.format_exc()) logger.error("model response parase faild!" + str(e)) diff --git a/pilot/scene/chat_db/professional_qa/out_parser.py b/pilot/scene/chat_db/professional_qa/out_parser.py index 0f7ccd791..0b8277d63 100644 --- a/pilot/scene/chat_db/professional_qa/out_parser.py +++ b/pilot/scene/chat_db/professional_qa/out_parser.py @@ -15,8 +15,5 @@ class NormalChatOutputParser(BaseOutputParser): def parse_prompt_response(self, model_out_text) -> T: return model_out_text - def parse_view_response(self, ai_text) -> str: - return super().parse_view_response(ai_text) - def get_format_instructions(self) -> str: pass diff --git a/pilot/scene/chat_execution/chat.py b/pilot/scene/chat_execution/chat.py index 27e79e3a5..464df9ba0 100644 --- a/pilot/scene/chat_execution/chat.py +++ b/pilot/scene/chat_execution/chat.py @@ -55,7 +55,7 @@ class ChatWithPlugin(BaseChat): def do_with_prompt_response(self, prompt_response): ## plugin command run - return execute_command(str(prompt_response), self.plugins_prompt_generator) + return execute_command(str(prompt_response.command.get('name')), prompt_response.command.get('args',{}), self.plugins_prompt_generator) def chat_show(self): super().chat_show() diff --git a/pilot/scene/chat_execution/out_parser.py b/pilot/scene/chat_execution/out_parser.py index ff5b6a0d7..f9796ef3d 100644 --- a/pilot/scene/chat_execution/out_parser.py +++ b/pilot/scene/chat_execution/out_parser.py @@ -23,8 +23,11 @@ class PluginChatOutputParser(BaseOutputParser): command, thoughts = response["command"], response["thoughts"] return PluginAction(command, thoughts) - def parse_view_response(self, ai_text) -> str: - return super().parse_view_response(ai_text) + def parse_view_response(self, speak, data) -> str: + ### tool out data to table view + print(f"parse_view_response:{speak},{str(data)}" ) + view_text = f"##### {speak}" + "\n" + str(data) + return view_text def get_format_instructions(self) -> str: pass diff --git a/pilot/scene/chat_knowledge/custom/out_parser.py b/pilot/scene/chat_knowledge/custom/out_parser.py index 0f7ccd791..0b8277d63 100644 --- a/pilot/scene/chat_knowledge/custom/out_parser.py +++ b/pilot/scene/chat_knowledge/custom/out_parser.py @@ -15,8 +15,5 @@ class NormalChatOutputParser(BaseOutputParser): def parse_prompt_response(self, model_out_text) -> T: return model_out_text - def parse_view_response(self, ai_text) -> str: - return super().parse_view_response(ai_text) - def get_format_instructions(self) -> str: pass diff --git a/pilot/scene/chat_knowledge/default/out_parser.py b/pilot/scene/chat_knowledge/default/out_parser.py index 0f7ccd791..0b8277d63 100644 --- a/pilot/scene/chat_knowledge/default/out_parser.py +++ b/pilot/scene/chat_knowledge/default/out_parser.py @@ -15,8 +15,5 @@ class NormalChatOutputParser(BaseOutputParser): def parse_prompt_response(self, model_out_text) -> T: return model_out_text - def parse_view_response(self, ai_text) -> str: - return super().parse_view_response(ai_text) - def get_format_instructions(self) -> str: pass diff --git a/pilot/scene/chat_knowledge/url/out_parser.py b/pilot/scene/chat_knowledge/url/out_parser.py index 0f7ccd791..0b8277d63 100644 --- a/pilot/scene/chat_knowledge/url/out_parser.py +++ b/pilot/scene/chat_knowledge/url/out_parser.py @@ -15,8 +15,5 @@ class NormalChatOutputParser(BaseOutputParser): def parse_prompt_response(self, model_out_text) -> T: return model_out_text - def parse_view_response(self, ai_text) -> str: - return super().parse_view_response(ai_text) - def get_format_instructions(self) -> str: pass diff --git a/pilot/server/webserver.py b/pilot/server/webserver.py index 515701255..af91fa4e9 100644 --- a/pilot/server/webserver.py +++ b/pilot/server/webserver.py @@ -246,7 +246,7 @@ def http_bot( state, selected, temperature, max_new_tokens, plugin_selector, mode, sql_mode, db_selector, url_input, knowledge_name ): - logger.info(f"User message send!{state.conv_id},{selected}") + logger.info(f"User message send!{state.conv_id},{selected},{plugin_selector},{mode},{sql_mode},{db_selector},{url_input}") if chat_mode_title['knowledge_qa'] == selected: scene: ChatScene = get_chat_mode(selected, mode) elif chat_mode_title['chat_use_plugin'] == selected: @@ -417,7 +417,6 @@ def build_single_model_ui(): value=dbs[0] if len(models) > 0 else "", interactive=True, show_label=True, - name="db_selector" ).style(container=False) sql_mode = gr.Radio( @@ -426,8 +425,7 @@ def build_single_model_ui(): get_lang_text("sql_generate_mode_none"), ], show_label=False, - value=get_lang_text("sql_generate_mode_none"), - name="sql_mode" + value=get_lang_text("sql_generate_mode_none") ) sql_vs_setting = gr.Markdown(get_lang_text("sql_vs_setting")) sql_mode.change(fn=change_sql_mode, inputs=sql_mode, outputs=sql_vs_setting) @@ -444,12 +442,12 @@ def build_single_model_ui(): value="", interactive=True, show_label=True, - type="value", - name="plugin_selector" + type="value" ).style(container=False) def plugin_change(evt: gr.SelectData): # SelectData is a subclass of EventData print(f"You selected {evt.value} at {evt.index} from {evt.target}") + print(f"user plugin:{plugins_select_info().get(evt.value)}") return plugins_select_info().get(evt.value) plugin_selected = gr.Textbox(show_label=False, visible=False, placeholder="Selected") @@ -466,14 +464,13 @@ def build_single_model_ui(): ], show_label=False, value=llm_native_dialogue, - name="mode" ) vs_setting = gr.Accordion( get_lang_text("configure_knowledge_base"), open=False, visible=False ) mode.change(fn=change_mode, inputs=mode, outputs=vs_setting) - url_input = gr.Textbox(label=get_lang_text("url_input_label"), lines=1, interactive=True, visible=False, name="url_input") + url_input = gr.Textbox(label=get_lang_text("url_input_label"), lines=1, interactive=True, visible=False) def show_url_input(evt:gr.SelectData): if evt.value == url_knowledge_dialogue: return gr.update(visible=True) @@ -484,7 +481,7 @@ def build_single_model_ui(): with vs_setting: vs_name = gr.Textbox( - label=get_lang_text("new_klg_name"), lines=1, interactive=True, name = "vs_name" + label=get_lang_text("new_klg_name"), lines=1, interactive=True ) vs_add = gr.Button(get_lang_text("add_as_new_klg")) with gr.Column() as doc2vec: @@ -530,7 +527,7 @@ def build_single_model_ui(): gr.Markdown(learn_more_markdown) - params = [plugin_selector, mode, sql_mode, db_selector, url_input, vs_name] + params = [plugin_selected, mode, sql_mode, db_selector, url_input, vs_name] btn_list = [regenerate_btn, clear_btn] diff --git a/plugins/DB-GPT-Plugin-ByteBase.zip b/plugins/DB-GPT-Plugin-ByteBase.zip new file mode 100644 index 0000000000000000000000000000000000000000..60ce2816dcd42907c41c3be79f7b1cd713b7116a GIT binary patch literal 30614 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 WnvdBRoH1i5^T&pHF}QR+`1BVh!%KSr literal 0 HcmV?d00001