From eb07addfa5a7fbf02edc01ab36903d6fdc1f50c6 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Sun, 6 Sep 2026 00:32:35 +0200 Subject: [PATCH] ui : reuse the conversation load read for sibling info Opening a conversation read every message from the database twice: once in loadConversation for the active path, once in ChatMessages for the sibling map. Hand the freshly read array over once so the chat screen builds sibling info from it, and set the conversation and its messages in one sync block so effects never see the new conversation paired with the previous one's messages. Assisted-by: pi:zai-org/GLM-5.3 --- .../app/chat/ChatMessages/ChatMessages.svelte | 14 +++++-- .../lib/stores/conversations/index.svelte.ts | 41 ++++++++++++------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessages.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessages.svelte index 4750a9f7c1..0a90097318 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessages.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessages.svelte @@ -97,9 +97,17 @@ const conversation = conversationsStore.activeConversation; if (conversation) { - conversationsStore.getConversationMessages(conversation.id).then((messages) => { - allConversationMessages = messages; - }); + // reuse the array loadConversation just read, when present; branch + // actions fall through to a fresh fetch + const preloaded = conversationsStore.consumeLastLoadedMessages(conversation.id); + + if (preloaded) { + allConversationMessages = preloaded; + } else { + conversationsStore.getConversationMessages(conversation.id).then((messages) => { + allConversationMessages = messages; + }); + } } else { allConversationMessages = []; } diff --git a/tools/ui/src/lib/stores/conversations/index.svelte.ts b/tools/ui/src/lib/stores/conversations/index.svelte.ts index caefe67901..c4fea2e4ee 100644 --- a/tools/ui/src/lib/stores/conversations/index.svelte.ts +++ b/tools/ui/src/lib/stores/conversations/index.svelte.ts @@ -52,6 +52,13 @@ class ConversationsStore implements ConversationsPreferencesHost { /** In-flight init run; shared by concurrent callers, reset on failure to allow retry */ private initPromise: Promise | null = null; + /** + * Messages loadConversation just read, handed off once so the chat + * screen can reuse them for sibling info instead of re-fetching the + * whole conversation a second time. + */ + private lastLoadedMessages: { convId: string; messages: DatabaseMessage[] } | null = null; + /** * Memo of the last findMessageIndex() lookup. Streaming calls it once per * chunk for the same message, so a validated cache hit keeps that O(1) @@ -239,6 +246,17 @@ class ConversationsStore implements ConversationsPreferencesHost { this.preferences.resetPending(); } + /** One-shot handoff of the messages the last loadConversation read. */ + consumeLastLoadedMessages(convId: string): DatabaseMessage[] | null { + if (this.lastLoadedMessages?.convId !== convId) return null; + + const messages = this.lastLoadedMessages.messages; + + this.lastLoadedMessages = null; + + return messages; + } + /** * Creates a new conversation and navigates to it * @param name - Optional name for the conversation @@ -512,22 +530,15 @@ class ConversationsStore implements ConversationsPreferencesHost { // it doesn't belong to this conversation. this.preferences.pendingCwd = null; + const allMessages = await DatabaseService.getConversationMessages(convId); + + // set conversation and messages in one sync block so effects never see + // the new conversation with the previous conversation's messages + this.lastLoadedMessages = { convId, messages: allMessages }; this.activeConversation = conversation; - - if (conversation.currNode) { - const allMessages = await DatabaseService.getConversationMessages(convId); - const filteredMessages = filterByLeafNodeId( - allMessages, - conversation.currNode, - false - ) as DatabaseMessage[]; - - this.activeMessages = filteredMessages; - } else { - const messages = await DatabaseService.getConversationMessages(convId); - - this.activeMessages = messages; - } + this.activeMessages = conversation.currNode + ? (filterByLeafNodeId(allMessages, conversation.currNode, false) as DatabaseMessage[]) + : allMessages; return true; } catch (error) {