Spaces:
Sleeping
Sleeping
| import base64 | |
| import os | |
| import shutil | |
| import threading | |
| import time | |
| import gradio as gr | |
| from api import audio_text | |
| from blog_class import generate_item, knowledge_class, save_feedback | |
| from design import ( | |
| custom_css, | |
| custom_head, | |
| js_func, | |
| params_text, | |
| speaker_text, | |
| title_html, | |
| title_text, | |
| ) | |
| from prompts import TRANS_Prompt, TRANS_Prompt_template | |
| knowledge_cls = knowledge_class() | |
| language_dict = {"en": "English", "cn": "Chinese"} | |
| def update_knowledge(): | |
| knowledge_cls.get_new_knowledge() | |
| choices_list = list(knowledge_cls.reference_dict.keys()) | |
| return gr.update(choices=choices_list) | |
| def user_message_fn(user_message, history): | |
| if history is None: | |
| history = [] | |
| history.append({"role": "user", "content": user_message}) | |
| return "", history | |
| def answer_question( | |
| history, creative_flag, full_flag, audio_flag, speaker_flag, language_flag | |
| ): | |
| print("chat Start") | |
| answer_text, info_title, audio_file_path = knowledge_cls.get_chat_answer( | |
| history, creative_flag, full_flag, speaker_flag | |
| ) | |
| if not answer_text: | |
| yield history | |
| return | |
| if language_flag not in ["jp"]: | |
| info_title = info_title + f"日本語返信:\n {answer_text}\n" | |
| sys_prompt = TRANS_Prompt.format(lang=language_dict[language_flag]) | |
| user_prompt = TRANS_Prompt_template.format( | |
| japanese_text=answer_text, lang=language_dict[language_flag] | |
| ) | |
| answer_text = generate_item(user_prompt, sys_prompt) | |
| # text | |
| history.append({"role": "assistant", "content": ""}) | |
| # audio | |
| history.append( | |
| { | |
| "role": "assistant", | |
| "content": "音声なし", | |
| "metadata": {"title": "🎧 音声返信", "status": "done"}, | |
| } | |
| ) | |
| # ref | |
| history.append( | |
| { | |
| "role": "assistant", | |
| "content": info_title, | |
| "metadata": {"title": "📚 参照ナレッジ", "status": "done"}, | |
| } | |
| ) | |
| def run_audio_answer(): | |
| run_audio_path = audio_text(answer_text, audio_file_path, speaker_flag) | |
| audio_str = base64.b64encode(open(run_audio_path, "rb").read()).decode("utf-8") | |
| history[-2]["content"] = gr.HTML( | |
| f""" | |
| <audio controls> | |
| <source src="data:audio/mp3;base64,{audio_str}" type="audio/mp3"> | |
| </audio> | |
| """ | |
| ) | |
| history[-2]["metadata"] = {"title": "🎧 音声返信", "status": "done"} | |
| if not audio_flag: | |
| audio_thread = threading.Thread(target=run_audio_answer) | |
| audio_thread.start() | |
| history[-2]["content"] = "音声作成中..." | |
| history[-2]["metadata"]["status"] = "pending" | |
| # | |
| for char in answer_text: | |
| history[-3]["content"] += char | |
| yield history | |
| time.sleep(0.03) | |
| if not audio_flag: | |
| while audio_thread.is_alive(): | |
| yield history | |
| time.sleep(0.2) | |
| yield history | |
| def handle_feedback(like_data: gr.LikeData): | |
| save_feedback(like_data.value[0], like_data.liked) | |
| def get_reference_info(selected_reference): | |
| reference_dict = knowledge_cls.reference_dict.get(selected_reference, None) | |
| if reference_dict: | |
| yield ( | |
| reference_dict["audio"], | |
| reference_dict["original_text"], | |
| reference_dict["summary"], | |
| ) | |
| else: | |
| yield (None, None, None) | |
| def zip_directory(): | |
| zip_path = "resource.zip" | |
| if os.path.exists(zip_path): | |
| os.remove(zip_path) | |
| shutil.make_archive(zip_path.replace(".zip", ""), "zip", "./resource") | |
| return zip_path | |
| def toggle_change(): | |
| return None, None | |
| with gr.Blocks(title="勉強会", css=custom_css, head=custom_head, js=js_func) as demo: | |
| with gr.Sidebar(label="回答スタイル調整", open=False): | |
| with gr.Accordion("回答スタイルの違いについて", open=False): | |
| gr.Markdown(params_text) | |
| creativity_toggle = gr.Radio( | |
| [("創造的な回答", True), ("事実的な回答", False)], | |
| value=False, | |
| label="回答スタイル", | |
| ) | |
| length_toggle = gr.Radio( | |
| [("詳細な説明", True), ("簡潔な説明", False)], | |
| value=False, | |
| label="説明スタイル", | |
| ) | |
| audio_toggle = gr.Radio( | |
| [("テキスト", True), ("音声とテキスト", False)], | |
| value=False, | |
| label="返信スタイル", | |
| ) | |
| language_toggle = gr.Radio( | |
| [("日本語", "jp"), ("中文", "cn"), ("English", "en")], | |
| value="jp", | |
| label="言語スタイル", | |
| ) | |
| with gr.Accordion("話者紹介", open=False): | |
| gr.Markdown(speaker_text) | |
| speaker_toggle = gr.Radio( | |
| [ | |
| ("さらとが", "matsu"), | |
| ("ケンシロウ", "ken"), | |
| ("まな", "mana"), | |
| ("藤井", "ren"), | |
| ("内山", "cai"), | |
| ], | |
| value="matsu", | |
| label="話者スタイル", | |
| ) | |
| # creativity_toggle = Toggle( | |
| # label="創意内容", | |
| # value=False, | |
| # interactive=True, | |
| # color="#007bff", | |
| # ) | |
| # length_toggle = Toggle( | |
| # label="詳細内容", | |
| # value=False, | |
| # interactive=True, | |
| # color="#007bff", | |
| # ) | |
| with gr.Column(elem_id="title-area"): | |
| gr.HTML(title_html) | |
| gr.HTML(title_text) | |
| with gr.Column(elem_id="chatbot-container"): | |
| gr.HTML( | |
| "<h3><i class='fa fa-question-circle'></i> 何かお困りですか?</h3>", | |
| ) | |
| chatbot = gr.Chatbot( | |
| show_label=False, | |
| type="messages", | |
| bubble_full_width=False, | |
| avatar_images=( | |
| None, | |
| "https://cdn.profile-image.st-hatena.com/users/saratoga623/profile.png?1728512391", | |
| ), | |
| ) | |
| with gr.Row(elem_id="submit-btn"): | |
| msg = gr.Textbox( | |
| placeholder="質問を入力してEnter...", | |
| show_label=False, | |
| scale=5, | |
| container=False, | |
| ) | |
| submit_btn = gr.Button(value="送信 🚀", scale=1) | |
| clear_btn = gr.ClearButton([msg, chatbot], value="クリア 🧹", scale=1) | |
| with gr.Accordion("ナレッジ一覧", elem_id="references-container", open=False): | |
| with gr.Column(): | |
| with gr.Row(): | |
| gr.HTML("<h3><i class='fa fa-book'></i> ナレッジ一覧</h3>") | |
| update_btn = gr.Button(value="🔄 更新", elem_id="update-btn") | |
| references_dropdown = gr.Dropdown( | |
| label="ナレッジを選ぶ", | |
| choices=list(knowledge_cls.reference_dict.keys()), | |
| value=None, | |
| ) | |
| reference_audio = gr.Audio( | |
| label="ナレッジ要約を聞く", | |
| type="filepath", | |
| interactive=False, | |
| waveform_options=gr.WaveformOptions( | |
| show_recording_waveform=False, | |
| show_controls=False, | |
| ), | |
| ) | |
| sum_references_box = gr.Textbox( | |
| label="ナレッジ要約", | |
| lines=4, | |
| interactive=False, | |
| ) | |
| with gr.Accordion("ナレッジ详情", open=False): | |
| all_references_box = gr.Markdown(max_height=250) | |
| with gr.Accordion("資源", open=False, elem_id="download-container"): | |
| download_btn = gr.Button("ダウンロード", elem_id="update-btn") | |
| file_output = gr.File(show_label=False, container=False) | |
| msg.submit( | |
| fn=user_message_fn, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False | |
| ).then( | |
| fn=answer_question, | |
| inputs=[ | |
| chatbot, | |
| creativity_toggle, | |
| length_toggle, | |
| audio_toggle, | |
| speaker_toggle, | |
| language_toggle, | |
| ], | |
| outputs=chatbot, | |
| ) | |
| submit_btn.click( | |
| fn=user_message_fn, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False | |
| ).then( | |
| fn=answer_question, | |
| inputs=[ | |
| chatbot, | |
| creativity_toggle, | |
| length_toggle, | |
| audio_toggle, | |
| speaker_toggle, | |
| language_toggle, | |
| ], | |
| outputs=chatbot, | |
| ) | |
| chatbot.like(handle_feedback, None, None, like_user_message=True) | |
| update_btn.click( | |
| fn=update_knowledge, | |
| outputs=references_dropdown, | |
| ) | |
| references_dropdown.change( | |
| fn=get_reference_info, | |
| inputs=references_dropdown, | |
| outputs=[reference_audio, all_references_box, sum_references_box], | |
| ) | |
| download_btn.click(fn=zip_directory, outputs=file_output) | |
| creativity_toggle.change(fn=toggle_change, inputs=None, outputs=[msg, chatbot]) | |
| length_toggle.change(fn=toggle_change, inputs=None, outputs=[msg, chatbot]) | |
| audio_toggle.change(fn=toggle_change, inputs=None, outputs=[msg, chatbot]) | |
| language_toggle.change(fn=toggle_change, inputs=None, outputs=[msg, chatbot]) | |
| speaker_toggle.change(fn=toggle_change, inputs=None, outputs=[msg, chatbot]) | |
| # app | |
| if __name__ == "__main__": | |
| demo.launch(inline=False, share=False, debug=True) | |