Repository: gradio-app/gradio
Pull request: Allow supplying custom `gr.Chatbot` with events to `gr.ChatInterface`
Fixes: https://github.com/gradio-app/gradio/issues/8675 so that now you can put a `gr.ChatInterface` inside a `gr.Blocks` with a custom `gr.Chatbot` and attach events, like this:

```py
import gradio as gr

def vote(data: gr.LikeData):
    print(data.value)
    if data.liked:
        print("You upvoted this response: " + data.value["value"])
    else:
        print("You downvoted this response: " + data.value["value"])

with gr.Blocks() as demo:
    chatbot = gr.Chatbot()
    chatbot.like(vote, None, None)
    gr.ChatInterface(fn=lambda x,y:x, chatbot=chatbot)
    
demo.launch()
```

Problem statement:
Error when passing in a custom chatbot to add like/dislike feature to Chatinterface
how can I add a like/dislike function to Chatinterface?
this is possible with blocks but I can't add to a Chatinterface.

import gradio as gr

def greet(history, input):
return history + [(input, "Hello, " + input)]

def vote(data: gr.LikeData):
if data.liked:
print("You upvoted this response: " + data.value)
else:
print("You downvoted this response: " + data.value)

with gr.Blocks() as demo:
chatbot = gr.Chatbot()
textbox = gr.Textbox()
textbox.submit(greet, [chatbot, textbox], [chatbot])
chatbot.like(vote, None, None) # Adding this line causes the like/dislike icons to appear in your chatbot

demo.launch()

Hints from issue discussion:
Hi @sajjadmosaheb to do this, you can pass in a custom `gr.Chatbot` object into the `chatbot` argument of `gr.ChatInterface` as described here: https://www.gradio.app/guides/creating-a-chatbot-fast#customizing-your-chatbot, and then attach a `.like` event to it. 
Hi @abidlabs ,
but when I attach the .like() event like below I got this error:

**AttributeError: Cannot call like outside of a gradio.Blocks context.**

```
demo= gr.ChatInterface(main,
    title="test",
    css=css,
    fill_height=True,
    chatbot=gr.Chatbot(rtl=True,likeable=True).like(vote, None, None))

demo.launch() 
```
Hi @sajjadmosaheb, you'll need to put everything under a `gr.Blocks`:

```py
with gr.Blocks():
  chatbot = gr.Chatbot(rtl=True,likeable=True)
  chatbot.like(vote, None, None)
  demo= gr.ChatInterface(main,
      title="test",
      css=css,
      fill_height=True,
      chatbot=chatbot)

demo.launch() 
```
thanks @abidlabs and I appreciate your response,
now I got this error! (I even add the render=False in the first chatbot but not working)
**DuplicateBlockError: A block with id: 174 has already been rendered in the current Blocks.**
Hmm let me reopen and investigate this 
For now, this should work, but looking into a better way of supporting this:

```py
import gradio as gr

with gr.Blocks() as demo:
    chatbot = gr.Chatbot(render=False)
    chatbot.like(lambda x:x, None, None)
    gr.ChatInterface(lambda x,y:x, chatbot=chatbot)

demo.launch() 
```

Commit message: add changeset

Patch to review:
diff --git a/.changeset/soft-months-behave.md b/.changeset/soft-months-behave.md
new file mode 100644
index 0000000000..688cfd78b0
--- /dev/null
+++ b/.changeset/soft-months-behave.md
@@ -0,0 +1,5 @@
+---
+"gradio": patch
+---
+
+fix:Allow putting suppling custom `gr.Chatbot` with events to `gr.ChatInterface`
diff --git a/gradio/chat_interface.py b/gradio/chat_interface.py
index 25c505f6e4..ca487f503f 100644
--- a/gradio/chat_interface.py
+++ b/gradio/chat_interface.py
@@ -182,7 +182,7 @@ def __init__(
                 Markdown(description)
 
             if chatbot:
-                self.chatbot = chatbot.render()
+                self.chatbot = get_component_instance(chatbot, render=True)
             else:
                 self.chatbot = Chatbot(
                     label="Chatbot", scale=1, height=200 if fill_height else None
@@ -211,7 +211,7 @@ def __init__(
                         else:
                             textbox.container = False
                         textbox.show_label = False
-                        textbox_ = textbox.render()
+                        textbox_ = get_component_instance(textbox, render=True)
                         if not isinstance(textbox_, (Textbox, MultimodalTextbox)):
                             raise TypeError(
                                 f"Expected a gr.Textbox or gr.MultimodalTextbox component, but got {type(textbox_)}"
diff --git a/guides/05_chatbots/01_creating-a-chatbot-fast.md b/guides/05_chatbots/01_creating-a-chatbot-fast.md
index 9a86fa0a82..7b989d1cd8 100644
--- a/guides/05_chatbots/01_creating-a-chatbot-fast.md
+++ b/guides/05_chatbots/01_creating-a-chatbot-fast.md
@@ -136,6 +136,25 @@ gr.ChatInterface(
 
 The placeholder appears vertically and horizontally centered in the chatbot.
 
+If you would like to attach event listeners to your custom chatbot, wrap the chatbot as well as the `gr.ChatInterface` inside of a `gr.Blocks` like this:
+
+```py
+import gradio as gr
+
+def vote(data: gr.LikeData):
+    if data.liked:
+        print("You upvoted this response: " + data.value["value"])
+    else:
+        print("You downvoted this response: " + data.value["value"])
+
+with gr.Blocks() as demo:
+    chatbot = gr.Chatbot()
+    chatbot.like(vote, None, None)
+    gr.ChatInterface(fn=lambda x,y:x, chatbot=chatbot)
+    
+demo.launch()
+```
+
 ## Add Multimodal Capability to your chatbot
 
 You may want to add multimodal capability to your chatbot. For example, you may want users to be able to easily upload images or files to your chatbot and ask questions about it. You can make your chatbot "multimodal" by passing in a single parameter (`multimodal=True`) to the `gr.ChatInterface` class.
diff --git a/guides/05_chatbots/02_creating-a-custom-chatbot-with-blocks.md b/guides/05_chatbots/02_creating-a-custom-chatbot-with-blocks.md
index e3974ff319..4a240a9c36 100644
--- a/guides/05_chatbots/02_creating-a-custom-chatbot-with-blocks.md
+++ b/guides/05_chatbots/02_creating-a-custom-chatbot-with-blocks.md
@@ -66,9 +66,9 @@ def greet(history, input):
 
 def vote(data: gr.LikeData):
     if data.liked:
-        print("You upvoted this response: " + data.value)
+        print("You upvoted this response: " + data.value["value"])
     else:
-        print("You downvoted this response: " + data.value)
+        print("You downvoted this response: " + data.value["value"])
     
 
 with gr.Blocks() as demo:
diff --git a/test/test_chat_interface.py b/test/test_chat_interface.py
index 6136043731..919485c4a1 100644
--- a/test/test_chat_interface.py
+++ b/test/test_chat_interface.py
@@ -227,6 +227,17 @@ def test_example_caching_with_additional_inputs_already_rendered(self, monkeypat
             assert prediction_hello[0].root[0] == ("hello", "robot hello")
             assert prediction_hi[0].root[0] == ("hi", "ro")
 
+    def test_custom_chatbot_with_events(self):
+        with gr.Blocks() as demo:
+            chatbot = gr.Chatbot()
+            chatbot.like(lambda: None, None, None)
+            gr.ChatInterface(fn=lambda x, y: x, chatbot=chatbot)
+        dependencies = demo.fns.values()
+        assert next(
+            (d for d in dependencies if d.targets == [(chatbot._id, "like")]),
+            None,
+        )
+
 
 class TestAPI:
     def test_get_api_info(self):


Code review comments:
diff_hunk: @@ -136,6 +136,25 @@ gr.ChatInterface(
 
 The placeholder appears vertically and horizontally centered in the chatbot.
 
+If you would like to attach event listeners to your custom chatbot, wrap the chatbot as well as the `gr.ChatInterface` inside of a `gr.Blocks` like this:
path: guides/05_chatbots/01_creating-a-chatbot-fast.md
text: @user1:
feel like the "creating a chatbot fast" guide should be quick and sweet, this particular usecase doesn't seem common enough to be here.

@author:
That's fair, this guide is getting quite bloated. It would be better to move this over to the docs page for `gr.ChatInterface`. Let me do that