refactor(chat): simplify baseDisplayMessages dedup — remove unnecessary reverse() (#2089)
* fix(chat): preserve chronological message order during history pagination The baseDisplayMessages dedup loop iterated from tail to head (newest to oldest), keeping the newer occurrence of each message ID. During history pagination (prepend mode), the server returns older messages that may overlap with the current view at the boundary. The tail-first iteration discarded the older (prepended) duplicate in favor of the newer (existing) one, breaking chronological ordering. Change the loop to iterate head to tail (oldest to newest) so the first occurrence of each time-sortable message ID is preserved. Remove the now-unnecessary .reverse() call. Fixes #2088 * test(chat): add dedup logic coverage for baseDisplayMessages Covers message ID deduplication in baseDisplayMessages useMemo: - First-occurrence preservation during dedup - Input order maintenance - Empty input, single-element, all-same-ID edge cases - History pagination prepend scenario with overlapping IDs --------- Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
bashrusakh
parent
d01126cf3c
commit
37768958f3
@@ -1344,20 +1344,24 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
|
||||
|
||||
|
||||
const baseDisplayMessages = React.useMemo(() => streamPerfMeasure('ui.message_list.base_display_ms', () => {
|
||||
const seenIdsFromTail = new Set<string>();
|
||||
const seenIds = new Set<string>();
|
||||
const dedupedMessages: ChatMessageEntry[] = [];
|
||||
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
||||
// Deduplicate from head to tail (oldest to newest) to preserve chronological
|
||||
// order during history pagination (prepend). Older messages have smaller
|
||||
// time-sortable IDs and appear first in the array. Keeping the first
|
||||
// occurrence ensures prepended history isn't incorrectly discarded in favor
|
||||
// of newer duplicates from the existing view.
|
||||
for (let index = 0; index < messages.length; index += 1) {
|
||||
const message = messages[index];
|
||||
const messageId = message.info?.id;
|
||||
if (typeof messageId === 'string') {
|
||||
if (seenIdsFromTail.has(messageId)) {
|
||||
if (seenIds.has(messageId)) {
|
||||
continue;
|
||||
}
|
||||
seenIdsFromTail.add(messageId);
|
||||
seenIds.add(messageId);
|
||||
}
|
||||
dedupedMessages.push(getNormalizedMessageForDisplay(message));
|
||||
}
|
||||
dedupedMessages.reverse();
|
||||
|
||||
const output: ChatMessageEntry[] = [];
|
||||
const compactionCommandIds = new Set<string>();
|
||||
|
||||
Reference in New Issue
Block a user