Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
# Upcoming Release

## New Features:
No changes to highlight.

### The `Chatbot` component now supports Markdown/HTML

You can now pass in Markdown or HTML to the Chatbot component and it will show up,
meaning that you can pass in images, videos, or audio files as well! by [@abidlabs](https://github.com/abidlabs) in [PR 2731](https://github.com/gradio-app/gradio/pull/2731)

Here's a simple example that references a local image `lion.jpg` that is in the same
folder as the Python script:

```py
import gradio as gr

with gr.Blocks() as demo:
gr.Chatbot([("hi", "hello **abubakar**"), ("![](/file=lion.jpg)", "cool pic")])

demo.launch()
```

![Alt text](https://user-images.githubusercontent.com/1778297/204357455-5c1a4002-eee7-479d-9a1e-ba2c12522723.png)

To see a more realistic example, see the new demo `/demo/chatbot_multimodal/run.py`.


## Bug Fixes:
* Fixed bug where requests timeout is missing from utils.version_check() by [@yujiehecs](https://github.com/yujiehecs) in [PR 2729](https://github.com/gradio-app/gradio/pull/2729)
Expand Down
1 change: 1 addition & 0 deletions demo/chatbot_multimodal/run.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: chatbot_multimodal"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "def add_text(state, text):\n", " state = state + [(text, text + \"?\")]\n", " return state, state\n", "\n", "def add_image(state, image):\n", " state = state + [(f\"![](/file={image.name})\", \"Cool pic!\")]\n", " return state, state\n", "\n", "\n", "with gr.Blocks(css=\"#chatbot .overflow-y-auto{height:500px}\") as demo:\n", " chatbot = gr.Chatbot(elem_id=\"chatbot\")\n", " state = gr.State([])\n", " \n", " with gr.Row():\n", " with gr.Column(scale=0.85):\n", " txt = gr.Textbox(show_label=False, placeholder=\"Enter text and press enter, or upload an image\").style(container=False)\n", " with gr.Column(scale=0.15, min_width=0):\n", " btn = gr.UploadButton(\"\ud83d\uddbc\ufe0f\", file_types=[\"image\"])\n", " \n", " txt.submit(add_text, [state, txt], [state, chatbot])\n", " txt.submit(lambda :\"\", None, txt)\n", " btn.upload(add_image, [state, btn], [state, chatbot])\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
27 changes: 27 additions & 0 deletions demo/chatbot_multimodal/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import gradio as gr

def add_text(state, text):
state = state + [(text, text + "?")]
return state, state

def add_image(state, image):
state = state + [(f"![](/file={image.name})", "Cool pic!")]
return state, state


with gr.Blocks(css="#chatbot .overflow-y-auto{height:500px}") as demo:
chatbot = gr.Chatbot(elem_id="chatbot")
state = gr.State([])

with gr.Row():
with gr.Column(scale=0.85):
txt = gr.Textbox(show_label=False, placeholder="Enter text and press enter, or upload an image").style(container=False)
with gr.Column(scale=0.15, min_width=0):
btn = gr.UploadButton("🖼️", file_types=["image"])

txt.submit(add_text, [state, txt], [state, chatbot])
txt.submit(lambda :"", None, txt)
btn.upload(add_image, [state, btn], [state, chatbot])

if __name__ == "__main__":
demo.launch()
21 changes: 14 additions & 7 deletions gradio/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -2857,11 +2857,13 @@ def process_single_file(f):
)
if self.type == "file":
if is_file:
file = processing_utils.create_tmp_copy_of_file(file_name)
file = processing_utils.create_tmp_copy_of_file(
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the UploadButton component to save files in the right location

file_name, dir=self.temp_dir
)
file.orig_name = file_name
else:
file = processing_utils.decode_base64_to_file(
data, file_path=file_name
data, file_path=file_name, dir=self.temp_dir
)
file.orig_name = file_name
return file
Expand Down Expand Up @@ -3610,9 +3612,9 @@ def __init__(
@document("change", "style")
class Chatbot(Changeable, IOComponent, JSONSerializable):
"""
Displays a chatbot output showing both user submitted messages and responses
Displays a chatbot output showing both user submitted messages and responses. Supports Markdown formatting.
Preprocessing: this component does *not* accept input.
Postprocessing: expects a {List[Tuple[str, str]]}, a list of tuples with user inputs and responses.
Postprocessing: expects a {List[Tuple[str, str]]}, a list of tuples with user inputs and responses as strings, which support Markdown formatting.

Demos: chatbot_demo
"""
Expand Down Expand Up @@ -3641,6 +3643,7 @@ def __init__(
"The 'color_map' parameter has been moved from the constructor to `Chatbot.style()` ",
)
self.color_map = color_map
self.md = MarkdownIt()

IOComponent.__init__(
self,
Expand Down Expand Up @@ -3680,11 +3683,15 @@ def update(
def postprocess(self, y: List[Tuple[str, str]]) -> List[Tuple[str, str]]:
"""
Parameters:
y: List of tuples representing the message and response
y: List of tuples representing the message and response pairs. Each message and response should be a string, which may be in Markdown format.
Returns:
List of tuples representing the message and response
List of tuples representing the message and response. Each message and response will be a string, rendered as HTML.
"""
return [] if y is None else y
if y is None:
return []
for i, (message, response) in enumerate(y):
y[i] = (self.md.render(message), self.md.render(response))
return y

def style(self, *, color_map: Optional[List[str, str]] = None, **kwargs):
"""
Expand Down
23 changes: 23 additions & 0 deletions test/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,29 @@ def highlight_vowels(sentence):
]


class TestChatbot:
def test_component_functions(self):
"""
Postprocess, get_config
"""
chatbot = gr.Chatbot()
assert chatbot.postprocess([("You are **cool**", "so are *you*")]) == [
("<p>You are <strong>cool</strong></p>\n", "<p>so are <em>you</em></p>\n")
]
assert chatbot.get_config() == {
"value": [],
"color_map": None,
"label": None,
"show_label": True,
"interactive": None,
"name": "chatbot",
"visible": True,
"elem_id": None,
"style": {},
"root_url": None,
}


class TestJSON:
def test_component_functions(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions ui/packages/chatbot/src/ChatBot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@
class="px-3 py-2 rounded-[22px] rounded-br-none text-white text-sm"
style={"background-color:" + _colors[0]}
>
{message[0]}
{@html message[0]}
</div>
<div
data-testid="bot"
class="px-3 py-2 rounded-[22px] rounded-bl-none place-self-start text-white text-sm"
style={"background-color:" + _colors[1]}
>
{message[1]}
{@html message[1]}
</div>
{/each}
</div>
Expand Down