Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chatbot buttons support #4763

Closed
1 task done
Tracked by #4800
taoari opened this issue Jul 3, 2023 · 13 comments · Fixed by #9989
Closed
1 task done
Tracked by #4800

chatbot buttons support #4763

taoari opened this issue Jul 3, 2023 · 13 comments · Fixed by #9989
Assignees
Labels
💬 Chatbot Related to the Chatbot component enhancement New feature or request needs designing The proposed feature needs to be discussed and designed before being implemented

Comments

@taoari
Copy link

taoari commented Jul 3, 2023

  • I have searched to see if a similar issue already exists.

Chatbot buttons are pretty much standard. It can restrict the user inputs and control the conversation flow. It would be great if gr.Chatbot() can have chatbot buttons support.

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

It would be great that gr.Chatbot() can natively support Buttons. Currently, I developed a workaround for chatbot buttons with the following script:

import gradio as gr

def bot(history, msg):
    bot_msg = """
Hello, how can I help you today? <br /><button type="button" class="btn btn-primary btn-chatbot">Primary</button> \
<button type="button" class="btn btn-primary btn-chatbot">Secondary</button>
"""
    return history + [[msg, bot_msg]], ""

with gr.Blocks() as demo:
    chatbot = gr.Chatbot()
    msg = gr.Textbox(show_label=False,
        placeholder="Enter text and press ENTER", container=False, elem_id="inputTextBox")
    msg.submit(bot, [chatbot, msg], [chatbot, msg])
    
def reload_javascript():
    js = """
// for bootstrap
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>

// for message buttons to work
<script>
function registerMessageButtons() {
	const collection = document.querySelectorAll(".btn-chatbot");
	for (let i = 0; i < collection.length; i++) {
      // NOTE: gradio use .value instead of .innerHTML for gr.Textbox
	  collection[i].onclick=function() {document.getElementById("inputTextBox").getElementsByTagName('textarea')[0].value = collection[i].innerHTML};
	}
}
// need to make sure registerMessageButtons() is executed all the time as new message can come out;
var intervalId = window.setInterval(function(){
  registerMessageButtons();
}, 1000);
</script>
"""
    def template_response(*args, **kwargs):
        res = GradioTemplateResponseOriginal(*args, **kwargs)
        res.body = res.body.replace(b'</html>', f'{js}</html>'.encode("utf8"))
        res.init_headers()
        return res

    gr.routes.templates.TemplateResponse = template_response

GradioTemplateResponseOriginal = gr.routes.templates.TemplateResponse

reload_javascript()
demo.launch()

image

It is almost done (click the button and the textbox got updated), but encountered a bug described in #4762 (the Textbox display text and sent text mismatch). Hope to find a solution.

Additional context
Add any other context or screenshots about the feature request here.

@abidlabs
Copy link
Member

abidlabs commented Jul 3, 2023

I agree this would be nice to support -- we just need to figure out the right API for this. cc @dawoodkhan82

@abidlabs abidlabs added enhancement New feature or request needs designing The proposed feature needs to be discussed and designed before being implemented labels Jul 3, 2023
@abidlabs abidlabs added this to the Component Cleanup milestone Jul 9, 2023
@dawoodkhan82 dawoodkhan82 self-assigned this Jul 10, 2023
@abidlabs abidlabs removed this from the Component Cleanup milestone Sep 4, 2023
@RobinIR
Copy link

RobinIR commented Nov 7, 2023

Would you please let me know when the issue will be fixed? I am also stuck on implementing the chatbot response button.

@freddyaboulton
Copy link
Collaborator

Can you try building a custom chatbot component @RobinIR ?

Getting started building custom components: https://www.gradio.app/guides/five-minute-guide
Building a custom chatbot: https://www.gradio.app/guides/multimodal-chatbot-part1

@freddyaboulton freddyaboulton added the new component Involves creating a new component label Nov 16, 2023
@s-wel
Copy link

s-wel commented Dec 4, 2023

Hi, it is not so clear for me what the modification of the Chatbot component should do different. As far as I understand, the "in chat" buttons must have the same behavior as a "submit". Where to start?

@abidlabs abidlabs removed the new component Involves creating a new component label Dec 5, 2023
@abidlabs abidlabs added the 💬 Chatbot Related to the Chatbot component label Mar 15, 2024
@codenprogressive
Copy link

I see a huge value in implementing a button or a selector radio functionalities in chatbot component.

@latinostats
Copy link

I found this ticket after I opened mine a few minutes ago.... I am basically requesting the same feature. It would be really a great component addition!
this is my issue in case you want to merge it... #8698

@ajayarora1235
Copy link

This would also be amazing for me as I can offer buttons for the user to press after the assistant sends back a response.

Watched the yt vid on building a custom component -- in this case would we just have to define a new type of message where we allow for button text + their connected function to be a part of the message that's returned? And then go into svelte and then create a button for each message?

if @freddyaboulton could just confirm if this is right or give a few pointers on what changes need to made to the chatbot component, would be super helpful

@ajayarora1235
Copy link

I guess as a follow up, curious as to why gr.Image, gr.Plot, gr.Audio, and gr.HTML are all possible to be included in the chatbot but not gr.Button. Thanks!

@learnasteve
Copy link

Also keen for this! Trying to get feedback from user on bot responses and require more granularity than like / dislike.

@ajayarora1235
Copy link

hi, any updates on this? tried making a custom component but ran into same issues everyone else is having with gradio cc dev!

@dawoodkhan82
Copy link
Collaborator

@ajayarora1235 Will work on this soon.

@taoari
Copy link
Author

taoari commented Aug 20, 2024

Surprised to see the issue is still open after more than one year. If someone is urgent for this feature. Here is a workaround by tweaking HTML and Javascript:

import gradio as gr

def bot(history, msg):
    bot_msg = """
Hello, how can I help you today? <br />
<a class="btn btn-primary btn-chatbot text-white" value="Primary">Primary</a> \
<a class="btn btn-primary btn-chatbot text-white" value="Secondary">Secondary</a>
"""
    return history + [[msg, bot_msg]], ""

with gr.Blocks() as demo:
    chatbot = gr.Chatbot()
    msg = gr.Textbox(show_label=False,
        placeholder="Enter text and press ENTER", container=False, elem_id="inputTextBox")
    msg.submit(bot, [chatbot, msg], [chatbot, msg])
    
def reload_javascript():
    js = """
// for bootstrap
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>

// for message buttons to work
<script>
function registerMessageButtons() {
    const collection = document.querySelectorAll(".btn-chatbot");
    for (let i = 0; i < collection.length; i++) {
      // NOTE: gradio use .value instead of .innerHTML for gr.Textbox
      collection[i].onclick=function() {
        elem = document.getElementById("inputTextBox").getElementsByTagName('textarea')[0];
        elem.value = collection[i].getAttribute("value"); // use value instead of innerHTML
        elem.dispatchEvent(new Event('input', {
            view: window,
            bubbles: true,
            cancelable: true
            }))
        };  
    }
}
// need to make sure registerMessageButtons() is executed all the time as new message can come out;
var intervalId = window.setInterval(function(){
  registerMessageButtons();
}, 1000);
</script>
"""
    def template_response(*args, **kwargs):
        res = GradioTemplateResponseOriginal(*args, **kwargs)
        res.body = res.body.replace(b'</html>', f'{js}</html>'.encode("utf8"))
        res.init_headers()
        return res

    gr.routes.templates.TemplateResponse = template_response

GradioTemplateResponseOriginal = gr.routes.templates.TemplateResponse

reload_javascript()
demo.launch()

@david-thrower
Copy link

david-thrower commented Oct 15, 2024

One comment I have on this one is that it would be ideal if the implementation of this feature supports conditional logic where some messages will display one list of options, and other messages will display others.

I am working on a clinical assistant, which asks around 25 questions, many of which are close ended with the same 2 sets of repetitive valid options. For the symptom related questions, most the valid options are ["no", "yes - mild", "Yes- moderate", "Yes- severe", "not sure"] ... and most of the lab result questions would have the options ["test not done yet", "result was normal", "result was, elevated and abnormal: ENTER NUMBER", "result was low and abnormal ENTER NUMBER", "I'm not sure"]. We want the user to not have to write the same answers repeatedly, and we also want to standardize how users enter answers to the questions and how the LLM sees them worded, so it can be practical to validate the bot objectively and fine tune a model to get it right consistently.

If the messages can be easily individually instantiated with a list of options to select based on a business logic or based on a sequential order in a list of initial questions, that may make this feature more robust and practical for advanced use cases like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 Chatbot Related to the Chatbot component enhancement New feature or request needs designing The proposed feature needs to be discussed and designed before being implemented
Projects
None yet
Development

Successfully merging a pull request may close this issue.