From d0f163f581727fdffdac43bf63da6438f63da170 Mon Sep 17 00:00:00 2001 From: qbc Date: Fri, 19 Jan 2024 16:54:38 +0800 Subject: [PATCH 1/7] support ms ui --- examples/game/app.py | 18 +++++++++-- examples/game/main.py | 60 ++++++++++++++++++++++++++++++------- examples/game/ruled_user.py | 26 ++++++++++++---- examples/game/utils.py | 15 ++++++---- 4 files changed, 94 insertions(+), 25 deletions(-) diff --git a/examples/game/app.py b/examples/game/app.py index 2b62f65d8..02e036887 100644 --- a/examples/game/app.py +++ b/examples/game/app.py @@ -16,7 +16,10 @@ ) import gradio as gr -from gradio_groupchat import GroupChat + +# from gradio_groupchat import GroupChat +import modelscope_gradio_components as mgr + enable_web_ui() @@ -50,6 +53,12 @@ def get_chat() -> List[List]: return glb_history_chat[-MAX_NUM_DISPLAY_MSG:] +def fn(data: gr.EventData): + # print(data._data['value']) + send_player_input(data._data["value"]) + # send_chat_msg("".join(data._data['value']), "你") + + if __name__ == "__main__": def start_game(): @@ -73,8 +82,8 @@ def start_game(): # Users can select the interested exp with gr.Row(): - chatbot = GroupChat(label="Dialog", show_label=False, height=600) - + # chatbot = GroupChat(label="Dialog", show_label=False, height=600) + chatbot = mgr.Chatbot(label="Dialog", show_label=False, height=600) with gr.Row(): with gr.Column(): user_chat_input = gr.Textbox( @@ -133,6 +142,9 @@ def update_suggest(): send_button.click(send_message, user_chat_input, user_chat_input) export_button.click(export_chat_history, [], export_output) user_chat_input.submit(send_message, user_chat_input, user_chat_input) + + chatbot.custom(fn=fn) + demo.load(get_chat, inputs=None, outputs=chatbot, every=0.5) demo.load(update_suggest, outputs=user_chat_bot_suggest, every=0.5) demo.load(start_game) diff --git a/examples/game/main.py b/examples/game/main.py index 2e961583f..fec14b443 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import json import os import yaml import inquirer @@ -50,15 +51,28 @@ def invited_group_chat( choices=["是", "否", "结束邀请对话"], ), ] + + choose_during_chatting = f"""【系统】你要发言吗? """ + + send_chat_msg({"text": choose_during_chatting, "flushing": False}) + answer = query_answer(questions, "ans") - if answer == "是": + if isinstance(answer, str): + send_chat_msg("【系统】请在列表中选择。") + continue + + if answer == ["是"]: msg = player(announcement) - elif answer == "否": + elif answer == ["否"]: msg = None - elif answer == "结束邀请对话": + elif answer == ["结束邀请对话"]: break else: - send_chat_msg("【系统】请重新选择。") + send_chat_msg("【系统】请在列表中选择。") continue for c in invited_customer: msg = c(msg) @@ -83,10 +97,18 @@ def invited_group_chat( choices=invited_names + ["跳过"], ), ] + + choose_role_story = f"""【系统】:需要以哪位角色的视角生成一段完整故事吗?: """ + + send_chat_msg({"text": choose_role_story, "flushing": False}) + answer = query_answer(questions, "ans") end_query_answer() for c in invited_customer: - if c.name == answer: + if c.name == answer[0]: c.generate_pov_story() for c in invited_customer: c.refine_background() @@ -168,7 +190,16 @@ def one_on_one_loop(customers, player): ), ] - answer = query_answer(questions, "ans") + choose_after_meal = f"""【系统】接下来你会说些什么吗? + """ + + send_chat_msg({"text": choose_after_meal, "flushing": False}) + + answer = query_answer(questions, "ans")[0] end_query_answer() if answer == "感谢您的光顾。(结束与该顾客的当天对话)": continue @@ -203,15 +234,24 @@ def invite_customers(customers): choices=available_customers + ["END"], ), ] + + choose_available_customers = f"""【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?: """ + + send_chat_msg({"text": choose_available_customers, "flushing": False}) + answer = query_answer(select_customer, "invited") if answer == "END": break - if answer not in available_customers: - send_chat_msg("【系统】请重新选择。") + if not set(answer).issubset(set(available_customers)): + send_chat_msg("【系统】请在列表中选择。") continue - invited_customers.append(answer) - available_customers.remove(answer) + invited_customers.extend(answer) + # available_customers.remove(answer) + break end_query_answer() return invited_customers diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index a0647d903..86dfac386 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -100,6 +100,8 @@ def reply( for key in required_keys: kwargs[key] = get_player_input(key) + # breakpoint() + if content == "做菜": content = self.cook() kwargs["food"] = content @@ -137,7 +139,7 @@ def cook(self): for item in sublist ] - ingredients_list = ["**清空**", "**结束**"] + ingredients_list + # ingredients_list = ["**清空**", "**结束**"] + ingredients_list cook_list = [] questions = [ inquirer.List( @@ -147,20 +149,32 @@ def cook(self): ), ] while True: - send_chat_msg(f"【系统】当前已选择的食材是{cook_list}。") + choose_ingredient = f"""请选择需要的食材: """ + + send_chat_msg({"text": choose_ingredient, "flushing": False}) + + # send_chat_msg(f"【系统】当前已选择的食材是{cook_list}。") sel_ingr = query_answer(questions, "ingredient") + if isinstance(sel_ingr, str): + send_chat_msg("【系统】请在列表中进行选择。") + continue - if sel_ingr in ["结束", "**结束**"]: # For gradio + if sel_ingr in [["结束"], ["**结束**"]]: # For gradio if len(cook_list) > 0: break send_chat_msg("【系统】你没有选中任何食材。") - elif sel_ingr in ["清空", "**清空**"]: # For gradio + elif sel_ingr in [["清空"], ["**清空**"]]: # For gradio cook_list.clear() - elif sel_ingr not in ingredients_list: + elif not set(sel_ingr).issubset(set(ingredients_list)): + print("cook list", cook_list) send_chat_msg("【系统】不可用食材,请重新选择。") continue else: - cook_list.append(sel_ingr) + cook_list.extend(sel_ingr) + break end_query_answer() prompt = self.cook_prompt.format_map( diff --git a/examples/game/utils.py b/examples/game/utils.py index fa4444cfd..71d5c4d0d 100644 --- a/examples/game/utils.py +++ b/examples/game/utils.py @@ -10,6 +10,9 @@ from agentscope.message import Msg from enums import StagePerNight +import gradio as gr + + USE_WEB_UI = False @@ -117,7 +120,7 @@ def enable_web_ui(): def send_chat_msg(msg, role="系统"): print(msg) if get_use_web_ui(): - glb_queue_chat_msg.put([role, msg]) + glb_queue_chat_msg.put([None, msg]) def get_chat_msg(): @@ -130,19 +133,19 @@ def get_chat_msg(): def send_player_input(msg, role="餐厅老板"): if get_use_web_ui(): - glb_queue_chat_input.put([role, msg]) + glb_queue_chat_input.put([msg, None]) def send_pretty_msg(msg): speak_print(msg) if get_use_web_ui(): - glb_queue_chat_msg.put([msg.name, msg.content]) + glb_queue_chat_msg.put([None, msg.content]) def get_player_input(name=None): if get_use_web_ui(): print("wait queue input") - content = glb_queue_chat_input.get(block=True)[1] + content = glb_queue_chat_input.get(block=True)[0] else: content = input(f"{name}: ") return content @@ -203,11 +206,11 @@ def query_answer(questions: List, key="ans"): print("suggests=", suggests) samples = [[choice] for choice in suggests.choices] msg = suggests.message - send_chat_msg(suggests_msg) + # send_chat_msg(suggests_msg) send_suggests((msg, samples)) return get_player_input() else: - answer = inquirer.prompt(questions)[key] + answer = [inquirer.prompt(questions)[key]] # return list return answer From ecf5dd95d7d7d494011f5fa10cf704b924daaf87 Mon Sep 17 00:00:00 2001 From: qbc Date: Fri, 19 Jan 2024 19:02:03 +0800 Subject: [PATCH 2/7] ready for merge --- examples/game/main.py | 82 ++++++++++++++++++------------------- examples/game/ruled_user.py | 16 +------- 2 files changed, 43 insertions(+), 55 deletions(-) diff --git a/examples/game/main.py b/examples/game/main.py index 51394d180..933beeb0c 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -60,24 +60,25 @@ def invited_group_chat( send_chat_msg({"text": choose_during_chatting, "flushing": False}, uid=uid) - - answer = query_answer(questions, "ans", uid=uid) - if isinstance(answer, str): - send_chat_msg("【系统】请在列表中选择。", uid=uid) - continue - - if answer == ["是"]: - msg = player(announcement) - elif answer == ["否"]: - msg = None - elif answer == ["结束邀请对话"]: + end_flag = False + while True: + answer = query_answer(questions, "ans", uid=uid) + if isinstance(answer, str): + send_chat_msg("【系统】请在列表中选择。", uid=uid) + continue + elif answer == ["是"]: + msg = player(announcement) + elif answer == ["否"]: + msg = None + elif answer == ["结束邀请对话"]: + end_flag = True + break + if end_flag: break else: - send_chat_msg("【系统】请重新选择。", uid=uid) - continue - for c in invited_customer: - msg = c(msg) - send_pretty_msg(msg, uid=uid) + for c in invited_customer: + msg = c(msg) + send_pretty_msg(msg, uid=uid) invited_names.sort() @@ -105,8 +106,12 @@ def invited_group_chat( send_chat_msg({"text": choose_role_story, "flushing": False}, uid=uid) - answer = query_answer(questions, "ans", uid=uid) - + while True: + answer = query_answer(questions, "ans", uid=uid) + if isinstance(answer, str): + send_chat_msg("【系统】请在列表中选择。", uid=uid) + continue + break for c in invited_customer: if c.name == answer[0]: c.generate_pov_story() @@ -242,35 +247,30 @@ def invite_customers(customers, uid): if len(available_customers) == 0: send_chat_msg("【系统】:您目前无法邀请任何一个顾客(所有顾客好感度均低于80)。", uid=uid) - while len(available_customers) > 0: - select_customer = [ - inquirer.List( - "invited", - message="【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?", - choices=available_customers + ["END"], - ), - ] + select_customer = [ + inquirer.List( + "invited", + message="【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?", + choices=available_customers, + ), + ] - choose_available_customers = f"""【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?: """ + choose_available_customers = f"""【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?: """ - send_chat_msg({"text": choose_available_customers, "flushing": - False}, uid=uid) + send_chat_msg({"text": choose_available_customers, "flushing": + False}, uid=uid) + while True: answer = query_answer(select_customer, "invited", uid=uid) - if answer == "END": - break - if not set(answer).issubset(set(available_customers)): + if isinstance(answer, str): send_chat_msg("【系统】请在列表中选择。", uid=uid) continue - - invited_customers.extend(answer) - # available_customers.remove(answer) - break - - return invited_customers + else: + invited_customers = answer + return invited_customers def main(args) -> None: diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index 0b5d509de..70604738d 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -163,20 +163,8 @@ def cook(self): if isinstance(sel_ingr, str): send_chat_msg("【系统】请在列表中进行选择。", uid=self.uid) continue - - if sel_ingr in [["结束"], ["**结束**"]]: # For gradio - if len(cook_list) > 0: - break - send_chat_msg("【系统】你没有选中任何食材。", uid=self.uid) - elif sel_ingr in [["清空"], ["**清空**"]]: # For gradio - cook_list.clear() - elif not set(sel_ingr).issubset(set(ingredients_list)): - print("cook list", cook_list) - send_chat_msg("【系统】不可用食材,请重新选择。", uid=self.uid) - continue - else: - cook_list.extend(sel_ingr) - break + cook_list = sel_ingr + break prompt = self.cook_prompt.format_map( From 11d321fedda321fdcf8b5e12b03c92845364a76a Mon Sep 17 00:00:00 2001 From: qbc Date: Fri, 19 Jan 2024 20:19:01 +0800 Subject: [PATCH 3/7] minor changes --- examples/game/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/game/main.py b/examples/game/main.py index f27d85927..869b93618 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -251,12 +251,12 @@ def invite_customers(customers, uid): select_customer = [ inquirer.List( "invited", - message="【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?", + message="【系统】今天就没有更多顾客了,您明天有什么邀请计划吗?", choices=available_customers, ), ] - choose_available_customers = f"""【系统】系统:今天就没有更多顾客了,您明天有什么邀请计划吗?: """ From 54df1399c7b55035b684e6a02b2cc529f452567d Mon Sep 17 00:00:00 2001 From: qbc Date: Fri, 19 Jan 2024 21:17:39 +0800 Subject: [PATCH 4/7] fix bug --- examples/game/main.py | 2 +- examples/game/ruled_user.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/game/main.py b/examples/game/main.py index 869b93618..eb2c27043 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -39,7 +39,7 @@ def invited_group_chat( if len(invited_customer) == 0: return cur_plots_indices invited_names = [c.name for c in invited_customer] - send_chat_msg("===== invited group chat ====", uid=uid) + send_chat_msg("【系统】群聊开始", uid=uid) send_chat_msg(f"老板今天邀请了{invited_names},大家一起聊聊", uid=uid) announcement = {"role": "user", "content": "今天老板邀请大家一起来聚聚。"} with msghub(invited_customer + [player], announcement=announcement): diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index 43d5767e8..09862079b 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -76,6 +76,9 @@ def reply( if x == {"content": "游戏开始"} and content == "": send_chat_msg("【系统】有顾客光临,请接待。", uid=self.uid) continue + elif isinstance(x, dict): + if x.get('content') == "今天老板邀请大家一起来聚聚。" and content == "": + content = "大家好" if not hasattr(self, "model") or len(content) == 0: break From 7f68b5d654df9d255b664830b23046a17e98f2d2 Mon Sep 17 00:00:00 2001 From: qbc Date: Mon, 22 Jan 2024 10:32:38 +0800 Subject: [PATCH 5/7] reform --- examples/game/app.py | 116 ++++++++++++++++++--------------- examples/game/customer.py | 14 ++-- examples/game/main.py | 19 +++--- examples/game/ruled_user.py | 11 ++-- examples/game/utils.py | 125 ++++++++++++++++-------------------- 5 files changed, 149 insertions(+), 136 deletions(-) diff --git a/examples/game/app.py b/examples/game/app.py index 95afb3f9f..c694e4ad2 100644 --- a/examples/game/app.py +++ b/examples/game/app.py @@ -35,25 +35,28 @@ def init_uid_list(): MAX_NUM_DISPLAY_MSG = 20 import base64 + + # 图片本地路径转换为 base64 格式 def covert_image_to_base64(image_path): # 获得文件后缀名 - ext = image_path.split('.')[-1] - if ext not in ['gif', 'jpeg', 'png']: - ext = 'jpeg' + ext = image_path.split(".")[-1] + if ext not in ["gif", "jpeg", "png"]: + ext = "jpeg" - with open(image_path, 'rb') as image_file: + with open(image_path, "rb") as image_file: # Read the file encoded_string = base64.b64encode(image_file.read()) # Convert bytes to string - base64_data = encoded_string.decode('utf-8') + base64_data = encoded_string.decode("utf-8") - # 生成base64编码的地址 - base64_url = f'data:image/{ext};base64,{base64_data}' + # 生成base64编码的地址 + base64_url = f"data:image/{ext};base64,{base64_data}" return base64_url -def format_cover_html(config: dict, bot_avatar_path='assets/bg.png'): + +def format_cover_html(config: dict, bot_avatar_path="assets/bg.png"): image_src = covert_image_to_base64(bot_avatar_path) return f"""
@@ -65,6 +68,7 @@ def format_cover_html(config: dict, bot_avatar_path='assets/bg.png'):
""" + def export_chat_history(uid): timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") export_filename = f"chat_history_{timestamp}.txt" @@ -129,27 +133,29 @@ def start_game(uid): except ResetException: print("重置成功") - with gr.Blocks(css='assets/app.css') as demo: + with gr.Blocks(css="assets/app.css") as demo: # Users can select the interested exp uuid = gr.State(uuid.uuid4) welcome = { "name": "饮食男女", - "description": "这是一款模拟餐馆经营的文字冒险游戏, 快来开始吧😊" + "description": "这是一款模拟餐馆经营的文字冒险游戏, 快来开始吧😊", } user_chat_bot_cover = gr.HTML(format_cover_html(welcome)) - chatbot = mgr.Chatbot(label="Dialog", show_label=False, height=600, visible=False) + chatbot = mgr.Chatbot( + label="Dialog", show_label=False, height=600, visible=False + ) with gr.Row(): with gr.Column(): - new_button = gr.Button( - value="🚀新的探险", - ) + new_button = gr.Button( + value="🚀新的探险", + ) with gr.Column(): - resume_button = gr.Button( - value="🔥续写情缘", - ) + resume_button = gr.Button( + value="🔥续写情缘", + ) with gr.Row(): with gr.Column(): @@ -161,11 +167,10 @@ def start_game(uid): visible=False, ) - with gr.Column(): send_button = gr.Button( value="📣发送", - visible=False + visible=False, ) export = gr.Accordion("导出选项", open=False, visible=False) @@ -174,10 +179,6 @@ def start_game(uid): export_button = gr.Button("导出完整游戏记录") export_output = gr.File(label="下载完整游戏记录", visible=False) - - - - def send_message(msg, uid): send_player_input(msg, uid=uid) send_player_msg(msg, "你", uid=uid) @@ -197,53 +198,68 @@ def send_reset_message(uid): def game_ui(): visible = True invisible = False - return {chatbot: mgr.Chatbot(visible=visible), - user_chat_input: gr.Text(visible=visible), - send_button: gr.Button(visible=visible), - new_button: gr.Button(visible=invisible), - resume_button: gr.Button(visible=invisible), - return_welcome_button: gr.Button(visible=visible), - export: gr.Accordion(visible=visible), - user_chat_bot_cover:gr.HTML(visible=invisible)} + return { + chatbot: mgr.Chatbot(visible=visible), + user_chat_input: gr.Text(visible=visible), + send_button: gr.Button(visible=visible), + new_button: gr.Button(visible=invisible), + resume_button: gr.Button(visible=invisible), + return_welcome_button: gr.Button(visible=visible), + export: gr.Accordion(visible=visible), + user_chat_bot_cover: gr.HTML(visible=invisible), + } def welcome_ui(): visible = True invisible = False - return {chatbot: mgr.Chatbot(visible=invisible), - user_chat_input: gr.Text(visible=invisible), - send_button: gr.Button(visible=invisible), - new_button: gr.Button(visible=visible), - resume_button: gr.Button(visible=visible), - return_welcome_button: gr.Button(visible=invisible), - export: gr.Accordion(visible=invisible), - user_chat_bot_cover:gr.HTML(visible=visible)} - - outputs = [chatbot, user_chat_input, send_button, new_button, resume_button,return_welcome_button, export, user_chat_bot_cover] - + return { + chatbot: mgr.Chatbot(visible=invisible), + user_chat_input: gr.Text(visible=invisible), + send_button: gr.Button(visible=invisible), + new_button: gr.Button(visible=visible), + resume_button: gr.Button(visible=visible), + return_welcome_button: gr.Button(visible=invisible), + export: gr.Accordion(visible=invisible), + user_chat_bot_cover: gr.HTML(visible=visible), + } + + outputs = [ + chatbot, + user_chat_input, + send_button, + new_button, + resume_button, + return_welcome_button, + export, + user_chat_bot_cover, + ] + # submit message - send_button.click(send_message, [user_chat_input, uuid], user_chat_input) - user_chat_input.submit(send_message, [user_chat_input, uuid], user_chat_input) + send_button.click( + send_message, [user_chat_input, uuid], user_chat_input + ) + user_chat_input.submit( + send_message, [user_chat_input, uuid], user_chat_input + ) chatbot.custom(fn=fn_choice, inputs=[uuid]) - # change ui + # change ui new_button.click(game_ui, outputs=outputs) resume_button.click(game_ui, outputs=outputs) return_welcome_button.click(welcome_ui, outputs=outputs) - # start game + # start game new_button.click(send_reset_message, inputs=[uuid]) resume_button.click(check_for_new_session, inputs=[uuid]) - - # export - export_button.click(export_chat_history, [uuid], export_output) + # export + export_button.click(export_chat_history, [uuid], export_output) # update chat history demo.load(init_game) demo.load(check_for_new_session, inputs=[uuid], every=0.1) demo.load(get_chat, inputs=[uuid], outputs=chatbot, every=0.5) - demo.queue() demo.launch() diff --git a/examples/game/customer.py b/examples/game/customer.py index 48e405fdd..3d1b5c37a 100644 --- a/examples/game/customer.py +++ b/examples/game/customer.py @@ -22,7 +22,7 @@ def __init__(self, game_config: dict, **kwargs: Any): self.game_config = game_config self.max_itr_preorder = 5 self.preorder_itr_count = 0 - self.avatar = self.config.get('avatar', get_a_random_avatar()) + self.avatar = self.config.get("avatar", get_a_random_avatar()) self.background = self.config["character_setting"]["background"] self.friendship = int(self.config.get("friendship", 60)) @@ -61,13 +61,15 @@ def activate_plot(self, active_plots: list[int]) -> None: # when the customer is the main role in a plot, it will be activated self.plot_stage = CustomerPlot.ACTIVE for p in active_plots: - if str(p) in self.config["character_setting"]["hidden_plot"] \ - and len(self.active_plots) == 0: + if ( + str(p) in self.config["character_setting"]["hidden_plot"] + and len(self.active_plots) == 0 + ): self.active_plots = [str(p)] elif str(p) in self.config["character_setting"]["hidden_plot"]: raise ValueError( "A customer can be in at most one plot in the current " - "version" + "version", ) def deactivate_plot(self) -> None: @@ -82,7 +84,9 @@ def reply(self, x: dict = None) -> Union[dict, tuple]: # the first/last message must have role 'user'. if x is not None: x["role"] = "user" - logger.debug(f"{self.name} state: {self.cur_state} {self.plot_stage} {self.active_plots}") + logger.debug( + f"{self.name} state: {self.cur_state} {self.plot_stage} {self.active_plots}" + ) return StateAgent.reply(self, x=x) def _recommendation_to_score(self, x: dict) -> dict: diff --git a/examples/game/main.py b/examples/game/main.py index eb2c27043..2b98aeae2 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -213,8 +213,10 @@ def one_on_one_loop(customers, player, uid): while True: answer = query_answer(questions, "ans", uid=uid) if isinstance(answer, str): - send_chat_msg("【系统】请在列表中选择。", - uid=uid) + send_chat_msg( + "【系统】请在列表中选择。", + uid=uid, + ) continue break @@ -223,14 +225,14 @@ def one_on_one_loop(customers, player, uid): if answer == "感谢您的光顾。(结束与该顾客的当天对话)": continue elif answer == "自定义输入": - answer = player({"content": answer})['content'] + answer = player({"content": answer})["content"] msg = Msg(role="user", name="餐馆老板", content=answer) player.observe(msg) while True: msg = customer(msg) # print(f"{customer_reply.name}(顾客):" + customer_reply.content) - send_pretty_msg(msg, uid=uid,avatar=customer.avatar) + send_pretty_msg(msg, uid=uid, avatar=customer.avatar) send_chat_msg("【系统】若不输入任何内容直接按回车键,顾客将离开餐馆。", uid=uid) msg = player(msg) if len(msg["content"]) == 0: @@ -264,7 +266,7 @@ def invite_customers(customers, uid): send_chat_msg(choose_available_customers, flushing=False, uid=uid) while True: - answer = query_answer(select_customer, "invited", uid=uid) + answer = query_answer(select_customer, "invited", uid=uid) if isinstance(answer, str): send_chat_msg("【系统】请在列表中选择。", uid=uid) continue @@ -361,9 +363,10 @@ def main(args) -> None: if done_plot_idx is not None: # once successful finish a current plot... # deactivate the active roles in the done plot - deactivate_customers = \ - GAME_CONFIG["plots"][done_plot_idx]["main_roles"] + \ - GAME_CONFIG["plots"][done_plot_idx]["supporting_roles"] + deactivate_customers = ( + GAME_CONFIG["plots"][done_plot_idx]["main_roles"] + + GAME_CONFIG["plots"][done_plot_idx]["supporting_roles"] + ) for c in checkpoint.customers: if c.name in deactivate_customers: c.deactivate_plot() diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index 09862079b..c24d103fb 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -77,7 +77,7 @@ def reply( send_chat_msg("【系统】有顾客光临,请接待。", uid=self.uid) continue elif isinstance(x, dict): - if x.get('content') == "今天老板邀请大家一起来聚聚。" and content == "": + if x.get("content") == "今天老板邀请大家一起来聚聚。" and content == "": content = "大家好" if not hasattr(self, "model") or len(content) == 0: @@ -97,7 +97,6 @@ def reply( except (UnicodeDecodeError, ValueError) as e: send_chat_msg(f"【系统】无效输入 {e}\n 请重试", "⚠️", uid=self.uid) - kwargs = {} if required_keys is not None: if isinstance(required_keys, str): @@ -160,8 +159,11 @@ def cook(self): '{json.dumps(ingredients_list)}' select-once submit-text="确定">""" - send_chat_msg(choose_ingredient, flushing=False, - uid=self.uid) + send_chat_msg( + choose_ingredient, + flushing=False, + uid=self.uid, + ) while True: sel_ingr = query_answer(questions, "ingredient", uid=self.uid) if isinstance(sel_ingr, str): @@ -170,7 +172,6 @@ def cook(self): cook_list = sel_ingr break - prompt = self.cook_prompt.format_map( {"ingredient": "+".join(cook_list)}, ) diff --git a/examples/game/utils.py b/examples/game/utils.py index 863417650..6790598b8 100644 --- a/examples/game/utils.py +++ b/examples/game/utils.py @@ -57,13 +57,16 @@ def load_game_checkpoint(checkpoint_path: str) -> GameCheckpoint: def speak_print(m: Msg): print(f"{BgBrightColor.BLUE}{m.name}{BgBrightColor.OFF}: {m.content}") -def get_avatar_files(assets_path='assets'): - files = Path(assets_path).glob('*avatar*') + +def get_avatar_files(assets_path="assets"): + files = Path(assets_path).glob("*avatar*") return [str(file) for file in files] + def get_a_random_avatar(): return random.choices(get_avatar_files()) + def check_active_plot( plots: list[dict], curr_done: Optional[int], @@ -108,8 +111,11 @@ def check_active_plot( # activate all plots has no dependency and not done yet if p["predecessor_plots"] is None and p["state"] == "non-active": to_be_activated += p["main_roles"] - to_be_activated += p["supporting_roles"] if p["supporting_roles"] \ - is not None else [] + to_be_activated += ( + p["supporting_roles"] + if p["supporting_roles"] is not None + else [] + ) p["state"] = "active" active_plots.append(idx) elif p["predecessor_plots"] is not None: @@ -123,8 +129,11 @@ def check_active_plot( if to_activate: p["state"] = "active" to_be_activated += p["main_roles"] - to_be_activated += p["supporting_roles"] if \ - p["supporting_roles"] is not None else [] + to_be_activated += ( + p["supporting_roles"] + if p["supporting_roles"] is not None + else [] + ) active_plots.append(idx) elif p["state"] == "active": active_plots.append(idx) @@ -153,29 +162,47 @@ def init_uid_queues(): "glb_queue_chat_input": Queue(), } + glb_uid_dict = defaultdict(init_uid_queues) -def send_chat_msg(msg, role="系统", uid=None, flushing=False, avatar='./assets/bot.jpg'): + +def send_chat_msg( + msg, role="系统", uid=None, flushing=False, avatar="./assets/bot.jpg" +): print(msg) if get_use_web_ui(): global glb_uid_dict glb_queue_chat_msg = glb_uid_dict[uid]["glb_queue_chat_msg"] - glb_queue_chat_msg.put([None, - {"text": msg, - "flushing": flushing, - "avatar": avatar - }]) - -def send_player_msg(msg, role="你", uid= None, flushing=False, avatar='./assets/user.jpg'): + glb_queue_chat_msg.put( + [ + None, + { + "text": msg, + "flushing": flushing, + "avatar": avatar, + }, + ] + ) + + +def send_player_msg( + msg, role="你", uid=None, flushing=False, avatar="./assets/user.jpg" +): print(msg) if get_use_web_ui(): global glb_uid_dict glb_queue_chat_msg = glb_uid_dict[uid]["glb_queue_chat_msg"] - glb_queue_chat_msg.put([ - {"text": msg, - "flushing": flushing, - "avatar": avatar - },None]) + glb_queue_chat_msg.put( + [ + { + "text": msg, + "flushing": flushing, + "avatar": avatar, + }, + None, + ] + ) + def get_chat_msg(uid=None): global glb_uid_dict @@ -186,17 +213,26 @@ def get_chat_msg(uid=None): return line return None + def send_player_input(msg, role="餐厅老板", uid=None): if get_use_web_ui(): global glb_uid_dict glb_queue_chat_input = glb_uid_dict[uid]["glb_queue_chat_input"] glb_queue_chat_input.put([None, msg]) -def send_pretty_msg(msg, uid=None,flushing=True, avatar='./assets/bot.jpg'): + +def send_pretty_msg(msg, uid=None, flushing=True, avatar="./assets/bot.jpg"): speak_print(msg) if get_use_web_ui(): global glb_uid_dict - send_chat_msg(msg.content, uid = uid, role=msg.name, flushing=flushing, avatar=avatar) + send_chat_msg( + msg.content, + uid=uid, + role=msg.name, + flushing=flushing, + avatar=avatar, + ) + def get_player_input(name=None, uid=None): global glb_uid_dict @@ -213,38 +249,6 @@ def get_player_input(name=None, uid=None): return content -# <<<<<<< HEAD -# ======= -# def send_suggests(suggests, uid=None): -# msg, _ = suggests -# global glb_uid_dict -# glb_queue_chat_suggests = glb_uid_dict[uid]["glb_queue_chat_suggests"] -# while not glb_queue_chat_suggests.empty(): -# try: -# glb_queue_chat_suggests.get_nowait() -# except Empty: -# break -# -# if msg == "end": -# return -# else: -# glb_queue_chat_suggests.put(suggests) -# -# -# def get_suggests(uid=None): -# msg = None -# samples = None -# -# global glb_uid_dict -# glb_queue_chat_suggests = glb_uid_dict[uid]["glb_queue_chat_suggests"] -# -# if not glb_queue_chat_suggests.empty(): -# msg, samples = glb_queue_chat_suggests.get(block=False) -# glb_queue_chat_suggests.put((msg, samples)) -# return msg, samples -# -# -# >>>>>>> origin/game_dev def format_choices(choices): formatted_choices = "" line_length = 0 @@ -267,27 +271,12 @@ def format_choices(choices): def query_answer(questions: List, key="ans", uid=None): if get_use_web_ui(): -# <<<<<<< HEAD -# -# ======= -# suggests = questions[0] -# assert isinstance(suggests, inquirer.questions.List) -# suggests_msg = ( -# suggests.message + "\n" + format_choices(suggests.choices) -# ) -# samples = [[choice] for choice in suggests.choices] -# msg = suggests.message -# send_chat_msg(suggests_msg, uid=uid) -# send_suggests((msg, samples), uid=uid) -# >>>>>>> origin/game_dev return get_player_input(uid=uid) else: answer = [inquirer.prompt(questions)[key]] # return list return answer - - @dataclass class CheckpointArgs: load_checkpoint: str = None From db2ab0213081d8352bfc894234718bc264c06b64 Mon Sep 17 00:00:00 2001 From: qbc Date: Mon, 22 Jan 2024 11:35:10 +0800 Subject: [PATCH 6/7] =?UTF-8?q?modify=20according=20comments=20and=20fix?= =?UTF-8?q?=20a=20bug=20when=20input=20nothing=20after=20=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=BE=93=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/game/app.py | 18 ++++++++++++++---- examples/game/customer.py | 3 ++- examples/game/main.py | 11 +++++------ examples/game/ruled_user.py | 13 ++++++++----- examples/game/utils.py | 16 ++++++++++++---- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/examples/game/app.py b/examples/game/app.py index c694e4ad2..54de9452f 100644 --- a/examples/game/app.py +++ b/examples/game/app.py @@ -144,7 +144,10 @@ def start_game(uid): user_chat_bot_cover = gr.HTML(format_cover_html(welcome)) chatbot = mgr.Chatbot( - label="Dialog", show_label=False, height=600, visible=False + label="Dialog", + show_label=False, + height=600, + visible=False, ) with gr.Row(): @@ -177,7 +180,10 @@ def start_game(uid): with export: with gr.Column(): export_button = gr.Button("导出完整游戏记录") - export_output = gr.File(label="下载完整游戏记录", visible=False) + export_output = gr.File( + label="下载完整游戏记录", + visible=False, + ) def send_message(msg, uid): send_player_input(msg, uid=uid) @@ -236,10 +242,14 @@ def welcome_ui(): # submit message send_button.click( - send_message, [user_chat_input, uuid], user_chat_input + send_message, + [user_chat_input, uuid], + user_chat_input, ) user_chat_input.submit( - send_message, [user_chat_input, uuid], user_chat_input + send_message, + [user_chat_input, uuid], + user_chat_input, ) chatbot.custom(fn=fn_choice, inputs=[uuid]) diff --git a/examples/game/customer.py b/examples/game/customer.py index 3d1b5c37a..651c95caa 100644 --- a/examples/game/customer.py +++ b/examples/game/customer.py @@ -85,7 +85,8 @@ def reply(self, x: dict = None) -> Union[dict, tuple]: if x is not None: x["role"] = "user" logger.debug( - f"{self.name} state: {self.cur_state} {self.plot_stage} {self.active_plots}" + f"{self.name} state: {self.cur_state} {self.plot_stage}" + f" {self.active_plots}", ) return StateAgent.reply(self, x=x) diff --git a/examples/game/main.py b/examples/game/main.py index 4586c2799..5ecfb44f1 100644 --- a/examples/game/main.py +++ b/examples/game/main.py @@ -58,8 +58,6 @@ def invited_group_chat( {json.dumps(["是", "否", "结束邀请对话"])}' select-once>""" - # send_chat_msg({"text": choose_during_chatting, "flushing": - # False}, uid=uid) send_chat_msg(choose_during_chatting, flushing=False, uid=uid) end_flag = False while True: @@ -89,7 +87,7 @@ def invited_group_chat( # TODO: decided by multi factor: chat history of msghub, correct_names if invited_names == correct_names: - send_chat_msg("===== successfully unlock a plot =======", uid=uid) + send_chat_msg("===== 剧情解锁成功 =======", uid=uid) questions = [ inquirer.List( "ans", @@ -101,7 +99,8 @@ def invited_group_chat( choose_role_story = f"""【系统】:需要以哪位角色的视角生成一段完整故事吗?: """ + '{json.dumps(invited_names + ["跳过"])}' + select-once>""" send_chat_msg(choose_role_story, flushing=False, uid=uid) @@ -258,8 +257,8 @@ def invite_customers(customers, uid): ), ] - choose_available_customers = f"""【系统】今天就没有更多顾客了,您明天有什么邀请计划吗?: """ diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index c24d103fb..4720ecf8f 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -13,6 +13,7 @@ send_chat_msg, query_answer, get_player_input, + ResetException, ) @@ -79,6 +80,8 @@ def reply( elif isinstance(x, dict): if x.get("content") == "今天老板邀请大家一起来聚聚。" and content == "": content = "大家好" + elif x.get("content") == "自定义输入" and content == "": + content = "你好" if not hasattr(self, "model") or len(content) == 0: break @@ -94,7 +97,9 @@ def reply( "⚠️", uid=self.uid, ) - except (UnicodeDecodeError, ValueError) as e: + except ResetException: + raise ResetException + except Exception as e: send_chat_msg(f"【系统】无效输入 {e}\n 请重试", "⚠️", uid=self.uid) kwargs = {} @@ -105,8 +110,6 @@ def reply( for key in required_keys: kwargs[key] = get_player_input(key, uid=self.uid) - # breakpoint() - if content == "做菜": content = self.cook() kwargs["food"] = content @@ -144,7 +147,6 @@ def cook(self): for item in sublist ] - # ingredients_list = ["**清空**", "**结束**"] + ingredients_list cook_list = [] questions = [ inquirer.List( @@ -155,7 +157,8 @@ def cook(self): ] choose_ingredient = f"""请选择需要的食材: """ diff --git a/examples/game/utils.py b/examples/game/utils.py index 6790598b8..00540a9e8 100644 --- a/examples/game/utils.py +++ b/examples/game/utils.py @@ -167,7 +167,11 @@ def init_uid_queues(): def send_chat_msg( - msg, role="系统", uid=None, flushing=False, avatar="./assets/bot.jpg" + msg, + role="系统", + uid=None, + flushing=False, + avatar="./assets/bot.jpg", ): print(msg) if get_use_web_ui(): @@ -181,12 +185,16 @@ def send_chat_msg( "flushing": flushing, "avatar": avatar, }, - ] + ], ) def send_player_msg( - msg, role="你", uid=None, flushing=False, avatar="./assets/user.jpg" + msg, + role="你", + uid=None, + flushing=False, + avatar="./assets/user.jpg", ): print(msg) if get_use_web_ui(): @@ -200,7 +208,7 @@ def send_player_msg( "avatar": avatar, }, None, - ] + ], ) From 602b4491cb1a3699f567f04da131fcd9c18f2a50 Mon Sep 17 00:00:00 2001 From: qbc Date: Mon, 22 Jan 2024 12:28:06 +0800 Subject: [PATCH 7/7] fix item width for ingredients --- examples/game/ruled_user.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/game/ruled_user.py b/examples/game/ruled_user.py index 4720ecf8f..4e3aeb92b 100644 --- a/examples/game/ruled_user.py +++ b/examples/game/ruled_user.py @@ -157,9 +157,8 @@ def cook(self): ] choose_ingredient = f"""请选择需要的食材: """ send_chat_msg(