How to terminate the chat?

HI,

I am currently integrating my chatbot backend and would like to add a ‘stop conversation’ button to the interface.

In my planning, I’m thinking of using a gr.State variable as a flag. During the processing of the streaming data loop, I’ll check this variable to see if it’s necessary to interrupt and exit.

However, I’m currently facing two issues:

  1. The ‘stop’ button is unresponsive during the data generation process.
  2. The usage of gr.State requires it to be passed as a parameter to the ‘conversation’ function. But once passed, isn’t it a local variable? So, if I modify the variable in the ‘stop’ function, it shouldn’t affect the ‘conversation’ function, right?

Based on the issues I’ve encountered and my objectives, does anyone have any suggestions on how to modify this?

P.S. For ease of discussion, I’ve created a sample code.

import gradio as gr
import time

with gr.Blocks() as block:
    chatbot = gr.Chatbot(height = 350)
    start_btn = gr.Button("produce")
    stop_btn = gr.Button("stop")

    is_running = gr.State(value=False)

    def chat(chat_history, is_running):
        is_running = True
        chat_history = [["test", ""]]
        yield chat_history, is_running

        for i in range(300):
            if is_running is False:
                break
            chat_history[-1][1] += f"{i} "
            yield chat_history, is_running
            time.sleep(0.5)

        is_running = False
        return chat_history, is_running

    def stop_chat():
        print("click 'stop_chat' btn")
        return False

    start_btn.click(chat, [chatbot, is_running], [chatbot, is_running], queue=False)
    stop_btn.click(stop_chat, [],[is_running])
    
block.queue()
block.launch(server_name="0.0.0.0",
    server_port=9999)

Best,
Cynthia

HA, I found a solution.

import gradio as gr
import time

with gr.Blocks() as block:
    chatbot = gr.Chatbot(height = 350)
    start_btn = gr.Button("produce")
    stop_btn = gr.Button("stop")

    def chat(chat_history):
        is_running = True
        chat_history = [["test", ""]]
        yield chat_history
        for i in range(300):
            if is_running is False:
                break
            chat_history[-1][1] += f"{i} "
            yield chat_history
            time.sleep(0.5)

        is_running = False
        return chat_history

    def stop_chat():
        print("click 'stop_chat' btn")
        return False

    click_event = start_btn.click(chat, [chatbot], [chatbot],  api_name=False)
    stop_btn.click(fn=None, inputs=None, outputs=None, cancels=[click_event])


block.queue()
block.launch(server_name="0.0.0.0",
    server_port=9999)