From 8755666912c61218600a89a6c59a9b64f2f9d031 Mon Sep 17 00:00:00 2001 From: Vellum Assistant Date: Tue, 26 May 2026 12:52:25 -0500 Subject: [PATCH] fix(macos): advance sidebar pagination by DB offset, not accumulated count After the cold-start drain loop, ConversationRestorer set serverOffset to foreground.conversations.count. The conversations endpoint appends injected pinned rows on page 1 (offset 0), so the accumulated count overshoots the server's DB cursor and the next loadMoreConversations() skips that many rows. Carry the server-provided nextOffset (DB pagination cursor) through the synthesized fetchAllConversationPages response and use it for serverOffset, mirroring the appendConversations pagination path. Addresses Codex review on #31924. --- .../MainWindow/ConversationRestorer.swift | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/MainWindow/ConversationRestorer.swift b/clients/macos/vellum-assistant/Features/MainWindow/ConversationRestorer.swift index 947d9803ceb..c091d6dce2f 100644 --- a/clients/macos/vellum-assistant/Features/MainWindow/ConversationRestorer.swift +++ b/clients/macos/vellum-assistant/Features/MainWindow/ConversationRestorer.swift @@ -546,7 +546,7 @@ final class ConversationRestorer { } // serverOffset is set by fetchConversationList before merging foreground + - // background, so it reflects foreground-only count for correct pagination. + // background, so it reflects the foreground-only DB cursor for correct pagination. log.info("Restored \(restoredConversations.count) conversations from daemon (hasMore: \(response.hasMore ?? false))") delegate.restoreLastActiveConversation() } @@ -692,10 +692,12 @@ final class ConversationRestorer { let uniqueBackground = (background?.conversations ?? []).filter { seenIds.insert($0.id).inserted } - // Set serverOffset from foreground count BEFORE merging. - // loadMoreConversations pages the foreground endpoint only, - // so the offset must not include merged background rows. - self.delegate?.serverOffset = foreground.conversations.count + // Set serverOffset to the foreground DB cursor BEFORE + // merging. loadMoreConversations pages the foreground + // endpoint only, so the offset must not include merged + // background rows; nextOffset is the DB cursor (see + // fetchAllConversationPages), not the inflated row count. + self.delegate?.serverOffset = foreground.nextOffset ?? foreground.conversations.count let merged = ConversationListResponse( type: foreground.type, conversations: foreground.conversations + uniqueBackground, @@ -735,6 +737,7 @@ final class ConversationRestorer { let pageSize = Self.conversationListPageSize var accumulated: [ConversationListResponseItem] = [] var firstPage: ConversationListResponse? + var nextOffset = 0 for page in 0..