@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.
Files changed (50) hide show
  1. package/dist/consolidator.d.ts.map +1 -1
  2. package/dist/consolidator.js +11 -12
  3. package/dist/consolidator.js.map +1 -1
  4. package/dist/event-grouper.d.ts +1 -0
  5. package/dist/event-grouper.d.ts.map +1 -1
  6. package/dist/event-grouper.js +18 -13
  7. package/dist/event-grouper.js.map +1 -1
  8. package/dist/hybrid-search.d.ts +1 -0
  9. package/dist/hybrid-search.d.ts.map +1 -1
  10. package/dist/hybrid-search.js +74 -6
  11. package/dist/hybrid-search.js.map +1 -1
  12. package/dist/index.d.ts +7 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/memory-capsule.d.ts +27 -0
  17. package/dist/memory-capsule.d.ts.map +1 -0
  18. package/dist/memory-capsule.js +111 -0
  19. package/dist/memory-capsule.js.map +1 -0
  20. package/dist/memory-engine.d.ts.map +1 -1
  21. package/dist/memory-engine.js +75 -34
  22. package/dist/memory-engine.js.map +1 -1
  23. package/dist/memory-gate.d.ts +5 -0
  24. package/dist/memory-gate.d.ts.map +1 -1
  25. package/dist/memory-gate.js +310 -37
  26. package/dist/memory-gate.js.map +1 -1
  27. package/dist/memory-relations.d.ts +3 -0
  28. package/dist/memory-relations.d.ts.map +1 -0
  29. package/dist/memory-relations.js +8 -0
  30. package/dist/memory-relations.js.map +1 -0
  31. package/dist/memory-relevance.d.ts +4 -0
  32. package/dist/memory-relevance.d.ts.map +1 -1
  33. package/dist/memory-relevance.js +27 -6
  34. package/dist/memory-relevance.js.map +1 -1
  35. package/dist/memory-store.d.ts +10 -1
  36. package/dist/memory-store.d.ts.map +1 -1
  37. package/dist/memory-store.js +78 -21
  38. package/dist/memory-store.js.map +1 -1
  39. package/dist/migrations/v12-to-v13.d.ts +3 -0
  40. package/dist/migrations/v12-to-v13.d.ts.map +1 -0
  41. package/dist/migrations/v12-to-v13.js +50 -0
  42. package/dist/migrations/v12-to-v13.js.map +1 -0
  43. package/dist/semantic-memory-compiler.d.ts +29 -0
  44. package/dist/semantic-memory-compiler.d.ts.map +1 -0
  45. package/dist/semantic-memory-compiler.js +148 -0
  46. package/dist/semantic-memory-compiler.js.map +1 -0
  47. package/dist/session-summarizer.d.ts +3 -0
  48. package/dist/session-summarizer.d.ts.map +1 -1
  49. package/dist/session-summarizer.js.map +1 -1
  50. package/package.json +4 -3
@@ -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
- console.log('[MemoryStore] Schema initialized', {
453
- dbPath: this.dbPath,
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
- console.log('[MemoryStore] Migrated', count.c, 'events to session_events');
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
- console.warn('[MemoryStore] Event migration skipped:', err.message);
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
- console.log('[MemoryStore] Memory added', { id, type: memType, status: entry.status ?? 'active' });
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
- console.log('[MemoryStore] Memory updated', { id, keys: Object.keys(updates) });
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
- console.log('[MemoryStore] Recovered orphan event sessions', { count: repaired });
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
- console.log('[MemoryStore] Session created', { id, project: projectRoot, task });
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
- console.log('[MemoryStore] Session closed', { id });
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
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
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
- console.log('[MemoryStore] Observation added', {
1425
- id, sessionId: obs.sessionId, type: obs.type, conceptCount: obs.concepts?.length ?? 0,
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 = semanticRichness(obs.narrative ?? '') > semanticRichness(exact.narrative)
1451
- ? obs.narrative ?? ''
1452
- : exact.narrative;
1453
- const title = semanticRichness(obs.title) > semanticRichness(exact.title) ? obs.title : exact.title;
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
- console.log('[MemoryStore] Signals recorded', { count: signals.length, sessionId: signals[0].sessionId });
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
- console.log('[MemoryStore] Retention sweep complete', total);
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);