chainlit icon indicating copy to clipboard operation
chainlit copied to clipboard

Allow users to edit previous messages and "fork"

Open Enoch2090 opened this issue 2 years ago • 7 comments

Support editing previous messages like ChatGPT. The conversation should "fork" when message is edited. If possible also creates a duplicate of the memory in LangChain?

Enoch2090 avatar Nov 22 '23 15:11 Enoch2090

This is an interesting feature and quite hard to implement in a framework agnostic way. I guess what we could do is add an edit button to root messages and a new cl decorator to let developers react to it?

willydouhard avatar Nov 22 '23 16:11 willydouhard

This is an interesting feature and quite hard to implement in a framework agnostic way. I guess what we could do is add an edit button to root messages and a new cl decorator to let developers react to it?

My understanding is that if we can attach buttons to messages as "states" instead of using the input components only at the beginning of a chat, this will allow implementation of chains forking.
Frame agnostic is preferred but not necessary, developers can definitely do the clone of chat history manually.

Enoch2090 avatar Nov 24 '23 06:11 Enoch2090

We can already achieve this with:

  1. An update action
  2. The action trigger a ask user message to get the edited value from the user
  3. Update the message and remove the following messages (this would require to store those messages in the user_session)

Not the best user experience but would be a good proof of concept!

willydouhard avatar Nov 24 '23 09:11 willydouhard

Hi Willy: Your proposed method is totally doable - but I do met a problem while implementing it:

Editing the memory from the framework is achieved, but for user experience we still need to remove messages after the edited ones.

  • For a normal chat this can be done by tracing all messages in the user session. The trace is maintained in the @cl.on_message decorated function, and in the @cl.action_callback decorated function we iterate through the traced message list and use message.remove(). But when it comes to resumed chats, this method fails because there seems no way to maintain the trace?
  • As for the cloud client's delete_message feature, I also implemented a test. It seems that though possible to remove messages via this API, it's only removing cloud messages, and the messages in the Chat UI are not removed unless I refresh and resume the chat.

Looking forward to your advices! Thanks!

Enoch2090 avatar Dec 19 '23 08:12 Enoch2090

Hey!

The the resumed chats, you have access to all the messages (including their ids) in the on_chat_resume decorated function.

From here you can probably instantiate a cl.Message with the correct id and call .remove() on it?

willydouhard avatar Dec 19 '23 08:12 willydouhard

Hey!

The the resumed chats, you have access to all the messages (including their ids) in the on_chat_resume decorated function.

From here you can probably instantiate a cl.Message with the correct id and call .remove() on it?

  1. I think the messages will be automatically instantiated when on_chat_resume decorated function is called. I can instantiate messages according to the MessageDict here but I still need to remove those already displayed ones, or find a way to operate them (this is quite similar to losing track of a pointer in C++...).

  2. Regarding getting the edited value from the user, is it possible to use unsafe_allow_html = true in the config, then use simple JavaScript in the message body? I've played with using HTML + CSS in message body and it worked:

msedge_December19-19-57-226b2a

but script within HTML doesn't seem to work:

<script>
  (function () {
      var textarea = document.getElementById('chat-input');

      textarea.value = 'New text in chat input';

      var event = new Event('input', {
          bubbles: true,
          cancelable: true,
      });

      textarea.dispatchEvent(event);

  })();
</script>

(pasting the JS alone in F12 console works tho) The idea of this hack is to set the chat input automatically.

Enoch2090 avatar Dec 19 '23 12:12 Enoch2090

@Enoch2090 - might it be possible to get your JS delivered via the custom JS feature? I don't know if it was present at the time you made your most recent comment, but it seems like it could help get around your problems getting it to run...

👉 https://docs.chainlit.io/customisation/custom-js

nmstoker avatar Feb 29 '24 19:02 nmstoker