import random from functools import partial from typing import List, Tuple import gradio as gr from refresh_bots import BotCache def middchat(bot_cache: BotCache, message: str, history: List[Tuple[str, str]]) -> str: """ Generate a message given a message history and bots Args: bot_cache (BotCache): a bot cache to get bot classes from message (str): the message sent by the user history (List[Tuple[str, str]]): history of messages/responses Returns: str: bot's response """ # get the bot options # for new chats, fetch new bots if message == "update bots" or len(history) <= 1: all_bots = bot_cache.update() else: all_bots = bot_cache.bots # check to see if the bot was set in the message history bot = None bot_set_id = None for i, (historical_message, _) in enumerate(history): # check if a bot has already been selected if historical_message.strip() in all_bots: # initialize the bot and store ID to start history of coversation # with the bot directly. bot = all_bots[historical_message.strip()]() bot_set_id = i # If the bot wasn't set before, check if the current message includes # a valid bot ID. If it does, tell the user that they are now successfully # chatting with the bot. # If it doesn't, tell the user about the options again. if bot is None: if message.strip() in all_bots: return f"You're now chatting with {message.strip()}! \ If you aren't sure what to say, type \"examples\"" else: bot_options = "Please choose one of the following bots:\n" bot_options += "\n".join(f"* {bot}" for bot in all_bots.keys()) return bot_options # Unfortunately, the only way that the gradio chat interface keeps track # of individual user's sessions is through the chat history. This means # that there isn't a good way to create a bot that keeps track of state # for different users on the server with instance variables. # This is an inefficient workaround: re-initialize the bot and go through # the full set of replies each time... random.seed(457) for historical_message, _ in history[bot_set_id + 1:]: bot.make_reply(historical_message) if message.strip().lower() == "examples": return "Here are some things you might want to say to me:\n" + \ "\n".join(f"* {ex}" for ex in bot.examples()) return bot.make_reply(message) cache = BotCache() chat_partial = partial(middchat, cache) initial_msg = "Welcome to MiddChat! Type anything to get a list of available bots.\nPlease note that if you want to reset your chat, you should refresh this page!\nIf you want to update the bot list, type \"update bots\"" chatbot = gr.Chatbot([(initial_msg, None)]) demo = gr.ChatInterface( fn=chat_partial, chatbot=chatbot, title="MiddChat") demo.launch(share=True)