@remnic/core 9.62.0 → 9.62.2
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/access-admin-ops-surface.d.ts +11 -11
- package/dist/access-admin-ops-surface.js +28 -28
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +29 -29
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +28 -28
- package/dist/access-cli.js +93 -91
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +11 -11
- package/dist/access-extraction-force-flush.js +28 -28
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +11 -11
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.js +28 -28
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +38 -38
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +28 -28
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +28 -28
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +33 -33
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-EMvicnrb.d.ts → access-namespace-preflight-yO4LMGFH.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +28 -28
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +28 -28
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +2 -2
- package/dist/access-operations-batch.js +29 -29
- package/dist/access-operations.d.ts +11 -11
- package/dist/access-operations.js +32 -32
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +28 -28
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +28 -28
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +28 -28
- package/dist/{access-service-BeDYQQ62.d.ts → access-service-M4LgO141.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +28 -28
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +30 -30
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +3 -3
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-FMWQQB3J.js → auto-sync-Z52VWMNC.js} +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-learner.js +2 -2
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +13 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-B2SxZ6LU.d.ts → catalog-CyYTf_ok.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +3 -3
- package/dist/causal-chain.js +3 -3
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +16 -16
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.js +2 -2
- package/dist/{chunk-B2QHVLJO.js → chunk-256FBCVX.js} +22 -10
- package/dist/chunk-256FBCVX.js.map +1 -0
- package/dist/{chunk-QP2IZTUR.js → chunk-2TYIAKU5.js} +2 -2
- package/dist/{chunk-HQBVQICL.js → chunk-347ZR6D4.js} +2 -2
- package/dist/{chunk-76YNCJ5H.js → chunk-3F3CVVDS.js} +2 -2
- package/dist/{chunk-TE4MKFT2.js → chunk-3MA7JVXN.js} +4 -4
- package/dist/{chunk-KHQ57QLJ.js → chunk-46WM6JX2.js} +7 -3
- package/dist/chunk-46WM6JX2.js.map +1 -0
- package/dist/chunk-47DU4SGJ.js +92 -0
- package/dist/chunk-47DU4SGJ.js.map +1 -0
- package/dist/{chunk-AWRJBAIH.js → chunk-4FFROSFG.js} +37 -14
- package/dist/{chunk-AWRJBAIH.js.map → chunk-4FFROSFG.js.map} +1 -1
- package/dist/{chunk-N4OYPGZS.js → chunk-4HO3542O.js} +2 -2
- package/dist/{chunk-HEEEMJ26.js → chunk-4IZ2IT7D.js} +3 -3
- package/dist/{chunk-4XAVQLBR.js → chunk-4Y2RHVCV.js} +2 -2
- package/dist/{chunk-33JBK2XP.js → chunk-5F6HMNMZ.js} +2 -2
- package/dist/{chunk-5WQMORU5.js → chunk-5PFGMO33.js} +2 -2
- package/dist/{chunk-6HEM6HTQ.js → chunk-6GGTATZF.js} +2 -2
- package/dist/{chunk-W3Y6FYRK.js → chunk-7BJYTX6Q.js} +2 -2
- package/dist/{chunk-2GRLJMKJ.js → chunk-7DRSWPUV.js} +3 -3
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-HXXGZ4KV.js → chunk-ALNZEWGN.js} +2 -2
- package/dist/{chunk-5WVUO6QT.js → chunk-AR253JBM.js} +1 -1
- package/dist/chunk-AR253JBM.js.map +1 -0
- package/dist/{chunk-S3B3UIQ3.js → chunk-AYIHDC5S.js} +2 -2
- package/dist/{chunk-2RIDW23Y.js → chunk-BBHFAVMP.js} +8 -8
- package/dist/{chunk-MJ4UGUR6.js → chunk-BHO6RHE5.js} +3 -3
- package/dist/{chunk-URN7XWGC.js → chunk-BP6WMYLP.js} +3 -3
- package/dist/{chunk-YUIBXMZY.js → chunk-CALURYWR.js} +284 -249
- package/dist/chunk-CALURYWR.js.map +1 -0
- package/dist/{chunk-D5HDJWNN.js → chunk-CH627RRV.js} +4 -4
- package/dist/{chunk-C3R732UY.js → chunk-CLJ5QS6J.js} +257 -60
- package/dist/chunk-CLJ5QS6J.js.map +1 -0
- package/dist/{chunk-YLHM5BQQ.js → chunk-DCUMFQYM.js} +171 -8
- package/dist/chunk-DCUMFQYM.js.map +1 -0
- package/dist/{chunk-ZBJMUXZH.js → chunk-DJ7HMNSL.js} +15 -8
- package/dist/chunk-DJ7HMNSL.js.map +1 -0
- package/dist/{chunk-XDK6ZFLL.js → chunk-DROAPP6N.js} +3 -3
- package/dist/{chunk-MU3TPZOV.js → chunk-DTLF2SLZ.js} +2 -2
- package/dist/{chunk-I67HKRBF.js → chunk-EFWHCTYJ.js} +2 -2
- package/dist/{chunk-XD4VGLDL.js → chunk-FF6E6HOT.js} +56 -52
- package/dist/chunk-FF6E6HOT.js.map +1 -0
- package/dist/{chunk-NP7FLVZW.js → chunk-G2FCSILA.js} +2 -2
- package/dist/{chunk-3GPBFDXH.js → chunk-H23GIXJC.js} +2 -2
- package/dist/{chunk-WT6UL3UA.js → chunk-H7PRHUBD.js} +2 -2
- package/dist/{chunk-4JGSG7QN.js → chunk-HSBQJRV2.js} +2 -2
- package/dist/{chunk-L33N3BCA.js → chunk-HVKMJAEF.js} +2 -2
- package/dist/{chunk-CSOYVTRX.js → chunk-IIPJKCZB.js} +3 -3
- package/dist/{chunk-E57E5SCS.js → chunk-IRLH4NM2.js} +3 -3
- package/dist/{chunk-H32ANIFP.js → chunk-IZRNVNPV.js} +2 -2
- package/dist/{chunk-XBR5BAKW.js → chunk-JCJGYNIS.js} +3 -3
- package/dist/{chunk-EIQFIJDM.js → chunk-JDI7G6EA.js} +2 -2
- package/dist/{chunk-QWPAQLYV.js → chunk-JFLKSD5V.js} +2 -2
- package/dist/{chunk-KQS72GCR.js → chunk-LJOIZPJH.js} +2 -2
- package/dist/{chunk-N4EPIKSY.js → chunk-LLGDVG52.js} +3 -3
- package/dist/{chunk-7N7DB4L5.js → chunk-LTJTP5YQ.js} +10 -9
- package/dist/chunk-LTJTP5YQ.js.map +1 -0
- package/dist/{chunk-VOELBUS4.js → chunk-NXH34IPL.js} +2 -2
- package/dist/{chunk-XL3TATMJ.js → chunk-OQIRBGUU.js} +21 -12
- package/dist/chunk-OQIRBGUU.js.map +1 -0
- package/dist/chunk-PJKTFXE2.js +119 -0
- package/dist/chunk-PJKTFXE2.js.map +1 -0
- package/dist/{chunk-JGW2EUCQ.js → chunk-PMRUMGK6.js} +2 -2
- package/dist/{chunk-KAB7TZN3.js → chunk-PSNN25DW.js} +2 -2
- package/dist/{chunk-LRGSLV7M.js → chunk-PYHOAXTI.js} +4 -4
- package/dist/{chunk-PA5OPZX2.js → chunk-QCI73Z7C.js} +2 -2
- package/dist/{chunk-EHMMRZOZ.js → chunk-QICOU4RY.js} +2 -2
- package/dist/{chunk-FW73HN33.js → chunk-RFH7U5LT.js} +2 -2
- package/dist/{chunk-4SGDYYWV.js → chunk-RPKJHYVE.js} +2 -2
- package/dist/{chunk-DSA47WBN.js → chunk-RYST72N5.js} +13 -2
- package/dist/chunk-RYST72N5.js.map +1 -0
- package/dist/{chunk-L4DLLKPN.js → chunk-SZ4HFZKB.js} +2 -2
- package/dist/chunk-T3GIETKV.js +152 -0
- package/dist/chunk-T3GIETKV.js.map +1 -0
- package/dist/{chunk-MYZ4NA43.js → chunk-TGSMU3F2.js} +3 -3
- package/dist/{chunk-CM4SZZBN.js → chunk-TIRJV2LW.js} +2 -2
- package/dist/{chunk-EGW4O32Z.js → chunk-UDTME32W.js} +7 -4
- package/dist/chunk-UDTME32W.js.map +1 -0
- package/dist/{chunk-CIA6ZUBA.js → chunk-WMOJIOIG.js} +2 -2
- package/dist/{chunk-W4Q54HM3.js → chunk-WR2YKUIW.js} +2 -2
- package/dist/{chunk-VWDTV6SH.js → chunk-X6E7TT3A.js} +2 -2
- package/dist/{chunk-D4OCJSLV.js → chunk-YDPAE2RD.js} +2 -2
- package/dist/{chunk-G3YBWFUC.js → chunk-YIIC5IDU.js} +35 -18
- package/dist/chunk-YIIC5IDU.js.map +1 -0
- package/dist/{chunk-QRKYABS6.js → chunk-YSR3DXGC.js} +2 -2
- package/dist/{chunk-LBJBNWS2.js → chunk-YTHQHH5U.js} +2 -2
- package/dist/{chunk-GN7HO2LA.js → chunk-ZPGHA7EO.js} +12 -12
- package/dist/{chunk-VUDALPI5.js → chunk-ZQKXRKMR.js} +19 -5
- package/dist/chunk-ZQKXRKMR.js.map +1 -0
- package/dist/{chunk-FQSDU634.js → chunk-ZS4JADYY.js} +3 -3
- package/dist/{cli-DB_uakTc.d.ts → cli-Bw9z-KqX.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +62 -62
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/coding/pre-action-gate.js +3 -3
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +13 -12
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +3 -3
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +13 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +13 -12
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +15 -14
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +15 -14
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-DcOVpK3y.d.ts → dependency-propagation-delivery-BxhvAppj.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer-wiring.js +3 -3
- package/dist/direct-answer.d.ts +1 -1
- package/dist/direct-answer.js +2 -2
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +13 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +92 -0
- package/dist/episodic-context.js +16 -0
- package/dist/episodic-context.js.map +1 -0
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +29 -29
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +11 -11
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-normalization.js +2 -2
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction-source-grounding.js +3 -3
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +18 -18
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-5TWK7CZT.js → forget-SZ2BXDGF.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-construction.js +2 -2
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +22 -21
- package/dist/index.js +118 -103
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +8 -2
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +9 -9
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +13 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -12
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +14 -13
- package/dist/{maintenance-5c1olVtB.d.ts → maintenance-uJb74j64.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +14 -13
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -5
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +13 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +16 -15
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +21 -20
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +18 -17
- package/dist/{orchestrator-HPuY6I4i.d.ts → orchestrator-CFi-5JSR.d.ts} +23 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +93 -91
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CvVe1Q2_.d.ts → pipeline-BdF3ferY.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/policy-runtime.js +3 -3
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/provenance.js +2 -2
- package/dist/{public-http-D0JKFkyf.d.ts → public-http-DK-QwaBu.d.ts} +1 -1
- package/dist/{qmd-Bd0Tp76_.d.ts → qmd-D_62bYNl.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-query-policy.js +2 -2
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-tokenization.d.ts +3 -1
- package/dist/recall-tokenization.js +5 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +10 -1
- package/dist/reconcile/manifest.js +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +6 -6
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-ClLtm9gK.d.ts → scope-profiles-CeMv7pP0.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +5 -4
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -8
- package/dist/search/lancedb-backend.d.ts +14 -1
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +22 -1
- package/dist/search/orama-backend.js +2 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-B1EkeEDj.d.ts → semantic-consolidation-B-85brYj.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +14 -14
- package/dist/semantic-rule-promotion.js +13 -12
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +13 -13
- package/dist/{service-Cf3ANQj9.d.ts → service-CoO0HA2E.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +15 -14
- package/dist/{storage-DS2O_6Qt.d.ts → storage-BVAVitkO.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +12 -11
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +31 -31
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/import-sqlite.js +2 -2
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/trust-zones.js +2 -2
- package/dist/{types-BOANGhCJ.d.ts → types-DWHOxlZP.d.ts} +3 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/user-message-cleaning.d.ts +23 -0
- package/dist/user-message-cleaning.js +10 -0
- package/dist/user-message-cleaning.js.map +1 -0
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +13 -13
- package/dist/whitespace.d.ts +26 -1
- package/dist/whitespace.js +11 -3
- package/dist/work-product-ledger.js +2 -2
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +12 -2
- package/src/access-service-offline-file-content.test.ts +1 -0
- package/src/cli.ts +14 -13
- package/src/config.ts +11 -0
- package/src/entity-retrieval.ts +4 -7
- package/src/episodic-context-recall.integration.test.ts +169 -0
- package/src/episodic-context.test.ts +266 -0
- package/src/episodic-context.ts +274 -0
- package/src/harmonic-construction.test.ts +187 -2
- package/src/harmonic-retrieval.ts +54 -32
- package/src/index.ts +3 -4
- package/src/lcm/engine.ts +18 -1
- package/src/lifecycle/tombstones.test.ts +134 -0
- package/src/lifecycle/tombstones.ts +29 -2
- package/src/orchestration/episodic-context-section.ts +255 -0
- package/src/orchestration/recall-internal-deps.ts +2 -0
- package/src/orchestration/recall-internal.ts +40 -25
- package/src/orchestration/recall-result-formatter.ts +37 -0
- package/src/orchestration/recall-section-coordinator.ts +20 -14
- package/src/recall-tokenization.ts +14 -8
- package/src/reconcile/manifest.test.ts +133 -4
- package/src/reconcile/manifest.ts +43 -7
- package/src/search/factory.ts +1 -0
- package/src/search/lancedb-backend.ts +24 -16
- package/src/search/orama-backend.test.ts +208 -1
- package/src/search/orama-backend.ts +133 -18
- package/src/search/orama-cjk-tokenizer.test.ts +108 -0
- package/src/search/orama-cjk-tokenizer.ts +143 -0
- package/src/storage/tombstone-migration-sources.test.ts +116 -0
- package/src/storage/tombstone-migration-sources.ts +90 -0
- package/src/storage.ts +13 -34
- package/src/types.ts +3 -3
- package/src/user-message-cleaning.ts +139 -0
- package/src/whitespace.test.ts +178 -0
- package/src/whitespace.ts +119 -0
- package/dist/chunk-5WVUO6QT.js.map +0 -1
- package/dist/chunk-6MKAMLQL.js +0 -16
- package/dist/chunk-6MKAMLQL.js.map +0 -1
- package/dist/chunk-7N7DB4L5.js.map +0 -1
- package/dist/chunk-B2QHVLJO.js.map +0 -1
- package/dist/chunk-C3R732UY.js.map +0 -1
- package/dist/chunk-DSA47WBN.js.map +0 -1
- package/dist/chunk-EGW4O32Z.js.map +0 -1
- package/dist/chunk-G3YBWFUC.js.map +0 -1
- package/dist/chunk-KHQ57QLJ.js.map +0 -1
- package/dist/chunk-VUDALPI5.js.map +0 -1
- package/dist/chunk-XD4VGLDL.js.map +0 -1
- package/dist/chunk-XL3TATMJ.js.map +0 -1
- package/dist/chunk-YLHM5BQQ.js.map +0 -1
- package/dist/chunk-YUIBXMZY.js.map +0 -1
- package/dist/chunk-ZBJMUXZH.js.map +0 -1
- /package/dist/{auto-sync-FMWQQB3J.js.map → auto-sync-Z52VWMNC.js.map} +0 -0
- /package/dist/{chunk-QP2IZTUR.js.map → chunk-2TYIAKU5.js.map} +0 -0
- /package/dist/{chunk-HQBVQICL.js.map → chunk-347ZR6D4.js.map} +0 -0
- /package/dist/{chunk-76YNCJ5H.js.map → chunk-3F3CVVDS.js.map} +0 -0
- /package/dist/{chunk-TE4MKFT2.js.map → chunk-3MA7JVXN.js.map} +0 -0
- /package/dist/{chunk-N4OYPGZS.js.map → chunk-4HO3542O.js.map} +0 -0
- /package/dist/{chunk-HEEEMJ26.js.map → chunk-4IZ2IT7D.js.map} +0 -0
- /package/dist/{chunk-4XAVQLBR.js.map → chunk-4Y2RHVCV.js.map} +0 -0
- /package/dist/{chunk-33JBK2XP.js.map → chunk-5F6HMNMZ.js.map} +0 -0
- /package/dist/{chunk-5WQMORU5.js.map → chunk-5PFGMO33.js.map} +0 -0
- /package/dist/{chunk-6HEM6HTQ.js.map → chunk-6GGTATZF.js.map} +0 -0
- /package/dist/{chunk-W3Y6FYRK.js.map → chunk-7BJYTX6Q.js.map} +0 -0
- /package/dist/{chunk-2GRLJMKJ.js.map → chunk-7DRSWPUV.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-HXXGZ4KV.js.map → chunk-ALNZEWGN.js.map} +0 -0
- /package/dist/{chunk-S3B3UIQ3.js.map → chunk-AYIHDC5S.js.map} +0 -0
- /package/dist/{chunk-2RIDW23Y.js.map → chunk-BBHFAVMP.js.map} +0 -0
- /package/dist/{chunk-MJ4UGUR6.js.map → chunk-BHO6RHE5.js.map} +0 -0
- /package/dist/{chunk-URN7XWGC.js.map → chunk-BP6WMYLP.js.map} +0 -0
- /package/dist/{chunk-D5HDJWNN.js.map → chunk-CH627RRV.js.map} +0 -0
- /package/dist/{chunk-XDK6ZFLL.js.map → chunk-DROAPP6N.js.map} +0 -0
- /package/dist/{chunk-MU3TPZOV.js.map → chunk-DTLF2SLZ.js.map} +0 -0
- /package/dist/{chunk-I67HKRBF.js.map → chunk-EFWHCTYJ.js.map} +0 -0
- /package/dist/{chunk-NP7FLVZW.js.map → chunk-G2FCSILA.js.map} +0 -0
- /package/dist/{chunk-3GPBFDXH.js.map → chunk-H23GIXJC.js.map} +0 -0
- /package/dist/{chunk-WT6UL3UA.js.map → chunk-H7PRHUBD.js.map} +0 -0
- /package/dist/{chunk-4JGSG7QN.js.map → chunk-HSBQJRV2.js.map} +0 -0
- /package/dist/{chunk-L33N3BCA.js.map → chunk-HVKMJAEF.js.map} +0 -0
- /package/dist/{chunk-CSOYVTRX.js.map → chunk-IIPJKCZB.js.map} +0 -0
- /package/dist/{chunk-E57E5SCS.js.map → chunk-IRLH4NM2.js.map} +0 -0
- /package/dist/{chunk-H32ANIFP.js.map → chunk-IZRNVNPV.js.map} +0 -0
- /package/dist/{chunk-XBR5BAKW.js.map → chunk-JCJGYNIS.js.map} +0 -0
- /package/dist/{chunk-EIQFIJDM.js.map → chunk-JDI7G6EA.js.map} +0 -0
- /package/dist/{chunk-QWPAQLYV.js.map → chunk-JFLKSD5V.js.map} +0 -0
- /package/dist/{chunk-KQS72GCR.js.map → chunk-LJOIZPJH.js.map} +0 -0
- /package/dist/{chunk-N4EPIKSY.js.map → chunk-LLGDVG52.js.map} +0 -0
- /package/dist/{chunk-VOELBUS4.js.map → chunk-NXH34IPL.js.map} +0 -0
- /package/dist/{chunk-JGW2EUCQ.js.map → chunk-PMRUMGK6.js.map} +0 -0
- /package/dist/{chunk-KAB7TZN3.js.map → chunk-PSNN25DW.js.map} +0 -0
- /package/dist/{chunk-LRGSLV7M.js.map → chunk-PYHOAXTI.js.map} +0 -0
- /package/dist/{chunk-PA5OPZX2.js.map → chunk-QCI73Z7C.js.map} +0 -0
- /package/dist/{chunk-EHMMRZOZ.js.map → chunk-QICOU4RY.js.map} +0 -0
- /package/dist/{chunk-FW73HN33.js.map → chunk-RFH7U5LT.js.map} +0 -0
- /package/dist/{chunk-4SGDYYWV.js.map → chunk-RPKJHYVE.js.map} +0 -0
- /package/dist/{chunk-L4DLLKPN.js.map → chunk-SZ4HFZKB.js.map} +0 -0
- /package/dist/{chunk-MYZ4NA43.js.map → chunk-TGSMU3F2.js.map} +0 -0
- /package/dist/{chunk-CM4SZZBN.js.map → chunk-TIRJV2LW.js.map} +0 -0
- /package/dist/{chunk-CIA6ZUBA.js.map → chunk-WMOJIOIG.js.map} +0 -0
- /package/dist/{chunk-W4Q54HM3.js.map → chunk-WR2YKUIW.js.map} +0 -0
- /package/dist/{chunk-VWDTV6SH.js.map → chunk-X6E7TT3A.js.map} +0 -0
- /package/dist/{chunk-D4OCJSLV.js.map → chunk-YDPAE2RD.js.map} +0 -0
- /package/dist/{chunk-QRKYABS6.js.map → chunk-YSR3DXGC.js.map} +0 -0
- /package/dist/{chunk-LBJBNWS2.js.map → chunk-YTHQHH5U.js.map} +0 -0
- /package/dist/{chunk-GN7HO2LA.js.map → chunk-ZPGHA7EO.js.map} +0 -0
- /package/dist/{chunk-FQSDU634.js.map → chunk-ZS4JADYY.js.map} +0 -0
- /package/dist/{forget-5TWK7CZT.js.map → forget-SZ2BXDGF.js.map} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the episodic-context recall section (issue #2331).
|
|
3
|
+
*
|
|
4
|
+
* Seeds a real Orchestrator with an LCM archive and one fact whose
|
|
5
|
+
* `sources` provenance carries a resolvable turn fingerprint, then asserts:
|
|
6
|
+
* - flag off: no `## Source Episodes` section and ZERO archive reads
|
|
7
|
+
* - flag on: grouped episode injected, within the recall budget
|
|
8
|
+
* - facts without structured sources are skipped
|
|
9
|
+
* - foreign-session provenance (cross-namespace) is skipped
|
|
10
|
+
*/
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
13
|
+
import os from "node:os";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
|
|
17
|
+
import { parseConfig } from "./config.js";
|
|
18
|
+
import { Orchestrator } from "./orchestrator.js";
|
|
19
|
+
import type { ProvenanceSource } from "./types.js";
|
|
20
|
+
|
|
21
|
+
const SEP = String.fromCharCode(1);
|
|
22
|
+
|
|
23
|
+
const SESSION_KEY = "session-atlas-7";
|
|
24
|
+
|
|
25
|
+
function fingerprint(turnIndex: number): string {
|
|
26
|
+
return `user${SEP}we settled the storage question${SEP}thread-1${SEP}${turnIndex}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function provenance(turnIndex: number): ProvenanceSource {
|
|
30
|
+
return {
|
|
31
|
+
sessionKey: SESSION_KEY,
|
|
32
|
+
turnId: fingerprint(turnIndex),
|
|
33
|
+
observedAt: "2026-08-16T00:00:00.000Z",
|
|
34
|
+
quote: "we settled the storage question",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function seedArchive(orchestrator: Orchestrator): Promise<void> {
|
|
39
|
+
const engine = orchestrator.lcmEngine!;
|
|
40
|
+
await engine.observeMessages(SESSION_KEY, [
|
|
41
|
+
{ role: "user", content: "turn zero greeting" },
|
|
42
|
+
{ role: "user", content: "we settled the storage question: postgres for the atlas cluster" },
|
|
43
|
+
{ role: "assistant", content: "understood, postgres it is" },
|
|
44
|
+
{ role: "user", content: "also note the replica lives in frankfurt" },
|
|
45
|
+
{ role: "assistant", content: "replica noted" },
|
|
46
|
+
]);
|
|
47
|
+
await engine.waitForObserveQueueIdle();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Wrap the engine's read surfaces with call counters. */
|
|
51
|
+
function countArchiveReads(orchestrator: Orchestrator): { reads: () => number } {
|
|
52
|
+
const engine = orchestrator.lcmEngine as unknown as {
|
|
53
|
+
getTurnRange: (...args: unknown[]) => Promise<unknown[]>;
|
|
54
|
+
searchContextFull: (...args: unknown[]) => Promise<unknown[]>;
|
|
55
|
+
};
|
|
56
|
+
let reads = 0;
|
|
57
|
+
const originalGetTurnRange = engine.getTurnRange.bind(engine);
|
|
58
|
+
const originalSearch = engine.searchContextFull.bind(engine);
|
|
59
|
+
engine.getTurnRange = async (...args: unknown[]) => {
|
|
60
|
+
reads += 1;
|
|
61
|
+
return originalGetTurnRange(...args);
|
|
62
|
+
};
|
|
63
|
+
engine.searchContextFull = async (...args: unknown[]) => {
|
|
64
|
+
reads += 1;
|
|
65
|
+
return originalSearch(...args);
|
|
66
|
+
};
|
|
67
|
+
return { reads: () => reads };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function buildOrchestrator(
|
|
71
|
+
memoryDir: string,
|
|
72
|
+
episodicContextEnabled: boolean,
|
|
73
|
+
): Promise<Orchestrator> {
|
|
74
|
+
const config = parseConfig({
|
|
75
|
+
memoryDir,
|
|
76
|
+
qmdEnabled: false,
|
|
77
|
+
lcmEnabled: true,
|
|
78
|
+
episodicContextEnabled,
|
|
79
|
+
transcriptEnabled: false,
|
|
80
|
+
injectQuestions: false,
|
|
81
|
+
sharedContextEnabled: false,
|
|
82
|
+
});
|
|
83
|
+
return new Orchestrator(config);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
test("episodic context: flag off = no section and zero archive reads", async () => {
|
|
87
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-episodic-off-"));
|
|
88
|
+
try {
|
|
89
|
+
const orchestrator = await buildOrchestrator(memoryDir, false);
|
|
90
|
+
await seedArchive(orchestrator);
|
|
91
|
+
const storage = await orchestrator.getStorage("default");
|
|
92
|
+
await storage.ensureDirectories();
|
|
93
|
+
await storage.writeMemory("fact", "The atlas cluster stores its graph in postgres.", {
|
|
94
|
+
source: "test",
|
|
95
|
+
sources: [provenance(1)],
|
|
96
|
+
});
|
|
97
|
+
const counter = countArchiveReads(orchestrator);
|
|
98
|
+
const context = await orchestrator.recall("where does the atlas cluster store data?", SESSION_KEY);
|
|
99
|
+
assert.ok(!context.includes("## Source Episodes"), "flag off must not inject the section");
|
|
100
|
+
assert.equal(counter.reads(), 0, "flag off must issue zero archive reads");
|
|
101
|
+
await orchestrator.destroy();
|
|
102
|
+
} finally {
|
|
103
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("episodic context: flag on injects grouped episodes within budget", async () => {
|
|
108
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-episodic-on-"));
|
|
109
|
+
try {
|
|
110
|
+
const orchestrator = await buildOrchestrator(memoryDir, true);
|
|
111
|
+
await seedArchive(orchestrator);
|
|
112
|
+
const storage = await orchestrator.getStorage("default");
|
|
113
|
+
await storage.ensureDirectories();
|
|
114
|
+
// Two facts whose windows overlap around turn 1: one merged episode.
|
|
115
|
+
await storage.writeMemory("fact", "The atlas cluster stores its graph in postgres.", {
|
|
116
|
+
source: "test",
|
|
117
|
+
sources: [provenance(1)],
|
|
118
|
+
});
|
|
119
|
+
await storage.writeMemory("fact", "The atlas replica lives in frankfurt.", {
|
|
120
|
+
source: "test",
|
|
121
|
+
sources: [provenance(3)],
|
|
122
|
+
});
|
|
123
|
+
// A fact with NO structured sources: silently skipped.
|
|
124
|
+
await storage.writeMemory("fact", "Legacy fact without provenance sources.", {
|
|
125
|
+
source: "test",
|
|
126
|
+
});
|
|
127
|
+
const context = await orchestrator.recall("where does the atlas cluster store data?", SESSION_KEY);
|
|
128
|
+
const sectionStart = context.indexOf("## Source Episodes");
|
|
129
|
+
assert.ok(sectionStart >= 0, `section must be injected, got: ${context.slice(0, 400)}`);
|
|
130
|
+
const section = context.slice(sectionStart);
|
|
131
|
+
assert.ok(section.includes("### Episode: session-"), "episode header uses shortened session key");
|
|
132
|
+
assert.ok(section.includes("supports ["), "episode cites supporting memory ids");
|
|
133
|
+
assert.ok(section.includes("postgres for the atlas cluster"), "raw source turn is injected");
|
|
134
|
+
assert.ok(section.includes("replica lives in frankfurt"), "merged window covers turn 3");
|
|
135
|
+
assert.ok(!section.includes("Legacy fact"), "fact without sources contributes nothing");
|
|
136
|
+
assert.ok(context.length <= orchestrator.config.recallBudgetChars + 2000, "context stays within budget envelope");
|
|
137
|
+
await orchestrator.destroy();
|
|
138
|
+
} finally {
|
|
139
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("episodic context: foreign-session provenance is skipped under namespace framing", async () => {
|
|
144
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-episodic-ns-"));
|
|
145
|
+
try {
|
|
146
|
+
const orchestrator = await buildOrchestrator(memoryDir, true);
|
|
147
|
+
await seedArchive(orchestrator);
|
|
148
|
+
// The fact's provenance points at a session whose rows live under a
|
|
149
|
+
// DIFFERENT namespace frame than this single-store recall resolves.
|
|
150
|
+
// Candidate keys never match, so no episode is injected.
|
|
151
|
+
const foreign: ProvenanceSource = {
|
|
152
|
+
sessionKey: "\u001fsome-other-tenant\u001fsession-atlas-7",
|
|
153
|
+
turnId: fingerprint(1),
|
|
154
|
+
observedAt: "2026-08-16T00:00:00.000Z",
|
|
155
|
+
quote: "we settled the storage question",
|
|
156
|
+
};
|
|
157
|
+
const storage = await orchestrator.getStorage("default");
|
|
158
|
+
await storage.ensureDirectories();
|
|
159
|
+
await storage.writeMemory("fact", "The atlas cluster stores its graph in postgres.", {
|
|
160
|
+
source: "test",
|
|
161
|
+
sources: [foreign],
|
|
162
|
+
});
|
|
163
|
+
const context = await orchestrator.recall("where does the atlas cluster store data?", SESSION_KEY);
|
|
164
|
+
assert.ok(!context.includes("## Source Episodes"), "foreign-session episode must be skipped");
|
|
165
|
+
await orchestrator.destroy();
|
|
166
|
+
} finally {
|
|
167
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
168
|
+
}
|
|
169
|
+
});
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
compareEpisodeWindows,
|
|
6
|
+
factsNeedingQuoteFallback,
|
|
7
|
+
planEpisodeWindows,
|
|
8
|
+
planEpisodeWindowsWithFallback,
|
|
9
|
+
resolveProvenanceTurnIndex,
|
|
10
|
+
type EpisodicFactInput,
|
|
11
|
+
} from "./episodic-context.js";
|
|
12
|
+
import { cleanArchivedUserMessage } from "./user-message-cleaning.js";
|
|
13
|
+
import { RecallResultFormatter } from "./orchestration/recall-result-formatter.js";
|
|
14
|
+
import { parseConfig } from "./config.js";
|
|
15
|
+
import type { ProvenanceSource } from "./types.js";
|
|
16
|
+
|
|
17
|
+
const SEP = String.fromCharCode(1);
|
|
18
|
+
|
|
19
|
+
function source(overrides: Partial<ProvenanceSource> = {}): ProvenanceSource {
|
|
20
|
+
return {
|
|
21
|
+
sessionKey: "session-a",
|
|
22
|
+
observedAt: "2026-08-16T00:00:00.000Z",
|
|
23
|
+
quote: "the atlas cluster stores edges",
|
|
24
|
+
...overrides,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fact(
|
|
29
|
+
memoryId: string,
|
|
30
|
+
rank: number,
|
|
31
|
+
sources: ProvenanceSource[] | undefined,
|
|
32
|
+
): EpisodicFactInput {
|
|
33
|
+
return { memoryId, rank, sources };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
test("resolveProvenanceTurnIndex parses the fingerprint's trailing turn index", () => {
|
|
37
|
+
const fingerprint = `user${SEP}hello world${SEP}thread-1${SEP}42`;
|
|
38
|
+
assert.equal(resolveProvenanceTurnIndex(fingerprint), 42);
|
|
39
|
+
assert.equal(resolveProvenanceTurnIndex("7"), 7);
|
|
40
|
+
assert.equal(resolveProvenanceTurnIndex("not-a-number"), null);
|
|
41
|
+
assert.equal(resolveProvenanceTurnIndex(`user${SEP}x${SEP}t${SEP}12x`), null);
|
|
42
|
+
assert.equal(resolveProvenanceTurnIndex(undefined), null);
|
|
43
|
+
assert.equal(resolveProvenanceTurnIndex("-3"), null);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("planEpisodeWindows returns [] before any work when limits are zero", () => {
|
|
47
|
+
const facts = [
|
|
48
|
+
fact("m1", 0, [source({ turnId: "5" })]),
|
|
49
|
+
];
|
|
50
|
+
assert.deepEqual(planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 0, maxTurnsPerEpisode: 8 }), []);
|
|
51
|
+
assert.deepEqual(planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 2, maxTurnsPerEpisode: 0 }), []);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("planEpisodeWindows skips facts without structured sources and unparseable turnIds", () => {
|
|
55
|
+
const facts = [
|
|
56
|
+
fact("m1", 0, undefined),
|
|
57
|
+
fact("m2", 1, []),
|
|
58
|
+
fact("m3", 2, [source({ turnId: "abc" })]),
|
|
59
|
+
fact("m4", 3, [source({ turnId: "10" })]),
|
|
60
|
+
];
|
|
61
|
+
const windows = planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 2, maxTurnsPerEpisode: 8 });
|
|
62
|
+
assert.equal(windows.length, 1);
|
|
63
|
+
assert.deepEqual(windows[0], {
|
|
64
|
+
sessionKey: "session-a",
|
|
65
|
+
fromTurn: 9,
|
|
66
|
+
toTurn: 12,
|
|
67
|
+
factRank: 3,
|
|
68
|
+
memoryIds: ["m4"],
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("planEpisodeWindows merges overlapping and adjacent windows without double-counting turns", () => {
|
|
73
|
+
// turn 5 -> [4,7); turn 6 -> [5,8): overlap -> one merged window [4,8).
|
|
74
|
+
const facts = [
|
|
75
|
+
fact("m1", 0, [source({ turnId: "5" })]),
|
|
76
|
+
fact("m2", 1, [source({ turnId: "6" })]),
|
|
77
|
+
];
|
|
78
|
+
const windows = planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 2, maxTurnsPerEpisode: 8 });
|
|
79
|
+
assert.equal(windows.length, 1);
|
|
80
|
+
assert.equal(windows[0]!.fromTurn, 4);
|
|
81
|
+
assert.equal(windows[0]!.toTurn, 8);
|
|
82
|
+
assert.deepEqual(windows[0]!.memoryIds, ["m1", "m2"]);
|
|
83
|
+
assert.equal(windows[0]!.factRank, 0);
|
|
84
|
+
|
|
85
|
+
// Boundary adjacency: turn 5 -> [4,7) and turn 7 -> [6,9) share no source
|
|
86
|
+
// turn but read as one episode; they must still merge into [4,9).
|
|
87
|
+
const adjacent = [
|
|
88
|
+
fact("m1", 0, [source({ turnId: "5" })]),
|
|
89
|
+
fact("m2", 1, [source({ turnId: "7" })]),
|
|
90
|
+
];
|
|
91
|
+
const mergedAdjacent = planEpisodeWindows({
|
|
92
|
+
recalledFacts: adjacent,
|
|
93
|
+
maxEpisodes: 2,
|
|
94
|
+
maxTurnsPerEpisode: 8,
|
|
95
|
+
});
|
|
96
|
+
assert.equal(mergedAdjacent.length, 1);
|
|
97
|
+
assert.equal(mergedAdjacent[0]!.toTurn - mergedAdjacent[0]!.fromTurn, 5);
|
|
98
|
+
|
|
99
|
+
// One gap: turn 5 -> [4,7) and turn 8 -> [7,10) are adjacent and merge;
|
|
100
|
+
// turn 9+ creates a second window only when disjoint.
|
|
101
|
+
const disjoint = [
|
|
102
|
+
fact("m1", 0, [source({ turnId: "2" })]),
|
|
103
|
+
fact("m2", 1, [source({ turnId: "50" })]),
|
|
104
|
+
];
|
|
105
|
+
const two = planEpisodeWindows({ recalledFacts: disjoint, maxEpisodes: 2, maxTurnsPerEpisode: 8 });
|
|
106
|
+
assert.equal(two.length, 2);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("planEpisodeWindows caps merged span and keeps the best-ranked fact's turn inside", () => {
|
|
110
|
+
// Overlapping sources at turns 2/4/6/8 merge into [1,10) — span 9 with a
|
|
111
|
+
// cap of 4. The trim must keep the rank-0 fact's turn 2 inside.
|
|
112
|
+
const facts = [
|
|
113
|
+
fact("m-best", 0, [source({ turnId: "2" })]),
|
|
114
|
+
fact("m-mid", 3, [source({ turnId: "4" })]),
|
|
115
|
+
fact("m-late", 5, [source({ turnId: "6" })]),
|
|
116
|
+
fact("m-last", 6, [source({ turnId: "8" })]),
|
|
117
|
+
];
|
|
118
|
+
const windows = planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 2, maxTurnsPerEpisode: 4 });
|
|
119
|
+
assert.equal(windows.length, 1);
|
|
120
|
+
const window = windows[0]!;
|
|
121
|
+
assert.equal(window.toTurn - window.fromTurn, 4);
|
|
122
|
+
assert.ok(
|
|
123
|
+
window.fromTurn <= 2 && 2 < window.toTurn,
|
|
124
|
+
`best turn 2 must be inside [${window.fromTurn},${window.toTurn})`,
|
|
125
|
+
);
|
|
126
|
+
assert.equal(window.factRank, 0);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("planEpisodeWindows is deterministic under input shuffle", () => {
|
|
130
|
+
const facts: EpisodicFactInput[] = [
|
|
131
|
+
fact("m1", 2, [source({ sessionKey: "s-b", turnId: "30" })]),
|
|
132
|
+
fact("m2", 0, [source({ sessionKey: "s-b", turnId: "5" })]),
|
|
133
|
+
fact("m3", 0, [source({ sessionKey: "s-a", turnId: "5" })]),
|
|
134
|
+
fact("m4", 1, [source({ sessionKey: "s-a", turnId: "40" })]),
|
|
135
|
+
];
|
|
136
|
+
const baseline = planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 3, maxTurnsPerEpisode: 8 });
|
|
137
|
+
for (let shuffle = 0; shuffle < 8; shuffle += 1) {
|
|
138
|
+
const copy = [...facts];
|
|
139
|
+
for (let i = copy.length - 1; i > 0; i -= 1) {
|
|
140
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
141
|
+
[copy[i], copy[j]] = [copy[j]!, copy[i]!];
|
|
142
|
+
}
|
|
143
|
+
assert.deepEqual(
|
|
144
|
+
planEpisodeWindows({ recalledFacts: copy, maxEpisodes: 3, maxTurnsPerEpisode: 8 }),
|
|
145
|
+
baseline,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
// Ordering contract: rank asc, then sessionKey asc, then fromTurn asc.
|
|
149
|
+
assert.deepEqual(
|
|
150
|
+
baseline.map((w) => w.sessionKey),
|
|
151
|
+
["s-a", "s-b", "s-a"],
|
|
152
|
+
);
|
|
153
|
+
assert.ok(compareEpisodeWindows(baseline[0]!, baseline[1]!) < 0);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("planEpisodeWindows honors maxEpisodes by best fact rank", () => {
|
|
157
|
+
const facts = [
|
|
158
|
+
fact("m-late", 9, [source({ sessionKey: "s-late", turnId: "5" })]),
|
|
159
|
+
fact("m-early", 0, [source({ sessionKey: "s-early", turnId: "5" })]),
|
|
160
|
+
];
|
|
161
|
+
const windows = planEpisodeWindows({ recalledFacts: facts, maxEpisodes: 1, maxTurnsPerEpisode: 8 });
|
|
162
|
+
assert.equal(windows.length, 1);
|
|
163
|
+
assert.equal(windows[0]!.sessionKey, "s-early");
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test("quote fallback: facts whose turnIds all fail resolve through the locator", async () => {
|
|
167
|
+
const facts = [
|
|
168
|
+
fact("m-fallback", 0, [source({ sessionKey: "session-a", turnId: "not-numeric" })]),
|
|
169
|
+
fact("m-direct", 1, [source({ sessionKey: "session-a", turnId: "20" })]),
|
|
170
|
+
];
|
|
171
|
+
assert.deepEqual(
|
|
172
|
+
factsNeedingQuoteFallback(facts).map((f) => f.memoryId),
|
|
173
|
+
["m-fallback"],
|
|
174
|
+
);
|
|
175
|
+
const located = await planEpisodeWindowsWithFallback({
|
|
176
|
+
recalledFacts: facts,
|
|
177
|
+
maxEpisodes: 2,
|
|
178
|
+
maxTurnsPerEpisode: 8,
|
|
179
|
+
locateQuote: async (quote, sessionKey) => {
|
|
180
|
+
assert.equal(quote, "the atlas cluster stores edges");
|
|
181
|
+
assert.equal(sessionKey, "session-a");
|
|
182
|
+
return 3;
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
// The located quote (turn 3) and the direct turn-20 source are disjoint
|
|
186
|
+
// sessions of turns: two windows, fallback first (better rank).
|
|
187
|
+
assert.equal(located.length, 2);
|
|
188
|
+
assert.deepEqual(located[0], {
|
|
189
|
+
sessionKey: "session-a",
|
|
190
|
+
fromTurn: 2,
|
|
191
|
+
toTurn: 5,
|
|
192
|
+
factRank: 0,
|
|
193
|
+
memoryIds: ["m-fallback"],
|
|
194
|
+
});
|
|
195
|
+
assert.deepEqual(located[1]!.memoryIds, ["m-direct"]);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test("quote fallback: a locator miss means no episode; locator errors are swallowed", async () => {
|
|
199
|
+
const facts = [fact("m1", 0, [source({ turnId: "???" })])];
|
|
200
|
+
const missed = await planEpisodeWindowsWithFallback({
|
|
201
|
+
recalledFacts: facts,
|
|
202
|
+
maxEpisodes: 2,
|
|
203
|
+
maxTurnsPerEpisode: 8,
|
|
204
|
+
locateQuote: async () => null,
|
|
205
|
+
});
|
|
206
|
+
assert.deepEqual(missed, []);
|
|
207
|
+
const threw = await planEpisodeWindowsWithFallback({
|
|
208
|
+
recalledFacts: facts,
|
|
209
|
+
maxEpisodes: 2,
|
|
210
|
+
maxTurnsPerEpisode: 8,
|
|
211
|
+
locateQuote: async () => {
|
|
212
|
+
throw new Error("archive unavailable");
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
assert.deepEqual(threw, []);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("formatEpisodicContext renders episodes and returns null when empty", () => {
|
|
219
|
+
const formatter = new RecallResultFormatter(parseConfig({ memoryDir: "/tmp/remnic-episodic-test" }));
|
|
220
|
+
assert.equal(formatter.formatEpisodicContext([]), null);
|
|
221
|
+
const rendered = formatter.formatEpisodicContext([
|
|
222
|
+
{
|
|
223
|
+
sessionKey: "session-alpha-long",
|
|
224
|
+
fromTurn: 4,
|
|
225
|
+
toTurn: 7,
|
|
226
|
+
memoryIds: ["m1", "m2"],
|
|
227
|
+
turns: [
|
|
228
|
+
{ role: "user", content: "we chose postgres" },
|
|
229
|
+
{ role: "assistant", content: "noted" },
|
|
230
|
+
],
|
|
231
|
+
},
|
|
232
|
+
]);
|
|
233
|
+
assert.ok(rendered!.startsWith("## Source Episodes\n\n### Episode: session-… turns 4-6 (supports [m1, m2])"));
|
|
234
|
+
assert.ok(rendered!.includes("user: we chose postgres"));
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test("cleanArchivedUserMessage strips an injected memory-context preamble (shipped cleaner contract)", () => {
|
|
238
|
+
// The shared cleaner (moved verbatim from the host wiring) strips a LEADING
|
|
239
|
+
// `## Memory Context` preamble up to the next `## ` header or end of string.
|
|
240
|
+
const leadingWithHeader =
|
|
241
|
+
"## Memory Context (Remnic)\n\n- old fact\n\n## Actual Question\nWhere do we stand?";
|
|
242
|
+
assert.equal(
|
|
243
|
+
cleanArchivedUserMessage(leadingWithHeader),
|
|
244
|
+
"## Actual Question\nWhere do we stand?",
|
|
245
|
+
);
|
|
246
|
+
const wrapped =
|
|
247
|
+
"<supermemory-context>injected</supermemory-context>Real question about the atlas cluster";
|
|
248
|
+
assert.equal(
|
|
249
|
+
cleanArchivedUserMessage(wrapped),
|
|
250
|
+
"Real question about the atlas cluster",
|
|
251
|
+
);
|
|
252
|
+
// A block that is not leading stays: a user writing this title mid-message
|
|
253
|
+
// keeps it (documented behavior — anchored strip, no free-form deletion).
|
|
254
|
+
const userAuthored =
|
|
255
|
+
"Reminder:\n## Memory Context (Remnic)\nthis is my own note";
|
|
256
|
+
assert.equal(cleanArchivedUserMessage(userAuthored), userAuthored);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("cleanArchivedUserMessage preserves text before and between wrappers (round 4 regression)", () => {
|
|
260
|
+
const mixed =
|
|
261
|
+
"keep this <supermemory-context>first</supermemory-context> and this <supermemory-context k=\"v\">second</supermemory-context> end";
|
|
262
|
+
assert.equal(
|
|
263
|
+
cleanArchivedUserMessage(mixed),
|
|
264
|
+
"keep this and this end",
|
|
265
|
+
);
|
|
266
|
+
});
|