diff --git a/src/services/sqlite/SessionStore.ts b/src/services/sqlite/SessionStore.ts index 29c4beed..cb22fdca 100644 --- a/src/services/sqlite/SessionStore.ts +++ b/src/services/sqlite/SessionStore.ts @@ -1659,15 +1659,23 @@ export class SessionStore { const storeTx = this.db.transaction(() => { const observationIds: number[] = []; - // 1. Store all observations + // 1. Store all observations (with content-hash deduplication) const obsStmt = this.db.prepare(` INSERT INTO observations (memory_session_id, project, type, title, subtitle, facts, narrative, concepts, - files_read, files_modified, prompt_number, discovery_tokens, created_at, created_at_epoch) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + files_read, files_modified, prompt_number, discovery_tokens, content_hash, created_at, created_at_epoch) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); for (const observation of observations) { + // Content-hash deduplication (same logic as storeObservation singular) + const contentHash = computeObservationContentHash(memorySessionId, observation.title, observation.narrative); + const existing = findDuplicateObservation(this.db, contentHash, timestampEpoch); + if (existing) { + observationIds.push(existing.id); + continue; + } + const result = obsStmt.run( memorySessionId, project, @@ -1681,6 +1689,7 @@ export class SessionStore { JSON.stringify(observation.files_modified), promptNumber || null, discoveryTokens, + contentHash, timestampIso, timestampEpoch ); @@ -1779,15 +1788,23 @@ export class SessionStore { const storeAndMarkTx = this.db.transaction(() => { const observationIds: number[] = []; - // 1. Store all observations + // 1. Store all observations (with content-hash deduplication) const obsStmt = this.db.prepare(` INSERT INTO observations (memory_session_id, project, type, title, subtitle, facts, narrative, concepts, - files_read, files_modified, prompt_number, discovery_tokens, created_at, created_at_epoch) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + files_read, files_modified, prompt_number, discovery_tokens, content_hash, created_at, created_at_epoch) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); for (const observation of observations) { + // Content-hash deduplication (same logic as storeObservation singular) + const contentHash = computeObservationContentHash(memorySessionId, observation.title, observation.narrative); + const existing = findDuplicateObservation(this.db, contentHash, timestampEpoch); + if (existing) { + observationIds.push(existing.id); + continue; + } + const result = obsStmt.run( memorySessionId, project, @@ -1801,6 +1818,7 @@ export class SessionStore { JSON.stringify(observation.files_modified), promptNumber || null, discoveryTokens, + contentHash, timestampIso, timestampEpoch );