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

Add allow_file_downloads param to allow downloading image/video/audio media in chatbot #9905

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions .changeset/huge-windows-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@gradio/chatbot": patch
"gradio": patch
---

fix:Add `allow_file_downloads` param to allow downloading image/video/audio media in chatbot
3 changes: 3 additions & 0 deletions gradio/components/chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ def __init__(
placeholder: str | None = None,
examples: list[ExampleMessage] | None = None,
show_copy_all_button=False,
allow_file_downloads=False,
):
"""
Parameters:
Expand Down Expand Up @@ -218,6 +219,7 @@ def __init__(
placeholder: a placeholder message to display in the chatbot when it is empty. Centered vertically and horizontally in the Chatbot. Supports Markdown and HTML. If None, no placeholder is displayed.
examples: A list of example messages to display in the chatbot before any user/assistant messages are shown. Each example should be a dictionary with an optional "text" key representing the message that should be populated in the Chatbot when clicked, an optional "files" key, whose value should be a list of files to populate in the Chatbot, an optional "icon" key, whose value should be a filepath or URL to an image to display in the example box, and an optional "display_text" key, whose value should be the text to display in the example box. If "display_text" is not provided, the value of "text" will be displayed.
show_copy_all_button: If True, will show a copy all button that copies all chatbot messages to the clipboard.
allow_file_downloads: If True, will show a download button for chatbot messages that contain media. Defaults to False.
"""
if type is None:
warnings.warn(
Expand Down Expand Up @@ -259,6 +261,7 @@ def __init__(
self.line_breaks = line_breaks
self.layout = layout
self.show_copy_all_button = show_copy_all_button
self.allow_file_downloads = allow_file_downloads
super().__init__(
label=label,
every=every,
Expand Down
21 changes: 4 additions & 17 deletions js/chatbot/Chatbot.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

<Story
name="Chatbot with math disabled, small height"
args={{ latex_delimiters: [], height: 200 }}
args={{ latex_delimiters: [], height: 200, show_copy_button: false }}
/>

<Story
Expand All @@ -85,24 +85,10 @@
/>

<Story
name="Chatbot with copy button"
args={{
show_copy_button: true
}}
/>

<Story
name="Chatbot with chat bubble full width disabled"
args={{
bubble_full_width: false
}}
/>
Comment on lines -88 to -99
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

removing these stories and consolidating their variants with other stories to reduce snapshot usage


<Story
name="Chatbot with panel layout enabled"
name="Chatbot with chat bubble full width disabled and copy button"
args={{
bubble_full_width: false,
layout: "panel"
show_copy_button: true
}}
/>

Expand Down Expand Up @@ -200,6 +186,7 @@ This document is a showcase of various Markdown capabilities.`,
<Story
name="Chatbot with image in markdown"
args={{
allow_file_downloads: true,
value: [
[
`![A cheetah](https://cdn.britannica.com/02/92702-120-6A02E613/Cheetah.jpg)`
Expand Down
2 changes: 2 additions & 0 deletions js/chatbot/Index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
undo: UndoRetryData;
clear: null;
}>;
export let allow_file_downloads = false;

let _value: NormalisedMessage[] | null = [];

Expand Down Expand Up @@ -157,6 +158,7 @@
load_component={gradio.load_component}
msg_format={type}
root={gradio.root}
{allow_file_downloads}
/>
</div>
</Block>
Expand Down
19 changes: 18 additions & 1 deletion js/chatbot/shared/ChatBot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import type { NormalisedMessage } from "../types";
import { copy } from "@gradio/utils";
import Message from "./Message.svelte";
import { DownloadLink } from "@gradio/wasm/svelte";

import { dequal } from "dequal/lite";
import {
Expand All @@ -22,7 +23,13 @@
} from "svelte";
import { Image } from "@gradio/image/shared";

import { Clear, Trash, Community, ScrollDownArrow } from "@gradio/icons";
import {
Clear,
Trash,
Community,
ScrollDownArrow,
Download
} from "@gradio/icons";
import { IconButtonWrapper, IconButton } from "@gradio/atoms";
import type { SelectData, LikeData } from "@gradio/utils";
import type { ExampleMessage } from "../types";
Expand Down Expand Up @@ -85,6 +92,7 @@
export let _undoable = false;
export let like_user_message = false;
export let root: string;
export let allow_file_downloads = false;

let target: HTMLElement | null = null;

Expand Down Expand Up @@ -292,6 +300,14 @@
on:click={() => (is_image_preview_open = false)}
label={"Clear"}
/>
{#if allow_file_downloads}
<DownloadLink
href={image_preview_source}
download={image_preview_source_alt || "image"}
>
<IconButton Icon={Download} label={"Download"} />
</DownloadLink>
{/if}
</IconButtonWrapper>
</div>
{/if}
Expand Down Expand Up @@ -326,6 +342,7 @@
{show_copy_button}
handle_action={(selected) => handle_like(i, messages[0], selected)}
scroll={is_browser ? scroll : () => {}}
{allow_file_downloads}
/>
{/each}
{#if pending_message}
Expand Down
7 changes: 4 additions & 3 deletions js/chatbot/shared/Component.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
export let i18n;
export let upload;
export let _fetch;
export let allow_file_downloads = false;
</script>

{#if type === "gallery"}
Expand Down Expand Up @@ -45,7 +46,7 @@
label=""
waveform_settings={{}}
waveform_options={{}}
show_download_button={false}
show_download_button={allow_file_downloads}
on:load
/>
{:else if type === "video"}
Expand All @@ -57,7 +58,7 @@
show_share_button={true}
{i18n}
{upload}
show_download_button={false}
show_download_button={allow_file_downloads}
on:load
>
<track kind="captions" />
Expand All @@ -68,7 +69,7 @@
{value}
show_label={false}
label="chatbot-image"
show_download_button={false}
show_download_button={allow_file_downloads}
on:load
{i18n}
/>
Expand Down
55 changes: 25 additions & 30 deletions js/chatbot/shared/Message.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
export let msg_format: "tuples" | "messages";
export let handle_action: (selected: string | null) => void;
export let scroll: () => void;
export let allow_file_downloads = false;

function handle_select(i: number, message: NormalisedMessage): void {
dispatch("select", {
Expand Down Expand Up @@ -147,11 +148,23 @@
aria-label={role + "'s message: " + get_message_label_data(message)}
>
{#if message.type === "text"}
{#if message.metadata.title}
<MessageBox
title={message.metadata.title}
expanded={is_last_bot_message([message], value)}
>
<div class="message-content">
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

to apply padding only to text message content

{#if message.metadata.title}
<MessageBox
title={message.metadata.title}
expanded={is_last_bot_message([message], value)}
>
<Markdown
message={message.content}
{latex_delimiters}
{sanitize_html}
{render_markdown}
{line_breaks}
on:load={scroll}
{root}
/>
</MessageBox>
{:else}
<Markdown
message={message.content}
{latex_delimiters}
Expand All @@ -161,18 +174,8 @@
on:load={scroll}
{root}
/>
</MessageBox>
{:else}
<Markdown
message={message.content}
{latex_delimiters}
{sanitize_html}
{render_markdown}
{line_breaks}
on:load={scroll}
{root}
/>
{/if}
{/if}
</div>
{:else if message.type === "component" && message.content.component in _components}
<Component
{target}
Expand All @@ -185,6 +188,7 @@
{upload}
{_fetch}
on:load={() => scroll()}
{allow_file_downloads}
/>
{:else if message.type === "component" && message.content.component === "file"}
<a
Expand Down Expand Up @@ -316,7 +320,6 @@
box-shadow: var(--shadow-drop);
align-self: flex-start;
text-align: right;
padding: var(--spacing-sm) var(--spacing-xl);
border-color: var(--border-color-accent-subdued);
background-color: var(--color-accent-soft);
}
Expand All @@ -330,7 +333,6 @@
box-shadow: var(--shadow-drop);
align-self: flex-start;
text-align: right;
padding: var(--spacing-sm) var(--spacing-xl);
}

.panel .user :global(*) {
Expand Down Expand Up @@ -417,17 +419,6 @@
overflow-wrap: break-word;
}

.user {
border-width: 1px;
border-radius: var(--radius-md);
align-self: flex-start;
border-bottom-right-radius: 0;
box-shadow: var(--shadow-drop);
text-align: right;
padding: var(--spacing-sm) var(--spacing-xl);
border-color: var(--border-color-accent-subdued);
background-color: var(--color-accent-soft);
}
@media (max-width: 480px) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

didn't need this, dupe of .user earlier in the file

.user-row.bubble {
align-self: flex-end;
Expand All @@ -441,6 +432,10 @@
}
}

.message-content {
padding: var(--spacing-sm) var(--spacing-xl);
}

.avatar-container {
align-self: flex-start;
position: relative;
Expand Down
Loading