Clear Chat Interface
Hi,I’m currently building a chatbot with Chat Interface and OpenAI.  I’ve been trying to write an input() event listener where the chat history gets cleared when I select a new option on a dropdown (basically automating the clear button).  I’ve read the code for the clear button on Gradio’s GitHub page, and it seems that all you have to do is set the component you want cleared to [  ] or None.Unfortunately, when I set the Chat Interface component to [  ] or None, I get the following error:gradio.exceptions.InvalidBlockError: Output component with id 1 used in input() event not found in this gr.Blocks context. You are allowed to nest gr.Blocks contexts, but there must be a gr.Blocks context that contains all components and events.I’m really not sure what the issue is, because I only have one Block and every component is inside it.The closest I’ve gotten it to working is making a Chatbot component before the Chat Interface and setting it to the chatbot parameter in the Chat Interface, then upon the dropdown selection, resetting the messages sent to OpenAI and setting the Chatbot component to [  ].  This will actually clear the chat history.  However, as soon as I submit another message in the Chat Interface, the chat history from before the dropdown change mysteriously reappears, as if I had never reset the Chatbot component in the first place?  This is super strange to me as my debugging has confirmed that the message history sent to OpenAI has been totally reset to default, so I wonder where the Chat Interface is getting it from.  Maybe Chat Interface is storing the chat history somewhere inaccessible to a reset?This issue isn’t at all present when I just press the clear button of the Chat Interface, so ideally, if there’s any way to just automate a click, that would be amazing.  Thanks.
2023-08-15T16:15:22Z
Hi@JFalejczykcan you share a code snippet we can use to reproduce?
2023-08-15T16:48:13Z
Hi@abidlabs, thanks so much for getting back to me on this.  I can’t share some variables like contentTypes (which is just a dictionary holding info to train the AI into the characters), but they’re not relevant to the code anyway.  Below you can find essentially what I’m doing.# Function that resets AI in event of character switching
def reset(input):

    return []

# Function that powers the chatbot by sending and receiving messages from OpenAI
def converse(input, history, character):

    # Setup default chat sequence in OpenAI's required format
    openAIHistory = [
        {
            "role": "system",
            "content": contentTypes[character]
        }
    ]
    for human, assistant in history:
        openAIHistory.append({"role": "user", "content": human })
        openAIHistory.append({"role": "assistant", "content": assistant})

    if input:

        # Continue chat sequence and append AI's response
        openAIHistory.append({"role": "user", "content": input})
        chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=openAIHistory) # Get response from OpenAI model
        reply = chat.choices[0].message.content
        
        return reply

# Gradio app
bot = gr.Chatbot()
with gr.Blocks() as demo:

    gr.Markdown(f"<h1 style='text-align: center; margin-bottom: 1rem'>{'My Chatbot'}</h1>")
    dropdown = gr.Dropdown(
        ["Character 1", "Character 2", "Character 3", "Character 4", "Character 5", "Character 6", "Character 7", "Character 8", "Character 9", "Character 10", "Character 11", "Character 12", "Character 13"], label="Characters", info="Select the character that you'd like to speak to", value="Character 1"
    )
    chat = gr.ChatInterface(
        fn=converse,
        chatbot=bot,
        additional_inputs=dropdown
    )
    dropdown.input(fn=reset, inputs=dropdown, outputs=bot) # Reset the chatbot to clear history automatically

demo.queue()
demo.launch()If I move the chatbot component into the main block before the chat interface, that’s where I get the following error:gradio.exceptions.DuplicateBlockError: A block with id: 1 has already been rendered in the current Blocks.So I’ve avoided that and kept it outside the main block.  Still though, I can select input on the dropdown and it’ll temporarily clear the chat history, but when I send another message, the old history will strangely come back.  I’m not quite sure what’s going on, in case it’s obvious to you.  Thanks.
2023-08-15T17:04:18Z
I’ll take a look. Some quick notes:If you’d like to bringgr.Chatbot()into the main Blocks, just setrender=False, e.g.gr.Chatbot(render=False)But in your code example you shouldn’t even need to define agr.Chatbotsince you’re using the default implementation ofgr.ChatInterfacewhich creates agr.Chatbotfor you. So you can just skip thechatbotparameter and everything will be the same.Does that fix anything for you?
2023-08-15T17:05:16Z
Oh never mind, I’m sorry youdouse theChatbotas the output, so you should do what I suggested in (1)
2023-08-15T17:09:12Z
Ah okay I know the issue. It’s a subtle problem that we’ll need to fix on our end but for now, you can fix this by manually resetting thechat.chatbot_state. Here’s a complete example:import gradio as gr

def converse(x, y, z):
    return z

def reset(z):
    return [], []

# Gradio app
with gr.Blocks() as demo:
    gr.Markdown(f"<h1 style='text-align: center; margin-bottom: 1rem'>{'My Chatbot'}</h1>")
    bot = gr.Chatbot(render=False)
    dropdown = gr.Dropdown(
        ["Character 1", "Character 2", "Character 3", "Character 4", "Character 5", "Character 6", "Character 7", "Character 8", "Character 9", "Character 10", "Character 11", "Character 12", "Character 13"], label="Characters", info="Select the character that you'd like to speak to", value="Character 1"
    )
    chat = gr.ChatInterface(
        fn=converse,
        chatbot=bot,
        additional_inputs=dropdown
    )
    dropdown.input(fn=reset, inputs=dropdown, outputs=[bot, chat.chatbot_state])

demo.queue()
demo.launch()
2023-08-15T17:55:09Z
That’s perfect, thank you so much for helping, I definitely wouldn’t have figured that out on my own.  Really appreciate it.