Skip to content

Add new_chat for conversation history - #399

Merged
cpsievert merged 5 commits into
mainfrom
fix/397-chat-clear-history-new
Sep 8, 2026
Merged

cpsievert merged 5 commits into
mainfrom
fix/397-chat-clear-history-new

Conversation

@gadenbuie

@gadenbuie gadenbuie commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #397

Summary

  • Add new_chat() to the managed R and Python chat handles. It saves the active conversation, clears the rendered messages and client turns, resets the active conversation ID, and refreshes the history drawer.
  • Keep clear() as the lower-level UI/client-turn reset. It errors when conversation history is enabled and directs callers to new_chat().
  • Keep the low-level UI clear APIs UI-only, and document the distinction.
  • Reject new_chat() while a response streams in R and Python, so a late response cannot enter the new conversation.

Verification

  • make r-check
  • make py-check

@gadenbuie
gadenbuie marked this pull request as ready for review September 8, 2026 20:04
@gadenbuie
gadenbuie requested a review from cpsievert September 8, 2026 20:23
@gadenbuie gadenbuie changed the title Fix chat clear with conversation history Add new_chat for conversation history Sep 8, 2026
Comment thread pkg-py/src/shinychat/_chat_client.py Outdated
Comment on lines +145 to +149
if history_controller is not None:
raise ValueError(
"Can't clear a chat with conversation history enabled; use "
"`await chat.client.new_chat()` to start a new conversation."
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I still think the concept of changing messages (& turns) for the currently active conversation is going to be useful (e.g., compacting a conversation).

This is also why (privately, via Slack) I was advocating for deprecating .clear() in favor of a new .set_messages() method, which would basically be the same as the current .clear(), but assumes you are going to provide 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.

Are you okay moving forward without working this out yet? I'm on board with the general idea but I think we'll need to think about it a little more carefully and make sure we're getting the API right in tandem with ellmer/chatlas APIs.

One small detail, I have generally aligned on messages being UI chat state and turns being client chat state. And here on first read compaction seems to be more about changing client state independently from UI state.

Anyway, we can work this out but I do want to find the minimal immediate fix for anyone using the history with chat_server().

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.

For posterity I mentioned on Slack that set_messages() makes sense to me if we think we can get it together quickly

I was advocating for deprecating .clear() in favor of a new .set_messages() method

I guess my last comment is just that if we're thinking of deprecating .clear(), I'd like to consider leaving it as an alias for .new_chat() and deprecating internal arguments. That would give most general-case users a chance to keep using .clear() without breaking their apps and we could the more advanced usecase users migrate in the right direction.

@cpsievert cpsievert Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Are you okay moving forward without working this out yet? I'm on board with the general idea but I think we'll need to think about it a little more carefully and make sure we're getting the API right in tandem with ellmer/chatlas APIs.

Yep, and the more I looked into this, the more I'm happy with the PR as it currently stands (i.e.., hard error when history is enabled, but no deprecation, at least for now).

I think .set_messages() is probably worth doing, but I also think it should probably come after #379, especially if we want it to automatically save to history before mutation of the current conversation.

Chat.history is always set in __init__, so the double getattr fallback
in ChatClient.clear()/new_chat() was unreachable. Addresses review
feedback on #399.
@cpsievert
cpsievert merged commit dde163e into main Sep 8, 2026
20 checks passed
@cpsievert
cpsievert deleted the fix/397-chat-clear-history-new branch September 8, 2026 23:37
simonpcouch pushed a commit to posit-dev/commons that referenced this pull request Sep 9, 2026
shinychat's clear() now aborts when conversation history is enabled
(the only configuration commons_server() creates), which broke this
test. Drop the clear() assertion since new_chat() covers the same
commons behavior, and replace controller$new_chat() with the public
chat$new_chat() added in posit-dev/shinychat#399.

Closes #324
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.

chat$clear() doesn't coordinate with the history controller: conversations are lost and new chats get grafted onto the previous record

2 participants