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

Support saving chat history in gr.ChatInterface #10191

Open
wants to merge 69 commits into
base: main
Choose a base branch
from
Open

Conversation

abidlabs
Copy link
Member

@abidlabs abidlabs commented Dec 13, 2024

Test with: demo/chatinterface_save_history/run.py

Closes: #10045

@abidlabs abidlabs marked this pull request as draft December 13, 2024 00:40
@gradio-pr-bot
Copy link
Collaborator

gradio-pr-bot commented Dec 13, 2024

🪼 branch checks and previews

Name Status URL
Spaces ready! Spaces preview
Website ready! Website preview
Storybook ready! Storybook preview
🦄 Changes detected! Details

Install Gradio from this PR

pip install https://gradio-pypi-previews.s3.amazonaws.com/abb8a8ea7405c25ee8f3c337cba8c11d6a5bd167/gradio-5.9.1-py3-none-any.whl

Install Gradio Python Client from this PR

pip install "gradio-client @ git+https://github.com/gradio-app/gradio@abb8a8ea7405c25ee8f3c337cba8c11d6a5bd167#subdirectory=client/python"

Install Gradio JS Client from this PR

npm install https://gradio-npm-previews.s3.amazonaws.com/abb8a8ea7405c25ee8f3c337cba8c11d6a5bd167/gradio-client-1.8.0.tgz

Use Lite from this PR

<script type="module" src="https://gradio-lite-previews.s3.amazonaws.com/abb8a8ea7405c25ee8f3c337cba8c11d6a5bd167/dist/lite.js""></script>

@gradio-pr-bot
Copy link
Collaborator

gradio-pr-bot commented Dec 13, 2024

🦄 change detected

This Pull Request includes changes to the following packages.

Package Version
@gradio/button minor
@gradio/dataset minor
@gradio/textbox minor
gradio minor
  • Maintainers can select this checkbox to manually select packages to update.

With the following changelog entry.

Support saving chat history in gr.ChatInterface

Maintainers or the PR author can modify the PR title to modify this entry.

Something isn't right?

  • Maintainers can change the version label to modify the version bump.
  • If the bot has failed to detect any changes, or if this pull request needs to update multiple packages to different versions or requires a more comprehensive changelog entry, maintainers can update the changelog file directly.

@dawoodkhan82
Copy link
Collaborator

@abidlabs I'll replace gr.State() here with gr.BrowserState(), and update the styling of the html "sidebar". Is that what you had in mind?

@abidlabs
Copy link
Member Author

Yes exactly. We also need to actually save the chat history to the browser state, that functionality is currently not implemented

@abidlabs
Copy link
Member Author

You may find this PR useful: #10245 (or maybe not, not sure)

abidlabs and others added 5 commits December 23, 2024 16:58
* Declare exports

* add changeset

* type fixes

* more type fixes

* add changeset

* notebooks

* changes

---------

Co-authored-by: gradio-pr-bot <[email protected]>
Co-authored-by: Freddy Boulton <[email protected]>
Co-authored-by: Abubakar Abid <[email protected]>
* changes

* changes

* add changeset

* format

* changes

---------

Co-authored-by: gradio-pr-bot <[email protected]>
@dawoodkhan82
Copy link
Collaborator

@abidlabs Did a first pass, and the functionality for chat conversation history should work, if you can test. Will push some changes to tweak the UI.

@abidlabs
Copy link
Member Author

Will take a look soon!

@abidlabs
Copy link
Member Author

Nice @dawoodkhan82! Core functionality to save to browser state is working for me and I like that the first message automatically becomes the title of the saved first chat. Some issues I noticed:

(1) Clicking on the trash button in Chatbot causes the history to error out. And in a permanent way: if you refresh the page, you'll see that none of the chats in the history remain and you actually need to restart the Gradio server to get the chat history working again:

Screen.Recording.2024-12-26.at.11.26.28.PM.mov

(2) Uploading an image breaks the chat history feature as well:

Screen.Recording.2024-12-26.at.11.27.45.PM.mov

(3) When you load the chat from the history, its not synchronized with the chat state, so that if you send a subsequent message, it wipes out the chat history instead of "resuming" from the last message:

Screen.Recording.2024-12-26.at.11.29.40.PM.mov

(4) Also, the final chat that is stored to history seems to be used as the value for all of the chats. So if you click through the chats, all of them will have the same value actually:

Screen.Recording.2024-12-26.at.11.31.17.PM.mov

@abidlabs
Copy link
Member Author

Fixed isseus (3) and (4), working on the others

@abidlabs
Copy link
Member Author

There are some edge cases I need to fix (e.g. handling images and other non-text messages) but let me open for feedback, especially on the design side

@abidlabs
Copy link
Member Author

Ok I've replaced everything with native Gradio components and I agree it looks a lot better, thanks @aliabid94 for the suggestion so it should be ready for a re-review:

Screen.Recording.2024-12-31.at.1.12.10.PM.mov

Btw I've made some changes to some other gradio components, which I'll explain below

@@ -29,8 +30,8 @@ def __init__(
every: Timer | float | None = None,
inputs: Component | Sequence[Component] | set[Component] | None = None,
variant: Literal["primary", "secondary", "stop", "huggingface"] = "secondary",
size: Literal["sm", "lg"] | None = None,
icon: str | None = None,
size: Literal["sm", "md", "lg"] | None = None,
Copy link
Member Author

Choose a reason for hiding this comment

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

I added a "md"-sized button as that was ideal for this UI and I think it could be more broadly useful.

Copy link
Member Author

Choose a reason for hiding this comment

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

Made the same change to all of the subclasses of Button below

components: Which component types to show in this dataset widget, can be passed in as a list of string names or Components instances. The following components are supported in a Dataset: Audio, Checkbox, CheckboxGroup, ColorPicker, Dataframe, Dropdown, File, HTML, Image, Markdown, Model3D, Number, Radio, Slider, Textbox, TimeSeries, Video
samples: a nested list of samples. Each sublist within the outer list represents a data sample, and each element within the sublist represents an value for each component
headers: Column headers in the Dataset widget, should be the same len as components. If not provided, inferred from component labels
type: "values" if clicking on a sample should pass the value of the sample, "index" if it should pass the index of the sample, or "tuple" if it should pass both the index and the value of the sample.
layout: "gallery" if the dataset should be displayed as a gallery with each sample in a clickable card, or "table" if it should be displayed as a table with each sample in a row. By default, "gallery" is used if there is a single component, and "table" is used if there are more than one component. If there are more than one component, the layout can only be "table".
Copy link
Member Author

Choose a reason for hiding this comment

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

I added some parameters to gr.Dataset that are broadly useful. For example, this one comes up a lot.

icon: str
| None = "https://huggingface.co/front/assets/huggingface_logo-noborder.svg",
size: Literal["sm", "md", "lg"] | None = None,
icon: str | Path | None = utils.get_icon_path("Huggingface-Logo.svg"),
Copy link
Member Author

Choose a reason for hiding this comment

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

So that this works offline

gradio/utils.py Outdated
@@ -1098,7 +1098,7 @@ def is_in_or_equal(path_1: str | Path, path_2: str | Path) -> bool:


@document()
def set_static_paths(paths: list[str | Path]) -> None:
def set_static_paths(paths: str | Path | list[str | Path]) -> list[str | Path]:
Copy link
Member Author

Choose a reason for hiding this comment

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

Its safer to accept a str explicitly because otherwise if a user passes in a str accidentally, every individual character will be treated as a separate "file"

gradio/utils.py Outdated Show resolved Hide resolved
await expect(page.locator("#num-recorded-api-calls")).toContainText(
`🪄 Recorded API Calls [${n_calls}]`
Copy link
Member Author

Choose a reason for hiding this comment

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

n_calls is an implementation detail

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Allow conversation retention & multiple conversations in gr.ChatInterface
5 participants