From 94708f8305ac5ce514f439b106aa7f3773f19544 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:30:15 +0800 Subject: [PATCH] Fix: regenerate chat message does not truncate history (#17087) --- web/src/hooks/logic-hooks.ts | 13 +++++++------ .../pages/next-chats/hooks/use-send-chat-message.ts | 10 ++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/web/src/hooks/logic-hooks.ts b/web/src/hooks/logic-hooks.ts index a8b926e771..da0b9272a1 100644 --- a/web/src/hooks/logic-hooks.ts +++ b/web/src/hooks/logic-hooks.ts @@ -26,7 +26,6 @@ import { useRef, useState, } from 'react'; -import { v4 as uuid } from 'uuid'; import { useTranslate } from './common-hooks'; import { useSetPaginationParams } from './route-hook'; import { useSaveSetting } from './use-user-setting-request'; @@ -714,12 +713,14 @@ export const useRegenerateMessage = ({ if (message.id) { removeMessagesAfterCurrentMessage(message.id); const index = messages.findIndex((x) => x.id === message.id); - let nextMessages; - if (index !== -1) { - nextMessages = messages.slice(0, index); - } + // Always pass the truncated history explicitly, even when it is + // empty (regenerating the first question), so the backend can + // overwrite the session with it via pass_all_history_messages. + const nextMessages = index !== -1 ? messages.slice(0, index) : []; sendMessage({ - message: { ...message, id: uuid() }, + // Keep the original id so the question/answer pair id stays + // consistent between local state and the persisted session. + message: { ...message }, messages: nextMessages, }); } diff --git a/web/src/pages/next-chats/hooks/use-send-chat-message.ts b/web/src/pages/next-chats/hooks/use-send-chat-message.ts index f72e9e0ada..49895d4530 100644 --- a/web/src/pages/next-chats/hooks/use-send-chat-message.ts +++ b/web/src/pages/next-chats/hooks/use-send-chat-message.ts @@ -102,10 +102,10 @@ export const useSendMessage = (controller: AbortController) => { { chat_id: chatId, session_id: sessionId, + // An explicitly provided list is authoritative, even when empty + // (e.g. regenerating the first question must truncate history). messages: [ - ...(Array.isArray(messages) && messages?.length > 0 - ? messages - : (derivedMessages ?? [])), + ...(Array.isArray(messages) ? messages : (derivedMessages ?? [])), message, ], pass_all_history_messages: true, @@ -171,7 +171,9 @@ export const useSendMessage = (controller: AbortController) => { setValue(''); sendMessage({ currentConversationId: targetConversationId, - messages: currentMessages, + // For an existing conversation currentMessages is empty; fall back + // to derivedMessages instead of sending an empty history. + messages: currentMessages.length > 0 ? currentMessages : undefined, message: { id, content: value.trim(),