Add chat bubble width param (#5334)

* chat width

* add changeset

* fixes

* fix

* test

* reformat

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Dawood Khan 2023-08-28 20:48:52 -04:00 committed by GitHub
parent 1dc797adcb
commit c5bf91385a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 2 deletions

View File

@ -0,0 +1,6 @@
---
"@gradio/chatbot": minor
"gradio": minor
---
feat:Add chat bubble width param

View File

@ -1 +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": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/chatbot_multimodal/avatar.png"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "import time\n", "\n", "# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.\n", "\n", "\n", "def add_text(history, text):\n", " history = history + [(text, None)]\n", " return history, gr.update(value=\"\", interactive=False)\n", "\n", "\n", "def add_file(history, file):\n", " history = history + [((file.name,), None)]\n", " return history\n", "\n", "\n", "def bot(history):\n", " response = \"**That's cool!**\"\n", " history[-1][1] = \"\"\n", " for character in response:\n", " history[-1][1] += character\n", " time.sleep(0.05)\n", " yield history\n", "\n", "\n", "with gr.Blocks() as demo:\n", " chatbot = gr.Chatbot(\n", " [],\n", " elem_id=\"chatbot\",\n", " avatar_images=(None, (os.path.join(os.path.abspath(''), \"avatar.png\"))),\n", " )\n", "\n", " with gr.Row():\n", " txt = gr.Textbox(\n", " scale=4,\n", " show_label=False,\n", " placeholder=\"Enter text and press enter, or upload an image\",\n", " container=False,\n", " )\n", " btn = gr.UploadButton(\"\ud83d\udcc1\", file_types=[\"image\", \"video\", \"audio\"])\n", "\n", " txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", " txt_msg.then(lambda: gr.update(interactive=True), None, [txt], queue=False)\n", " file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", "\n", "demo.queue()\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"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": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/chatbot_multimodal/avatar.png"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "import time\n", "\n", "# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.\n", "\n", "\n", "def add_text(history, text):\n", " history = history + [(text, None)]\n", " return history, gr.update(value=\"\", interactive=False)\n", "\n", "\n", "def add_file(history, file):\n", " history = history + [((file.name,), None)]\n", " return history\n", "\n", "\n", "def bot(history):\n", " response = \"**That's cool!**\"\n", " history[-1][1] = \"\"\n", " for character in response:\n", " history[-1][1] += character\n", " time.sleep(0.05)\n", " yield history\n", "\n", "\n", "with gr.Blocks() as demo:\n", " chatbot = gr.Chatbot(\n", " [],\n", " elem_id=\"chatbot\",\n", " bubble_full_width=False,\n", " avatar_images=(None, (os.path.join(os.path.abspath(''), \"avatar.png\"))),\n", " )\n", "\n", " with gr.Row():\n", " txt = gr.Textbox(\n", " scale=4,\n", " show_label=False,\n", " placeholder=\"Enter text and press enter, or upload an image\",\n", " container=False,\n", " )\n", " btn = gr.UploadButton(\"\ud83d\udcc1\", file_types=[\"image\", \"video\", \"audio\"])\n", "\n", " txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", " txt_msg.then(lambda: gr.update(interactive=True), None, [txt], queue=False)\n", " file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", "\n", "demo.queue()\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}

View File

@ -28,6 +28,7 @@ with gr.Blocks() as demo:
chatbot = gr.Chatbot(
[],
elem_id="chatbot",
bubble_full_width=False,
avatar_images=(None, (os.path.join(os.path.dirname(__file__), "avatar.png"))),
)

View File

@ -55,6 +55,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
show_share_button: bool | None = None,
show_copy_button: bool = False,
avatar_images: tuple[str | Path | None, str | Path | None] | None = None,
bubble_full_width: bool = True,
**kwargs,
):
"""
@ -76,6 +77,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs to Hugging Face Spaces Discussions. If False, icon does not appear. If set to None (default behavior), then the icon appears if this Gradio app is launched on Spaces, but not otherwise.
show_copy_button: If True, will show a copy button for each chatbot message.
avatar_images: Tuple of two avatar image paths or URLs for user and bot (in that order). Pass None for either the user or bot image to skip. Must be within the working directory of the Gradio app or an external URL.
bubble_full_width: If False, the chat bubble will fit to the content of the message. If True (default), the chat bubble will be the full width of the component.
"""
if color_map is not None:
warn_deprecation("The 'color_map' parameter has been deprecated.")
@ -97,6 +99,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
else show_share_button
)
self.show_copy_button = show_copy_button
self.bubble_full_width = bubble_full_width
IOComponent.__init__(
self,
label=label,
@ -122,6 +125,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
"rtl": self.rtl,
"show_copy_button": self.show_copy_button,
"avatar_images": self.avatar_images,
"bubble_full_width": self.bubble_full_width,
**IOComponent.get_config(self),
}
@ -142,6 +146,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
show_share_button: bool | None = None,
show_copy_button: bool | None = None,
avatar_images: tuple[str | Path | None] | None = None,
bubble_full_width: bool | None = None,
):
updated_config = {
"label": label,
@ -157,6 +162,7 @@ class Chatbot(Changeable, Selectable, IOComponent, JSONSerializable):
"latex_delimiters": latex_delimiters,
"show_copy_button": show_copy_button,
"avatar_images": avatar_images,
"bubble_full_width": bubble_full_width,
"__type__": "update",
}
return updated_config

View File

@ -66,3 +66,10 @@
show_copy_button: true
}}
/>
<Story
name="Chatbot with chat bubble full width disabled"
args={{
bubble_full_width: false
}}
/>

View File

@ -5,7 +5,6 @@
import { beforeUpdate, afterUpdate, createEventDispatcher } from "svelte";
import { ShareButton } from "@gradio/atoms";
import type { SelectData } from "@gradio/utils";
import type { ThemeMode } from "js/app/src/components/types";
import type { FileData } from "@gradio/upload";
import { MarkdownCode as Markdown } from "@gradio/markdown/static";
import { get_fetchable_url_or_file } from "@gradio/upload";
@ -28,6 +27,7 @@
export let rtl = false;
export let show_copy_button = false;
export let avatar_images: [string | null, string | null] = [null, null];
export let bubble_full_width = true;
export let root: string;
export let root_url: null | string;
@ -116,6 +116,7 @@
data-testid={j == 0 ? "user" : "bot"}
class:latest={i === value.length - 1}
class="message {j == 0 ? 'user' : 'bot'}"
class:message-fit={!bubble_full_width}
class:hide={message === null}
class:selectable
on:click={() => handle_select(i, j, message)}
@ -235,6 +236,12 @@
line-height: var(--line-lg);
overflow-wrap: break-word;
}
.message-fit {
width: fit-content !important;
}
.message-fit.user {
margin-left: auto;
}
.user {
align-self: flex-end;
border-bottom-right-radius: 0;

View File

@ -23,6 +23,7 @@
export let show_share_button = false;
export let rtl = false;
export let show_copy_button = false;
export let bubble_full_width = true;
export let latex_delimiters: {
left: string;
right: string;
@ -96,6 +97,7 @@
on:share={(e) => gradio.dispatch("share", e.detail)}
on:error={(e) => gradio.dispatch("error", e.detail)}
{avatar_images}
{bubble_full_width}
{root_url}
{root}
/>

View File

@ -2018,6 +2018,7 @@ class TestChatbot:
"rtl": False,
"show_copy_button": False,
"avatar_images": (None, None),
"bubble_full_width": True,
}