Skip to content

Save and restore chat#303

Open
brichet wants to merge 15 commits intojupyterlite:mainfrom
brichet:backup-chat
Open

Save and restore chat#303
brichet wants to merge 15 commits intojupyterlite:mainfrom
brichet:backup-chat

Conversation

@brichet
Copy link
Copy Markdown
Collaborator

@brichet brichet commented Mar 24, 2026

This PR add commands and buttons to save and restore chats.

Fixe #299

In the current state, the chats are JSON serialized and save as a file in a hidden directory.

Saving can be done manually with the toolbar button, or automatically with the small button next to the save button image. The automatic save is triggered when messages list updated, with a 3s debouncer to avoid triggering several times during streaming.

Restoring is done automatically from the chat name when restoring the session, and can also be done manually using the commands (a file is then required).

(auto)save and auto restoration

output.webm

manual restoration

output.webm

To do

  • add automatic save option
  • add automatic restoration when restoring the session after reload
  • disable the command when restoration is not possible
  • fix the chat toolbar in the side panel, that may contain too many icon. We should probably use a reactive toolbar in @jupyter/chat
  • add tests

@jtpio jtpio added the enhancement New feature or request label Mar 25, 2026
@brichet
Copy link
Copy Markdown
Collaborator Author

brichet commented Mar 25, 2026

Automatic saving could use a signal when messages list is updated or a single message is updated (jupyterlab/jupyter-chat#389).

@brichet brichet marked this pull request as ready for review March 26, 2026 15:47
@brichet brichet marked this pull request as draft March 26, 2026 15:48
@brichet brichet marked this pull request as ready for review March 26, 2026 16:00
@jtpio
Copy link
Copy Markdown
Member

jtpio commented Mar 27, 2026

Thanks @brichet.

Trying on the RTD demo, it seems the chats are not restored after reloading the page:

jupyterlite-ai-saved-chat.mp4

And there seems to be an error when trying to restore the chat manually, even though it appears in chat-backups:

jupyterlite-ai-chat-restore.mp4

@jtpio
Copy link
Copy Markdown
Member

jtpio commented Mar 27, 2026

In the current state, the chats are JSON serialized and save as a file in a hidden directory.

Wondering if it could make sense for jupyterlite-ai to follow the same UX as in jupyterlab-chat, and save chats as .chat files? Even if the content of such chat files would be completely different.

This would help make the UX similar to the one in jupyterlab-chat and jupyter-ai.

Although such files would then not be usable across these projects , while they look the same and end with .chat.

@brichet
Copy link
Copy Markdown
Collaborator Author

brichet commented Mar 27, 2026

Thanks for trying, I haven't tested it on RTD.

Wondering if it could make sense for jupyterlite-ai to follow the same UX as in jupyterlab-chat, and save chats as .chat files? Even if the content of such chat files would be completely different.

Good point 👍 .
Actually the format are quite similar, a JSON including a message list, a user object and some metadata. The ExportedChat type in this PR could easily fit the format from jupyterlab-chat.
In future, we could define and version this schema in @jupyter/chat: jupyterlab/jupyter-chat#24

@brichet brichet marked this pull request as draft March 27, 2026 09:10
@brichet brichet marked this pull request as ready for review March 27, 2026 20:59
@brichet
Copy link
Copy Markdown
Collaborator Author

brichet commented Mar 27, 2026

It should be fixed now, and the chat format is compatible with jupyterlab-chat, in one way or the other 🎉 .

attachments
};
});
this.clearMessages();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like this clears the previous conversation, meaning that continuing from a previous chat will not include the previous messages as part of the context?

Image

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Right, I wonder what policy we should adopt regarding context history, especially now that chats can be restored. This could cause the context to contain too much messages.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added a commit to restore the agent history for now.

export function SaveComponent(props: ISaveButtonProps): JSX.Element {
const { model, translator: trans } = props;

const [autosave, setAutosave] = useState(model.autosave);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this properly pick up the new state when the restore() method (setting the value of autosave) is called in the chat model?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It actually did, but it may be a race condition. Let's add a signal to handle it properly.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, the autosave state depends on the model state now.

"items": { "type": "string" },
"default": [".agents/skills", "_agents/skills"]
},
"chatBackupDirectory": {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wondering if we need this new directory? Or should just handle .chat files as regular files like in jupyter-chat?

There could still be a setting to decided whether or not to enable the saving / auto-saving of such files.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't have a strong opinion on it, maybe we could keep the option in settings but set it to the root directory by default.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, default to root directory, but it is still configurable in settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants