Add render_markdown parameter to chatbot (#5604)

* disable markdown

* add changeset

* pr fixes

* format

* add changeset

* new line

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
This commit is contained in:
Dawood Khan 2023-09-22 14:53:09 -04:00 committed by GitHub
parent 21c7225bda
commit faad01f8e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 4 deletions

View File

@ -0,0 +1,7 @@
---
"@gradio/chatbot": patch
"@gradio/markdown": patch
"gradio": patch
---
fix:Add `render_markdown` parameter to chatbot

View File

@ -58,6 +58,7 @@ class Chatbot(Changeable, Selectable, Likeable, IOComponent, JSONSerializable):
show_copy_button: bool = False,
avatar_images: tuple[str | Path | None, str | Path | None] | None = None,
sanitize_html: bool = True,
render_markdown: bool = True,
bubble_full_width: bool = True,
**kwargs,
):
@ -81,6 +82,7 @@ class Chatbot(Changeable, Selectable, Likeable, IOComponent, JSONSerializable):
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.
sanitize_html: If False, will disable HTML sanitization for chatbot messages. This is not recommended, as it can lead to security vulnerabilities.
render_markdown: If False, will disable Markdown rendering for chatbot messages.
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:
@ -108,6 +110,7 @@ class Chatbot(Changeable, Selectable, Likeable, IOComponent, JSONSerializable):
if show_share_button is None
else show_share_button
)
self.render_markdown = render_markdown
self.show_copy_button = show_copy_button
self.sanitize_html = sanitize_html
self.bubble_full_width = bubble_full_width
@ -145,6 +148,7 @@ class Chatbot(Changeable, Selectable, Likeable, IOComponent, JSONSerializable):
avatar_images: tuple[str | Path | None] | None = None,
sanitize_html: bool | None = None,
bubble_full_width: bool | None = None,
render_markdown: bool | None = None,
):
warnings.warn(
"Using the update method is deprecated. Simply return a new object instead, e.g. `return gr.Chatbot(...)` instead of `return gr.Chatbot.update(...)`."
@ -165,6 +169,7 @@ class Chatbot(Changeable, Selectable, Likeable, IOComponent, JSONSerializable):
"avatar_images": avatar_images,
"sanitize_html": sanitize_html,
"bubble_full_width": bubble_full_width,
"render_markdown": render_markdown,
"__type__": "update",
}
return updated_config

View File

@ -30,6 +30,7 @@
export let avatar_images: [string | null, string | null] = [null, null];
export let sanitize_html = true;
export let bubble_full_width = true;
export let render_markdown = true;
export let root: string;
export let root_url: null | string;
@ -136,6 +137,7 @@
class:latest={i === value.length - 1}
class="message {j == 0 ? 'user' : 'bot'}"
class:message-fit={!bubble_full_width}
class:message-markdown-disabled={!render_markdown}
class:selectable
on:click={() => handle_select(i, j, message)}
dir={rtl ? "rtl" : "ltr"}
@ -167,6 +169,7 @@
{message}
{latex_delimiters}
{sanitize_html}
{render_markdown}
on:load={scroll}
/>
{:else if message !== null && message.mime_type?.includes("audio")}
@ -275,6 +278,9 @@
.message-fit.user {
margin-left: auto;
}
.message-markdown-disabled {
white-space: pre-line;
}
.user {
align-self: flex-end;
border-bottom-right-radius: 0;

View File

@ -26,6 +26,7 @@
export let show_copy_button = false;
export let sanitize_html = true;
export let bubble_full_width = true;
export let render_markdown = true;
export let latex_delimiters: {
left: string;
right: string;
@ -93,6 +94,7 @@
{show_share_button}
value={_value}
{latex_delimiters}
{render_markdown}
pending_message={loading_status?.status === "pending"}
{rtl}
{show_copy_button}

View File

@ -14,6 +14,7 @@
right: string;
display: boolean;
}[] = [];
export let render_markdown = true;
let el: HTMLSpanElement;
let html: string;
@ -24,10 +25,19 @@
node.setAttribute("rel", "noopener noreferrer");
}
});
function process_message(value: string): string {
if (render_markdown) {
value = marked.parse(value);
}
if (sanitize_html) {
value = DOMPurify.sanitize(value);
}
return value;
}
$: if (message && message.trim()) {
html = sanitize_html
? DOMPurify.sanitize(marked.parse(message))
: marked.parse(message);
html = process_message(message);
} else {
html = "";
}
@ -43,7 +53,11 @@
</script>
<span class:chatbot bind:this={el} class="md">
{@html html}
{#if render_markdown}
{@html html}
{:else}
{html}
{/if}
</span>
<style>

View File

@ -2097,6 +2097,7 @@ class TestChatbot:
"show_copy_button": False,
"avatar_images": (None, None),
"sanitize_html": True,
"render_markdown": True,
"bubble_full_width": True,
}