perf(activity): keep only loaded activity pages in the renderer, driven by Main's summary
The renderer no longer holds the whole history. Startup sends queued changes, lets Main reconcile leftover pending/running records against the stored tasks (same localized interruptedOnRestart line), then loads the first page (200). The Activity page loads a full visible batch (500, as before paging); "load more" shows the next batch and loads the next page behind it; a filter switch refetches that filter's first page; leaving the page trims to one batch. Counts, project/conversation groups, titles, conversation status and the clear count come from activityHistory.summary (refreshed on entry, by the page timer, the refresh button and after load more / filter changes). Records that are not loaded are still updated incrementally: the update contract gains content-matched changes (upsert-call, update-request, resolve-approval, settle-request, remove-request, remove-call) that Main applies in SQL to shown rows; the store applies the same semantics to its pages through the shared reference. update returns Main's stored call records so a call whose earlier record was not loaded keeps one id. Task refresh reconciles via Main SQL. Legacy localStorage records migrate as incremental changes; the renderer no longer calls replace. Tests: randomized sequences of every action, page loads, trims, flushes and injected failures against the former full-list code on a real database; first page <= 200 after startup; flush payload depends only on changed records (including unloaded ones); ActivityPanel output with pages + summary equals the full-list rendering for randomized datasets with duplicates; restart interrupts leftover records with the same detail; clear empties the database, pages and summary; SQL change semantics equal the reference.
This commit is contained in:
+2
-7
@@ -6869,7 +6869,7 @@ export function registerIpcHandlers(
|
||||
ipcChannels.activityHistoryUpdate,
|
||||
(event, input: unknown) => {
|
||||
assertTrustedSender(event, window)
|
||||
assistantDatabase.updateActivityHistory(input)
|
||||
return assistantDatabase.updateActivityHistory(input)
|
||||
}
|
||||
)
|
||||
registerHandler(ipcChannels.activityHistoryClear, (event) => {
|
||||
@@ -6886,12 +6886,7 @@ export function registerIpcHandlers(
|
||||
})
|
||||
registerHandler(ipcChannels.activityHistoryReconcile, (event, input: unknown) => {
|
||||
assertTrustedSender(event, window)
|
||||
const request = activityHistoryReconcileRequestSchema.parse(input)
|
||||
// Requests still running in Main are active too, whichever window started them.
|
||||
return assistantDatabase.reconcileActivityHistory({
|
||||
...request,
|
||||
activeRequestIds: [...new Set([...request.activeRequestIds, ...activeRequests.keys()])]
|
||||
})
|
||||
return assistantDatabase.reconcileActivityHistory(activityHistoryReconcileRequestSchema.parse(input))
|
||||
})
|
||||
|
||||
registerHandler(ipcChannels.tokenUsageSummary, (event) => {
|
||||
|
||||
Reference in New Issue
Block a user