vercel / ai

Build AI-powered applications with React, Svelte, Vue, and Solid
https://sdk.vercel.ai/docs
Other
9.98k stars 1.47k forks source link

Add support for edit history #2251

Open stodoran opened 3 months ago

stodoran commented 3 months ago

Feature Description

Exact implementation could vary. One potential approach would be to add the following properties to the object returned from useChat. This is off the top of my head, and not necessarily the best/most minimal interface.

{
    editMessage: (index: number, newMessage: Message) => void,
    cycleHistory: (index: number, direction: -1|1) => void,

    // Length equal to `messages`. If a message has never been edited this is one
    // for that index, if it has been edited once, then it is two, etc.
    numBranches: number[],  

    // Length equal to `messages`. Each number represents which edit version
    // of the message at the corresponding index is currently "active". 
    activeBranch: number[],
}

When the user edits a message, this should create a new "branch" of the chat, since to keep track messages we need a tree, but the apparent effect on messages when editing should be: all messages prior to the given index are preserved, the message at the given index is modified, and subsequent messages are removed. The language model is then prompted again with the new message. If the user cycles the history back on this message, the old "branch" would be restored (the version of the message prior to the edit, and all subsequent messages, if any).

I'm not sure how well I've explained this but if it is difficult to visualize, simply navigate to chatgpt.com and try editing some messages.

Use Case

When using conversational AI chatbots such as OpenAI's ChatGPT, the user can edit a previous message, allowing them to send a new prompt while preserving the previous chat context. This is useful for a myriad of reasons. Firstly, if the response to an edited message is worse, the user is able to recover their previous chat. Secondly, a full edit history allows for easy comparison of similar prompts without losing the previous chat context, which can help build trust in models. Lastly, it enables the user to dive more in depth on certain topics, but then zoom back out to the original conversation, much like how threads work in Slack.

Additional context

With the current useChat API, it is fairly trivial to implement the ability for users to edit their chats. To edit at some index, simply slice messages up to the index, add the modified message, then use setMessages and reload.

However, because the only exposed methods for modifying messages are append and setMessages, implementing full edit history is a huge pain. This is because the developer must maintain their own copy of state (the edit history tree) and keep it synced with the state of useChat.

If there is a good way to implement edit history with the current version of useChat and I'm just missing it, please let me know.

dion-blutui commented 2 months ago

@lgrammel any update on this? would be super useful for our application as well which lets the user edit previous messages to change the context.

adolphnov commented 1 day ago

I think it's not just about modifying historical dialogues; there should be control over each step. Direct modification of the model, the existing dialogue records, and other parameters should be allowed at each step. Currently, I achieve this by constructing streamText/generateText multiple times.