fix(web): regenerate a single-chat answer as a new turn (#18202)

This commit is contained in:
chanx
2026-08-13 14:17:04 +08:00
committed by GitHub
parent 4148193494
commit 9ac5008139
2 changed files with 20 additions and 56 deletions

View File

@@ -44,7 +44,6 @@ export type ChatStreamState = {
failStream(conversationId: string, pendingInput: string): void;
consumePendingInput(conversationId: string): void;
removeMessageById(conversationId: string, messageId: string): void;
truncateAfterMessage(conversationId: string, messageId: string): void;
endStream(conversationId: string): void;
stopStream(conversationId: string): void;
removeSessions(conversationIds: string[]): void;
@@ -324,44 +323,6 @@ export const useChatStreamStore = create<ChatStreamState>()(
);
},
truncateAfterMessage: (conversationId, messageId) => {
if (!conversationId) return;
set(
(state) => {
const previous = state.sessions[conversationId];
if (!previous) return state;
const index = previous.messages.findIndex(
(x) => x.id === messageId,
);
if (index === -1) return state;
const kept = previous.messages.slice(0, index + 2);
const latest = kept.at(-1);
const messages = latest
? [
...kept.slice(0, -1),
{
...latest,
content: '',
reference: undefined,
prompt: undefined,
},
]
: kept;
return {
sessions: {
...state.sessions,
[conversationId]: { ...previous, messages },
},
};
},
false,
'truncateAfterMessage',
);
},
endStream: (conversationId) => {
if (!conversationId) return;
set(

View File

@@ -2,11 +2,10 @@ import { NextMessageInputOnPressEnterParameter } from '@/components/message-inpu
import { MessageType } from '@/constants/chat';
import {
useHandleMessageInputChange,
useRegenerateMessage,
useScrollToBottom,
} from '@/hooks/logic-hooks';
import { useGetChatSearchParams } from '@/hooks/use-chat-request';
import { IMessage } from '@/interfaces/database/chat';
import { IMessage, Message } from '@/interfaces/database/chat';
import notification from '@/utils/notification';
import { trim } from 'lodash';
import { useCallback, useEffect, useRef } from 'react';
@@ -83,9 +82,6 @@ export const useSendMessage = () => {
const removeMessageFromStore = useChatStreamStore(
(state) => state.removeMessageById,
);
const truncateAfterMessage = useChatStreamStore(
(state) => state.truncateAfterMessage,
);
const hydrateFromServer = useChatStreamStore(
(state) => state.hydrateFromServer,
);
@@ -138,13 +134,6 @@ export const useSendMessage = () => {
setValue(pendingInput);
}, [pendingInput, value, conversationId, consumePendingInput, setValue]);
const removeMessagesAfterCurrentMessage = useCallback(
(messageId: string) => {
truncateAfterMessage(conversationId, messageId);
},
[conversationId, truncateAfterMessage],
);
const removeMessageById = useCallback(
(messageId: string) => {
removeMessageFromStore(conversationId, messageId);
@@ -152,11 +141,25 @@ export const useSendMessage = () => {
[conversationId, removeMessageFromStore],
);
const { regenerateMessage } = useRegenerateMessage({
removeMessagesAfterCurrentMessage,
sendMessage,
messages,
});
// Regenerating re-asks the same question as a new turn instead of rewriting
// the original exchange, so every earlier answer stays in the transcript.
const regenerateMessage = useCallback(
(message: Message) => {
if (isStreaming) return;
const questionMessage: IMessage = {
content: message.content,
files: message.files,
id: uuid(),
role: MessageType.User,
conversationId,
};
appendQuestion(conversationId, questionMessage);
sendMessage({ message: questionMessage });
},
[conversationId, isStreaming, appendQuestion, sendMessage],
);
const { createConversationBeforeSendMessage } =
useCreateConversationBeforeSendMessage();