Skip to content

Commit

Permalink
Reset flagged values when switching conversations in chat history (#1…
Browse files Browse the repository at this point in the history
…0292)

* chat history

* add changeset

* changes

* add changeset

* changes

* changes

* more changes

* changes

* changes

* format

* notebook

* fix test

* changes

* add changeset

* changes

* changes

* changes

* add changeset

---------

Co-authored-by: gradio-pr-bot <[email protected]>
Co-authored-by: Ali Abid <[email protected]>
  • Loading branch information
3 people authored Jan 6, 2025
1 parent 890eaa3 commit f2bd72f
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 45 deletions.
7 changes: 7 additions & 0 deletions .changeset/short-rice-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@gradio/atoms": minor
"@gradio/chatbot": minor
"gradio": minor
---

feat:Reset flagged values when switching conversations in chat history
2 changes: 1 addition & 1 deletion demo/chatinterface_streaming_echo/run.ipynb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatinterface_streaming_echo"]}, {"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 time\n", "import gradio as gr\n", "\n", "def slow_echo(message, history):\n", " for i in range(len(message)):\n", " time.sleep(0.05)\n", " yield \"You typed: \" + message[: i + 1]\n", "\n", "demo = gr.ChatInterface(\n", " slow_echo,\n", " type=\"messages\",\n", " flagging_mode=\"manual\",\n", " flagging_options=[\"Like\", \"Spam\", \"Inappropriate\", \"Other\"], \n", " save_history=True,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatinterface_streaming_echo"]}, {"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 time\n", "import gradio as gr\n", "\n", "def slow_echo(message, history):\n", " for i in range(len(message)):\n", " time.sleep(0.05)\n", " yield \"You typed: \" + message[: i + 1]\n", "\n", "demo = gr.ChatInterface(\n", " slow_echo,\n", " type=\"messages\",\n", " flagging_mode=\"manual\",\n", " flagging_options=[\"Like\", \"Spam\", \"Inappropriate\", \"Other\"],\n", " save_history=True,\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
2 changes: 1 addition & 1 deletion demo/chatinterface_streaming_echo/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def slow_echo(message, history):
slow_echo,
type="messages",
flagging_mode="manual",
flagging_options=["Like", "Spam", "Inappropriate", "Other"],
flagging_options=["Like", "Spam", "Inappropriate", "Other"],
save_history=True,
)

Expand Down
49 changes: 36 additions & 13 deletions gradio/chat_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def __init__(

with self:
self.saved_conversations = BrowserState(
[], storage_key="_saved_conversations"
[], storage_key=f"_saved_conversations_{self._id}"
)
self.conversation_id = State(None)
self.saved_input = State() # Stores the most recent user message
Expand Down Expand Up @@ -279,7 +279,7 @@ def _render_history_area(self):
with Column(scale=1, min_width=100):
self.new_chat_button = Button(
"New chat",
variant="secondary",
variant="primary",
size="md",
icon=utils.get_icon_path("plus.svg"),
)
Expand Down Expand Up @@ -467,6 +467,28 @@ def _delete_conversation(
saved_conversations.pop(index)
return None, saved_conversations

def _load_chat_history(self, conversations):
return Dataset(
samples=[
[self._generate_chat_title(conv)]
for conv in conversations or []
if conv
]
)

def _load_conversation(
self,
index: int,
conversations: list[list[MessageDict]],
):
return (
index,
Chatbot(
value=conversations[index], # type: ignore
feedback_value=[],
),
)

def _setup_events(self) -> None:
from gradio import on

Expand Down Expand Up @@ -645,28 +667,29 @@ def _setup_events(self) -> None:
queue=False,
)

@on(
[self.load, self.saved_conversations.change],
on(
triggers=[self.load, self.saved_conversations.change],
fn=self._load_chat_history,
inputs=[self.saved_conversations],
outputs=[self.chat_history_dataset],
show_api=False,
queue=False,
)
def load_chat_history(conversations):
return Dataset(
samples=[
[self._generate_chat_title(conv)]
for conv in conversations or []
if conv
]
)

self.chat_history_dataset.click(
lambda index, conversations: (index, conversations[index]),
lambda: [],
None,
[self.chatbot],
show_api=False,
queue=False,
show_progress="hidden",
).then(
self._load_conversation,
[self.chat_history_dataset, self.saved_conversations],
[self.conversation_id, self.chatbot],
show_api=False,
queue=False,
show_progress="hidden",
).then(**synchronize_chat_state_kwargs)

if self.flagging_mode != "never":
Expand Down
3 changes: 3 additions & 0 deletions gradio/components/chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ def __init__(
sanitize_html: bool = True,
render_markdown: bool = True,
feedback_options: list[str] | tuple[str, ...] | None = ("Like", "Dislike"),
feedback_value: Sequence[str | None] | None = None,
bubble_full_width=None,
line_breaks: bool = True,
layout: Literal["panel", "bubble"] | None = None,
Expand Down Expand Up @@ -234,6 +235,7 @@ def __init__(
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.
feedback_options: A list of strings representing the feedback options that will be displayed to the user. The exact case-sensitive strings "Like" and "Dislike" will render as thumb icons, but any other choices will appear under a separate flag icon.
feedback_value: A list of strings representing the feedback state for entire chat. Only works when type="messages". Each entry in the list corresponds to that assistant message, in order, and the value is the feedback given (e.g. "Like", "Dislike", or any custom feedback option) or None if no feedback was given for that message.
bubble_full_width: Deprecated.
line_breaks: If True (default), will enable Github-flavored Markdown line breaks in chatbot messages. If False, single new lines will be ignored. Only applies if `render_markdown` is True.
layout: If "panel", will display the chatbot in a llm style layout. If "bubble", will display the chatbot with message bubbles, with the user and bot messages on alterating sides. Will default to "bubble".
Expand Down Expand Up @@ -290,6 +292,7 @@ def __init__(
self.show_copy_all_button = show_copy_all_button
self.allow_file_downloads = allow_file_downloads
self.feedback_options = feedback_options
self.feedback_value = feedback_value
super().__init__(
label=label,
every=every,
Expand Down
2 changes: 1 addition & 1 deletion gradio/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def test(value, like_data: gr.LikeData):
"chatbot_value": value,
"liked_message": like_data.value,
"liked_index": like_data.index,
"liked_or_disliked_as_bool": like_data.liked
"liked_or_disliked": like_data.liked
}
with gr.Blocks() as demo:
c = gr.Chatbot([("abc", "def")])
Expand Down
4 changes: 2 additions & 2 deletions gradio/icons/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions js/atoms/src/IconButtonWrapper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,9 @@
}
.icon-button-wrapper
:global(
a.download-link:not(:last-child):not(.extra-feedback-option)::after
),
:global(a.download-link:not(:last-child):not(.no-border *)::after),
.icon-button-wrapper
:global(button:not(:last-child):not(.extra-feedback-option)::after) {
:global(button:not(:last-child):not(.no-border *)::after) {
content: "";
position: absolute;
right: -4.5px;
Expand Down
2 changes: 2 additions & 0 deletions js/chatbot/Index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
export let _selectable = false;
export let likeable = false;
export let feedback_options: string[] = ["Like", "Dislike"];
export let feedback_value: (string | null)[] | null = null;
export let show_share_button = false;
export let rtl = false;
export let show_copy_button = true;
Expand Down Expand Up @@ -128,6 +129,7 @@
selectable={_selectable}
{likeable}
{feedback_options}
{feedback_value}
{show_share_button}
{show_copy_all_button}
value={_value}
Expand Down
7 changes: 6 additions & 1 deletion js/chatbot/shared/ButtonPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
export let position: "right" | "left";
export let avatar: FileData | null;
export let generating: boolean;
export let current_feedback: string | null;
export let handle_action: (selected: string | null) => void;
export let layout: "bubble" | "panel";
Expand Down Expand Up @@ -94,7 +95,11 @@
/>
{/if}
{#if likeable}
<LikeDislike {handle_action} {feedback_options} />
<LikeDislike
{handle_action}
{feedback_options}
selected={current_feedback}
/>
{/if}
{/if}
</IconButtonWrapper>
Expand Down
15 changes: 12 additions & 3 deletions js/chatbot/shared/ChatBot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
export let selectable = false;
export let likeable = false;
export let feedback_options: string[];
export let feedback_value: (string | null)[] | null = null;
export let editable: "user" | "all" | null = null;
export let show_share_button = false;
export let show_copy_all_button = false;
Expand Down Expand Up @@ -204,11 +205,11 @@
});
} else {
let feedback =
selected === "like"
selected === "Like"
? true
: selected === "dislike"
: selected === "Dislike"
? false
: selected?.substring(9); // remove "feedback:" prefix
: selected || "";
if (msg_format === "tuples") {
dispatch("like", {
index: message.index,
Expand Down Expand Up @@ -283,6 +284,13 @@
{@const role = messages[0].role === "user" ? "user" : "bot"}
{@const avatar_img = avatar_images[role === "user" ? 0 : 1]}
{@const opposite_avatar_img = avatar_images[role === "user" ? 0 : 1]}
{@const feedback_index = groupedMessages
.slice(0, i)
.filter((m) => m[0].role === "assistant").length}
{@const current_feedback =
role === "bot" && feedback_value && feedback_value[feedback_index]
? feedback_value[feedback_index]
: null}
<Message
{messages}
{display_consecutive_in_same_bubble}
Expand All @@ -309,6 +317,7 @@
{generating}
{msg_format}
{feedback_options}
{current_feedback}
show_like={role === "user" ? likeable && like_user_message : likeable}
show_retry={_retryable && is_last_bot_message(messages, value)}
show_undo={_undoable && is_last_bot_message(messages, value)}
Expand Down
34 changes: 16 additions & 18 deletions js/chatbot/shared/LikeDislike.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,42 @@
export let handle_action: (selected: string | null) => void;
export let feedback_options: string[];
export let selected: string | null = null;
$: extra_feedback = feedback_options.filter(
(option) => option !== "Like" && option !== "Dislike"
);
let selected: string | null = null;
function toggleSelection(newSelection: string): void {
selected = selected === newSelection ? null : newSelection;
handle_action(selected);
}
</script>

{#if feedback_options.includes("Like") || feedback_options.includes("Dislike")}
{#if feedback_options.includes("Dislike")}
<IconButton
Icon={selected === "dislike" ? ThumbDownActive : ThumbDownDefault}
label={selected === "dislike" ? "clicked dislike" : "dislike"}
color={selected === "dislike"
Icon={selected === "Dislike" ? ThumbDownActive : ThumbDownDefault}
label={selected === "Dislike" ? "clicked dislike" : "dislike"}
color={selected === "Dislike"
? "var(--color-accent)"
: "var(--block-label-text-color)"}
on:click={() => {
selected = "dislike";
handle_action(selected);
}}
on:click={() => toggleSelection("Dislike")}
/>
{/if}
{#if feedback_options.includes("Like")}
<IconButton
Icon={selected === "like" ? ThumbUpActive : ThumbUpDefault}
label={selected === "like" ? "clicked like" : "like"}
color={selected === "like"
Icon={selected === "Like" ? ThumbUpActive : ThumbUpDefault}
label={selected === "Like" ? "clicked like" : "like"}
color={selected === "Like"
? "var(--color-accent)"
: "var(--block-label-text-color)"}
on:click={() => {
selected = "like";
handle_action(selected);
}}
on:click={() => toggleSelection("Like")}
/>
{/if}
{/if}

{#if extra_feedback.length > 0}
<div class="extra-feedback">
<div class="extra-feedback no-border">
<IconButton
Icon={selected && extra_feedback.includes(selected) ? FlagActive : Flag}
label="Feedback"
Expand All @@ -60,8 +58,8 @@
class="extra-feedback-option"
style:font-weight={selected === option ? "bold" : "normal"}
on:click={() => {
selected = option;
handle_action("feedback:" + selected);
toggleSelection(option);
handle_action(selected ? selected : null);
}}>{option}</button
>
{/each}
Expand Down
6 changes: 5 additions & 1 deletion js/chatbot/shared/Message.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
export let in_edit_mode: boolean;
export let edit_message: string;
export let display_consecutive_in_same_bubble: boolean;
export let current_feedback: string | null = null;
let messageElements: HTMLDivElement[] = [];
let previous_edit_mode = false;
let last_message_width = 0;
Expand Down Expand Up @@ -102,6 +103,7 @@
layout: "bubble" | "panel";
avatar: FileData | null;
dispatch: any;
current_feedback: string | null;
};
let button_panel_props: ButtonPanelProps;
Expand All @@ -119,7 +121,8 @@
position: role === "user" ? "right" : "left",
avatar: avatar_img,
layout,
dispatch
dispatch,
current_feedback
};
</script>

Expand Down Expand Up @@ -235,6 +238,7 @@
{#if layout === "panel"}
<ButtonPanel
{...button_panel_props}
{current_feedback}
on:copy={(e) => dispatch("copy", e.detail)}
/>
{/if}
Expand Down
1 change: 1 addition & 0 deletions test/components/test_chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def test_component_functions(self):
"placeholder": None,
"height": 400,
"feedback_options": ("Like", "Dislike"),
"feedback_value": None,
"resizeable": False,
"max_height": None,
"min_height": None,
Expand Down

0 comments on commit f2bd72f

Please sign in to comment.