@remnic/core 9.3.735 → 9.3.736

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 (151) hide show
  1. package/dist/access-boundary.d.ts +5 -5
  2. package/dist/access-cli.js +1 -1
  3. package/dist/access-http.d.ts +5 -5
  4. package/dist/access-mcp.d.ts +5 -5
  5. package/dist/access-operations.d.ts +5 -5
  6. package/dist/access-schema.d.ts +4 -4
  7. package/dist/{access-service-CVx7mmvK.d.ts → access-service-CdC0q4pr.d.ts} +3 -3
  8. package/dist/access-service.d.ts +5 -5
  9. package/dist/access-surface-catalog.d.ts +5 -5
  10. package/dist/action-confidence.d.ts +1 -1
  11. package/dist/active-memory-bridge.d.ts +1 -1
  12. package/dist/active-recall.d.ts +1 -1
  13. package/dist/behavior-learner.d.ts +1 -1
  14. package/dist/behavior-signals.d.ts +1 -1
  15. package/dist/bootstrap.d.ts +4 -4
  16. package/dist/briefing.d.ts +1 -1
  17. package/dist/buffer-surprise-report.d.ts +1 -1
  18. package/dist/buffer.d.ts +1 -1
  19. package/dist/calibration.d.ts +1 -1
  20. package/dist/capabilities.d.ts +1 -1
  21. package/dist/{catalog-BVhDEUhT.d.ts → catalog-D2NLDg4S.d.ts} +1 -1
  22. package/dist/causal-behavior.d.ts +1 -1
  23. package/dist/causal-consolidation.d.ts +1 -1
  24. package/dist/causal-trajectory-graph.d.ts +1 -1
  25. package/dist/{chunk-FLCYY5JX.js → chunk-AE2HPUP7.js} +208 -185
  26. package/dist/chunk-AE2HPUP7.js.map +1 -0
  27. package/dist/{cli-Cx5Mxwk7.d.ts → cli-BHy6Bo6u.d.ts} +3 -3
  28. package/dist/cli.d.ts +6 -6
  29. package/dist/compounding/engine.d.ts +1 -1
  30. package/dist/compounding/preference-consolidator.d.ts +1 -1
  31. package/dist/compression-optimizer.d.ts +1 -1
  32. package/dist/config.d.ts +1 -1
  33. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  34. package/dist/connectors/codex-materialize.d.ts +1 -1
  35. package/dist/connectors/index.d.ts +1 -1
  36. package/dist/consolidation-provenance-check.d.ts +1 -1
  37. package/dist/consolidation-undo.d.ts +1 -1
  38. package/dist/contradiction/index.d.ts +1 -1
  39. package/dist/conversation-index/backend.d.ts +1 -1
  40. package/dist/conversation-index/chunker.d.ts +1 -1
  41. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  42. package/dist/conversation-index/indexer.d.ts +1 -1
  43. package/dist/conversation-index/search.d.ts +1 -1
  44. package/dist/day-summary.d.ts +1 -1
  45. package/dist/delinearize.d.ts +1 -1
  46. package/dist/direct-answer-wiring.d.ts +1 -1
  47. package/dist/direct-answer.d.ts +1 -1
  48. package/dist/embedding-fallback.d.ts +1 -1
  49. package/dist/enrichment/index.d.ts +1 -1
  50. package/dist/entity-retrieval.d.ts +1 -1
  51. package/dist/entity-schema.d.ts +1 -1
  52. package/dist/explicit-capture.d.ts +4 -4
  53. package/dist/extraction-faithfulness.d.ts +1 -1
  54. package/dist/extraction-judge-telemetry.d.ts +1 -1
  55. package/dist/extraction-judge-training.d.ts +1 -1
  56. package/dist/extraction-judge.d.ts +1 -1
  57. package/dist/extraction.d.ts +1 -1
  58. package/dist/fallback-llm.d.ts +1 -1
  59. package/dist/graph-dashboard-diff.d.ts +1 -1
  60. package/dist/graph-dashboard-key.d.ts +1 -1
  61. package/dist/graph-dashboard-parser.d.ts +1 -1
  62. package/dist/graph-edge-reinforcement.d.ts +1 -1
  63. package/dist/graph-snapshot.d.ts +1 -1
  64. package/dist/graph.d.ts +1 -1
  65. package/dist/identity-continuity.d.ts +1 -1
  66. package/dist/importance.d.ts +1 -1
  67. package/dist/index.d.ts +9 -9
  68. package/dist/index.js +1 -1
  69. package/dist/intent.d.ts +1 -1
  70. package/dist/lcm/engine.d.ts +1 -1
  71. package/dist/lcm/index.d.ts +1 -1
  72. package/dist/lcm/tools.d.ts +1 -1
  73. package/dist/lifecycle.d.ts +1 -1
  74. package/dist/live-connectors-runner.d.ts +1 -1
  75. package/dist/local-llm.d.ts +1 -1
  76. package/dist/local-model-endpoint.d.ts +1 -1
  77. package/dist/maintenance/memory-governance.d.ts +1 -1
  78. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  79. package/dist/memory-action-policy.d.ts +1 -1
  80. package/dist/memory-cache.d.ts +1 -1
  81. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  82. package/dist/memory-projection-store.d.ts +1 -1
  83. package/dist/memory-provenance.d.ts +1 -1
  84. package/dist/memory-worth-outcomes.d.ts +1 -1
  85. package/dist/models-json.d.ts +1 -1
  86. package/dist/namespaces/migrate.d.ts +2 -2
  87. package/dist/namespaces/principal.d.ts +1 -1
  88. package/dist/namespaces/search.d.ts +1 -1
  89. package/dist/namespaces/storage.d.ts +2 -2
  90. package/dist/native-knowledge.d.ts +1 -1
  91. package/dist/operator-toolkit.d.ts +1 -1
  92. package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
  93. package/dist/orchestration/maintenance.d.ts +2 -2
  94. package/dist/{orchestrator-oF0cceBX.d.ts → orchestrator-C-xp_rtZ.d.ts} +64 -5
  95. package/dist/orchestrator.d.ts +4 -4
  96. package/dist/orchestrator.js +1 -3
  97. package/dist/patterns-cli.d.ts +1 -1
  98. package/dist/policy-runtime.d.ts +1 -1
  99. package/dist/provenance.d.ts +1 -1
  100. package/dist/qmd-recall-cache.d.ts +1 -1
  101. package/dist/qmd.d.ts +1 -1
  102. package/dist/recall-disclosure-escalation.d.ts +1 -1
  103. package/dist/recall-explain-renderer.d.ts +1 -1
  104. package/dist/recall-planner-llm.d.ts +1 -1
  105. package/dist/recall-state.d.ts +1 -1
  106. package/dist/recall-tag-filter.d.ts +1 -1
  107. package/dist/recall-xray-cli.d.ts +1 -1
  108. package/dist/recall-xray-renderer.d.ts +1 -1
  109. package/dist/recall-xray.d.ts +1 -1
  110. package/dist/resolve-auth-token.d.ts +1 -1
  111. package/dist/retrieval-agents.d.ts +1 -1
  112. package/dist/retrieval-tiers.d.ts +1 -1
  113. package/dist/routing/engine.d.ts +1 -1
  114. package/dist/routing/store.d.ts +1 -1
  115. package/dist/schemas.d.ts +24 -24
  116. package/dist/search/embed-helper.d.ts +1 -1
  117. package/dist/search/factory.d.ts +1 -1
  118. package/dist/search/index.d.ts +1 -1
  119. package/dist/search/lancedb-backend.d.ts +1 -1
  120. package/dist/search/meilisearch-backend.d.ts +1 -1
  121. package/dist/search/noop-backend.d.ts +1 -1
  122. package/dist/search/orama-backend.d.ts +1 -1
  123. package/dist/search/port.d.ts +1 -1
  124. package/dist/search/remote-backend.d.ts +1 -1
  125. package/dist/{semantic-consolidation-DKGbufYO.d.ts → semantic-consolidation-COdwU-me.d.ts} +1 -1
  126. package/dist/semantic-consolidation.d.ts +2 -2
  127. package/dist/semantic-rule-verifier.d.ts +1 -1
  128. package/dist/session-observer-bands.d.ts +1 -1
  129. package/dist/session-observer-state.d.ts +1 -1
  130. package/dist/shared-context/manager.d.ts +3 -3
  131. package/dist/signal.d.ts +1 -1
  132. package/dist/storage.d.ts +1 -1
  133. package/dist/summarizer.d.ts +1 -1
  134. package/dist/summary-snapshot.d.ts +1 -1
  135. package/dist/temporal-supersession.d.ts +1 -1
  136. package/dist/temporal-validity.d.ts +1 -1
  137. package/dist/threading.d.ts +1 -1
  138. package/dist/tier-migration.d.ts +1 -1
  139. package/dist/tier-routing.d.ts +1 -1
  140. package/dist/topics.d.ts +1 -1
  141. package/dist/transcript.d.ts +1 -1
  142. package/dist/transfer/types.d.ts +42 -42
  143. package/dist/trust-score-stage.d.ts +1 -1
  144. package/dist/trust-score.d.ts +1 -1
  145. package/dist/{types-C7UCxpuO.d.ts → types-w3Y232yi.d.ts} +1 -1
  146. package/dist/types.d.ts +1 -1
  147. package/dist/utility-runtime.d.ts +1 -1
  148. package/package.json +2 -2
  149. package/src/orchestration/entity-synthesis-coordinator.ts +319 -0
  150. package/src/orchestrator.ts +12 -235
  151. package/dist/chunk-FLCYY5JX.js.map +0 -1
@@ -508,7 +508,7 @@ import {
508
508
  // src/orchestrator.ts
509
509
  import path4 from "path";
510
510
  import os2 from "os";
511
- import { createHash, randomBytes } from "crypto";
511
+ import { createHash as createHash2, randomBytes } from "crypto";
512
512
  import { existsSync, readFileSync } from "fs";
513
513
  import {
514
514
  lstat,
@@ -1436,6 +1436,196 @@ var LifecyclePolicyCoordinator = class {
1436
1436
  }
1437
1437
  };
1438
1438
 
1439
+ // src/orchestration/entity-synthesis-coordinator.ts
1440
+ import { createHash } from "crypto";
1441
+ function dedupeEntitySynthesisEvidenceEntries(entries) {
1442
+ const dedupedEvidenceEntries = [];
1443
+ const evidenceByFact = /* @__PURE__ */ new Map();
1444
+ for (const entry of entries) {
1445
+ const normalizedFact = entry.text.trim();
1446
+ if (!normalizedFact) continue;
1447
+ const existing = evidenceByFact.get(normalizedFact);
1448
+ if (!existing) {
1449
+ evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
1450
+ continue;
1451
+ }
1452
+ if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
1453
+ existing.newest = entry;
1454
+ }
1455
+ if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
1456
+ existing.oldest = entry;
1457
+ }
1458
+ }
1459
+ for (const { newest, oldest } of evidenceByFact.values()) {
1460
+ dedupedEvidenceEntries.push(newest);
1461
+ const newestKey = [
1462
+ newest.timestamp,
1463
+ newest.source ?? "",
1464
+ newest.sessionKey ?? "",
1465
+ newest.principal ?? "",
1466
+ newest.text
1467
+ ].join("\0");
1468
+ const oldestKey = [
1469
+ oldest.timestamp,
1470
+ oldest.source ?? "",
1471
+ oldest.sessionKey ?? "",
1472
+ oldest.principal ?? "",
1473
+ oldest.text
1474
+ ].join("\0");
1475
+ if (oldestKey !== newestKey) {
1476
+ dedupedEvidenceEntries.push(oldest);
1477
+ }
1478
+ }
1479
+ return dedupedEvidenceEntries;
1480
+ }
1481
+ function flattenStructuredSectionEvidence(sections) {
1482
+ return (sections ?? []).flatMap(
1483
+ (section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
1484
+ timestamp: "",
1485
+ text: fact,
1486
+ source: `section:${section.title}`
1487
+ }))
1488
+ );
1489
+ }
1490
+ function fingerprintEntitySynthesisEvidence(entity) {
1491
+ const fingerprint = createHash("sha256");
1492
+ const timelineEntries = entity.timeline.map((entry) => [
1493
+ entry.timestamp,
1494
+ entry.source ?? "",
1495
+ entry.sessionKey ?? "",
1496
+ entry.principal ?? "",
1497
+ entry.text
1498
+ ].join("\0")).sort();
1499
+ const timelineEntrySeparator = String.fromCharCode(1);
1500
+ const structuredFactsSeparator = String.fromCharCode(2);
1501
+ fingerprint.update(timelineEntries.join(timelineEntrySeparator));
1502
+ fingerprint.update(structuredFactsSeparator);
1503
+ fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
1504
+ return fingerprint.digest("hex");
1505
+ }
1506
+ var EntitySynthesisCoordinator = class {
1507
+ constructor(deps) {
1508
+ this.deps = deps;
1509
+ }
1510
+ deps;
1511
+ /**
1512
+ * Process up to `maxEntities` entities from the synthesis queue for the
1513
+ * given namespace. Returns the number of entities whose synthesis was
1514
+ * successfully refreshed.
1515
+ */
1516
+ async processQueue(namespace, maxEntities = 5) {
1517
+ const { config } = this.deps;
1518
+ if (!config.entitySummaryEnabled || maxEntities <= 0 || config.entitySynthesisMaxTokens <= 0) return 0;
1519
+ const storage = await this.deps.getStorage(namespace);
1520
+ const queued = await storage.refreshEntitySynthesisQueue();
1521
+ let processed = 0;
1522
+ let attempted = 0;
1523
+ for (const entityName of queued) {
1524
+ if (attempted >= maxEntities) break;
1525
+ attempted += 1;
1526
+ try {
1527
+ const raw = await storage.readEntity(entityName);
1528
+ if (!raw) continue;
1529
+ const entity = parseEntityFile(raw, config.entitySchemas);
1530
+ const previousSynthesis = entity.synthesis || entity.summary || "";
1531
+ const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
1532
+ const newerTimelineEntries = sortedTimelineEntries.filter(
1533
+ (entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
1534
+ );
1535
+ const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
1536
+ const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
1537
+ const structuredEvidenceCount = structuredEvidenceEntries.length;
1538
+ const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
1539
+ const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
1540
+ const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
1541
+ const candidateEvidenceEntries = [
1542
+ ...newerTimelineEntries,
1543
+ ...appendedTimelineEntries,
1544
+ ...appendedStructuredEvidenceEntries
1545
+ ].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
1546
+ const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
1547
+ candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
1548
+ );
1549
+ const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
1550
+ if (chronologicalEvidenceEntries.length === 0) continue;
1551
+ const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
1552
+ const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
1553
+ const nextSynthesisUpdatedAt = compareEntityTimestamps(
1554
+ latestEvidenceTimestamp,
1555
+ previousSynthesisUpdatedAt
1556
+ ) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
1557
+ const evidenceBatches = [];
1558
+ for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
1559
+ evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
1560
+ }
1561
+ let nextSynthesis = previousSynthesis;
1562
+ let batchFailed = false;
1563
+ for (const evidenceEntries of evidenceBatches) {
1564
+ const evidenceText = evidenceEntries.map((entry) => {
1565
+ const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
1566
+ const metadata = [
1567
+ `timestamp=${entry.timestamp}`,
1568
+ sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
1569
+ entry.sessionKey ? `session=${entry.sessionKey}` : "",
1570
+ entry.principal ? `principal=${entry.principal}` : ""
1571
+ ].filter(Boolean).join(", ");
1572
+ return `- ${metadata}: ${entry.text}`;
1573
+ }).join("\n");
1574
+ const response = await this.deps.fastChatCompletion(
1575
+ [
1576
+ {
1577
+ role: "system",
1578
+ content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
1579
+ },
1580
+ {
1581
+ role: "user",
1582
+ content: [
1583
+ `Entity: ${entity.name} (${entity.type})`,
1584
+ nextSynthesis ? `Previous synthesis:
1585
+ ${nextSynthesis}` : "Previous synthesis: none",
1586
+ `New evidence:
1587
+ ${evidenceText}`
1588
+ ].join("\n\n")
1589
+ }
1590
+ ],
1591
+ {
1592
+ temperature: 0.2,
1593
+ maxTokens: config.entitySynthesisMaxTokens,
1594
+ operation: "entity_summary",
1595
+ priority: "background"
1596
+ }
1597
+ );
1598
+ const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
1599
+ const maxSynthesisChars = Math.max(2e3, config.entitySynthesisMaxTokens * 8);
1600
+ if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
1601
+ batchFailed = true;
1602
+ break;
1603
+ }
1604
+ nextSynthesis = synthesis;
1605
+ }
1606
+ if (batchFailed || nextSynthesis.length === 0) continue;
1607
+ const latestRaw = await storage.readEntity(entityName);
1608
+ if (!latestRaw) continue;
1609
+ const latestEntity = parseEntityFile(latestRaw, config.entitySchemas);
1610
+ if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
1611
+ continue;
1612
+ }
1613
+ await storage.updateEntitySynthesis(entityName, nextSynthesis, {
1614
+ entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1615
+ synthesisStructuredFactDigest: structuredEvidenceDigest,
1616
+ synthesisStructuredFactCount: structuredEvidenceCount,
1617
+ synthesisTimelineCount: entity.timeline.length,
1618
+ updatedAt: nextSynthesisUpdatedAt
1619
+ });
1620
+ processed += 1;
1621
+ } catch (err) {
1622
+ log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
1623
+ }
1624
+ }
1625
+ return processed;
1626
+ }
1627
+ };
1628
+
1439
1629
  // src/maintenance/pattern-reinforcement.ts
1440
1630
  function patternReinforcementKey(content) {
1441
1631
  return content.trim().toLowerCase().replace(/\s+/g, " ").slice(0, 200);
@@ -2792,71 +2982,6 @@ var BulkImportBatchPartialFailureError = class extends Error {
2792
2982
  this.originalError = originalError;
2793
2983
  }
2794
2984
  };
2795
- function dedupeEntitySynthesisEvidenceEntries(entries) {
2796
- const dedupedEvidenceEntries = [];
2797
- const evidenceByFact = /* @__PURE__ */ new Map();
2798
- for (const entry of entries) {
2799
- const normalizedFact = entry.text.trim();
2800
- if (!normalizedFact) continue;
2801
- const existing = evidenceByFact.get(normalizedFact);
2802
- if (!existing) {
2803
- evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
2804
- continue;
2805
- }
2806
- if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
2807
- existing.newest = entry;
2808
- }
2809
- if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
2810
- existing.oldest = entry;
2811
- }
2812
- }
2813
- for (const { newest, oldest } of evidenceByFact.values()) {
2814
- dedupedEvidenceEntries.push(newest);
2815
- const newestKey = [
2816
- newest.timestamp,
2817
- newest.source ?? "",
2818
- newest.sessionKey ?? "",
2819
- newest.principal ?? "",
2820
- newest.text
2821
- ].join("\0");
2822
- const oldestKey = [
2823
- oldest.timestamp,
2824
- oldest.source ?? "",
2825
- oldest.sessionKey ?? "",
2826
- oldest.principal ?? "",
2827
- oldest.text
2828
- ].join("\0");
2829
- if (oldestKey !== newestKey) {
2830
- dedupedEvidenceEntries.push(oldest);
2831
- }
2832
- }
2833
- return dedupedEvidenceEntries;
2834
- }
2835
- function flattenStructuredSectionEvidence(sections) {
2836
- return (sections ?? []).flatMap(
2837
- (section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
2838
- timestamp: "",
2839
- text: fact,
2840
- source: `section:${section.title}`
2841
- }))
2842
- );
2843
- }
2844
- function fingerprintEntitySynthesisEvidence(entity) {
2845
- const fingerprint = createHash("sha256");
2846
- const timelineEntries = entity.timeline.map((entry) => [
2847
- entry.timestamp,
2848
- entry.source ?? "",
2849
- entry.sessionKey ?? "",
2850
- entry.principal ?? "",
2851
- entry.text
2852
- ].join("\0")).sort();
2853
- const timelineEntrySeparator = String.fromCharCode(1);
2854
- const structuredFactsSeparator = String.fromCharCode(2);
2855
- fingerprint.update(timelineEntries.join(timelineEntrySeparator));
2856
- fingerprint.update(structuredFactsSeparator);
2857
- fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
2858
- return fingerprint.digest("hex");
2859
- }
2860
2985
  function mapRecallSourceToXrayServedBy(source) {
2861
2986
  switch (source) {
2862
2987
  case "recent_scan":
@@ -3041,7 +3166,7 @@ function defaultWorkspaceDir() {
3041
3166
  }
3042
3167
  function sanitizeSessionKeyForFilename(sessionKey) {
3043
3168
  const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
3044
- const hash = createHash("sha256").update(sessionKey).digest("hex").slice(0, 12);
3169
+ const hash = createHash2("sha256").update(sessionKey).digest("hex").slice(0, 12);
3045
3170
  return `${readable}-${hash}`;
3046
3171
  }
3047
3172
  function latestSourceValidAtFromTurns(turns) {
@@ -3597,6 +3722,7 @@ var Orchestrator = class _Orchestrator {
3597
3722
  compressionGuidelineCoordinator;
3598
3723
  semanticConsolidationCoordinator;
3599
3724
  lifecyclePolicyCoordinator;
3725
+ entitySynthesisCoordinator;
3600
3726
  /**
3601
3727
  * In-memory X-ray snapshot from the most recent `recall()` call that
3602
3728
  * was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
@@ -4427,6 +4553,11 @@ var Orchestrator = class _Orchestrator {
4427
4553
  getStorage: () => this.storage,
4428
4554
  fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
4429
4555
  });
4556
+ this.entitySynthesisCoordinator = new EntitySynthesisCoordinator({
4557
+ config,
4558
+ getStorage: (namespace) => this.getStorage(namespace),
4559
+ fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
4560
+ });
4430
4561
  this.sessionObserver = new SessionObserverState({
4431
4562
  memoryDir: config.memoryDir,
4432
4563
  debounceMs: config.sessionObserverDebounceMs ?? 12e4,
@@ -4571,7 +4702,7 @@ var Orchestrator = class _Orchestrator {
4571
4702
  utilityPromoteThresholdDelta: this.utilityRuntimeValues?.promoteThresholdDelta ?? 0,
4572
4703
  utilityDemoteThresholdDelta: this.utilityRuntimeValues?.demoteThresholdDelta ?? 0
4573
4704
  };
4574
- return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 12);
4705
+ return createHash2("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 12);
4575
4706
  }
4576
4707
  effectiveLifecycleThresholds() {
4577
4708
  const archiveDecayThreshold = this.config.lifecycleArchiveDecayThreshold;
@@ -5440,114 +5571,7 @@ ${doc.content}` : doc.content,
5440
5571
  return this.storageRouter.storageFor(ns);
5441
5572
  }
5442
5573
  async processEntitySynthesisQueue(namespace, maxEntities = 5) {
5443
- if (!this.config.entitySummaryEnabled || maxEntities <= 0 || this.config.entitySynthesisMaxTokens <= 0) return 0;
5444
- const storage = await this.getStorage(namespace);
5445
- const queued = await storage.refreshEntitySynthesisQueue();
5446
- let processed = 0;
5447
- let attempted = 0;
5448
- for (const entityName of queued) {
5449
- if (attempted >= maxEntities) break;
5450
- attempted += 1;
5451
- try {
5452
- const raw = await storage.readEntity(entityName);
5453
- if (!raw) continue;
5454
- const entity = parseEntityFile(raw, this.config.entitySchemas);
5455
- const previousSynthesis = entity.synthesis || entity.summary || "";
5456
- const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
5457
- const newerTimelineEntries = sortedTimelineEntries.filter(
5458
- (entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
5459
- );
5460
- const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
5461
- const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
5462
- const structuredEvidenceCount = structuredEvidenceEntries.length;
5463
- const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
5464
- const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
5465
- const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
5466
- const candidateEvidenceEntries = [
5467
- ...newerTimelineEntries,
5468
- ...appendedTimelineEntries,
5469
- ...appendedStructuredEvidenceEntries
5470
- ].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
5471
- const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
5472
- candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
5473
- );
5474
- const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
5475
- if (chronologicalEvidenceEntries.length === 0) continue;
5476
- const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
5477
- const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
5478
- const nextSynthesisUpdatedAt = compareEntityTimestamps(
5479
- latestEvidenceTimestamp,
5480
- previousSynthesisUpdatedAt
5481
- ) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
5482
- const evidenceBatches = [];
5483
- for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
5484
- evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
5485
- }
5486
- let nextSynthesis = previousSynthesis;
5487
- let batchFailed = false;
5488
- for (const evidenceEntries of evidenceBatches) {
5489
- const evidenceText = evidenceEntries.map((entry) => {
5490
- const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
5491
- const metadata = [
5492
- `timestamp=${entry.timestamp}`,
5493
- sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
5494
- entry.sessionKey ? `session=${entry.sessionKey}` : "",
5495
- entry.principal ? `principal=${entry.principal}` : ""
5496
- ].filter(Boolean).join(", ");
5497
- return `- ${metadata}: ${entry.text}`;
5498
- }).join("\n");
5499
- const response = await this.fastChatCompletion(
5500
- [
5501
- {
5502
- role: "system",
5503
- content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
5504
- },
5505
- {
5506
- role: "user",
5507
- content: [
5508
- `Entity: ${entity.name} (${entity.type})`,
5509
- nextSynthesis ? `Previous synthesis:
5510
- ${nextSynthesis}` : "Previous synthesis: none",
5511
- `New evidence:
5512
- ${evidenceText}`
5513
- ].join("\n\n")
5514
- }
5515
- ],
5516
- {
5517
- temperature: 0.2,
5518
- maxTokens: this.config.entitySynthesisMaxTokens,
5519
- operation: "entity_summary",
5520
- priority: "background"
5521
- }
5522
- );
5523
- const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
5524
- const maxSynthesisChars = Math.max(2e3, this.config.entitySynthesisMaxTokens * 8);
5525
- if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
5526
- batchFailed = true;
5527
- break;
5528
- }
5529
- nextSynthesis = synthesis;
5530
- }
5531
- if (batchFailed || nextSynthesis.length === 0) continue;
5532
- const latestRaw = await storage.readEntity(entityName);
5533
- if (!latestRaw) continue;
5534
- const latestEntity = parseEntityFile(latestRaw, this.config.entitySchemas);
5535
- if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
5536
- continue;
5537
- }
5538
- await storage.updateEntitySynthesis(entityName, nextSynthesis, {
5539
- entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
5540
- synthesisStructuredFactDigest: structuredEvidenceDigest,
5541
- synthesisStructuredFactCount: structuredEvidenceCount,
5542
- synthesisTimelineCount: entity.timeline.length,
5543
- updatedAt: nextSynthesisUpdatedAt
5544
- });
5545
- processed += 1;
5546
- } catch (err) {
5547
- log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
5548
- }
5549
- }
5550
- return processed;
5574
+ return this.entitySynthesisCoordinator.processQueue(namespace, maxEntities);
5551
5575
  }
5552
5576
  async generateDaySummary(memories) {
5553
5577
  if (this.initPromise) {
@@ -6716,7 +6740,7 @@ ${r.snippet.trim()}
6716
6740
  if (!options.onDebugSnapshot) return;
6717
6741
  await options.onDebugSnapshot({
6718
6742
  recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
6719
- queryHash: createHash("sha256").update(prompt).digest("hex"),
6743
+ queryHash: createHash2("sha256").update(prompt).digest("hex"),
6720
6744
  queryLength: prompt.length,
6721
6745
  collection: options.collection,
6722
6746
  namespaces: options.recallNamespaces,
@@ -7045,7 +7069,7 @@ ${r.snippet.trim()}
7045
7069
  const payload = {
7046
7070
  recordedAt: now,
7047
7071
  mode: options.recallMode,
7048
- queryHash: createHash("sha256").update(options.prompt).digest("hex"),
7072
+ queryHash: createHash2("sha256").update(options.prompt).digest("hex"),
7049
7073
  queryLength: options.prompt.length,
7050
7074
  namespaces: options.recallNamespaces,
7051
7075
  seedCount: totalSeedCount,
@@ -7387,8 +7411,8 @@ ${r.snippet.trim()}
7387
7411
  timings,
7388
7412
  logger: log
7389
7413
  });
7390
- const promptHash = createHash("sha256").update(prompt).digest("hex");
7391
- const traceId = createHash("sha256").update(`${sessionKey ?? "default"}:${recallStart}:${promptHash}`).digest("hex").slice(0, 16);
7414
+ const promptHash = createHash2("sha256").update(prompt).digest("hex");
7415
+ const traceId = createHash2("sha256").update(`${sessionKey ?? "default"}:${recallStart}:${promptHash}`).digest("hex").slice(0, 16);
7392
7416
  const sectionBuckets = /* @__PURE__ */ new Map();
7393
7417
  const queryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {
7394
7418
  cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,
@@ -7397,7 +7421,7 @@ ${r.snippet.trim()}
7397
7421
  cronConversationRecallMode: this.config.cronConversationRecallMode
7398
7422
  });
7399
7423
  const retrievalQuery = queryPolicy.retrievalQuery || prompt;
7400
- const retrievalQueryHash = createHash("sha256").update(retrievalQuery).digest("hex");
7424
+ const retrievalQueryHash = createHash2("sha256").update(retrievalQuery).digest("hex");
7401
7425
  const policyVersion = this.currentPolicyVersion();
7402
7426
  let impressionRecorded = false;
7403
7427
  let recallSource = "none";
@@ -11437,7 +11461,7 @@ _Context: ${topQuestion.context}_`
11437
11461
  const shouldUseStableBatchKey = turns.some(
11438
11462
  (turn) => turn.persistProcessedFingerprint === true || typeof turn.turnFingerprint === "string" && turn.turnFingerprint.length > 0
11439
11463
  );
11440
- const stableBatchFingerprint = shouldUseStableBatchKey ? createHash("sha256").update(
11464
+ const stableBatchFingerprint = shouldUseStableBatchKey ? createHash2("sha256").update(
11441
11465
  turns.map(
11442
11466
  (turn) => [
11443
11467
  turn.role,
@@ -11687,7 +11711,7 @@ _Context: ${topQuestion.context}_`
11687
11711
  buildExtractionFingerprint(turns, bufferKey) {
11688
11712
  const normalized = this.normalizeExtractionFingerprintTurns(turns).join("\n");
11689
11713
  if (!normalized) return null;
11690
- return createHash("sha256").update(`${bufferKey}
11714
+ return createHash2("sha256").update(`${bufferKey}
11691
11715
  ${normalized}`).digest("hex");
11692
11716
  }
11693
11717
  shouldQueueExtraction(turns, options = {}) {
@@ -16332,7 +16356,6 @@ export {
16332
16356
  WearablesService,
16333
16357
  locateTranscriptPath,
16334
16358
  BulkImportBatchPartialFailureError,
16335
- dedupeEntitySynthesisEvidenceEntries,
16336
16359
  defaultWorkspaceDir,
16337
16360
  sanitizeSessionKeyForFilename,
16338
16361
  isArtifactMemoryPath,
@@ -16360,4 +16383,4 @@ export {
16360
16383
  resolvePersistedMemoryRelativePath,
16361
16384
  Orchestrator
16362
16385
  };
16363
- //# sourceMappingURL=chunk-FLCYY5JX.js.map
16386
+ //# sourceMappingURL=chunk-AE2HPUP7.js.map