@graphrefly/graphrefly 0.46.0 → 0.47.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 (99) hide show
  1. package/dist/base/composition/index.cjs +69 -15
  2. package/dist/base/composition/index.cjs.map +1 -1
  3. package/dist/base/composition/index.d.cts +1 -2
  4. package/dist/base/composition/index.d.ts +1 -2
  5. package/dist/base/composition/index.js +1 -1
  6. package/dist/base/index.cjs +69 -15
  7. package/dist/base/index.cjs.map +1 -1
  8. package/dist/base/index.d.cts +1 -2
  9. package/dist/base/index.d.ts +1 -2
  10. package/dist/base/index.js +1 -1
  11. package/dist/{chunk-CGHORL6G.js → chunk-7ADWWI2T.js} +2 -2
  12. package/dist/{chunk-RGL53X5G.js → chunk-B4AKFXGE.js} +4 -4
  13. package/dist/{chunk-FW23JYNQ.js → chunk-CEVNQ74M.js} +2 -2
  14. package/dist/{chunk-JGFRAFDL.js → chunk-FVINAAKA.js} +3 -3
  15. package/dist/{chunk-WKSWLSCX.js → chunk-J5WFUEO4.js} +2 -2
  16. package/dist/{chunk-HULCUY35.js → chunk-K7PDZYQE.js} +4 -4
  17. package/dist/{chunk-Z6EGP5D7.js → chunk-LDCSZ72P.js} +2 -2
  18. package/dist/{chunk-KIIXR252.js → chunk-MTTRCEJT.js} +2 -2
  19. package/dist/{chunk-Q3EYOCZB.js → chunk-NPRP3MCV.js} +111 -2
  20. package/dist/chunk-NPRP3MCV.js.map +1 -0
  21. package/dist/{chunk-5THCXDWY.js → chunk-RGMTUZCL.js} +3 -3
  22. package/dist/{chunk-FR6RGA3B.js → chunk-U225SKB4.js} +472 -37
  23. package/dist/chunk-U225SKB4.js.map +1 -0
  24. package/dist/{chunk-GBCENOLN.js → chunk-V4Y3TM7U.js} +5 -5
  25. package/dist/{chunk-LBAJK24K.js → chunk-VLAGJZSL.js} +11 -3
  26. package/dist/chunk-VLAGJZSL.js.map +1 -0
  27. package/dist/{chunk-OO5BM6CJ.js → chunk-YXCPV26R.js} +2 -2
  28. package/dist/chunk-Z65DVDEQ.js +146 -0
  29. package/dist/chunk-Z65DVDEQ.js.map +1 -0
  30. package/dist/compat/index.cjs +156 -93
  31. package/dist/compat/index.cjs.map +1 -1
  32. package/dist/compat/index.d.cts +3 -3
  33. package/dist/compat/index.d.ts +3 -3
  34. package/dist/compat/index.js +2 -2
  35. package/dist/compat/nestjs/index.cjs +156 -93
  36. package/dist/compat/nestjs/index.cjs.map +1 -1
  37. package/dist/compat/nestjs/index.d.cts +4 -4
  38. package/dist/compat/nestjs/index.d.ts +4 -4
  39. package/dist/compat/nestjs/index.js +4 -5
  40. package/dist/{index-5SU_O78r.d.cts → index-B_p8tnvf.d.cts} +19 -3
  41. package/dist/{index-CEXCtYYJ.d.ts → index-_HDSmPyp.d.ts} +19 -3
  42. package/dist/index.cjs +1449 -856
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +3 -4
  45. package/dist/index.d.ts +3 -4
  46. package/dist/index.js +36 -14
  47. package/dist/index.js.map +1 -1
  48. package/dist/observable-B25XqCbZ.d.cts +59 -0
  49. package/dist/observable-B25XqCbZ.d.ts +59 -0
  50. package/dist/presets/ai/index.cjs.map +1 -1
  51. package/dist/presets/ai/index.js +6 -6
  52. package/dist/presets/harness/index.cjs.map +1 -1
  53. package/dist/presets/harness/index.js +9 -9
  54. package/dist/presets/index.cjs.map +1 -1
  55. package/dist/presets/index.js +13 -13
  56. package/dist/presets/inspect/index.cjs.map +1 -1
  57. package/dist/presets/inspect/index.js +4 -4
  58. package/dist/solutions/index.cjs.map +1 -1
  59. package/dist/solutions/index.js +10 -10
  60. package/dist/utils/ai/index.cjs.map +1 -1
  61. package/dist/utils/ai/index.js +5 -5
  62. package/dist/utils/index.cjs +939 -400
  63. package/dist/utils/index.cjs.map +1 -1
  64. package/dist/utils/index.d.cts +2 -2
  65. package/dist/utils/index.d.ts +2 -2
  66. package/dist/utils/index.js +28 -6
  67. package/dist/utils/inspect/index.cjs.map +1 -1
  68. package/dist/utils/inspect/index.js +2 -2
  69. package/dist/utils/memory/index.cjs +470 -40
  70. package/dist/utils/memory/index.cjs.map +1 -1
  71. package/dist/utils/memory/index.d.cts +669 -2
  72. package/dist/utils/memory/index.d.ts +669 -2
  73. package/dist/utils/memory/index.js +19 -1
  74. package/dist/utils/messaging/index.cjs +109 -0
  75. package/dist/utils/messaging/index.cjs.map +1 -1
  76. package/dist/utils/messaging/index.d.cts +115 -2
  77. package/dist/utils/messaging/index.d.ts +115 -2
  78. package/dist/utils/messaging/index.js +5 -1
  79. package/dist/utils/orchestration/index.cjs.map +1 -1
  80. package/dist/utils/orchestration/index.js +2 -2
  81. package/package.json +1 -5
  82. package/dist/chunk-3QZY5BI7.js +0 -92
  83. package/dist/chunk-3QZY5BI7.js.map +0 -1
  84. package/dist/chunk-FR6RGA3B.js.map +0 -1
  85. package/dist/chunk-LBAJK24K.js.map +0 -1
  86. package/dist/chunk-Q3EYOCZB.js.map +0 -1
  87. package/dist/observable-BXQoW1P-.d.cts +0 -36
  88. package/dist/observable-BXQoW1P-.d.ts +0 -36
  89. /package/dist/{chunk-CGHORL6G.js.map → chunk-7ADWWI2T.js.map} +0 -0
  90. /package/dist/{chunk-RGL53X5G.js.map → chunk-B4AKFXGE.js.map} +0 -0
  91. /package/dist/{chunk-FW23JYNQ.js.map → chunk-CEVNQ74M.js.map} +0 -0
  92. /package/dist/{chunk-JGFRAFDL.js.map → chunk-FVINAAKA.js.map} +0 -0
  93. /package/dist/{chunk-WKSWLSCX.js.map → chunk-J5WFUEO4.js.map} +0 -0
  94. /package/dist/{chunk-HULCUY35.js.map → chunk-K7PDZYQE.js.map} +0 -0
  95. /package/dist/{chunk-Z6EGP5D7.js.map → chunk-LDCSZ72P.js.map} +0 -0
  96. /package/dist/{chunk-KIIXR252.js.map → chunk-MTTRCEJT.js.map} +0 -0
  97. /package/dist/{chunk-5THCXDWY.js.map → chunk-RGMTUZCL.js.map} +0 -0
  98. /package/dist/{chunk-GBCENOLN.js.map → chunk-V4Y3TM7U.js.map} +0 -0
  99. /package/dist/{chunk-OO5BM6CJ.js.map → chunk-YXCPV26R.js.map} +0 -0
@@ -20,15 +20,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/utils/memory/index.ts
21
21
  var memory_exports = {};
22
22
  __export(memory_exports, {
23
+ admissionLlmJudge: () => admissionLlmJudge,
24
+ bitemporalQuery: () => bitemporalQuery,
23
25
  collection: () => collection,
26
+ consolidationRem: () => consolidationRem,
24
27
  cosineSimilarity: () => cosineSimilarity,
28
+ decayExponential: () => decayExponential,
29
+ influenceAnalysis: () => influenceAnalysis,
30
+ invalidationTracer: () => invalidationTracer,
25
31
  knowledgeGraph: () => knowledgeGraph,
32
+ persistentReactiveFactStore: () => persistentReactiveFactStore,
26
33
  reactiveFactStore: () => reactiveFactStore,
34
+ scoringByOutcome: () => scoringByOutcome,
35
+ shardByTenant: () => shardByTenant,
27
36
  vectorIndex: () => vectorIndex
28
37
  });
29
38
  module.exports = __toCommonJS(memory_exports);
30
- var import_core3 = require("@graphrefly/pure-ts/core");
31
- var import_extra3 = require("@graphrefly/pure-ts/extra");
39
+ var import_core10 = require("@graphrefly/pure-ts/core");
40
+ var import_extra8 = require("@graphrefly/pure-ts/extra");
32
41
  var import_graph3 = require("@graphrefly/pure-ts/graph");
33
42
 
34
43
  // src/base/meta/domain-meta.ts
@@ -247,6 +256,8 @@ function reactiveFactStore(config) {
247
256
  graph
248
257
  });
249
258
  const seqCursor = registerCursor(graph, "seq", 0);
259
+ const ingestLog = config.recordIngest ? (0, import_extra2.reactiveLog)([], { name: "ingest_log" }) : void 0;
260
+ if (ingestLog) graph.addDisposer(() => ingestLog.dispose());
250
261
  const emptyStore = () => ({ byId: /* @__PURE__ */ new Map() });
251
262
  const shards = [];
252
263
  for (let s = 0; s < shardCount; s += 1) {
@@ -402,6 +413,8 @@ function reactiveFactStore(config) {
402
413
  factId: dep,
403
414
  rootFactId: f.id,
404
415
  reason: "obsolete",
416
+ // `obsolete` guard above guarantees `f.validTo` is set.
417
+ rootValidTo: f.validTo,
405
418
  iteration: cascadeIteration + 1,
406
419
  causalReason: `dependentsIndex[${f.id}] \u2192 ${dep} (obsolete: validTo set)`
407
420
  });
@@ -474,11 +487,10 @@ function reactiveFactStore(config) {
474
487
  actions.emit([]);
475
488
  return;
476
489
  }
477
- const now = (0, import_core2.monotonicNs)();
478
- for (const [id] of byId) {
490
+ for (const [id, e] of byId) {
479
491
  replaceFragment(
480
492
  id,
481
- (prev) => prev.validTo !== void 0 ? prev : { ...prev, validTo: BigInt(now) }
493
+ (prev) => prev.validTo !== void 0 ? prev : { ...prev, validTo: e.rootValidTo }
482
494
  );
483
495
  }
484
496
  actions.emit([...byId.values()]);
@@ -636,6 +648,7 @@ function reactiveFactStore(config) {
636
648
  t_ns: (0, import_core2.wallClockNs)(),
637
649
  seq: bumpCursor(seqCursor)
638
650
  });
651
+ ingestLog?.append(f);
639
652
  }
640
653
  actions.emit(f ?? null);
641
654
  },
@@ -672,19 +685,436 @@ function reactiveFactStore(config) {
672
685
  review,
673
686
  consolidated,
674
687
  events,
688
+ ...ingestLog ? { ingestLog } : {},
675
689
  itemNode
676
690
  });
677
691
  return out;
678
692
  }
679
693
 
694
+ // src/utils/memory/persistent-fact-store.ts
695
+ var import_core3 = require("@graphrefly/pure-ts/core");
696
+ var import_extra3 = require("@graphrefly/pure-ts/extra");
697
+ function persistMeta(kind) {
698
+ return domainMeta("memory", kind);
699
+ }
700
+ function persistentReactiveFactStore(config) {
701
+ const persistName = config.persistName ?? "fact_store_ingest";
702
+ const codec = config.codec ?? (0, import_extra3.bigintJsonCodecFor)();
703
+ const tier = (0, import_extra3.appendLogStorage)(config.storage, {
704
+ name: persistName,
705
+ codec
706
+ });
707
+ const store = reactiveFactStore({ ...config, recordIngest: true });
708
+ const ingestLog = store.ingestLog;
709
+ async function* loadHistory() {
710
+ if (typeof tier.loadEntries !== "function") return;
711
+ const page = await tier.loadEntries();
712
+ for (const f of page.entries) yield f;
713
+ }
714
+ const replaySource = (0, import_extra3.fromAny)(loadHistory(), {
715
+ name: "_replay_source",
716
+ meta: persistMeta("persist_replay_source")
717
+ });
718
+ store.add(replaySource, { name: "_replay_source" });
719
+ let replayed = 0;
720
+ const replayPump = (0, import_core3.node)(
721
+ [replaySource],
722
+ (batchData, actions) => {
723
+ const b = batchData[0];
724
+ if (b != null && b.length > 0) {
725
+ for (const f of b) {
726
+ config.ingest.emit(f);
727
+ replayed += 1;
728
+ }
729
+ actions.emit(replayed);
730
+ }
731
+ },
732
+ {
733
+ name: "_replay_pump",
734
+ describeKind: "derived",
735
+ initial: 0,
736
+ meta: persistMeta("persist_replay_pump")
737
+ }
738
+ );
739
+ store.add(replayPump, { name: "_replay_pump" });
740
+ store.addDisposer((0, import_extra3.keepalive)(replayPump));
741
+ const attached = (0, import_core3.node)([], {
742
+ initial: false,
743
+ name: "_storage_attached",
744
+ describeKind: "state",
745
+ meta: persistMeta("persist_attached")
746
+ });
747
+ store.add(attached, { name: "_storage_attached" });
748
+ store.addDisposer((0, import_extra3.keepalive)(attached));
749
+ let detachStorage;
750
+ const replaySub = replaySource.subscribe((msgs) => {
751
+ for (const m of msgs) {
752
+ if (m[0] === import_core3.COMPLETE && detachStorage === void 0) {
753
+ const sizeAtAttach = ingestLog.size;
754
+ detachStorage = ingestLog.attachStorage([tier]);
755
+ if (sizeAtAttach > replayed) {
756
+ const slice = [];
757
+ for (let i = replayed; i < sizeAtAttach; i += 1) {
758
+ const v = ingestLog.at(i);
759
+ if (v === void 0) {
760
+ throw new Error(
761
+ `persistentReactiveFactStore: ingestLog hole at index ${i} in reconciliation slice [${replayed}, ${sizeAtAttach}); pre-attach-live durability cannot be guaranteed.`
762
+ );
763
+ }
764
+ slice.push(v);
765
+ }
766
+ if (slice.length > 0) {
767
+ const r = tier.appendEntries(slice);
768
+ if (r instanceof Promise) r.catch(() => {
769
+ });
770
+ }
771
+ }
772
+ attached.emit(true);
773
+ }
774
+ }
775
+ });
776
+ store.addDisposer(() => {
777
+ replaySub();
778
+ detachStorage?.();
779
+ });
780
+ const position = (0, import_core3.node)(
781
+ [ingestLog.entries, attached],
782
+ (batchData, actions, ctx) => {
783
+ const eb = batchData[0];
784
+ const arr = eb != null && eb.length > 0 ? eb.at(-1) : ctx.prevData[0];
785
+ const ab = batchData[1];
786
+ const isAttached = ab != null && ab.length > 0 ? ab.at(-1) : ctx.prevData[1];
787
+ actions.emit(isAttached === true ? arr?.length ?? 0 : 0);
788
+ },
789
+ {
790
+ name: "_durable_position",
791
+ describeKind: "derived",
792
+ initial: 0,
793
+ meta: persistMeta("persist_position")
794
+ }
795
+ );
796
+ store.add(position, { name: "_durable_position" });
797
+ store.addDisposer((0, import_extra3.keepalive)(position));
798
+ const out = Object.assign(store, {
799
+ position,
800
+ replayedCount: replayPump,
801
+ tier,
802
+ async flush() {
803
+ await tier.flush?.();
804
+ }
805
+ });
806
+ return out;
807
+ }
808
+
809
+ // src/utils/memory/recipes/admission-llm-judge.ts
810
+ var import_core4 = require("@graphrefly/pure-ts/core");
811
+ function admissionLlmJudge(verdicts, opts = {}) {
812
+ const dflt = opts.defaultVerdict ?? false;
813
+ const buildFilter = (m) => (f) => m.get(f.id) ?? dflt;
814
+ return (0, import_core4.node)(
815
+ [verdicts],
816
+ (batchData, actions, ctx) => {
817
+ const m = batchData[0]?.at(-1) ?? ctx.prevData[0] ?? /* @__PURE__ */ new Map();
818
+ actions.emit(buildFilter(m));
819
+ },
820
+ {
821
+ name: opts.name ?? "admission_llm_judge",
822
+ describeKind: "derived",
823
+ // Before any verdict arrives, apply the default policy.
824
+ initial: buildFilter(/* @__PURE__ */ new Map())
825
+ }
826
+ );
827
+ }
828
+
829
+ // src/utils/memory/recipes/bitemporal-query.ts
830
+ var import_core5 = require("@graphrefly/pure-ts/core");
831
+
832
+ // src/utils/memory/recipes/_shared.ts
833
+ function lastOf2(batch2, prev) {
834
+ return batch2 != null && batch2.length > 0 ? batch2.at(-1) : prev;
835
+ }
836
+ function validAt(f, asOf) {
837
+ if (asOf === void 0) return f.validTo === void 0;
838
+ if (f.validFrom !== void 0 && asOf < f.validFrom) return false;
839
+ if (f.validTo !== void 0 && asOf >= f.validTo) return false;
840
+ return true;
841
+ }
842
+
843
+ // src/utils/memory/recipes/bitemporal-query.ts
844
+ function bitemporalQuery(mem, asOf, opts = {}) {
845
+ const asOfOrNull = (0, import_core5.node)(
846
+ [asOf],
847
+ (b, a, c) => a.emit(lastOf2(b[0], c.prevData[0]) ?? null),
848
+ { name: `${opts.name ?? "bitemporal_query"}_asof`, describeKind: "derived", initial: null }
849
+ );
850
+ return (0, import_core5.node)(
851
+ [asOfOrNull, mem.factStore],
852
+ (batchData, actions, ctx) => {
853
+ const raw = lastOf2(batchData[0], ctx.prevData[0]);
854
+ const at = raw ?? void 0;
855
+ const fs = lastOf2(batchData[1], ctx.prevData[1]);
856
+ if (fs == null) {
857
+ actions.emit([]);
858
+ return;
859
+ }
860
+ const results = [...fs.byId.values()].filter((f) => {
861
+ if (!validAt(f, at)) return false;
862
+ if (opts.tags && opts.tags.length > 0 && !opts.tags.some((t) => f.tags.includes(t))) {
863
+ return false;
864
+ }
865
+ if (opts.minConfidence !== void 0 && f.confidence < opts.minConfidence) return false;
866
+ return true;
867
+ });
868
+ results.sort((a, b) => b.confidence - a.confidence || Number(b.t_ns - a.t_ns));
869
+ actions.emit(results);
870
+ },
871
+ {
872
+ name: opts.name ?? "bitemporal_query",
873
+ describeKind: "derived",
874
+ initial: []
875
+ }
876
+ );
877
+ }
878
+
879
+ // src/utils/memory/recipes/consolidation-rem.ts
880
+ var import_extra4 = require("@graphrefly/pure-ts/extra");
881
+ function consolidationRem(opts) {
882
+ const consolidateTrigger = (0, import_extra4.fromTimer)(opts.periodMs, { period: opts.periodMs });
883
+ const consolidate = (store) => {
884
+ const live = [...store.values()].filter((f) => f.validTo === void 0);
885
+ if (live.length === 0) return [];
886
+ let pool = live;
887
+ if (opts.recentWindowNs !== void 0) {
888
+ const newest = live.reduce((m, f) => f.t_ns > m ? f.t_ns : m, live[0].t_ns);
889
+ const cutoff = newest - opts.recentWindowNs;
890
+ pool = live.filter((f) => f.t_ns >= cutoff);
891
+ }
892
+ pool.sort((a, b) => b.confidence - a.confidence || Number(b.t_ns - a.t_ns));
893
+ const replayed = pool.slice(0, Math.max(0, opts.topK));
894
+ return replayed.length > 0 ? opts.summarize(replayed) : [];
895
+ };
896
+ return { consolidateTrigger, consolidate };
897
+ }
898
+
899
+ // src/utils/memory/recipes/decay-exponential.ts
900
+ var import_core6 = require("@graphrefly/pure-ts/core");
901
+ var import_extra5 = require("@graphrefly/pure-ts/extra");
902
+ function decayExponential(mem, ingest, opts) {
903
+ const floor = opts.floor ?? 0;
904
+ const epsilon = Math.max(opts.epsilon ?? 1e-4, Number.EPSILON);
905
+ const half = Number(opts.halfLifeNs);
906
+ const lastTick = /* @__PURE__ */ new Map();
907
+ const timer = (0, import_extra5.fromTimer)(opts.periodMs, { period: opts.periodMs });
908
+ const driver = (0, import_core6.node)(
909
+ [timer],
910
+ (_batchData, actions) => {
911
+ const fs = mem.factStore.cache;
912
+ if (!fs) {
913
+ actions.emit([]);
914
+ return;
915
+ }
916
+ const now = BigInt((0, import_core6.wallClockNs)());
917
+ const decayed = [];
918
+ const liveIds = /* @__PURE__ */ new Set();
919
+ for (const f of fs.byId.values()) {
920
+ liveIds.add(f.id);
921
+ if (f.validTo !== void 0) continue;
922
+ if (f.confidence <= floor) continue;
923
+ const lt = lastTick.get(f.id);
924
+ const since = lt !== void 0 && lt >= f.t_ns ? lt : f.t_ns;
925
+ const elapsed = Number(now - since);
926
+ if (elapsed <= 0) continue;
927
+ const factor = 0.5 ** (half > 0 ? elapsed / half : 0);
928
+ if (!Number.isFinite(factor)) continue;
929
+ let next = f.confidence * factor;
930
+ if (next < floor) next = floor;
931
+ if (f.confidence - next < epsilon) continue;
932
+ const liveNow = mem.factStore.cache?.byId.get(f.id);
933
+ if (liveNow && liveNow.validTo !== void 0) continue;
934
+ lastTick.set(f.id, now);
935
+ const drifted = { ...f, confidence: next };
936
+ decayed.push(drifted);
937
+ ingest.emit(drifted);
938
+ }
939
+ if (lastTick.size > liveIds.size) {
940
+ for (const id of lastTick.keys()) if (!liveIds.has(id)) lastTick.delete(id);
941
+ }
942
+ actions.emit(decayed);
943
+ },
944
+ {
945
+ name: opts.name ?? "decay_exponential",
946
+ describeKind: "derived",
947
+ initial: []
948
+ }
949
+ );
950
+ mem.add(driver, { name: opts.name ?? "decay_exponential" });
951
+ mem.addDisposer((0, import_extra5.keepalive)(timer));
952
+ mem.addDisposer((0, import_extra5.keepalive)(driver));
953
+ return driver;
954
+ }
955
+
956
+ // src/utils/memory/recipes/influence-analysis.ts
957
+ var import_core7 = require("@graphrefly/pure-ts/core");
958
+ var import_extra6 = require("@graphrefly/pure-ts/extra");
959
+ function closureOf(index, root) {
960
+ const seen = /* @__PURE__ */ new Set();
961
+ const queue = [root];
962
+ while (queue.length > 0) {
963
+ const cur = queue.shift();
964
+ for (const dep of index.get(cur) ?? []) {
965
+ if (seen.has(dep) || dep === root) continue;
966
+ seen.add(dep);
967
+ queue.push(dep);
968
+ }
969
+ }
970
+ return [...seen];
971
+ }
972
+ function influenceAnalysis(mem, opts = {}) {
973
+ const prefix = opts.name ?? "influence";
974
+ const maxRanked = Math.max(1, opts.maxRanked ?? 64);
975
+ const ranked = (0, import_core7.node)(
976
+ [mem.dependentsIndex],
977
+ (batchData, actions, ctx) => {
978
+ const index = lastOf2(batchData[0], ctx.prevData[0]);
979
+ if (index == null) {
980
+ actions.emit([]);
981
+ return;
982
+ }
983
+ const rows = [];
984
+ for (const key of index.keys()) {
985
+ rows.push({ factId: key, influence: closureOf(index, key).length });
986
+ }
987
+ rows.sort((a, b) => b.influence - a.influence);
988
+ actions.emit(rows.slice(0, maxRanked));
989
+ },
990
+ {
991
+ name: `${prefix}_ranked`,
992
+ describeKind: "derived",
993
+ initial: []
994
+ }
995
+ );
996
+ mem.add(ranked, { name: `${prefix}_ranked` });
997
+ mem.addDisposer((0, import_extra6.keepalive)(ranked));
998
+ const builtFor = /* @__PURE__ */ new Map();
999
+ function influenceOf(rootId) {
1000
+ const existing = builtFor.get(rootId);
1001
+ if (existing) return existing;
1002
+ const n = (0, import_core7.node)(
1003
+ [mem.dependentsIndex],
1004
+ (batchData, actions, ctx) => {
1005
+ const index = lastOf2(batchData[0], ctx.prevData[0]);
1006
+ actions.emit(index == null ? [] : closureOf(index, rootId));
1007
+ },
1008
+ {
1009
+ name: `${prefix}_of_${rootId}`,
1010
+ describeKind: "derived",
1011
+ initial: []
1012
+ }
1013
+ );
1014
+ mem.add(n, { name: `${prefix}_of_${rootId}` });
1015
+ mem.addDisposer((0, import_extra6.keepalive)(n));
1016
+ builtFor.set(rootId, n);
1017
+ return n;
1018
+ }
1019
+ return { influenceOf, ranked };
1020
+ }
1021
+
1022
+ // src/utils/memory/recipes/invalidation-tracer.ts
1023
+ var import_core8 = require("@graphrefly/pure-ts/core");
1024
+ var import_extra7 = require("@graphrefly/pure-ts/extra");
1025
+ function invalidationTracer(mem, opts = {}) {
1026
+ const limit = Math.max(1, opts.limit ?? 256);
1027
+ const ring = [];
1028
+ const push = (e) => {
1029
+ ring.push(e);
1030
+ if (ring.length > limit) ring.splice(0, ring.length - limit);
1031
+ };
1032
+ const tracer = (0, import_core8.node)(
1033
+ [mem.cascade, mem.cascadeOverflow],
1034
+ (batchData, actions) => {
1035
+ const cascadeWaves = batchData[0] ?? [];
1036
+ for (const wave of cascadeWaves) {
1037
+ for (const ev of wave) {
1038
+ push({
1039
+ kind: "cascade",
1040
+ factId: ev.factId,
1041
+ rootFactId: ev.rootFactId,
1042
+ reason: ev.reason,
1043
+ iteration: ev.iteration,
1044
+ causalReason: ev.causalReason
1045
+ });
1046
+ }
1047
+ }
1048
+ const overflows = batchData[1] ?? [];
1049
+ for (const ov of overflows) {
1050
+ if (ov == null) continue;
1051
+ push({
1052
+ kind: "overflow",
1053
+ factId: ov.sample[0] ?? "",
1054
+ rootFactId: ov.rootFactId,
1055
+ reason: "overflow",
1056
+ causalReason: `cascade overflow: ${ov.droppedCount} dropped (root ${ov.rootFactId})`
1057
+ });
1058
+ }
1059
+ actions.emit([...ring]);
1060
+ },
1061
+ {
1062
+ name: opts.name ?? "invalidation_tracer",
1063
+ describeKind: "derived",
1064
+ initial: []
1065
+ }
1066
+ );
1067
+ mem.add(tracer, { name: opts.name ?? "invalidation_tracer" });
1068
+ mem.addDisposer((0, import_extra7.keepalive)(tracer));
1069
+ return tracer;
1070
+ }
1071
+
1072
+ // src/utils/memory/recipes/scoring-by-outcome.ts
1073
+ var import_core9 = require("@graphrefly/pure-ts/core");
1074
+ var clamp01 = (n) => n < 0 ? 0 : n > 1 ? 1 : n;
1075
+ function scoringByOutcome(outcomes, opts = {}) {
1076
+ const base = opts.base ?? ((f) => f.confidence);
1077
+ const learningRate = opts.learningRate ?? 1;
1078
+ const acc = /* @__PURE__ */ new Map();
1079
+ const buildPolicy = () => (fragment) => clamp01(base(fragment) + learningRate * (acc.get(fragment.id) ?? 0));
1080
+ return (0, import_core9.node)(
1081
+ [outcomes],
1082
+ (batchData, actions) => {
1083
+ const wave = batchData[0] ?? [];
1084
+ for (const sig of wave) acc.set(sig.factId, (acc.get(sig.factId) ?? 0) + sig.reward);
1085
+ actions.emit(buildPolicy());
1086
+ },
1087
+ {
1088
+ name: opts.name ?? "scoring_by_outcome",
1089
+ describeKind: "derived",
1090
+ // Usable scorer before any outcome arrives (base-only).
1091
+ initial: buildPolicy()
1092
+ }
1093
+ );
1094
+ }
1095
+
1096
+ // src/utils/memory/recipes/shard-by-tenant.ts
1097
+ function shardByTenant(tenantOf, opts = {}) {
1098
+ if (opts.tenants && opts.tenants.length > 0) {
1099
+ const idx = new Map(opts.tenants.map((t, i) => [t, i]));
1100
+ const overflow = opts.tenants.length;
1101
+ return {
1102
+ shardBy: (f) => idx.get(tenantOf(f)) ?? overflow,
1103
+ shardCount: opts.tenants.length + 1
1104
+ };
1105
+ }
1106
+ const shardCount = Math.max(1, opts.shardCount ?? 4);
1107
+ return { shardBy: (f) => tenantOf(f), shardCount };
1108
+ }
1109
+
680
1110
  // src/utils/memory/index.ts
681
1111
  var NS_PER_SEC = 1e9;
682
1112
  function memoryMeta(kind, extra) {
683
1113
  return domainMeta("memory", kind, extra);
684
1114
  }
685
1115
  function toNode(v, name) {
686
- if (v instanceof import_core3.NodeImpl) return v;
687
- return (0, import_core3.node)([], { initial: v, ...name ? { name } : void 0 });
1116
+ if (v instanceof import_core10.NodeImpl) return v;
1117
+ return (0, import_core10.node)([], { initial: v, ...name ? { name } : void 0 });
688
1118
  }
689
1119
  function ageSeconds(now, lastNs) {
690
1120
  return (now - lastNs) / NS_PER_SEC;
@@ -738,14 +1168,14 @@ function collection(name, opts = {}) {
738
1168
  }
739
1169
  const scoreFnDefault = () => ranked ? 1 : 0;
740
1170
  const scoreInput = opts.score ?? scoreFnDefault;
741
- const scoreNode = ranked && scoreInput instanceof import_core3.NodeImpl ? scoreInput : void 0;
1171
+ const scoreNode = ranked && scoreInput instanceof import_core10.NodeImpl ? scoreInput : void 0;
742
1172
  const readScoreFn = () => {
743
1173
  if (scoreNode) return scoreNode.cache ?? scoreFnDefault;
744
1174
  return scoreInput;
745
1175
  };
746
1176
  const graph = new import_graph3.Graph(name);
747
- const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds((0, import_core3.monotonicNs)(), v.lastAccessNs), decayRate, minScore) : v.lastAccessNs;
748
- const items = (0, import_extra3.reactiveMap)({
1177
+ const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds((0, import_core10.monotonicNs)(), v.lastAccessNs), decayRate, minScore) : v.lastAccessNs;
1178
+ const items = (0, import_extra8.reactiveMap)({
749
1179
  name: "items",
750
1180
  ...maxSize !== void 0 ? { retention: { score: retentionScore, maxSize } } : {}
751
1181
  });
@@ -753,16 +1183,16 @@ function collection(name, opts = {}) {
753
1183
  let refreshTick;
754
1184
  if (ranked && decayRate > 0) {
755
1185
  const intervalMs = opts.refreshIntervalMs ?? Math.max(1, 1e3 * Math.LN2 / (10 * decayRate));
756
- const tickCounter = (0, import_extra3.fromTimer)(intervalMs, { period: intervalMs });
757
- refreshTick = (0, import_core3.node)(
1186
+ const tickCounter = (0, import_extra8.fromTimer)(intervalMs, { period: intervalMs });
1187
+ refreshTick = (0, import_core10.node)(
758
1188
  [tickCounter],
759
1189
  (_batchData, actions) => {
760
- actions.emit((0, import_core3.monotonicNs)());
1190
+ actions.emit((0, import_core10.monotonicNs)());
761
1191
  },
762
1192
  {
763
1193
  name: "refresh_tick_ns",
764
1194
  describeKind: "derived",
765
- initial: (0, import_core3.monotonicNs)(),
1195
+ initial: (0, import_core10.monotonicNs)(),
766
1196
  meta: memoryMeta("clock")
767
1197
  }
768
1198
  );
@@ -773,7 +1203,7 @@ function collection(name, opts = {}) {
773
1203
  const rankedDeps = [items.entries];
774
1204
  if (refreshTick) rankedDeps.push(refreshTick);
775
1205
  if (scoreNode) rankedDeps.push(scoreNode);
776
- rankedNode = (0, import_core3.node)(
1206
+ rankedNode = (0, import_core10.node)(
777
1207
  rankedDeps,
778
1208
  (batchData, actions, ctx) => {
779
1209
  const values = batchData.map(
@@ -783,9 +1213,9 @@ function collection(name, opts = {}) {
783
1213
  let now;
784
1214
  if (refreshTick) {
785
1215
  const tickValue = values[1];
786
- now = typeof tickValue === "number" ? tickValue : (0, import_core3.monotonicNs)();
1216
+ now = typeof tickValue === "number" ? tickValue : (0, import_core10.monotonicNs)();
787
1217
  } else {
788
- now = (0, import_core3.monotonicNs)();
1218
+ now = (0, import_core10.monotonicNs)();
789
1219
  }
790
1220
  if (!snapshot || snapshot.size === 0) {
791
1221
  actions.emit([]);
@@ -810,7 +1240,7 @@ function collection(name, opts = {}) {
810
1240
  );
811
1241
  graph.add(rankedNode, { name: "ranked" });
812
1242
  } else {
813
- rankedNode = (0, import_core3.node)([], {
1243
+ rankedNode = (0, import_core10.node)([], {
814
1244
  initial: [],
815
1245
  name: "ranked",
816
1246
  describeKind: "state",
@@ -818,7 +1248,7 @@ function collection(name, opts = {}) {
818
1248
  });
819
1249
  graph.add(rankedNode, { name: "ranked" });
820
1250
  }
821
- const size = (0, import_core3.node)(
1251
+ const size = (0, import_core10.node)(
822
1252
  [items.entries],
823
1253
  (batchData, actions, ctx) => {
824
1254
  const data = batchData.map(
@@ -835,7 +1265,7 @@ function collection(name, opts = {}) {
835
1265
  }
836
1266
  );
837
1267
  graph.add(size, { name: "size" });
838
- graph.addDisposer((0, import_extra3.keepalive)(size));
1268
+ graph.addDisposer((0, import_extra8.keepalive)(size));
839
1269
  const events = createAuditLog({
840
1270
  name: "events",
841
1271
  retainedLimit: 1024,
@@ -843,7 +1273,7 @@ function collection(name, opts = {}) {
843
1273
  });
844
1274
  const seqCursor = registerCursor(graph, "seq", 0);
845
1275
  const upsertImpl = (id, value, _opts) => {
846
- const now = (0, import_core3.monotonicNs)();
1276
+ const now = (0, import_core10.monotonicNs)();
847
1277
  const prev = items.get(id);
848
1278
  const baseScore = _opts?.score ?? readScoreFn()(value);
849
1279
  items.set(id, {
@@ -899,7 +1329,7 @@ function collection(name, opts = {}) {
899
1329
  });
900
1330
  function itemNode(id) {
901
1331
  const idN = toNode(id, "id");
902
- return (0, import_core3.node)(
1332
+ return (0, import_core10.node)(
903
1333
  [items.entries, idN],
904
1334
  (batchData, actions, ctx) => {
905
1335
  const data = batchData.map(
@@ -917,7 +1347,7 @@ function collection(name, opts = {}) {
917
1347
  }
918
1348
  function hasNode(id) {
919
1349
  const idN = toNode(id, "id");
920
- return (0, import_core3.node)(
1350
+ return (0, import_core10.node)(
921
1351
  [items.entries, idN],
922
1352
  (batchData, actions, ctx) => {
923
1353
  const data = batchData.map(
@@ -992,7 +1422,7 @@ function vectorIndex(opts = {}) {
992
1422
  graph
993
1423
  });
994
1424
  const seqCursor = registerCursor(graph, "seq", 0);
995
- const entries = (0, import_extra3.reactiveMap)({
1425
+ const entries = (0, import_extra8.reactiveMap)({
996
1426
  name: "entries",
997
1427
  ...maxSize !== void 0 ? {
998
1428
  retention: {
@@ -1004,7 +1434,7 @@ function vectorIndex(opts = {}) {
1004
1434
  events.append({
1005
1435
  action: "evict",
1006
1436
  id: key,
1007
- t_ns: (0, import_core3.wallClockNs)(),
1437
+ t_ns: (0, import_core10.wallClockNs)(),
1008
1438
  seq: bumpCursor(seqCursor)
1009
1439
  });
1010
1440
  }
@@ -1012,7 +1442,7 @@ function vectorIndex(opts = {}) {
1012
1442
  } : {}
1013
1443
  });
1014
1444
  graph.add(entries.entries, { name: "entries" });
1015
- graph.addDisposer((0, import_extra3.keepalive)(entries.entries));
1445
+ graph.addDisposer((0, import_extra8.keepalive)(entries.entries));
1016
1446
  if (hnsw?.dispose) {
1017
1447
  const disposeAdapter = hnsw.dispose.bind(hnsw);
1018
1448
  graph.addDisposer(() => disposeAdapter());
@@ -1029,7 +1459,7 @@ function vectorIndex(opts = {}) {
1029
1459
  id,
1030
1460
  vector: [...vector],
1031
1461
  ...copiedMeta !== void 0 ? { meta: copiedMeta } : {},
1032
- upsertedAtNs: (0, import_core3.monotonicNs)()
1462
+ upsertedAtNs: (0, import_core10.monotonicNs)()
1033
1463
  };
1034
1464
  entries.set(id, record);
1035
1465
  };
@@ -1085,7 +1515,7 @@ function vectorIndex(opts = {}) {
1085
1515
  });
1086
1516
  function searchNode(query, k = 5) {
1087
1517
  const kN = toNode(k, "k");
1088
- return (0, import_core3.node)(
1518
+ return (0, import_core10.node)(
1089
1519
  [entries.entries, query, kN],
1090
1520
  (batchData, actions, ctx) => {
1091
1521
  const values = batchData.map(
@@ -1191,17 +1621,17 @@ function knowledgeGraph(name, opts = {}) {
1191
1621
  throw new RangeError("knowledgeGraph: edgesMaxSize must be >= 1");
1192
1622
  }
1193
1623
  const graph = new import_graph3.Graph(name);
1194
- const entitiesMap = (0, import_extra3.reactiveMap)({
1624
+ const entitiesMap = (0, import_extra8.reactiveMap)({
1195
1625
  name: "entities",
1196
1626
  ...opts.entitiesMaxSize !== void 0 ? { maxSize: opts.entitiesMaxSize } : {}
1197
1627
  });
1198
- const edgesMap = (0, import_extra3.reactiveMap)({
1628
+ const edgesMap = (0, import_extra8.reactiveMap)({
1199
1629
  name: "edges",
1200
1630
  ...opts.edgesMaxSize !== void 0 ? { maxSize: opts.edgesMaxSize } : {}
1201
1631
  });
1202
1632
  graph.add(entitiesMap.entries, { name: "entities" });
1203
1633
  graph.add(edgesMap.entries, { name: "edges" });
1204
- const adjacencyOut = (0, import_core3.node)(
1634
+ const adjacencyOut = (0, import_core10.node)(
1205
1635
  [edgesMap.entries],
1206
1636
  (batchData, actions, ctx) => {
1207
1637
  const data = batchData.map(
@@ -1218,7 +1648,7 @@ function knowledgeGraph(name, opts = {}) {
1218
1648
  meta: memoryMeta("adjacency_out")
1219
1649
  }
1220
1650
  );
1221
- const adjacencyIn = (0, import_core3.node)(
1651
+ const adjacencyIn = (0, import_core10.node)(
1222
1652
  [edgesMap.entries],
1223
1653
  (batchData, actions, ctx) => {
1224
1654
  const data = batchData.map(
@@ -1237,9 +1667,9 @@ function knowledgeGraph(name, opts = {}) {
1237
1667
  );
1238
1668
  graph.add(adjacencyOut, { name: "adjacencyOut" });
1239
1669
  graph.add(adjacencyIn, { name: "adjacencyIn" });
1240
- graph.addDisposer((0, import_extra3.keepalive)(adjacencyOut));
1241
- graph.addDisposer((0, import_extra3.keepalive)(adjacencyIn));
1242
- const entityCount = (0, import_core3.node)(
1670
+ graph.addDisposer((0, import_extra8.keepalive)(adjacencyOut));
1671
+ graph.addDisposer((0, import_extra8.keepalive)(adjacencyIn));
1672
+ const entityCount = (0, import_core10.node)(
1243
1673
  [entitiesMap.entries],
1244
1674
  (batchData, actions, ctx) => {
1245
1675
  const data = batchData.map(
@@ -1250,7 +1680,7 @@ function knowledgeGraph(name, opts = {}) {
1250
1680
  },
1251
1681
  { name: "entityCount", describeKind: "derived", initial: 0, meta: memoryMeta("entity_count") }
1252
1682
  );
1253
- const edgeCount = (0, import_core3.node)(
1683
+ const edgeCount = (0, import_core10.node)(
1254
1684
  [edgesMap.entries],
1255
1685
  (batchData, actions, ctx) => {
1256
1686
  const data = batchData.map(
@@ -1263,8 +1693,8 @@ function knowledgeGraph(name, opts = {}) {
1263
1693
  );
1264
1694
  graph.add(entityCount, { name: "entityCount" });
1265
1695
  graph.add(edgeCount, { name: "edgeCount" });
1266
- graph.addDisposer((0, import_extra3.keepalive)(entityCount));
1267
- graph.addDisposer((0, import_extra3.keepalive)(edgeCount));
1696
+ graph.addDisposer((0, import_extra8.keepalive)(entityCount));
1697
+ graph.addDisposer((0, import_extra8.keepalive)(edgeCount));
1268
1698
  const events = createAuditLog({
1269
1699
  name: "events",
1270
1700
  retainedLimit: 1024,
@@ -1287,7 +1717,7 @@ function knowledgeGraph(name, opts = {}) {
1287
1717
  events.append({
1288
1718
  action: "orphanRemove",
1289
1719
  id: candidate,
1290
- t_ns: (0, import_core3.wallClockNs)(),
1720
+ t_ns: (0, import_core10.wallClockNs)(),
1291
1721
  seq: bumpCursor(seqCursor)
1292
1722
  });
1293
1723
  }
@@ -1382,7 +1812,7 @@ function knowledgeGraph(name, opts = {}) {
1382
1812
  const idN = toNode(id, "id");
1383
1813
  const relN = relation !== void 0 ? toNode(relation, "relation") : void 0;
1384
1814
  const deps = relN ? [adjacencyOut, adjacencyIn, idN, relN] : [adjacencyOut, adjacencyIn, idN];
1385
- return (0, import_core3.node)(
1815
+ return (0, import_core10.node)(
1386
1816
  deps,
1387
1817
  (batchData, actions, ctx) => {
1388
1818
  const values = batchData.map(