From 7fd3aae222178e993d3598e7d406bb5e9984bd81 Mon Sep 17 00:00:00 2001 From: m4air Date: Sat, 12 Sep 2026 00:30:38 -0700 Subject: [PATCH] perf(ai-vault): reduce scan-local occurrence metadata --- .../ai-vault/codex-session-collection.test.ts | 25 +++++++++++++++++++ src/main/ai-vault/codex-session-root-dedup.ts | 21 ++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/main/ai-vault/codex-session-collection.test.ts b/src/main/ai-vault/codex-session-collection.test.ts index d600f16f311..0e815f1b279 100644 --- a/src/main/ai-vault/codex-session-collection.test.ts +++ b/src/main/ai-vault/codex-session-collection.test.ts @@ -65,6 +65,31 @@ describe('CodexSessionCollection', () => { ).toEqual([first, first, first]) }) + it('preserves order as winning rows alternate between single and repeated occurrences', () => { + const other = session({ agent: 'claude' }) + const custom = session({ codexHome: '/tmp/custom' }) + const managed = session({ codexHome: '/tmp/codex-runtime-home/home' }) + const newerManaged = session({ ...managed, updatedAt: '1970-01-01T00:00:03Z' }) + const real = session() + const newerReal = session({ updatedAt: '1970-01-01T00:00:05Z' }) + const tied = session({ ...newerReal }) + + expect( + checkBatches([ + [custom, other], + [managed], + [managed, other, managed], + [newerManaged], + [real], + [real], + [real, other], + [newerReal], + [newerReal], + [tied] + ]) + ).toEqual([other, other, other, newerReal, newerReal]) + }) + it('retains non-Codex and non-rollout occurrences unchanged', () => { const claude = session({ agent: 'claude' }) const otherFile = session({ filePath: '/tmp/session.jsonl' }) diff --git a/src/main/ai-vault/codex-session-root-dedup.ts b/src/main/ai-vault/codex-session-root-dedup.ts index c8b17600cf4..ca46354a51a 100644 --- a/src/main/ai-vault/codex-session-root-dedup.ts +++ b/src/main/ai-vault/codex-session-root-dedup.ts @@ -255,7 +255,10 @@ export function dedupeCodexSessionsBySessionId( /** Scan-local accumulation; parsed rows must not be mutated after admission. */ export class CodexSessionCollection { private readonly sessions = new Map() - private readonly bestByKey = new Map() + private readonly bestByKey = new Map< + string, + { session: AiVaultSession; indices: number | number[] } + >() private nextIndex = 0 get size(): number { @@ -273,17 +276,25 @@ export class CodexSessionCollection { const best = this.bestByKey.get(key) if (best?.session === session) { // The batch filter retains every occurrence of the winning object. - best.indices.push(index) + if (typeof best.indices === 'number') { + best.indices = [best.indices, index] + } else { + best.indices.push(index) + } } else { if (best) { if (!codexSessionAliasBeats(session, best.session)) { return } - for (const previousIndex of best.indices) { - this.sessions.delete(previousIndex) + if (typeof best.indices === 'number') { + this.sessions.delete(best.indices) + } else { + for (const previousIndex of best.indices) { + this.sessions.delete(previousIndex) + } } } - this.bestByKey.set(key, { session, indices: [index] }) + this.bestByKey.set(key, { session, indices: index }) } } this.sessions.set(index, session)