Users expect modern chatbot UIs to let them easily interact with individual chat messages: for example, users might want to retry message generations, undo messages, or click on a like/dislike button to upvote or downvote a generated message.
Thankfully, the Gradio Chatbot exposes several events, such as .retry, .undo, .like, and .clear, to let you build this functionality into your application. As an application developer, you can attach functions to any of these events, allowing you to run arbitrary Python functions when a user interacts with a message.
gr.ChatInterface automatically uses the retry and .undo events so it’s best to start there in order to get a fully working application quickly.
The UI
First, we’ll build the UI without handling these events and build from there. We’ll use the Hugging Face InferenceClient in order to get started without setting up any API keys.
This is what the first draft of our application looks like:
The undo event
Our undo event will populate the textbox with the previous user message and also remove all subsequent assistant responses.
In order to know the index of the last user message, we can pass gr.UndoData to our event handler function like so:
We then pass this function to the undo event:
You’ll notice that every bot response will now have an “undo icon” you can use to undo the response.
You can also access the content of the user message with undo_data.value.
The retry event
The retry event will work similarly. We’ll use gr.RetryData to get the index of the previous user message and remove all the subsequent messages from the history. Then we’ll use the respond function to generate a new response. We could also get the previous prompt via the value property of gr.RetryData.
You’ll see that the bot messages have a “retry” icon now.
The Hugging Face inference API caches responses, so in this demo, the retry button will not generate a new response.
The like event
By now you should hopefully be seeing the pattern! To let users like a message, we’ll add a .like event to our chatbot. We’ll pass it a function that accepts a gr.LikeData object. In this case, we’ll just print the message that was either liked or disliked.
The edit event
Same idea with the edit listener! With gr.Chatbot(editable=True), you can capture user edits. The gr.EditData object tells us the index of the message edited and the new text of the message. Below, we use this object to edit the history, and delete any subsequent messages:
The clear event
As a bonus, we’ll also cover the .clear() event, which is triggered when the user clicks the clear icon to clear all messages. As a developer, you can attach additional events that should happen when this icon is clicked, e.g. to handle clearing of additional chatbot state:
In this example, the clear function, bound to the chatbot.clear event, returns a new UUID into our session state, when the chat history is cleared via the trash icon. This can be seen in the chat_fn function, which references the UUID saved in our session state.
This example also shows that you can use these events with gr.ChatInterface by passing in a custom gr.Chatbot object.
Conclusion
That’s it! You now know how you can implement the retry, undo, like, edit, and clear events for the Chatbot.