fix(chat): improve performance for longer sessions

This commit is contained in:
Bohdan Triapitsyn
2025-12-19 00:13:46 +02:00
parent 84339edb28
commit 78e0c47bf9
3 changed files with 59 additions and 0 deletions
+3
View File
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
- Polished chat expirience for longer session
- Fixed file link from git view to diff
## [1.2.4] - 2025-12-18
+43
View File
@@ -45,6 +45,25 @@ const computeTextLength = (parts: Part[] | undefined | null): number => {
return length;
};
const MIN_SORTABLE_LENGTH = 10;
const extractSortableId = (id: unknown): string | null => {
if (typeof id !== 'string') return null;
const trimmed = id.trim();
if (!trimmed) return null;
const underscoreIndex = trimmed.indexOf('_');
const candidate = underscoreIndex >= 0 ? trimmed.slice(underscoreIndex + 1) : trimmed;
if (!candidate || candidate.length < MIN_SORTABLE_LENGTH) return null;
return candidate;
};
const isIdNewer = (id: string, referenceId: string): boolean => {
const currentSortable = extractSortableId(id);
const referenceSortable = extractSortableId(referenceId);
if (!currentSortable || !referenceSortable) return true;
if (currentSortable.length !== referenceSortable.length) return true;
return currentSortable > referenceSortable;
};
const messageCache = new Map<string, { sessionId: string; message: { info: Message; parts: Part[] } | null }>();
const getMessageFromStore = (sessionId: string, messageId: string): { info: Message; parts: Part[] } | null => {
const cacheKey = `${sessionId}:${messageId}`;
@@ -376,6 +395,18 @@ export const useEventStream = () => {
const sessionId = resolvedSessionId;
const messageId = resolvedMessageId;
const trimmedHeadMaxId = useSessionStore.getState().sessionMemoryState.get(sessionId)?.trimmedHeadMaxId;
if (trimmedHeadMaxId && !isIdNewer(messageId, trimmedHeadMaxId)) {
if (streamDebugEnabled()) {
console.debug('[useEventStream] Skipping message.part.updated for trimmed message', {
sessionId,
messageId,
trimmedHeadMaxId,
});
}
break;
}
let roleInfo = 'assistant';
if (messageInfo && typeof (messageInfo as { role?: unknown }).role === 'string') {
roleInfo = (messageInfo as { role?: string }).role as string;
@@ -433,6 +464,18 @@ export const useEventStream = () => {
const sessionId = resolvedSessionId;
const messageId = resolvedMessageId;
const trimmedHeadMaxId = useSessionStore.getState().sessionMemoryState.get(sessionId)?.trimmedHeadMaxId;
if (trimmedHeadMaxId && !isIdNewer(messageId, trimmedHeadMaxId)) {
if (streamDebugEnabled()) {
console.debug('[useEventStream] Skipping message.updated for trimmed message', {
sessionId,
messageId,
trimmedHeadMaxId,
});
}
break;
}
if (isDesktopRuntimeRef.current && streamDebugEnabled()) {
try {
const serverParts = (props as { parts?: unknown }).parts || (messageExt as { parts?: unknown }).parts || [];
+13
View File
@@ -812,6 +812,13 @@ export const useMessageStore = create<MessageStore>()(
if (ignoredAssistantMessageIds.has(messageId)) {
return;
}
const trimmedHeadMaxId = stateSnapshot.sessionMemoryState.get(sessionId)?.trimmedHeadMaxId;
if (trimmedHeadMaxId && !isIdNewer(messageId, trimmedHeadMaxId)) {
(window as any).__messageTracker?.(messageId, 'ignored_trimmed_stream_part');
return;
}
const existingMessagesSnapshot = stateSnapshot.messages.get(sessionId) || [];
const existingMessageSnapshot = existingMessagesSnapshot.find((m) => m.info.id === messageId);
@@ -1435,6 +1442,12 @@ export const useMessageStore = create<MessageStore>()(
updateMessageInfo: (sessionId: string, messageId: string, messageInfo: any) => {
set((state) => {
const trimmedHeadMaxId = state.sessionMemoryState.get(sessionId)?.trimmedHeadMaxId;
if (trimmedHeadMaxId && !isIdNewer(messageId, trimmedHeadMaxId)) {
(window as any).__messageTracker?.(messageId, 'ignored_trimmed_update');
return state;
}
const sessionMessages = state.messages.get(sessionId) ?? [];
const normalizedSessionMessages = [...sessionMessages];