@devflow-tools/memory-engine 0.16.34 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consolidator.d.ts.map +1 -1
- package/dist/consolidator.js +11 -12
- package/dist/consolidator.js.map +1 -1
- package/dist/event-grouper.d.ts +1 -0
- package/dist/event-grouper.d.ts.map +1 -1
- package/dist/event-grouper.js +18 -13
- package/dist/event-grouper.js.map +1 -1
- package/dist/hybrid-search.d.ts +1 -0
- package/dist/hybrid-search.d.ts.map +1 -1
- package/dist/hybrid-search.js +74 -6
- package/dist/hybrid-search.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-capsule.d.ts +27 -0
- package/dist/memory-capsule.d.ts.map +1 -0
- package/dist/memory-capsule.js +111 -0
- package/dist/memory-capsule.js.map +1 -0
- package/dist/memory-engine.d.ts.map +1 -1
- package/dist/memory-engine.js +75 -34
- package/dist/memory-engine.js.map +1 -1
- package/dist/memory-gate.d.ts +5 -0
- package/dist/memory-gate.d.ts.map +1 -1
- package/dist/memory-gate.js +310 -37
- package/dist/memory-gate.js.map +1 -1
- package/dist/memory-relations.d.ts +3 -0
- package/dist/memory-relations.d.ts.map +1 -0
- package/dist/memory-relations.js +8 -0
- package/dist/memory-relations.js.map +1 -0
- package/dist/memory-relevance.d.ts +4 -0
- package/dist/memory-relevance.d.ts.map +1 -1
- package/dist/memory-relevance.js +27 -6
- package/dist/memory-relevance.js.map +1 -1
- package/dist/memory-store.d.ts +10 -1
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/memory-store.js +78 -21
- package/dist/memory-store.js.map +1 -1
- package/dist/migrations/v12-to-v13.d.ts +3 -0
- package/dist/migrations/v12-to-v13.d.ts.map +1 -0
- package/dist/migrations/v12-to-v13.js +50 -0
- package/dist/migrations/v12-to-v13.js.map +1 -0
- package/dist/semantic-memory-compiler.d.ts +29 -0
- package/dist/semantic-memory-compiler.d.ts.map +1 -0
- package/dist/semantic-memory-compiler.js +148 -0
- package/dist/semantic-memory-compiler.js.map +1 -0
- package/dist/session-summarizer.d.ts +3 -0
- package/dist/session-summarizer.d.ts.map +1 -1
- package/dist/session-summarizer.js.map +1 -1
- package/package.json +4 -3
package/dist/memory-store.js
CHANGED
|
@@ -12,9 +12,11 @@ import { applyV8ToV9Migration } from './migrations/v8-to-v9.js';
|
|
|
12
12
|
import { applyV9ToV10Migration } from './migrations/v9-to-v10.js';
|
|
13
13
|
import { applyV10ToV11Migration } from './migrations/v10-to-v11.js';
|
|
14
14
|
import { applyV11ToV12Migration } from './migrations/v11-to-v12.js';
|
|
15
|
+
import { applyV12ToV13Migration } from './migrations/v12-to-v13.js';
|
|
15
16
|
import { observationDedupKey, } from './observation-types.js';
|
|
16
17
|
import { analysesConflict, analyzePreference, analyzePreferenceObservation, } from './preference-conflicts.js';
|
|
17
18
|
import { mergeSemanticEntities, normalizeEntityKey, normalizeSemanticMemory, } from './semantic-memory.js';
|
|
19
|
+
import { emitSemanticControlLog } from '@devflow-tools/telemetry';
|
|
18
20
|
// ── Schema ─────────────────────────────────────────────
|
|
19
21
|
const SCHEMA_V2 = `
|
|
20
22
|
-- ============================================================
|
|
@@ -448,10 +450,11 @@ export class MemoryStore {
|
|
|
448
450
|
applyV9ToV10Migration(this.db);
|
|
449
451
|
applyV10ToV11Migration(this.db);
|
|
450
452
|
applyV11ToV12Migration(this.db, rootPath);
|
|
453
|
+
applyV12ToV13Migration(this.db);
|
|
451
454
|
this.repairOrphanSessions(rootPath);
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
tableCount: this.countTables(),
|
|
455
|
+
emitSemanticControlLog({
|
|
456
|
+
event: 'memory.engine.transitioned', identity: { projectRoot: this.defaultProjectRoot }, level: 'debug', timestamp: Date.now(),
|
|
457
|
+
data: { stage: 'store_initialized', database: 'memories.db', tableCount: this.countTables() },
|
|
455
458
|
});
|
|
456
459
|
}
|
|
457
460
|
setLeaseStore(store) {
|
|
@@ -538,10 +541,16 @@ export class MemoryStore {
|
|
|
538
541
|
COALESCE(l1_score, 0), COALESCE(dialog_score, 0), user_message
|
|
539
542
|
FROM events
|
|
540
543
|
`);
|
|
541
|
-
|
|
544
|
+
emitSemanticControlLog({
|
|
545
|
+
event: 'memory.write.completed', identity: { projectRoot: this.defaultProjectRoot }, level: 'info', timestamp: Date.now(),
|
|
546
|
+
data: { stage: 'event_migration', migrated: count.c },
|
|
547
|
+
});
|
|
542
548
|
}
|
|
543
549
|
catch (err) {
|
|
544
|
-
|
|
550
|
+
emitSemanticControlLog({
|
|
551
|
+
event: 'memory.write.degraded', identity: { projectRoot: this.defaultProjectRoot }, level: 'warn', timestamp: Date.now(),
|
|
552
|
+
data: { stage: 'event_migration', reason: memoryStoreErrorReason(err), fallback: 'existing_schema' },
|
|
553
|
+
});
|
|
545
554
|
}
|
|
546
555
|
}
|
|
547
556
|
}
|
|
@@ -625,7 +634,10 @@ export class MemoryStore {
|
|
|
625
634
|
confidence, strength, scope, session_id, created_at, updated_at)
|
|
626
635
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
627
636
|
`).run(id, memType, title, entry.content, entry.originalText ?? null, entry.source ?? 'auto', entry.status ?? 'active', entry.confidence ?? 0.5, entry.strength ?? 0.5, entry.scope ?? '', entry.sessionId ?? null, now, now);
|
|
628
|
-
|
|
637
|
+
emitSemanticControlLog({
|
|
638
|
+
event: 'memory.write.completed', identity: { projectRoot: this.defaultProjectRoot, sessionId: entry.sessionId }, level: 'info', timestamp: now,
|
|
639
|
+
data: { stage: 'memory_add', memoryId: id, type: memType, status: entry.status ?? 'active' },
|
|
640
|
+
});
|
|
629
641
|
return this.get(id);
|
|
630
642
|
}
|
|
631
643
|
get(id) {
|
|
@@ -647,7 +659,10 @@ export class MemoryStore {
|
|
|
647
659
|
return;
|
|
648
660
|
vals.push(id);
|
|
649
661
|
this.db.prepare(`UPDATE memories SET ${sets.join(', ')} WHERE id = ?`).run(...vals);
|
|
650
|
-
|
|
662
|
+
emitSemanticControlLog({
|
|
663
|
+
event: 'memory.write.completed', identity: { projectRoot: this.defaultProjectRoot }, level: 'debug', timestamp: Date.now(),
|
|
664
|
+
data: { stage: 'memory_update', memoryId: id, fields: Object.keys(updates) },
|
|
665
|
+
});
|
|
651
666
|
}
|
|
652
667
|
delete(id) {
|
|
653
668
|
this.db.prepare('DELETE FROM memories WHERE id = ?').run(id);
|
|
@@ -945,6 +960,9 @@ export class MemoryStore {
|
|
|
945
960
|
`).run(input.receiptId ?? null, input.reason ?? 'canonical_turn_commit', now, row.turn_event_id, row.observation_id, input.receiptId ?? null).changes;
|
|
946
961
|
continue;
|
|
947
962
|
}
|
|
963
|
+
if (row.status === 'committed' && row.receipt_id && row.receipt_id !== input.receiptId) {
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
948
966
|
const hasOtherCommittedLineage = Boolean(this.db.prepare(`
|
|
949
967
|
SELECT 1 FROM turn_observation_lineage
|
|
950
968
|
WHERE observation_id = ? AND turn_event_id <> ? AND status = 'committed'
|
|
@@ -1337,13 +1355,19 @@ export class MemoryStore {
|
|
|
1337
1355
|
});
|
|
1338
1356
|
const repaired = repair();
|
|
1339
1357
|
if (repaired > 0) {
|
|
1340
|
-
|
|
1358
|
+
emitSemanticControlLog({
|
|
1359
|
+
event: 'memory.engine.transitioned', identity: { projectRoot: this.defaultProjectRoot }, level: 'warn', timestamp: Date.now(),
|
|
1360
|
+
data: { stage: 'orphan_session_repair', recovered: repaired },
|
|
1361
|
+
});
|
|
1341
1362
|
}
|
|
1342
1363
|
return repaired;
|
|
1343
1364
|
}
|
|
1344
1365
|
createSession(id, projectRoot, task = '') {
|
|
1345
1366
|
this.ensureSession(id, projectRoot, task);
|
|
1346
|
-
|
|
1367
|
+
emitSemanticControlLog({
|
|
1368
|
+
event: 'memory.engine.transitioned', identity: { projectRoot, sessionId: id }, level: 'debug', timestamp: Date.now(),
|
|
1369
|
+
data: { from: 'missing', to: 'active', stage: 'session_create' },
|
|
1370
|
+
});
|
|
1347
1371
|
}
|
|
1348
1372
|
closeSession(id) {
|
|
1349
1373
|
this.ensureSession(id, this.defaultProjectRoot, 'Recovered session close');
|
|
@@ -1352,7 +1376,10 @@ export class MemoryStore {
|
|
|
1352
1376
|
UPDATE sessions SET status = 'closed', closed_at = ?
|
|
1353
1377
|
WHERE id = ? AND status = 'active'
|
|
1354
1378
|
`).run(now, id);
|
|
1355
|
-
|
|
1379
|
+
emitSemanticControlLog({
|
|
1380
|
+
event: 'memory.engine.transitioned', identity: { projectRoot: this.defaultProjectRoot, sessionId: id }, level: 'info', timestamp: now,
|
|
1381
|
+
data: { from: 'active', to: 'closed', stage: 'session_close' },
|
|
1382
|
+
});
|
|
1356
1383
|
}
|
|
1357
1384
|
getSession(id) {
|
|
1358
1385
|
return this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) ?? null;
|
|
@@ -1400,8 +1427,9 @@ export class MemoryStore {
|
|
|
1400
1427
|
quality_status, quarantine_reason, quality_details, quarantined_at,
|
|
1401
1428
|
failure_category, resolution_state, evidence_status, evidence_details,
|
|
1402
1429
|
semantic_subject, semantic_predicate, semantic_value, semantic_polarity,
|
|
1403
|
-
semantic_key, facet_key, entities, temporal, reinforce_count, last_reinforced_at
|
|
1404
|
-
|
|
1430
|
+
semantic_key, facet_key, entities, temporal, reinforce_count, last_reinforced_at,
|
|
1431
|
+
capsule, projection, extraction_version)
|
|
1432
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1405
1433
|
`).run(id, obs.sessionId, obs.project ?? this.defaultProjectRoot, obs.type, obs.title, obs.narrative ?? '', JSON.stringify(obs.facts ?? []), JSON.stringify(obs.files ?? []), JSON.stringify(obs.tools ?? []), JSON.stringify(obs.concepts ?? []), obs.importance ?? 5, obs.confidence ?? 0.5, obs.source ?? 'distill', dedupKey, JSON.stringify(obs.sourceEventIds ?? []), now, now, obs.qualityStatus ?? 'accepted', obs.quarantineReason ?? null, obs.qualityDetails ? JSON.stringify(obs.qualityDetails) : null, obs.qualityStatus === 'quarantined' ? now : null, obs.failureCategory ?? null, obs.resolutionState ?? 'current', obs.evidenceStatus
|
|
1406
1434
|
?? (obs.source === 'explicit_intent'
|
|
1407
1435
|
? 'unverified'
|
|
@@ -1411,7 +1439,19 @@ export class MemoryStore {
|
|
|
1411
1439
|
kind: 'source_event',
|
|
1412
1440
|
source,
|
|
1413
1441
|
summary: 'Observation was accepted from an evidence-bound session event.',
|
|
1414
|
-
}))), obs.semantic?.subject ?? '', obs.semantic?.predicate ?? '', obs.semantic?.value ?? '', obs.semantic?.polarity ?? 'neutral', obs.semantic?.semanticKey ?? null, obs.semantic?.facetKey ?? null, JSON.stringify(obs.semantic?.entities ?? []), obs.semantic?.temporal ? JSON.stringify(obs.semantic.temporal) : null, 0, null
|
|
1442
|
+
}))), obs.semantic?.subject ?? '', obs.semantic?.predicate ?? '', obs.semantic?.value ?? '', obs.semantic?.polarity ?? 'neutral', obs.semantic?.semanticKey ?? null, obs.semantic?.facetKey ?? null, JSON.stringify(obs.semantic?.entities ?? []), obs.semantic?.temporal ? JSON.stringify(obs.semantic.temporal) : null, 0, null, JSON.stringify(obs.capsule ?? {
|
|
1443
|
+
narrative: obs.narrative ?? '',
|
|
1444
|
+
sourceEvidenceIds: obs.sourceEventIds ?? [],
|
|
1445
|
+
entities: obs.semantic?.entities ?? [],
|
|
1446
|
+
temporalStatus: obs.semantic?.temporal?.status ?? 'current',
|
|
1447
|
+
extractionVersion: 'legacy-compatible.v1',
|
|
1448
|
+
}), JSON.stringify(obs.projection ?? {
|
|
1449
|
+
subject: obs.semantic?.subject ?? '',
|
|
1450
|
+
predicate: obs.semantic?.predicate ?? '',
|
|
1451
|
+
value: obs.semantic?.value ?? '',
|
|
1452
|
+
polarity: obs.semantic?.polarity ?? 'neutral',
|
|
1453
|
+
facet: obs.semantic?.facet ?? 'generic',
|
|
1454
|
+
}), obs.capsule?.extractionVersion ?? 'legacy-compatible.v1');
|
|
1415
1455
|
// Insert concept junction rows
|
|
1416
1456
|
if (obs.concepts && obs.concepts.length > 0) {
|
|
1417
1457
|
const insertConcept = this.db.prepare('INSERT OR IGNORE INTO observation_concepts (observation_id, concept) VALUES (?, ?)');
|
|
@@ -1421,8 +1461,9 @@ export class MemoryStore {
|
|
|
1421
1461
|
}
|
|
1422
1462
|
this.replaceObservationEntities(id, obs.project ?? this.defaultProjectRoot, obs.semantic?.entities ?? []);
|
|
1423
1463
|
this.bumpRetrievalRevision();
|
|
1424
|
-
|
|
1425
|
-
|
|
1464
|
+
emitSemanticControlLog({
|
|
1465
|
+
event: 'memory.write.completed', identity: { projectRoot: obs.project ?? this.defaultProjectRoot, sessionId: obs.sessionId }, level: 'info', timestamp: Date.now(),
|
|
1466
|
+
data: { stage: 'observation_add', observationId: id, type: obs.type, conceptCount: obs.concepts?.length ?? 0 },
|
|
1426
1467
|
});
|
|
1427
1468
|
return this.getObservation(id);
|
|
1428
1469
|
}
|
|
@@ -1447,10 +1488,14 @@ export class MemoryStore {
|
|
|
1447
1488
|
...obs.semantic.entities.map(normalizeEntityKey),
|
|
1448
1489
|
]);
|
|
1449
1490
|
const entities = mergeSemanticEntities(parseStringArray(exact.entities), obs.semantic.entities);
|
|
1450
|
-
const narrative =
|
|
1451
|
-
? obs.narrative ??
|
|
1452
|
-
: exact.narrative
|
|
1453
|
-
|
|
1491
|
+
const narrative = obs.preferIncomingNarrative
|
|
1492
|
+
? obs.narrative ?? exact.narrative
|
|
1493
|
+
: semanticRichness(obs.narrative ?? '') > semanticRichness(exact.narrative)
|
|
1494
|
+
? obs.narrative ?? ''
|
|
1495
|
+
: exact.narrative;
|
|
1496
|
+
const title = obs.preferIncomingNarrative
|
|
1497
|
+
? obs.title
|
|
1498
|
+
: semanticRichness(obs.title) > semanticRichness(exact.title) ? obs.title : exact.title;
|
|
1454
1499
|
const contentChanged = exact.title !== title
|
|
1455
1500
|
|| exact.narrative !== narrative;
|
|
1456
1501
|
this.db.prepare(`
|
|
@@ -1592,6 +1637,9 @@ export class MemoryStore {
|
|
|
1592
1637
|
VALUES (?, ?, ?, ?)
|
|
1593
1638
|
`).run(sourceObservationId, targetObservationId, type, createdAt);
|
|
1594
1639
|
}
|
|
1640
|
+
addSemanticObservationRelation(sourceObservationId, targetObservationId, type, createdAt = Date.now()) {
|
|
1641
|
+
this.addObservationRelation(sourceObservationId, targetObservationId, type, createdAt);
|
|
1642
|
+
}
|
|
1595
1643
|
supersedeSemanticFacetConflicts(project, winnerId, semantic, now) {
|
|
1596
1644
|
const conflicts = this.findCurrentObservationsByFacetKey(project, semantic.facetKey)
|
|
1597
1645
|
.filter(candidate => candidate.id !== winnerId)
|
|
@@ -2080,7 +2128,10 @@ export class MemoryStore {
|
|
|
2080
2128
|
insert.run(s.id, s.sessionId, s.type, s.strength, JSON.stringify(s.sourceEventIds), JSON.stringify(s.payload), s.timestamp);
|
|
2081
2129
|
}
|
|
2082
2130
|
if (signals.length > 0) {
|
|
2083
|
-
|
|
2131
|
+
emitSemanticControlLog({
|
|
2132
|
+
event: 'memory.write.completed', identity: { projectRoot: this.defaultProjectRoot, sessionId: signals[0].sessionId }, level: 'debug', timestamp: Date.now(),
|
|
2133
|
+
data: { stage: 'signal_write', count: signals.length },
|
|
2134
|
+
});
|
|
2084
2135
|
}
|
|
2085
2136
|
}
|
|
2086
2137
|
getSessionSignals(sessionId) {
|
|
@@ -2307,7 +2358,10 @@ export class MemoryStore {
|
|
|
2307
2358
|
? this.db.prepare('DELETE FROM session_events WHERE processed = 1 AND created_at < ?').run(sevenDaysAgo)
|
|
2308
2359
|
: this.deleteOldProcessedEventsExcept(sevenDaysAgo, pendingEventIds);
|
|
2309
2360
|
const total = { swept: candidates.length, kept, downgraded, expired: expired + pendingExpired.changes, cleanedEvents: cleanedEvents.changes };
|
|
2310
|
-
|
|
2361
|
+
emitSemanticControlLog({
|
|
2362
|
+
event: 'memory.engine.transitioned', identity: { projectRoot: this.defaultProjectRoot }, level: 'debug', timestamp: Date.now(),
|
|
2363
|
+
data: { stage: 'retention_sweep', ...total },
|
|
2364
|
+
});
|
|
2311
2365
|
return total;
|
|
2312
2366
|
}
|
|
2313
2367
|
deleteOldProcessedEventsExcept(before, excludedIds) {
|
|
@@ -2469,6 +2523,9 @@ function semanticFromExplicitEnrichment(enrichment) {
|
|
|
2469
2523
|
function camelToSnake(str) {
|
|
2470
2524
|
return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
|
|
2471
2525
|
}
|
|
2526
|
+
function memoryStoreErrorReason(error) {
|
|
2527
|
+
return (error instanceof Error ? error.message : String(error)).trim().slice(0, 500) || 'memory_store_failed';
|
|
2528
|
+
}
|
|
2472
2529
|
function parseStringArray(value) {
|
|
2473
2530
|
try {
|
|
2474
2531
|
const parsed = JSON.parse(value);
|