@remnic/core 9.27.0 → 9.29.0
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 +13 -10
- package/dist/access-admin-ops-surface.js +46 -41
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +13 -10
- package/dist/access-authorization-probe.js +47 -42
- package/dist/access-boundary.d.ts +13 -10
- package/dist/access-boundary.js +46 -41
- package/dist/access-cli.js +105 -96
- package/dist/access-cli.js.map +1 -1
- package/dist/access-health-types.d.ts +10 -1
- package/dist/access-http-lcm-compaction.d.ts +13 -10
- package/dist/access-http.d.ts +13 -10
- package/dist/access-http.js +56 -51
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +46 -41
- package/dist/access-lcm-surface.d.ts +13 -10
- package/dist/access-lcm-surface.js +46 -41
- package/dist/access-mcp.d.ts +13 -10
- package/dist/access-mcp.js +51 -46
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/access-memory-search-fanout.js +3 -3
- package/dist/{access-namespace-preflight-wRSZEO5V.d.ts → access-namespace-preflight-DCXBkDp0.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +46 -41
- package/dist/access-observe-write-surface.d.ts +13 -10
- package/dist/access-observe-write-surface.js +46 -41
- package/dist/access-operations-batch.js +48 -43
- package/dist/access-operations.d.ts +16 -13
- package/dist/access-operations.js +50 -45
- package/dist/access-recall-concurrency.d.ts +13 -10
- package/dist/access-recall-concurrency.js +46 -41
- package/dist/access-recall-response.d.ts +13 -10
- package/dist/access-recall-response.js +46 -41
- package/dist/access-recall-surface.d.ts +13 -10
- package/dist/access-recall-surface.js +46 -41
- package/dist/access-schema.d.ts +80 -80
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-B4-Fu9x2.d.ts → access-service-DvPW_M5j.d.ts} +12 -8
- package/dist/access-service.d.ts +13 -10
- package/dist/access-service.js +46 -41
- package/dist/access-surface-catalog.d.ts +13 -10
- package/dist/access-wearables-meetings-surface.d.ts +4 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +4 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -8
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +14 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/buffer.js +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +3 -2
- package/dist/capabilities.js +1 -1
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/{catalog-BLLxZ5L5.d.ts → catalog-BIVgftWu.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +15 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-CI26JDZA.js → chunk-2HNUMF5V.js} +6 -4
- package/dist/{chunk-CI26JDZA.js.map → chunk-2HNUMF5V.js.map} +1 -1
- package/dist/{chunk-NUWMZIYZ.js → chunk-2XC73SHY.js} +61 -43
- package/dist/chunk-2XC73SHY.js.map +1 -0
- package/dist/{chunk-RDQGLJRR.js → chunk-2XRE6FLM.js} +2 -1
- package/dist/{chunk-RDQGLJRR.js.map → chunk-2XRE6FLM.js.map} +1 -1
- package/dist/{chunk-2H7OEVPO.js → chunk-3GD2HFR6.js} +2 -2
- package/dist/{chunk-4TFIRMTE.js → chunk-4A6YGWQN.js} +2 -2
- package/dist/{chunk-JDOJZTFF.js → chunk-4PBVXX7L.js} +2 -2
- package/dist/{chunk-IKMAO55B.js → chunk-55MDBZLC.js} +2 -2
- package/dist/{chunk-VDX2J7OX.js → chunk-5W7CTZ2E.js} +4 -4
- package/dist/{chunk-B7GROTXD.js → chunk-6LKEUCEM.js} +2 -2
- package/dist/{chunk-2AJ72VVS.js → chunk-7BZOBA5J.js} +3 -3
- package/dist/{chunk-44DUJETW.js → chunk-7HXCF4RE.js} +2 -2
- package/dist/{chunk-X3SQYAPP.js → chunk-ACXPX4AG.js} +2 -2
- package/dist/{chunk-AJ7QCSIS.js → chunk-ALSGMEJR.js} +5 -5
- package/dist/{chunk-JGUXPJUQ.js → chunk-AS7YMSL6.js} +2 -2
- package/dist/{chunk-77CNV7DY.js → chunk-BLAKS3CP.js} +4 -4
- package/dist/{chunk-5BRT4Z2I.js → chunk-CMRQ34J5.js} +2 -2
- package/dist/{chunk-HEXSNYJD.js → chunk-CSMCNOPH.js} +8 -8
- package/dist/chunk-CVILPI77.js +432 -0
- package/dist/chunk-CVILPI77.js.map +1 -0
- package/dist/{chunk-SK3EYPKC.js → chunk-D2ANTDGO.js} +3 -3
- package/dist/{chunk-JCVQV6QX.js → chunk-D3LMYTBV.js} +7 -7
- package/dist/{chunk-GJJBPI6I.js → chunk-DRBXHRXE.js} +7 -3
- package/dist/chunk-DRBXHRXE.js.map +1 -0
- package/dist/{chunk-XY7QPJDA.js → chunk-E6EE5B67.js} +2 -2
- package/dist/{chunk-LLISELSY.js → chunk-EP5BVCRI.js} +2 -2
- package/dist/{chunk-PTN6UAUA.js → chunk-ES36HTSC.js} +4 -4
- package/dist/{chunk-WEAO45M4.js → chunk-ESBQWC3U.js} +4 -4
- package/dist/{chunk-EUSLKI4X.js → chunk-EVX44I7C.js} +5 -5
- package/dist/{chunk-CIQXI47W.js → chunk-FCDWWCLX.js} +1195 -271
- package/dist/chunk-FCDWWCLX.js.map +1 -0
- package/dist/{chunk-X6ROIHFE.js → chunk-G5R3D5UP.js} +2 -2
- package/dist/{chunk-MG6MNSP4.js → chunk-G6LBWZRF.js} +7 -7
- package/dist/{chunk-TKBDJTXG.js → chunk-GBJ4RDFR.js} +94 -20
- package/dist/chunk-GBJ4RDFR.js.map +1 -0
- package/dist/{chunk-FRVTCCGD.js → chunk-GGUBDXRR.js} +2 -2
- package/dist/{chunk-QH6CS6XJ.js → chunk-H24WNPA2.js} +2 -2
- package/dist/{chunk-V25OWXAC.js → chunk-HUHX2OCX.js} +1 -1
- package/dist/chunk-HUHX2OCX.js.map +1 -0
- package/dist/{chunk-TGQ2NTWH.js → chunk-IJ6WHMFB.js} +16 -2
- package/dist/{chunk-TGQ2NTWH.js.map → chunk-IJ6WHMFB.js.map} +1 -1
- package/dist/{chunk-EOLC6EXV.js → chunk-IMA2EWLV.js} +24 -3
- package/dist/chunk-IMA2EWLV.js.map +1 -0
- package/dist/{chunk-MQVINOJQ.js → chunk-IYZ5K7MU.js} +3 -3
- package/dist/{chunk-RPA2RX5P.js → chunk-JDZRYH2N.js} +2 -2
- package/dist/{chunk-M5EPMNS4.js → chunk-K5GB36ME.js} +2 -2
- package/dist/{chunk-UT3OQPFA.js → chunk-KUJQHXPH.js} +2 -2
- package/dist/{chunk-7RZJWZ46.js → chunk-LEPOP46W.js} +5 -5
- package/dist/{chunk-EYJSW2RV.js → chunk-NBDCZWP4.js} +4 -4
- package/dist/{chunk-XKGPIWGI.js → chunk-OFHFH655.js} +6 -6
- package/dist/{chunk-FGBJBYWP.js → chunk-OVRQLAYR.js} +3 -3
- package/dist/{chunk-BXLOS5AJ.js → chunk-OWHERGF2.js} +2 -2
- package/dist/chunk-P2BM76KT.js +528 -0
- package/dist/chunk-P2BM76KT.js.map +1 -0
- package/dist/{chunk-U3TH5Q2Q.js → chunk-P3MH72CI.js} +2 -2
- package/dist/{chunk-P2OZKKYP.js → chunk-PHWUFPCO.js} +2 -2
- package/dist/{chunk-KGTD2KZJ.js → chunk-PKRIQL3V.js} +2 -2
- package/dist/{chunk-BNGPHGVZ.js → chunk-Q6VFVAKZ.js} +13 -6
- package/dist/{chunk-BNGPHGVZ.js.map → chunk-Q6VFVAKZ.js.map} +1 -1
- package/dist/{chunk-4MJZTF42.js → chunk-QAOGGNE3.js} +3 -3
- package/dist/{chunk-RGJBM7Z3.js → chunk-QMBNMPQM.js} +84 -84
- package/dist/{chunk-RGJBM7Z3.js.map → chunk-QMBNMPQM.js.map} +1 -1
- package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/chunk-RMMVQQA6.js +70 -0
- package/dist/chunk-RMMVQQA6.js.map +1 -0
- package/dist/{chunk-FCCMFVS6.js → chunk-RPSYDM6C.js} +2 -2
- package/dist/chunk-RPW2NOU6.js +33 -0
- package/dist/chunk-RPW2NOU6.js.map +1 -0
- package/dist/{chunk-RYHWZ52A.js → chunk-S2BBISHU.js} +4 -4
- package/dist/{chunk-RSYJV25N.js → chunk-SG265CVF.js} +10 -10
- package/dist/{chunk-UGH6VPPO.js → chunk-SH6YO3LT.js} +3 -3
- package/dist/{chunk-2RAC4JIG.js → chunk-T3GCXULH.js} +16 -16
- package/dist/chunk-T3GCXULH.js.map +1 -0
- package/dist/{chunk-FMLKOL2Z.js → chunk-TC3VNKGX.js} +4 -4
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-BJJAX3IZ.js → chunk-UTRO5UJU.js} +2 -2
- package/dist/{chunk-DQEMWVMT.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/chunk-VNA7W7QF.js +134 -0
- package/dist/chunk-VNA7W7QF.js.map +1 -0
- package/dist/{chunk-BHLN7L7M.js → chunk-VVIW3PTA.js} +17 -17
- package/dist/chunk-WNIUPHWV.js +152 -0
- package/dist/chunk-WNIUPHWV.js.map +1 -0
- package/dist/chunk-WOCNN776.js +742 -0
- package/dist/chunk-WOCNN776.js.map +1 -0
- package/dist/{chunk-XQ4EH6DI.js → chunk-WONS4RZ2.js} +3 -3
- package/dist/chunk-WRJVB3C2.js +118 -0
- package/dist/chunk-WRJVB3C2.js.map +1 -0
- package/dist/{chunk-HORJVJ6K.js → chunk-WZ7UB7XQ.js} +42 -37
- package/dist/chunk-WZ7UB7XQ.js.map +1 -0
- package/dist/{chunk-MEBQFQ26.js → chunk-XEQ7OT7U.js} +8 -6
- package/dist/chunk-XEQ7OT7U.js.map +1 -0
- package/dist/{chunk-CSXHRAJJ.js → chunk-XOZ4ALGB.js} +3 -3
- package/dist/{chunk-XKO7BM2C.js → chunk-YGHMSDLK.js} +187 -26
- package/dist/chunk-YGHMSDLK.js.map +1 -0
- package/dist/chunk-YXZG5TVN.js +40 -0
- package/dist/chunk-YXZG5TVN.js.map +1 -0
- package/dist/{chunk-6NNNURLK.js → chunk-Z54EM5YZ.js} +4 -4
- package/dist/{chunk-YSGBD3QN.js → chunk-ZGOQTOYA.js} +3 -3
- package/dist/{chunk-4DJQYKMN.js → chunk-ZIKENA2C.js} +2 -2
- package/dist/chunk-ZIKENA2C.js.map +1 -0
- package/dist/{chunk-RNY3BO35.js → chunk-ZXAGJFHJ.js} +4 -4
- package/dist/{cli-Bz7X7dGx.d.ts → cli-CxoSOiG0.d.ts} +5 -5
- package/dist/cli.d.ts +14 -12
- package/dist/cli.js +73 -68
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +15 -13
- 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 +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +14 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +15 -13
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/contradiction/index.d.ts +3 -2
- package/dist/contradiction/index.js +6 -6
- package/dist/{contradiction-scan-HMF7CNKD.js → contradiction-scan-HYLIRMJ2.js} +3 -3
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- 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 +15 -2
- package/dist/corpus-watermark.js +27 -23
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-id-normalization.d.ts +4 -0
- package/dist/entity-id-normalization.js +10 -0
- package/dist/entity-id-normalization.js.map +1 -0
- package/dist/entity-retrieval-boundaries.d.ts +3 -0
- package/dist/entity-retrieval-boundaries.js +8 -0
- package/dist/entity-retrieval-boundaries.js.map +1 -0
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +15 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/entity-schema.js +1 -1
- package/dist/explicit-capture.d.ts +9 -8
- package/dist/explicit-capture.js +2 -2
- 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-source-grounding-helpers.d.ts +34 -0
- package/dist/extraction-source-grounding-helpers.js +62 -0
- package/dist/extraction-source-grounding-helpers.js.map +1 -0
- package/dist/extraction-source-grounding-rules.d.ts +18 -0
- package/dist/extraction-source-grounding-rules.js +12 -0
- package/dist/extraction-source-grounding-rules.js.map +1 -0
- package/dist/extraction-source-grounding.d.ts +11 -0
- package/dist/extraction-source-grounding.js +13 -0
- package/dist/extraction-source-grounding.js.map +1 -0
- package/dist/extraction.d.ts +3 -1
- package/dist/extraction.js +7 -4
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-F2QJD66E.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-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- 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 +407 -405
- package/dist/index.js +154 -145
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +2 -2
- 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-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +14 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -12
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +15 -13
- package/dist/{maintenance-DgnD2z8S.d.ts → maintenance-Cb-PjxQd.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +13 -10
- 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-mutations.d.ts +4 -0
- package/dist/memory-projection-mutations.js +15 -0
- package/dist/memory-projection-mutations.js.map +1 -0
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +3 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +24 -22
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +10 -10
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +14 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +7 -7
- package/dist/operator-doctor-corpus.d.ts +22 -3
- package/dist/operator-doctor-corpus.js +34 -24
- package/dist/operator-doctor-replica.d.ts +52 -0
- package/dist/operator-doctor-replica.js +15 -0
- package/dist/operator-doctor-replica.js.map +1 -0
- package/dist/operator-toolkit.d.ts +7 -3
- package/dist/operator-toolkit.js +37 -31
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +21 -19
- package/dist/{orchestrator-rIHmHpv1.d.ts → orchestrator-5GKqb_HL.d.ts} +7 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +105 -96
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-Bq5zU6Bp.d.ts → pipeline-3Qi1TpRo.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-3ILJkC70.d.ts → qmd-D9JqzzRX.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-state.d.ts +1 -1
- package/dist/recall-state.js +2 -2
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -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/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 +279 -0
- package/dist/replica-divergence.js +28 -0
- package/dist/replica-divergence.js.map +1 -0
- package/dist/replica-peers-config.d.ts +5 -0
- package/dist/replica-peers-config.js +13 -0
- package/dist/replica-peers-config.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +21 -2
- package/dist/resolve-auth-token.js +5 -1
- package/dist/resume-bundles.js +5 -3
- 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/schemas.d.ts +54 -54
- package/dist/{scope-profiles-D0-ff4xT.d.ts → scope-profiles-C4g6_UdP.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +9 -9
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -9
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-4Tfh7c1g.d.ts → semantic-consolidation-BrxqnzTW.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +15 -13
- package/dist/semantic-rule-promotion.js +14 -12
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +14 -12
- package/dist/{service-cTvil7D_.d.ts → service-Bi1JgxdP.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 +9 -9
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/{storage-C9ibpTme.d.ts → storage-CcH6yPk2.d.ts} +13 -19
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +15 -12
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +3 -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 +3 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-XKD7SXYY.js → tier-stats-OPTSBNRH.js} +2 -2
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-DHBxIF0s.d.ts → types-Dg0w9ADr.d.ts} +54 -4
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +14 -12
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-health-types.ts +8 -0
- package/src/access-http.test.ts +4 -0
- package/src/access-service-health.test.ts +23 -0
- package/src/access-service.ts +27 -4
- package/src/capabilities.test.ts +1 -0
- package/src/capabilities.ts +7 -7
- package/src/cli.ts +9 -7
- package/src/config.test.ts +5 -0
- package/src/config.ts +3 -2
- package/src/corpus-watermark.test.ts +21 -0
- package/src/corpus-watermark.ts +25 -3
- package/src/entity-id-normalization.ts +55 -0
- package/src/entity-retrieval-boundaries.ts +134 -0
- package/src/entity-retrieval.ts +253 -27
- package/src/entity-schema.ts +2 -1
- package/src/extraction-source-grounding-helpers.ts +603 -0
- package/src/extraction-source-grounding-rules.ts +1031 -0
- package/src/extraction-source-grounding.test.ts +2337 -0
- package/src/extraction-source-grounding.ts +50 -0
- package/src/extraction.ts +120 -15
- package/src/memory-projection-mutations.ts +132 -0
- package/src/namespaces/storage.ts +5 -3
- package/src/operator-doctor-corpus.ts +41 -0
- package/src/operator-doctor-replica.test.ts +261 -0
- package/src/operator-doctor-replica.ts +129 -0
- package/src/operator-toolkit.ts +5 -4
- package/src/orchestration/orchestrator-init.ts +2 -2
- package/src/replica-divergence.test.ts +1475 -0
- package/src/replica-divergence.ts +910 -0
- package/src/replica-peers-config.ts +250 -0
- package/src/resolve-auth-token.ts +38 -0
- package/src/storage/entity-canonical-id-migration-adapter.ts +72 -0
- package/src/storage/entity-canonical-id-migration-runner.ts +68 -0
- package/src/storage/entity-canonical-id-migration.ts +904 -0
- package/src/storage/entity-store.ts +44 -0
- package/src/storage/memory-frontmatter-metadata.ts +17 -0
- package/src/storage/memory-migration-serialization.ts +37 -0
- package/src/storage/memory-read-store.ts +3 -2
- package/src/storage/profile-header.ts +8 -7
- package/src/storage-profile-timestamp.test.ts +68 -0
- package/src/storage.ts +68 -69
- package/src/types.ts +5 -5
- package/dist/chunk-2RAC4JIG.js.map +0 -1
- package/dist/chunk-4DJQYKMN.js.map +0 -1
- package/dist/chunk-CIQXI47W.js.map +0 -1
- package/dist/chunk-EOLC6EXV.js.map +0 -1
- package/dist/chunk-GJJBPI6I.js.map +0 -1
- package/dist/chunk-HORJVJ6K.js.map +0 -1
- package/dist/chunk-MEBQFQ26.js.map +0 -1
- package/dist/chunk-NUWMZIYZ.js.map +0 -1
- package/dist/chunk-TKBDJTXG.js.map +0 -1
- package/dist/chunk-V25OWXAC.js.map +0 -1
- package/dist/chunk-XKO7BM2C.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{chunk-2H7OEVPO.js.map → chunk-3GD2HFR6.js.map} +0 -0
- /package/dist/{chunk-4TFIRMTE.js.map → chunk-4A6YGWQN.js.map} +0 -0
- /package/dist/{chunk-JDOJZTFF.js.map → chunk-4PBVXX7L.js.map} +0 -0
- /package/dist/{chunk-IKMAO55B.js.map → chunk-55MDBZLC.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-5W7CTZ2E.js.map} +0 -0
- /package/dist/{chunk-B7GROTXD.js.map → chunk-6LKEUCEM.js.map} +0 -0
- /package/dist/{chunk-2AJ72VVS.js.map → chunk-7BZOBA5J.js.map} +0 -0
- /package/dist/{chunk-44DUJETW.js.map → chunk-7HXCF4RE.js.map} +0 -0
- /package/dist/{chunk-X3SQYAPP.js.map → chunk-ACXPX4AG.js.map} +0 -0
- /package/dist/{chunk-AJ7QCSIS.js.map → chunk-ALSGMEJR.js.map} +0 -0
- /package/dist/{chunk-JGUXPJUQ.js.map → chunk-AS7YMSL6.js.map} +0 -0
- /package/dist/{chunk-77CNV7DY.js.map → chunk-BLAKS3CP.js.map} +0 -0
- /package/dist/{chunk-5BRT4Z2I.js.map → chunk-CMRQ34J5.js.map} +0 -0
- /package/dist/{chunk-HEXSNYJD.js.map → chunk-CSMCNOPH.js.map} +0 -0
- /package/dist/{chunk-SK3EYPKC.js.map → chunk-D2ANTDGO.js.map} +0 -0
- /package/dist/{chunk-JCVQV6QX.js.map → chunk-D3LMYTBV.js.map} +0 -0
- /package/dist/{chunk-XY7QPJDA.js.map → chunk-E6EE5B67.js.map} +0 -0
- /package/dist/{chunk-LLISELSY.js.map → chunk-EP5BVCRI.js.map} +0 -0
- /package/dist/{chunk-PTN6UAUA.js.map → chunk-ES36HTSC.js.map} +0 -0
- /package/dist/{chunk-WEAO45M4.js.map → chunk-ESBQWC3U.js.map} +0 -0
- /package/dist/{chunk-EUSLKI4X.js.map → chunk-EVX44I7C.js.map} +0 -0
- /package/dist/{chunk-X6ROIHFE.js.map → chunk-G5R3D5UP.js.map} +0 -0
- /package/dist/{chunk-MG6MNSP4.js.map → chunk-G6LBWZRF.js.map} +0 -0
- /package/dist/{chunk-FRVTCCGD.js.map → chunk-GGUBDXRR.js.map} +0 -0
- /package/dist/{chunk-QH6CS6XJ.js.map → chunk-H24WNPA2.js.map} +0 -0
- /package/dist/{chunk-MQVINOJQ.js.map → chunk-IYZ5K7MU.js.map} +0 -0
- /package/dist/{chunk-RPA2RX5P.js.map → chunk-JDZRYH2N.js.map} +0 -0
- /package/dist/{chunk-M5EPMNS4.js.map → chunk-K5GB36ME.js.map} +0 -0
- /package/dist/{chunk-UT3OQPFA.js.map → chunk-KUJQHXPH.js.map} +0 -0
- /package/dist/{chunk-7RZJWZ46.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-EYJSW2RV.js.map → chunk-NBDCZWP4.js.map} +0 -0
- /package/dist/{chunk-XKGPIWGI.js.map → chunk-OFHFH655.js.map} +0 -0
- /package/dist/{chunk-FGBJBYWP.js.map → chunk-OVRQLAYR.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-U3TH5Q2Q.js.map → chunk-P3MH72CI.js.map} +0 -0
- /package/dist/{chunk-P2OZKKYP.js.map → chunk-PHWUFPCO.js.map} +0 -0
- /package/dist/{chunk-KGTD2KZJ.js.map → chunk-PKRIQL3V.js.map} +0 -0
- /package/dist/{chunk-4MJZTF42.js.map → chunk-QAOGGNE3.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-FCCMFVS6.js.map → chunk-RPSYDM6C.js.map} +0 -0
- /package/dist/{chunk-RYHWZ52A.js.map → chunk-S2BBISHU.js.map} +0 -0
- /package/dist/{chunk-RSYJV25N.js.map → chunk-SG265CVF.js.map} +0 -0
- /package/dist/{chunk-UGH6VPPO.js.map → chunk-SH6YO3LT.js.map} +0 -0
- /package/dist/{chunk-FMLKOL2Z.js.map → chunk-TC3VNKGX.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-BJJAX3IZ.js.map → chunk-UTRO5UJU.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-BHLN7L7M.js.map → chunk-VVIW3PTA.js.map} +0 -0
- /package/dist/{chunk-XQ4EH6DI.js.map → chunk-WONS4RZ2.js.map} +0 -0
- /package/dist/{chunk-CSXHRAJJ.js.map → chunk-XOZ4ALGB.js.map} +0 -0
- /package/dist/{chunk-6NNNURLK.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-YSGBD3QN.js.map → chunk-ZGOQTOYA.js.map} +0 -0
- /package/dist/{chunk-RNY3BO35.js.map → chunk-ZXAGJFHJ.js.map} +0 -0
- /package/dist/{contradiction-scan-HMF7CNKD.js.map → contradiction-scan-HYLIRMJ2.js.map} +0 -0
- /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-F2QJD66E.js.map} +0 -0
- /package/dist/{tier-stats-XKD7SXYY.js.map → tier-stats-OPTSBNRH.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StorageManager
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FCDWWCLX.js";
|
|
4
4
|
import {
|
|
5
5
|
namespaceIdentityToken,
|
|
6
6
|
normalizeNamespaceIdentity
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
resolveNamespaceCapabilities,
|
|
20
20
|
resolveRecallAuxiliaryCapabilities
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2XRE6FLM.js";
|
|
22
22
|
import {
|
|
23
23
|
ALL_CATEGORY_DIRS
|
|
24
24
|
} from "./chunk-VS2IYZRU.js";
|
|
@@ -176,6 +176,7 @@ var NamespaceStorageRouter = class {
|
|
|
176
176
|
root = await this.defaultNamespaceRoot();
|
|
177
177
|
const cached = this.cache.get(ns);
|
|
178
178
|
if (cached && cached.dir === root) {
|
|
179
|
+
await this.applySecureStoreConfig(cached);
|
|
179
180
|
this.notifyResolved(ns, root);
|
|
180
181
|
return cached;
|
|
181
182
|
}
|
|
@@ -183,6 +184,7 @@ var NamespaceStorageRouter = class {
|
|
|
183
184
|
const cached = this.cache.get(ns);
|
|
184
185
|
root = await this.namespaceRoot(ns);
|
|
185
186
|
if (cached && cached.dir === root) {
|
|
187
|
+
await this.applySecureStoreConfig(cached);
|
|
186
188
|
this.notifyResolved(ns, root);
|
|
187
189
|
return cached;
|
|
188
190
|
}
|
|
@@ -202,7 +204,7 @@ var NamespaceStorageRouter = class {
|
|
|
202
204
|
sm.citationTemplate = this.config.inlineSourceAttributionFormat;
|
|
203
205
|
this.bindCatalogWriteHook(sm, ns);
|
|
204
206
|
this.applyTombstonesConfig(sm, ns);
|
|
205
|
-
this.applySecureStoreConfig(sm);
|
|
207
|
+
await this.applySecureStoreConfig(sm);
|
|
206
208
|
this.cache.set(ns, sm);
|
|
207
209
|
this.onStorageCreated?.(sm, ns);
|
|
208
210
|
this.notifyResolved(ns, root);
|
|
@@ -285,12 +287,12 @@ var NamespaceStorageRouter = class {
|
|
|
285
287
|
* root keyring id — exactly the id the orchestrator and `secure-store unlock`
|
|
286
288
|
* register under. No-op when secure-store is disabled.
|
|
287
289
|
*/
|
|
288
|
-
applySecureStoreConfig(sm) {
|
|
290
|
+
async applySecureStoreConfig(sm) {
|
|
289
291
|
if (!resolveRecallAuxiliaryCapabilities(this.config).secureStore) return;
|
|
290
292
|
sm.setSecureStoreRequired(true);
|
|
291
293
|
const existingKey = keyring_exports.getKey(secureStoreDir(this.config.memoryDir));
|
|
292
294
|
if (existingKey) {
|
|
293
|
-
sm.
|
|
295
|
+
await sm.setSecureStoreKeyAndWait(existingKey, this.config.secureStoreEncryptOnWrite);
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
/**
|
|
@@ -386,4 +388,4 @@ export {
|
|
|
386
388
|
resolveNamespaceStorageRoot,
|
|
387
389
|
NamespaceStorageRouter
|
|
388
390
|
};
|
|
389
|
-
//# sourceMappingURL=chunk-
|
|
391
|
+
//# sourceMappingURL=chunk-XEQ7OT7U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/namespaces/storage.ts"],"sourcesContent":["import { resolveNamespaceCapabilities, resolveRecallAuxiliaryCapabilities } from \"../capabilities.js\";\nimport path from \"node:path\";\nimport { access, lstat, readdir } from \"node:fs/promises\";\nimport { isSafeRouteNamespace } from \"../routing/engine.js\";\nimport { StorageManager } from \"../storage.js\";\nimport { keyring, secureStoreDir } from \"../secure-store/index.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport { ALL_CATEGORY_DIRS } from \"../utils/category-dir.js\";\nimport { namespaceIdentityToken, normalizeNamespaceIdentity } from \"./identity.js\";\nimport type { NamespaceCatalog } from \"./catalog.js\";\nimport { MutationSerializer } from \"../utils/serialize-mutations.js\";\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function hasStoredEntries(p: string): Promise<boolean> {\n try {\n const entry = await lstat(p);\n if (entry.isSymbolicLink()) return true;\n if (!entry.isDirectory()) return true;\n const children = await readdir(p, { withFileTypes: true });\n for (const child of children) {\n const childPath = path.join(p, child.name);\n if (child.isSymbolicLink() || child.isFile()) return true;\n if (child.isDirectory() && (await hasStoredEntries(childPath))) return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n// Build a per-namespace directory under `<memoryDir>/namespaces` and assert the\n// resolved path stays inside that base. Namespace identifiers can originate from\n// operator config (config.defaultNamespace) and request-derived routing, so this\n// containment check prevents directory traversal (CodeQL js/path-injection).\n// For safe segments this returns exactly `path.join(base, segment)`, so there is\n// no behavioral change for valid namespaces.\nfunction resolveNamespaceDir(memoryDir: string, segment: string): string {\n // Mirror isSafeRouteNamespace's separator/parent-ref rejection (without its\n // 64-char cap, so identity tokens still pass). Rejecting separators and \"..\"\n // up front keeps the value a single contained child of <memoryDir>/namespaces.\n if (\n segment.length === 0 ||\n segment.includes(\"/\") ||\n segment.includes(\"\\\\\") ||\n segment.includes(\"..\") ||\n path.isAbsolute(segment)\n ) {\n throw new Error(`unsafe namespace path segment: ${segment}`);\n }\n return path.join(memoryDir, \"namespaces\", segment);\n}\n\nconst LEGACY_NAMESPACE_CONTENT_CHILDREN = [\n ...ALL_CATEGORY_DIRS,\n \"entities\",\n \"artifacts\",\n \"identity\",\n \"config\",\n \"summaries\",\n \"profile.md\",\n] as const;\n\nconst LEGACY_NAMESPACE_RUNTIME_CHILDREN = [\"state\"] as const;\n\nasync function hasAnyLegacyData(\n rootDir: string,\n options: { includeRuntimeState?: boolean } = {},\n): Promise<boolean> {\n const children = options.includeRuntimeState === true\n ? [...LEGACY_NAMESPACE_CONTENT_CHILDREN, ...LEGACY_NAMESPACE_RUNTIME_CHILDREN]\n : LEGACY_NAMESPACE_CONTENT_CHILDREN;\n for (const child of children) {\n if (await hasStoredEntries(path.join(rootDir, child))) return true;\n }\n return false;\n}\n\nasync function hasAnyNamespaceStorageMarker(\n rootDir: string,\n options: { includeRuntimeState?: boolean } = {},\n): Promise<boolean> {\n const children = options.includeRuntimeState === true\n ? [...LEGACY_NAMESPACE_CONTENT_CHILDREN, ...LEGACY_NAMESPACE_RUNTIME_CHILDREN]\n : LEGACY_NAMESPACE_CONTENT_CHILDREN;\n for (const child of children) {\n if (await exists(path.join(rootDir, child))) return true;\n }\n return false;\n}\n\n/**\n * Storage routing for namespaces.\n *\n * Compatibility note:\n * - When namespaces are enabled, existing raw namespace roots are preserved.\n * New namespace roots use tokenized names under `memoryDir/namespaces/<token>`.\n * - The default namespace continues to use the legacy `memoryDir` root unless the caller\n * has created `memoryDir/namespaces/<defaultNamespace>` (in which case we use that).\n *\n * This avoids surprising \"lost memories\" when an install flips namespaces on without\n * migrating existing data.\n */\n/**\n * Optional hooks for the storage router. `onResolve` fires whenever a namespace's\n * storage is resolved/created, so a downstream consumer (e.g. the namespace\n * catalog, issue #1499) can register the namespace. The hook MUST NOT throw into\n * the router; the router invokes it defensively and a hook failure never affects\n * storage resolution.\n *\n * The hook MAY return (or resolve to) a boolean indicating whether the\n * registration actually PERSISTED (round 6, codex P2 — NEFoX). When it resolves\n * to `false` (a dropped/no-op registration), the router does NOT mark the\n * (namespace, storageDir) pair as notified, so the next resolve RETRIES it\n * instead of suppressing it forever. A `void`/`undefined` result is treated as\n * success (legacy hooks).\n */\nexport interface NamespaceStorageRouterHooks {\n onResolve?: (\n namespace: string,\n storageDir: string,\n ) => void | boolean | Promise<void | boolean>;\n}\n\n/**\n * Resolve the runtime storage root for the configured DEFAULT namespace.\n *\n * Shared between the live router (`NamespaceStorageRouter.defaultNamespaceRoot`)\n * and the rebuildable catalog (`NamespaceCatalog.rebuildFromDisk`) so the two\n * can never diverge (CLAUDE.md rule #22/#42 — read & write paths resolve through\n * the same logic). The contract is: while legacy memory data still lives\n * directly under `memoryDir`, the default root stays `memoryDir`; only once the\n * legacy root is empty and a `namespaces/<default|token>` dir holds data does\n * the default migrate into that tokenized/legacy-named dir.\n */\nexport async function resolveDefaultNamespaceRoot(config: PluginConfig): Promise<string> {\n if (!resolveNamespaceCapabilities(config).namespaces) {\n return config.memoryDir;\n }\n\n // Build the legacy default root from the NORMALIZED (trimmed) name so a\n // whitespace-padded `defaultNamespace` still finds the live `namespaces/default`\n // root (NIabe). `storageFor()` classifies the trimmed value as the default, and\n // the on-disk legacy dir is created under the trimmed name; using the raw spaced\n // name here would look for `namespaces/<spaced>` and miss the real root, falling\n // back to memoryDir/tokenized. `namespaceIdentityToken` already normalizes\n // internally, so the tokenized path is unaffected.\n const defaultIdentity = normalizeNamespaceIdentity(config.defaultNamespace);\n const legacyNsDir = resolveNamespaceDir(config.memoryDir, defaultIdentity);\n const tokenizedNsDir = resolveNamespaceDir(\n config.memoryDir,\n namespaceIdentityToken(config.defaultNamespace),\n );\n const tokenizedHasData =\n (await exists(tokenizedNsDir)) &&\n (await hasAnyNamespaceStorageMarker(tokenizedNsDir, { includeRuntimeState: true }));\n const nsDir = tokenizedHasData\n ? tokenizedNsDir\n : (await exists(legacyNsDir))\n ? legacyNsDir\n : tokenizedNsDir;\n return (await exists(nsDir)) && !(await hasAnyLegacyData(config.memoryDir))\n ? nsDir\n : config.memoryDir;\n}\n\n/**\n * Resolve the runtime storage root for ANY namespace exactly as the live router\n * would (`NamespaceStorageRouter.namespaceRoot`). Shared so the rebuildable\n * catalog records the SAME on-disk root the router routes to — a recall/read\n * touch must not guess `namespaces/<token>` when the router actually serves a\n * legacy raw-name dir or a migrated default root (CLAUDE.md rule #22/#42; round\n * 4, cursor Medium). The default namespace delegates to `resolveDefaultNamespaceRoot`;\n * every other namespace prefers the tokenized root when it has a storage marker,\n * else a legacy raw-name dir when present, else the tokenized root.\n */\nexport async function resolveNamespaceStorageRoot(\n config: PluginConfig,\n namespace: string,\n): Promise<string> {\n if (!resolveNamespaceCapabilities(config).namespaces) return config.memoryDir;\n // Compare on NORMALIZED identity so a whitespace-padded configured default name\n // still routes to the default root rather than a tokenized non-default dir\n // (NH-FH). The catalog keys records by the same normalized identity.\n if (normalizeNamespaceIdentity(namespace) === normalizeNamespaceIdentity(config.defaultNamespace)) {\n return resolveDefaultNamespaceRoot(config);\n }\n const legacyRoot = resolveNamespaceDir(config.memoryDir, namespace);\n const tokenizedRoot = resolveNamespaceDir(config.memoryDir, namespaceIdentityToken(namespace));\n if (\n (await exists(tokenizedRoot)) &&\n (await hasAnyNamespaceStorageMarker(tokenizedRoot, { includeRuntimeState: true }))\n ) {\n return tokenizedRoot;\n }\n return (await exists(legacyRoot)) ? legacyRoot : tokenizedRoot;\n}\n\nexport class NamespaceStorageRouter {\n private readonly cache = new Map<string, StorageManager>();\n private defaultNsRootResolved: string | null = null;\n // Dedup the resolve hook (round 6, cursor Medium — NCNL2). Recall/extraction\n // call `storageFor` repeatedly; firing `onResolve` (→ catalog loadCompacted +\n // append) on every cache hit grows `namespaces.jsonl` without bound between\n // rebuilds. We fire the hook only when the (namespace, storageDir) pair is new\n // or its dir changed, so a steady-state cache hit is a no-op for the catalog.\n private readonly notifiedResolved = new Map<string, string>();\n // Instance-scoped serializer for the resolve hook (issue #1524 adoption).\n // Replaces the bespoke `inFlightResolved` marker-then-clear pattern: the\n // serializer's per-key chain strictly orders concurrent notifications for the\n // SAME namespace, and the task re-checks `notifiedResolved` once it runs, so a\n // burst of cache hits before the first hook settles collapses to a single\n // hook invocation (the once-per-namespace intent). Recovery is preserved —\n // one rejected hook never poisons subsequent notifications for that key.\n private readonly resolveSerializer = new MutationSerializer();\n // (namespace, storageDir) pairs whose resolve hook is currently pending. Set SYNCHRONOUSLY in\n // notifyResolved (before queueing) so a burst of concurrent storageFor()\n // cache hits collapses onto the one in-flight hook instead of each enqueuing\n // its own task. Cleared when the queued hook settles. Without this, a dropped\n // hook (returns false on a rebuild-lock timeout) leaves notifiedResolved\n // unset, so every queued sibling task would re-run the hook — N serial lock\n // waits (cursor Medium 06f58a7c, codex P2).\n private readonly inFlightResolveHooks = new Set<string>();\n // Tracks every in-flight resolve-hook promise so callers can deterministically\n // await the fire-and-forget registrations that `storageFor()` kicks off (see\n // `whenResolveHooksSettled`). Entries are removed as each hook settles, so the\n // set holds at most one promise per concurrently-resolving namespace.\n private readonly pendingResolveHooks = new Set<Promise<unknown>>();\n // Pending post-write catalog touch promises (#1522). Like pendingResolveHooks,\n // lets tests await fire-and-forget write touches deterministically.\n private readonly pendingWriteTouches = new Set<Promise<unknown>>();\n\n // Normalized (trimmed) default namespace identity (NH-FH). `storageFor`\n // normalizes its input, so default-namespace branches must compare against the\n // normalized config default too — otherwise a whitespace-padded configured\n // default name routes the default namespace to a tokenized non-default root.\n private readonly defaultNamespaceIdentity: string;\n\n /** #2019: hook fired when a new namespace storage is created via storageFor. */\n onStorageCreated?: (storage: StorageManager, namespace: string) => void;\n\n constructor(\n private readonly config: PluginConfig,\n private readonly hooks: NamespaceStorageRouterHooks = {},\n /** Catalog reference for post-write/read touches (issue #1522 chokepoint). */\n private readonly catalog?: NamespaceCatalog,\n ) {\n this.defaultNamespaceIdentity = normalizeNamespaceIdentity(config.defaultNamespace);\n }\n\n private async defaultNamespaceRoot(): Promise<string> {\n this.defaultNsRootResolved = await resolveDefaultNamespaceRoot(this.config);\n return this.defaultNsRootResolved;\n }\n\n private async namespaceRoot(namespace: string): Promise<string> {\n // NOTE: only used after defaultNamespaceRoot() resolution.\n if (!resolveNamespaceCapabilities(this.config).namespaces) return this.config.memoryDir;\n if (normalizeNamespaceIdentity(namespace) === this.defaultNamespaceIdentity) {\n return this.defaultNsRootResolved ?? this.config.memoryDir;\n }\n return resolveNamespaceStorageRoot(this.config, namespace);\n }\n\n async storageFor(namespace: string): Promise<StorageManager> {\n const ns = normalizeNamespaceIdentity(namespace || this.config.defaultNamespace);\n if (ns !== this.defaultNamespaceIdentity && !isSafeRouteNamespace(ns)) {\n throw new Error(`unsafe namespace: ${ns}`);\n }\n // Even when the default namespace is exempt from the check above, every\n // on-disk path is built through resolveNamespaceDir(), which rejects\n // traversal segments — so an unsafe configured default still cannot escape\n // <memoryDir>/namespaces (CodeQL js/path-injection).\n\n let root: string;\n if (ns === this.defaultNamespaceIdentity) {\n root = await this.defaultNamespaceRoot();\n const cached = this.cache.get(ns);\n if (cached && cached.dir === root) {\n await this.applySecureStoreConfig(cached);\n this.notifyResolved(ns, root);\n return cached;\n }\n } else {\n const cached = this.cache.get(ns);\n root = await this.namespaceRoot(ns);\n if (cached && cached.dir === root) {\n await this.applySecureStoreConfig(cached);\n this.notifyResolved(ns, root);\n return cached;\n }\n }\n\n // Pass the hot-memories cache gate explicitly (issue #1902, Codex P2): a\n // per-namespace child root is never registered in the per-dir default map,\n // so without this it would fall back to the process-wide default and ignore\n // THIS daemon's hotMemoriesCacheEnabled config. Threading it from config\n // keeps every namespace storage aligned with its owning orchestrator.\n const sm = new StorageManager(\n root,\n this.config.entitySchemas,\n this.config.hotMemoriesCacheEnabled,\n );\n // Register this child root's gate AND TTL in the per-dir maps (issue #1902,\n // Codex P2). The constructor override above fixes the child's own gate, but\n // its TTL is resolved via the per-dir map (hotCacheTtlMs); an unregistered\n // child root would fall back to the last process-wide TTL and could inherit\n // another daemon's value. Registering keyed by root keeps both per-dir.\n StorageManager.setHotMemoriesCacheDefault(\n root,\n this.config.hotMemoriesCacheEnabled,\n this.config.hotMemoriesCacheTtlMs,\n );\n const { scopedCacheInvalidationEnabled } = this.config;\n StorageManager.setScopedCacheInvalidationDefault(root, scopedCacheInvalidationEnabled);\n // Propagate the inline-attribution template so that router-created storages\n // (used by extraction and shared-promotion paths) strip citations consistently,\n // matching the behaviour of the primary this.storage instance in the orchestrator.\n sm.citationTemplate = this.config.inlineSourceAttributionFormat;\n // #1522: install the post-write catalog touch at the chokepoint — every\n // successful write on this StorageManager records the namespace touch.\n this.bindCatalogWriteHook(sm, ns);\n // #1579: apply the tombstone non-resurrection config so every namespace\n // storage enforces the invariant at its own writeMemory chokepoint.\n this.applyTombstonesConfig(sm, ns);\n // #2033: install the secure-store context on router-created stores. The\n // orchestrator keys ONLY its primary default-namespace storage; without\n // this, a store resolved through the router reads isSecureStoreUnlocked()\n // === false even after the operator unlocked the keyring, so secure-store\n // recovery paths (e.g. the CLI lifecycle-ledger rebuild) refuse an encrypted\n // ledger they could actually rewrite, and namespace writes could silently\n // fall back to plaintext. Mirror the orchestrator's setup exactly.\n await this.applySecureStoreConfig(sm);\n this.cache.set(ns, sm);\n // #2019: let the orchestrator wire write-triggered prioritized embedding on\n // every router-created namespace storage, not just the primary default store.\n this.onStorageCreated?.(sm, ns);\n this.notifyResolved(ns, root);\n return sm;\n }\n\n /**\n * Fire the resolve hook defensively. A hook failure (e.g. a catalog write\n * error) MUST NOT crash storage resolution — see CLAUDE.md gotcha #13.\n *\n * Issue #1524 adoption: hook invocations for the SAME namespace are now\n * strictly ordered through the shared `MutationSerializer` rather than the\n * bespoke `inFlightResolved` marker-then-clear pattern. The serializer\n * guarantees one in-flight hook per namespace; a concurrent burst of\n * `storageFor()` cache hits collapses to a single hook invocation because\n * each queued task re-checks `notifiedResolved` before invoking the hook. A\n * dropped (`false`) or rejected hook leaves `notifiedResolved` unset so the\n * next `storageFor()` retries — the serializer recovers from the rejection,\n * so a failed hook never poisons later notifications.\n */\n private notifyResolved(namespace: string, storageDir: string): void {\n const hook = this.hooks.onResolve;\n if (!hook) return;\n // Permanent dedup: skip once we've SUCCESSFULLY notified this exact\n // (namespace, storageDir). A changed dir (rare: migration/realignment)\n // still re-fires once. The mark is set ONLY AFTER the hook succeeds, so a\n // dropped registration (e.g. rebuild-lock timeout) is RETRIED on the next\n // cache hit instead of being suppressed forever (round 6, cursor Medium —\n // ND3EJ).\n if (this.notifiedResolved.get(namespace) === storageDir) return;\n // In-flight dedup (cursor Medium 06f58a7c, codex P2): if a hook for THIS\n // namespace is already pending, collapse this call onto it instead of\n // enqueueing another task. The serializer strictly orders queued tasks, but\n // ordering alone is not enough — when the first hook returns `false`\n // (dropped touch, e.g. rebuild-lock timeout), `notifiedResolved` stays\n // unset, so each queued sibling task would pass its re-check and re-run the\n // hook. With the real catalog hook each retry can spend the full lock wait,\n // so N cache hits during a rebuild leave N serial background lock attempts.\n // Collapsing here means at most ONE hook runs per in-flight registration;\n // its result (set `notifiedResolved` on success, leave unset on drop)\n // decides whether a LATER `storageFor()` retries — collapsing loses\n // nothing because the drop is already retried on the next cache hit.\n // Keyed by the composite (namespace, storageDir) so a CHANGED dir\n // (migration/realignment) for the same namespace still gets its own hook —\n // it is NOT collapsed onto the old dir's pending registration (cursor\n // Medium, codex P2).\n const inFlightKey = namespace + \"\\u0000\" + storageDir;\n if (this.inFlightResolveHooks.has(inFlightKey)) return;\n this.inFlightResolveHooks.add(inFlightKey);\n // Queue through the serializer. Concurrent calls for the same namespace\n // strictly order here; the 2nd call's task runs only after the 1st's hook\n // settles, by which point `notifiedResolved` is either set (no-op) or still\n // unset (retry). The returned promise is tracked for\n // `whenResolveHooksSettled()`. Rejections from the task body are caught so\n // they never reach the caller (best-effort hook contract); the serializer's\n // recovered tail still lets subsequent notifications run.\n const task = async (): Promise<void> => {\n // Re-check after queueing: a prior task in this same chain may have just\n // marked the pair as notified.\n if (this.notifiedResolved.get(namespace) === storageDir) return;\n try {\n // Hook may be sync or async; Promise.resolve normalizes both. A result\n // of `false` means the registration was dropped/no-op (e.g. rebuild-lock\n // timeout) — leave notifiedResolved UNSET so the next storageFor retries\n // (round 6, codex P2 — NEFoX). `void`/`undefined` is success for legacy\n // hooks. A rejection leaves notifiedResolved unset for the same reason.\n const persisted = await Promise.resolve(hook(namespace, storageDir));\n if (persisted !== false) {\n this.notifiedResolved.set(namespace, storageDir);\n }\n } catch {\n // Best-effort: a hook failure MUST NOT crash storage resolution. Leave\n // notifiedResolved unset so a later storageFor retries the registration.\n }\n };\n const queued = this.resolveSerializer.serialize(namespace, task);\n this.pendingResolveHooks.add(queued);\n // Clear the in-flight marker when the hook settles so a subsequent\n // storageFor() can retry after a drop, or short-circuit via notifiedResolved\n // after a success.\n const cleanup = (): void => {\n this.inFlightResolveHooks.delete(inFlightKey);\n this.pendingResolveHooks.delete(queued);\n };\n void queued.then(cleanup, cleanup);\n }\n\n /**\n * Install the post-write catalog touch hook on an externally-constructed\n * StorageManager (issue #1522). Used by the orchestrator for the legacy\n * default-namespace storage (`this.storage`) that bypasses the router.\n */\n bindCatalogWriteHook(sm: StorageManager, namespace: string): void {\n // Issue #1903: pure state-file writes only touch the catalog when explicitly\n // opted in. Router-created storages (storageFor) and the legacy default\n // storage both flow through here, so this is the single wiring point.\n sm.touchStateWrites = this.config.namespacesCatalogTouchStateWrites === true;\n sm.onCatalogWrite = () => this.touchCatalogWrite(namespace, sm.dir);\n }\n\n /**\n * Install the tombstone config on an externally-constructed StorageManager\n * (issue #1579). Mirrors `bindCatalogWriteHook` — used for the legacy\n * default-namespace storage that bypasses the router. Router-created\n * storages are wired inline in `storageFor()` via `applyTombstonesConfig`.\n */\n bindTombstonesConfig(\n sm: StorageManager,\n namespace: string,\n config: { enabled: boolean; semanticMatch: boolean; semanticThreshold: number },\n ): void {\n this.tombstonesGlobalConfig = { ...config };\n sm.setTombstonesConfig({ ...config, namespace });\n }\n\n private tombstonesGlobalConfig: {\n enabled: boolean;\n semanticMatch: boolean;\n semanticThreshold: number;\n } = { enabled: false, semanticMatch: false, semanticThreshold: 0.9 };\n\n /**\n * Apply the tombstone config to a router-created StorageManager. Called\n * inline in `storageFor()` so every namespace storage enforces the\n * non-resurrection invariant, namespace-scoped (rule 42).\n */\n private applyTombstonesConfig(sm: StorageManager, namespace: string): void {\n sm.setTombstonesConfig({ ...this.tombstonesGlobalConfig, namespace });\n }\n\n /**\n * Install the at-rest secure-store context on a router-created StorageManager\n * (#2033). Mirrors the orchestrator's primary-storage setup: mark the store\n * required so a locked store throws instead of silently writing plaintext, and\n * install the master key when the process-local keyring already holds it (the\n * operator unlocked). The secure store is one key per memory ROOT (single\n * header + per-file path-bound AAD), so every namespace store keys off the\n * root keyring id — exactly the id the orchestrator and `secure-store unlock`\n * register under. No-op when secure-store is disabled.\n */\n private async applySecureStoreConfig(sm: StorageManager): Promise<void> {\n if (!resolveRecallAuxiliaryCapabilities(this.config).secureStore) return;\n sm.setSecureStoreRequired(true);\n const existingKey = keyring.getKey(secureStoreDir(this.config.memoryDir));\n if (existingKey) {\n await sm.setSecureStoreKeyAndWait(existingKey, this.config.secureStoreEncryptOnWrite);\n }\n }\n\n /**\n * Post-write catalog touch (issue #1522 chokepoint). Called by every\n * StorageManager's post-write hook AFTER a successful write. Best-effort\n * and failure-tolerant — a catalog error MUST NOT affect the primary write\n * (gotcha #13, rule #40). Fire-and-forget by design.\n */\n private touchCatalogWrite(namespace: string, storageDir: string): void {\n if (!this.catalog) return;\n const touch = this.catalog\n .markWrite(namespace, { discoveredBy: \"write\", storageDir })\n .catch(() => undefined);\n this.pendingWriteTouches.add(touch);\n void touch.then(\n () => { this.pendingWriteTouches.delete(touch); },\n () => { this.pendingWriteTouches.delete(touch); },\n );\n }\n\n /**\n * Record a namespace read in the catalog (issue #1522 chokepoint move).\n * Best-effort and failure-tolerant. Used by recall paths so the read touch\n * lives in the storage layer, not at the caller.\n */\n recordRead(namespace: string, storageDir?: string): void {\n if (!this.catalog) return;\n const ns = normalizeNamespaceIdentity(namespace || this.config.defaultNamespace);\n void this.catalog\n .markRead(ns, { discoveredBy: \"read\", storageDir })\n .catch(() => undefined);\n }\n /**\n * Record a namespace write touch in the catalog (issue #1522). Best-effort\n * and failure-tolerant. Used by consolidation/cleanup passes that may mutate\n * the store via delete-only paths (e.g. entity-file merges, TTL cleanup) so\n * the namespace's lastWriteAt stays fresh even when no explicit write went\n * through the storage chokepoint. This is NOT a substitute for the chokepoint\n * — it's a belt-and-suspenders for paths the chokepoint doesn't cover.\n */\n recordWrite(namespace: string, storageDir?: string): void {\n if (!this.catalog) return;\n const ns = normalizeNamespaceIdentity(namespace || this.config.defaultNamespace);\n const touch = this.catalog\n .markWrite(ns, { discoveredBy: \"write\", storageDir })\n .catch(() => undefined);\n this.pendingWriteTouches.add(touch);\n void touch.then(\n () => { this.pendingWriteTouches.delete(touch); },\n () => { this.pendingWriteTouches.delete(touch); },\n );\n }\n\n /**\n * Resolve once every in-flight post-write catalog touch has settled (#1522).\n * Mirrors `whenResolveHooksSettled()`: the StorageManager's post-write hook\n * fires the catalog touch fire-and-forget, so tests asserting lastWriteAt\n * moved should await this instead of racing a timer.\n */\n async whenWriteTouchesSettled(): Promise<void> {\n // Flush any coalesced (buffered) touches first so their appends join the\n // pending set below — otherwise this could resolve while a buffered touch's\n // lastWriteAt is still unwritten on disk (#1903, Cursor). No-op when\n // coalescing is disabled (window 0) or the catalog is inert.\n await this.catalog?.flushPendingTouches().catch(() => undefined);\n while (this.pendingWriteTouches.size > 0) {\n await Promise.allSettled([...this.pendingWriteTouches]);\n }\n }\n\n /**\n * Resolve once every in-flight `onResolve` registration has settled.\n *\n * `storageFor()` fires the resolve hook fire-and-forget, so its catalog side\n * effect (e.g. `registerResolved(...)`) is not observable the moment\n * `storageFor()` returns. Callers that must act on that side effect — notably\n * tests asserting the catalog was updated — should await this instead of\n * racing a timer. Resolves immediately when no hook is registered or nothing\n * is in flight. The loop re-checks because a settling hook could, in\n * principle, trigger a follow-on resolution.\n */\n async whenResolveHooksSettled(): Promise<void> {\n while (this.pendingResolveHooks.size > 0) {\n await Promise.allSettled([...this.pendingResolveHooks]);\n }\n }\n\n /**\n * #2019: iterate the currently cached router storages with their namespace so\n * callers can wire hooks on stores resolved before the hook was installed.\n */\n forEachCachedStorage(fn: (storage: StorageManager, namespace: string) => void): void {\n for (const [namespace, storage] of this.cache) fn(storage, namespace);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseXrayFormat
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-K5GB36ME.js";
|
|
4
4
|
import {
|
|
5
5
|
RECALL_DISCLOSURE_LEVELS,
|
|
6
6
|
isRecallDisclosure
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HUHX2OCX.js";
|
|
8
8
|
|
|
9
9
|
// src/recall-xray-cli.ts
|
|
10
10
|
function parseXrayDisclosureFlag(value) {
|
|
@@ -50,4 +50,4 @@ export {
|
|
|
50
50
|
parseXrayBudgetFlag,
|
|
51
51
|
parseXrayCliOptions
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-XOZ4ALGB.js.map
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
containsPhrase
|
|
3
|
+
} from "./chunk-VNA7W7QF.js";
|
|
1
4
|
import {
|
|
2
5
|
collectNativeKnowledgeChunks
|
|
3
6
|
} from "./chunk-2DQ2XREU.js";
|
|
4
7
|
import {
|
|
5
|
-
compareEntityTimestamps
|
|
6
|
-
|
|
7
|
-
} from "./chunk-CIQXI47W.js";
|
|
8
|
+
compareEntityTimestamps
|
|
9
|
+
} from "./chunk-FCDWWCLX.js";
|
|
8
10
|
import {
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
normalizeEntityName
|
|
12
|
+
} from "./chunk-YXZG5TVN.js";
|
|
11
13
|
import {
|
|
12
14
|
normalizeEntityText,
|
|
13
15
|
resolveRequestedEntitySectionKeys
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ZIKENA2C.js";
|
|
17
|
+
import {
|
|
18
|
+
sanitizeMemoryContent
|
|
19
|
+
} from "./chunk-5GKPFL3S.js";
|
|
15
20
|
import {
|
|
16
21
|
resolveNamespaceCapabilities
|
|
17
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-2XRE6FLM.js";
|
|
18
23
|
|
|
19
24
|
// src/entity-retrieval.ts
|
|
20
25
|
import { createHash } from "crypto";
|
|
@@ -33,11 +38,6 @@ function tokenize(value) {
|
|
|
33
38
|
function uniqueStrings(values) {
|
|
34
39
|
return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))];
|
|
35
40
|
}
|
|
36
|
-
function containsPhrase(haystack, needle) {
|
|
37
|
-
if (!needle) return false;
|
|
38
|
-
const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
39
|
-
return new RegExp(`(^|\\b)${escaped}(\\b|$)`, "i").test(haystack);
|
|
40
|
-
}
|
|
41
41
|
function compactLine(value, maxLength = 220) {
|
|
42
42
|
const normalized = value.replace(/\s+/g, " ").trim();
|
|
43
43
|
if (normalized.length <= maxLength) return normalized;
|
|
@@ -274,6 +274,33 @@ async function readEntityIndexState(storage) {
|
|
|
274
274
|
return null;
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
+
async function readCurrentPersistedEntityIndex(storage, config, recallNamespaces, namespaceStorage) {
|
|
278
|
+
if (resolveNamespaceCapabilities(config).namespaces && namespaceStorage && recallNamespaces && recallNamespaces.length > 0) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
const index = await readEntityIndexState(storage);
|
|
282
|
+
if (!index || index.entityStatusVersion !== storage.getMemoryStatusVersion()) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return index;
|
|
286
|
+
}
|
|
287
|
+
var namespaceEntityIndexCache = /* @__PURE__ */ new Map();
|
|
288
|
+
var MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES = 32;
|
|
289
|
+
function namespaceEntityIndexCacheKey(storages, recallNamespaces) {
|
|
290
|
+
const namespaceKey = uniqueStrings(recallNamespaces).sort().join("");
|
|
291
|
+
const storageKey = storages.map((scopedStorage) => {
|
|
292
|
+
const aliases = Object.entries(scopedStorage.entityAliases).sort(([left], [right]) => left.localeCompare(right));
|
|
293
|
+
return `${path.resolve(scopedStorage.dir)}@${scopedStorage.getMemoryStatusVersion()}:${scopedStorage.getMemoryCorpusVersion()}:${scopedStorage.hotCacheKeyId()}:${JSON.stringify(aliases)}`;
|
|
294
|
+
}).sort().join("");
|
|
295
|
+
return `${namespaceKey}${storageKey}`;
|
|
296
|
+
}
|
|
297
|
+
function rememberNamespaceEntityIndex(key, index) {
|
|
298
|
+
if (namespaceEntityIndexCache.size >= MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES) {
|
|
299
|
+
const oldestKey = namespaceEntityIndexCache.keys().next().value;
|
|
300
|
+
if (typeof oldestKey === "string") namespaceEntityIndexCache.delete(oldestKey);
|
|
301
|
+
}
|
|
302
|
+
namespaceEntityIndexCache.set(key, index);
|
|
303
|
+
}
|
|
277
304
|
async function writeEntityIndexState(storage, index) {
|
|
278
305
|
const statePath = entityIndexStatePath(storage);
|
|
279
306
|
await mkdir(path.dirname(statePath), { recursive: true });
|
|
@@ -325,27 +352,40 @@ function mergeNativeChunk(entry, chunk) {
|
|
|
325
352
|
});
|
|
326
353
|
entry.aliases = uniqueStrings([...entry.aliases, ...chunk.aliases ?? []]);
|
|
327
354
|
}
|
|
328
|
-
|
|
329
|
-
|
|
355
|
+
function hasFreshNativeExplicitMention(index, nativeChunks, query) {
|
|
356
|
+
if (nativeChunks.length === 0) return false;
|
|
357
|
+
const nativeCanonicalIds = new Set(nativeChunks.map(nativePseudoCanonicalId));
|
|
358
|
+
const freshNativeIndex = {
|
|
359
|
+
...index,
|
|
360
|
+
entities: [
|
|
361
|
+
...index.entities.filter((entry) => !nativeCanonicalIds.has(entry.canonicalId)),
|
|
362
|
+
...nativeChunks.map(createPseudoNativeEntry)
|
|
363
|
+
]
|
|
364
|
+
};
|
|
365
|
+
return resolveLanguageIndependentExplicitCandidates(freshNativeIndex, query).length > 0;
|
|
366
|
+
}
|
|
367
|
+
async function buildEntityMentionIndex(storage, config, recallNamespaces, namespaceStorage, nativeChunksOverride, resolvedStorages) {
|
|
368
|
+
const storages = resolvedStorages ?? await resolveEntityIndexStorages(
|
|
330
369
|
storage,
|
|
331
370
|
config,
|
|
332
371
|
recallNamespaces,
|
|
333
372
|
namespaceStorage
|
|
334
373
|
);
|
|
335
374
|
const shouldPersistIndex = storages.length === 1 && path.resolve(storages[0].dir) === path.resolve(storage.dir);
|
|
375
|
+
const entityStatusVersionBefore = shouldPersistIndex ? storage.getMemoryStatusVersion() : void 0;
|
|
336
376
|
const [previousIndex, entityFileSets, memorySets, nativeChunks] = await Promise.all([
|
|
337
377
|
shouldPersistIndex ? readEntityIndexState(storage) : Promise.resolve(null),
|
|
338
378
|
Promise.all(storages.map((scopedStorage) => scopedStorage.readAllEntityFiles())),
|
|
339
379
|
Promise.all(storages.map((scopedStorage) => scopedStorage.readAllMemories())),
|
|
340
|
-
readNativeChunks(config, recallNamespaces)
|
|
380
|
+
nativeChunksOverride ? Promise.resolve(nativeChunksOverride) : readNativeChunks(config, recallNamespaces)
|
|
341
381
|
]);
|
|
342
382
|
const entityRecords = entityFileSets.flatMap(
|
|
343
|
-
(set, index2) => set.map((entity) => ({ entity,
|
|
383
|
+
(set, index2) => set.map((entity) => ({ entity, storage: storages[index2] }))
|
|
344
384
|
);
|
|
345
385
|
const memories = memorySets.flat();
|
|
346
386
|
const entities = /* @__PURE__ */ new Map();
|
|
347
|
-
for (const { entity,
|
|
348
|
-
const canonicalId = normalizeEntityName(entity.name, entity.type,
|
|
387
|
+
for (const { entity, storage: entityStorage } of entityRecords) {
|
|
388
|
+
const canonicalId = typeof entityStorage.normalizeEntityName === "function" ? entityStorage.normalizeEntityName(entity.name, entity.type) : normalizeEntityName(entity.name, entity.type, entityStorage.entityAliases);
|
|
349
389
|
const rawStructuredSections = entity.structuredSections ?? [];
|
|
350
390
|
const rawBeliefLedgerFactKeys = beliefLedgerFactKeys(rawStructuredSections);
|
|
351
391
|
const sanitizedFacts = entity.facts.map((fact) => sanitizeEntityFact(fact)).filter(Boolean).filter((fact) => !rawBeliefLedgerFactKeys.has(normalizeEntityText(fact))).map((fact) => compactLine(fact, 180));
|
|
@@ -403,12 +443,15 @@ async function buildEntityMentionIndex(storage, config, recallNamespaces, namesp
|
|
|
403
443
|
const sortedEntities = [...entities.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
404
444
|
const previousEntities = previousIndex ? JSON.stringify(previousIndex.entities) : "";
|
|
405
445
|
const nextEntities = JSON.stringify(sortedEntities);
|
|
446
|
+
const entityStatusVersionAfter = shouldPersistIndex ? storage.getMemoryStatusVersion() : void 0;
|
|
447
|
+
const canPersistIndex = shouldPersistIndex && entityStatusVersionBefore === entityStatusVersionAfter;
|
|
406
448
|
const index = {
|
|
407
449
|
version: ENTITY_INDEX_VERSION,
|
|
408
450
|
updatedAt: previousIndex && previousEntities === nextEntities ? previousIndex.updatedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
451
|
+
entityStatusVersion: canPersistIndex ? entityStatusVersionAfter : void 0,
|
|
409
452
|
entities: sortedEntities
|
|
410
453
|
};
|
|
411
|
-
if (
|
|
454
|
+
if (canPersistIndex) {
|
|
412
455
|
await writeEntityIndexState(storage, index);
|
|
413
456
|
}
|
|
414
457
|
return index;
|
|
@@ -431,6 +474,96 @@ function resolveExplicitCandidates(index, query) {
|
|
|
431
474
|
}
|
|
432
475
|
return candidates.sort((left, right) => right.score - left.score);
|
|
433
476
|
}
|
|
477
|
+
var EXPLICIT_ENTITY_MENTION_SCORE = 9;
|
|
478
|
+
var IMPLICIT_ENTITY_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
479
|
+
"a",
|
|
480
|
+
"an",
|
|
481
|
+
"and",
|
|
482
|
+
"are",
|
|
483
|
+
"as",
|
|
484
|
+
"at",
|
|
485
|
+
"be",
|
|
486
|
+
"by",
|
|
487
|
+
"can",
|
|
488
|
+
"do",
|
|
489
|
+
"for",
|
|
490
|
+
"from",
|
|
491
|
+
"has",
|
|
492
|
+
"how",
|
|
493
|
+
"i",
|
|
494
|
+
"if",
|
|
495
|
+
"in",
|
|
496
|
+
"is",
|
|
497
|
+
"it",
|
|
498
|
+
"me",
|
|
499
|
+
"my",
|
|
500
|
+
"of",
|
|
501
|
+
"on",
|
|
502
|
+
"or",
|
|
503
|
+
"the",
|
|
504
|
+
"to",
|
|
505
|
+
"was",
|
|
506
|
+
"what",
|
|
507
|
+
"when",
|
|
508
|
+
"where",
|
|
509
|
+
"who",
|
|
510
|
+
"why",
|
|
511
|
+
"with",
|
|
512
|
+
"you",
|
|
513
|
+
"your"
|
|
514
|
+
]);
|
|
515
|
+
function isDistinctiveImplicitAlias(normalizedAlias) {
|
|
516
|
+
const tokens = normalizedAlias.split(/\s+/).filter(Boolean);
|
|
517
|
+
if (tokens.length > 1 && tokens.every((token2) => IMPLICIT_ENTITY_STOP_WORDS.has(token2))) return false;
|
|
518
|
+
if (tokens.length !== 1) return true;
|
|
519
|
+
const token = tokens[0];
|
|
520
|
+
return Array.from(token).length > 1 && !IMPLICIT_ENTITY_STOP_WORDS.has(token);
|
|
521
|
+
}
|
|
522
|
+
function isShortLatinAlias(alias) {
|
|
523
|
+
return /^[A-Za-z]{2,3}$/.test(alias.trim());
|
|
524
|
+
}
|
|
525
|
+
function hasStrongShortLatinAliasMention(query, alias) {
|
|
526
|
+
const normalizedAlias = alias.trim();
|
|
527
|
+
const titleCaseAlias = `${normalizedAlias[0].toUpperCase()}${normalizedAlias.slice(1).toLowerCase()}`;
|
|
528
|
+
const forms = /* @__PURE__ */ new Set([normalizedAlias, normalizedAlias.toUpperCase(), titleCaseAlias]);
|
|
529
|
+
return [...forms].some((form) => {
|
|
530
|
+
if (form === form.toLowerCase()) return false;
|
|
531
|
+
const escaped = form.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
532
|
+
return new RegExp(`(?:^|[^A-Za-z0-9])${escaped}(?:$|[^A-Za-z0-9])`).test(query);
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
function resolveLanguageIndependentExplicitCandidates(index, query) {
|
|
536
|
+
const canonicalIdsByAlias = /* @__PURE__ */ new Map();
|
|
537
|
+
for (const entry of index.entities) {
|
|
538
|
+
for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {
|
|
539
|
+
const normalizedAlias = normalizeEntityText(alias);
|
|
540
|
+
if (!normalizedAlias) continue;
|
|
541
|
+
const canonicalIds = canonicalIdsByAlias.get(normalizedAlias) ?? /* @__PURE__ */ new Set();
|
|
542
|
+
canonicalIds.add(entry.canonicalId);
|
|
543
|
+
canonicalIdsByAlias.set(normalizedAlias, canonicalIds);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const candidates = [];
|
|
547
|
+
for (const entry of index.entities) {
|
|
548
|
+
let bestAlias = "";
|
|
549
|
+
let bestScore = 0;
|
|
550
|
+
for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {
|
|
551
|
+
const normalizedAlias = normalizeEntityText(alias);
|
|
552
|
+
const score = scoreAliasMatch(query, alias);
|
|
553
|
+
if (!normalizedAlias || !isDistinctiveImplicitAlias(normalizedAlias) || isShortLatinAlias(alias) && !hasStrongShortLatinAliasMention(query, alias) || canonicalIdsByAlias.get(normalizedAlias)?.size !== 1 || score < EXPLICIT_ENTITY_MENTION_SCORE || score <= bestScore) {
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
bestAlias = alias;
|
|
557
|
+
bestScore = score;
|
|
558
|
+
}
|
|
559
|
+
if (bestAlias) {
|
|
560
|
+
candidates.push({ entry, alias: bestAlias, score: bestScore, source: "query" });
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return candidates.sort(
|
|
564
|
+
(left, right) => right.score - left.score || left.entry.name.localeCompare(right.entry.name)
|
|
565
|
+
);
|
|
566
|
+
}
|
|
434
567
|
function resolveRecentTurnCandidates(index, transcriptEntries, recentTurns) {
|
|
435
568
|
if (recentTurns <= 0 || transcriptEntries.length === 0) return [];
|
|
436
569
|
const recentEntries = transcriptEntries.slice(-recentTurns);
|
|
@@ -624,20 +757,48 @@ function formatEntityHintSection(candidates, queryTokens, mode, maxRelatedEntiti
|
|
|
624
757
|
return result.trim().length > 0 ? result.trimEnd() : null;
|
|
625
758
|
}
|
|
626
759
|
async function buildEntityRecallSection(options) {
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
const index = await buildEntityMentionIndex(
|
|
760
|
+
const prefixedMode = detectEntityQueryMode(options.query);
|
|
761
|
+
const persistedIndex = prefixedMode ? null : await readCurrentPersistedEntityIndex(
|
|
630
762
|
options.storage,
|
|
631
763
|
options.config,
|
|
632
764
|
options.recallNamespaces,
|
|
633
765
|
options.namespaceStorage
|
|
634
766
|
);
|
|
635
|
-
|
|
767
|
+
let nativeChunks;
|
|
768
|
+
if (!prefixedMode && persistedIndex && resolveLanguageIndependentExplicitCandidates(persistedIndex, options.query).length === 0) {
|
|
769
|
+
nativeChunks = await readNativeChunks(options.config, options.recallNamespaces);
|
|
770
|
+
if (!hasFreshNativeExplicitMention(persistedIndex, nativeChunks, options.query)) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
const namespaceScoped = resolveNamespaceCapabilities(options.config).namespaces && options.namespaceStorage !== void 0 && (options.recallNamespaces?.length ?? 0) > 0;
|
|
775
|
+
const resolvedStorages = namespaceScoped ? await resolveEntityIndexStorages(
|
|
776
|
+
options.storage,
|
|
777
|
+
options.config,
|
|
778
|
+
options.recallNamespaces,
|
|
779
|
+
options.namespaceStorage
|
|
780
|
+
) : void 0;
|
|
781
|
+
const namespaceCacheKey = resolvedStorages && options.recallNamespaces ? namespaceEntityIndexCacheKey(resolvedStorages, options.recallNamespaces) : void 0;
|
|
782
|
+
let index = namespaceCacheKey ? namespaceEntityIndexCache.get(namespaceCacheKey) : void 0;
|
|
783
|
+
if (!index) {
|
|
784
|
+
index = await buildEntityMentionIndex(
|
|
785
|
+
options.storage,
|
|
786
|
+
options.config,
|
|
787
|
+
options.recallNamespaces,
|
|
788
|
+
options.namespaceStorage,
|
|
789
|
+
nativeChunks,
|
|
790
|
+
resolvedStorages
|
|
791
|
+
);
|
|
792
|
+
if (namespaceCacheKey) rememberNamespaceEntityIndex(namespaceCacheKey, index);
|
|
793
|
+
}
|
|
636
794
|
const explicitCandidates = resolveExplicitCandidates(index, options.query);
|
|
637
|
-
const
|
|
795
|
+
const queryCandidates = prefixedMode ? explicitCandidates : resolveLanguageIndependentExplicitCandidates(index, options.query);
|
|
796
|
+
const mode = prefixedMode ?? (queryCandidates.length > 0 ? "direct" : null);
|
|
797
|
+
if (!mode) return null;
|
|
798
|
+
const candidates = queryCandidates.length > 0 ? queryCandidates : resolveRecentTurnCandidates(index, options.transcriptEntries, options.recentTurns);
|
|
638
799
|
if (candidates.length === 0) return null;
|
|
639
800
|
const queryTokens = tokenize(options.query);
|
|
640
|
-
const candidateLimit =
|
|
801
|
+
const candidateLimit = queryCandidates.length === 0 && mode === "follow_up" ? 1 : options.maxHints;
|
|
641
802
|
const rankedCandidates = candidates.slice(0, candidateLimit);
|
|
642
803
|
const enriched = await Promise.all(
|
|
643
804
|
rankedCandidates.map(async (candidate) => {
|
|
@@ -682,4 +843,4 @@ export {
|
|
|
682
843
|
entityIndexVersion,
|
|
683
844
|
entityRecentTranscriptLookbackHours
|
|
684
845
|
};
|
|
685
|
-
//# sourceMappingURL=chunk-
|
|
846
|
+
//# sourceMappingURL=chunk-YGHMSDLK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/entity-retrieval.ts"],"sourcesContent":["import { resolveNamespaceCapabilities } from \"./capabilities.js\";\nimport { createHash } from \"node:crypto\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { collectNativeKnowledgeChunks, type NativeKnowledgeChunk } from \"./native-knowledge.js\";\nimport { compareEntityTimestamps, normalizeEntityName, type StorageManager } from \"./storage.js\";\nimport { normalizeEntityText, resolveRequestedEntitySectionKeys } from \"./entity-schema.js\";\nimport type { EntityStructuredSection, MemoryFile, PluginConfig, TranscriptEntry } from \"./types.js\";\nimport { containsPhrase } from \"./entity-retrieval-boundaries.js\";\n\nconst ENTITY_INDEX_VERSION = 3;\nconst RECENT_TRANSCRIPT_LOOKBACK_HOURS = 24;\nconst INSTRUCTION_LIKE_RE = /\\b(always|never|must|should|remember to|do not|don't|process|workflow|template|checklist|instruction)\\b/i;\nconst METADATA_WRAPPER_RE = /^(source|context|metadata|notes?):/i;\nconst ENTITY_PRONOUN_RE = /\\b(he|him|his|she|her|they|them|their|it|its)\\b/i;\nconst BELIEF_LEDGER_SECTION_KEY = \"belief_ledger\";\nconst BELIEF_LEDGER_FACT_RE = /^claim=([^;]+);\\s*status=([^;]+);\\s*updatedAt=([^;]+);\\s*(.+)$/;\n\ntype EntityQueryMode = \"direct\" | \"timeline\" | \"follow_up\";\n\ntype EntityMentionIndexEntry = {\n canonicalId: string;\n name: string;\n type: string;\n aliases: string[];\n summary?: string;\n facts: string[];\n timelineFacts: string[];\n structuredSections: EntityStructuredSection[];\n timeline: Array<{\n timestamp: string;\n text: string;\n source?: string;\n sessionKey?: string;\n principal?: string;\n }>;\n relationships: Array<{ target: string; label: string }>;\n activity: Array<{ date: string; note: string }>;\n factCount: number;\n memorySnippets: string[];\n nativeChunks: Array<{\n chunkId: string;\n title: string;\n sourceKind: NativeKnowledgeChunk[\"sourceKind\"];\n sourcePath: string;\n snippet: string;\n derivedDate?: string;\n }>;\n};\n\ntype EntityMentionIndex = {\n version: number;\n updatedAt: string;\n entityStatusVersion?: number;\n entities: EntityMentionIndexEntry[];\n};\n\ntype EntityCandidate = {\n entry: EntityMentionIndexEntry;\n alias: string;\n score: number;\n source: \"query\" | \"recent_turn\";\n};\n\ntype EntityHintSnippet = {\n text: string;\n score: number;\n kind: \"summary\" | \"fact\" | \"section\" | \"relationship\" | \"activity\" | \"memory\" | \"native\";\n};\n\nexport interface BuildEntityRecallSectionOptions {\n config: PluginConfig;\n storage: StorageManager;\n namespaceStorage?: (namespace: string) => Promise<StorageManager>;\n query: string;\n recallNamespaces?: string[];\n recentTurns: number;\n maxHints: number;\n maxSupportingFacts: number;\n maxRelatedEntities: number;\n maxChars: number;\n transcriptEntries: TranscriptEntry[];\n}\n\nfunction tokenize(value: string): string[] {\n return normalizeEntityText(value).split(/\\s+/).filter((token) => token.length >= 2);\n}\n\nfunction uniqueStrings(values: string[]): string[] {\n return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))];\n}\n\nfunction compactLine(value: string, maxLength: number = 220): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) return normalized;\n return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\nfunction dedupeHintSnippetsByText(snippets: EntityHintSnippet[]): EntityHintSnippet[] {\n const seen = new Set<string>();\n const result: EntityHintSnippet[] = [];\n for (const snippet of snippets) {\n const key = normalizeEntityText(snippet.text);\n if (seen.has(key)) continue;\n seen.add(key);\n result.push(snippet);\n }\n return result;\n}\n\nfunction isBeliefLedgerSection(section: Pick<EntityStructuredSection, \"key\">): boolean {\n return normalizeEntityText(section.key).replace(/\\s+/g, \"_\") === BELIEF_LEDGER_SECTION_KEY;\n}\n\nfunction beliefLedgerFactKeys(sections: EntityStructuredSection[]): Set<string> {\n const keys = new Set<string>();\n for (const section of sections) {\n if (!isBeliefLedgerSection(section)) continue;\n for (const fact of section.facts) {\n keys.add(normalizeEntityText(fact));\n }\n }\n return keys;\n}\n\nfunction recallFactsForStructuredSection(section: EntityStructuredSection): string[] {\n if (!isBeliefLedgerSection(section)) return section.facts;\n return currentActiveBeliefLedgerFactTexts(section.facts);\n}\n\nfunction currentActiveBeliefLedgerFactTexts(facts: string[]): string[] {\n const byClaim = new Map<string, { status: string; updatedAtMs: number; texts: string[] }>();\n for (const fact of facts) {\n const match = BELIEF_LEDGER_FACT_RE.exec(fact.trim());\n if (!match) continue;\n const [, claimId, status, updatedAt, text] = match;\n const updatedAtMs = Date.parse(updatedAt);\n if (!claimId?.trim() || !status?.trim() || !Number.isFinite(updatedAtMs) || !text?.trim()) continue;\n const normalizedStatus = status.trim().toLowerCase();\n const normalizedClaimId = claimId.trim();\n const current = byClaim.get(normalizedClaimId);\n const inactiveTieWins =\n current &&\n updatedAtMs === current.updatedAtMs &&\n current.status === \"active\" &&\n normalizedStatus !== \"active\";\n if (!current || updatedAtMs > current.updatedAtMs || inactiveTieWins) {\n byClaim.set(normalizedClaimId, { status: normalizedStatus, updatedAtMs, texts: [text.trim()] });\n continue;\n }\n if (updatedAtMs === current.updatedAtMs && current.status === normalizedStatus) {\n current.texts.push(text.trim());\n }\n }\n const result: string[] = [];\n for (const current of byClaim.values()) {\n if (current.status === \"active\") {\n result.push(...current.texts);\n }\n }\n return result;\n}\n\nfunction relationLine(entry: EntityMentionIndexEntry, relationship: { target: string; label: string }): string {\n const normalizedLabel = relationship.label.replace(/\\s+/g, \" \").trim();\n if (normalizedLabel.length === 0) return `${entry.name} is connected to ${relationship.target}`;\n return `${entry.name} ${normalizedLabel} ${relationship.target}`;\n}\n\nfunction detectEntityQueryMode(query: string): EntityQueryMode | null {\n const normalized = normalizeEntityText(query);\n if (!normalized) return null;\n if (\n /^(what about|and what about|how about|what happened (with|to) (he|him|his|she|her|they|them|their|it|its)|did (he|she|they|it)|is (he|she|they|it)|was (he|she|they|it))\\b/.test(normalized)\n ) {\n return \"follow_up\";\n }\n if (\n /^(who is|who s|what do we know about|what does|tell me about|what can you tell me about|what s new with|what happened with|what happened to|status of|where is|how is)\\b/.test(normalized)\n ) {\n if (/^what does\\b/.test(normalized)) {\n if (/^what does (?:this|that|it|the|a|an|my|our|your|their)\\b/.test(normalized)) {\n return null;\n }\n if (\n /^what does [a-z0-9-]+ (?:error|warning|exception|failure|stack|trace|code|message|log)\\b/.test(normalized)\n && /\\b(mean|means|indicate|indicates|imply|implies)\\b/.test(normalized)\n ) {\n return null;\n }\n }\n return /what happened|what s new|status of|how is|where is/.test(normalized) ? \"timeline\" : \"direct\";\n }\n if (ENTITY_PRONOUN_RE.test(normalized) && normalized.split(/\\s+/).length <= 8) {\n return \"follow_up\";\n }\n return null;\n}\n\nfunction scoreAliasMatch(query: string, alias: string): number {\n const normalizedQuery = normalizeEntityText(query);\n const normalizedAlias = normalizeEntityText(alias);\n if (!normalizedAlias) return 0;\n if (normalizedQuery === normalizedAlias) return 10;\n if (containsPhrase(normalizedQuery, normalizedAlias)) return 8 + Math.min(normalizedAlias.split(/\\s+/).length, 3);\n const queryTokens = new Set(tokenize(normalizedQuery));\n const aliasTokens = tokenize(normalizedAlias);\n if (aliasTokens.length === 0) return 0;\n const overlap = aliasTokens.filter((token) => queryTokens.has(token)).length;\n if (overlap === 0) return 0;\n // Cross-entity contamination guard (#682 PR 2/3 R-2). For multi-token\n // aliases, partial-token overlap that hits ONLY shared common tokens\n // (like \"person\" in \"Person-A1\" / \"Person-B1\") would surface every\n // similarly-prefixed entity for a query that named only one. Require\n // that the overlap include at least one DISTINCTIVE alias token —\n // i.e. a token that does not also appear in any other entity's\n // alias-token vocabulary. Since this function is pure / per-pair, we\n // approximate \"distinctive\" by requiring the overlap to include at\n // least one token that is not a substring-of common identifier\n // affixes. The aliasTokens with length > 1 must contribute at least\n // one non-affix overlap. \"Alice Example\" ([\"alice\", \"example\"])\n // matched by query \"Tell me about Alice\" → overlap = 1 on \"alice\",\n // and \"alice\" is not an affix → score = 1. \"Person-A1\" tokens\n // [\"person\", \"a1\"] matched by query \"Who is Person-B1?\" → overlap =\n // 1 on \"person\", and \"person\" IS an affix → score = 0.\n if (aliasTokens.length > 1) {\n const nonAffixOverlap = aliasTokens.filter(\n (token) => queryTokens.has(token) && !isAliasAffixToken(token),\n ).length;\n if (nonAffixOverlap === 0) return 0;\n }\n return overlap;\n}\n\n/**\n * Tokens that look like type prefixes / generic role identifiers and\n * therefore should not, on their own, count as evidence that a\n * multi-token alias matches a query (#682 PR 2/3 R-2).\n *\n * Kept as a small explicit list rather than a regex so additions are\n * deliberate. The list mirrors the entity types listed in\n * `entity-schema.ts` plus the most common generic role identifiers\n * that frequently appear as the leading token of a display name.\n */\nconst ALIAS_AFFIX_TOKENS = new Set<string>([\n \"person\", \"people\", \"user\", \"users\", \"team\", \"teams\",\n \"project\", \"projects\", \"topic\", \"topics\",\n \"org\", \"orgs\", \"organization\", \"organizations\", \"company\", \"companies\",\n \"place\", \"places\", \"tool\", \"tools\", \"service\", \"services\",\n \"system\", \"systems\", \"agent\", \"agents\", \"bot\", \"bots\",\n]);\n\nfunction isAliasAffixToken(token: string): boolean {\n return ALIAS_AFFIX_TOKENS.has(token);\n}\n\nfunction isLikelyInstructionLike(value: string): boolean {\n return INSTRUCTION_LIKE_RE.test(value) || METADATA_WRAPPER_RE.test(value);\n}\n\nfunction sanitizeEntityFact(fact: string): string {\n const sanitized = sanitizeMemoryContent(fact);\n const clean = sanitized.text.trim();\n if (!clean) return \"\";\n if (INSTRUCTION_LIKE_RE.test(clean) && clean.length > 100) return \"\";\n return clean;\n}\n\nfunction scoreHintSnippet(snippet: EntityHintSnippet, queryTokens: string[]): EntityHintSnippet | null {\n const normalized = normalizeEntityText(snippet.text);\n if (!normalized) return null;\n const scored = { ...snippet };\n if (isLikelyInstructionLike(scored.text) && scored.kind !== \"summary\") {\n scored.score -= 3;\n }\n const overlap = queryTokens.filter((token) => normalized.includes(token)).length;\n scored.score += overlap * 2;\n if (METADATA_WRAPPER_RE.test(scored.text)) scored.score -= 2;\n if (scored.text.length <= 160) scored.score += 1;\n return scored.score > 0 ? scored : null;\n}\n\nfunction sortTimelineEntriesDesc(\n left: EntityMentionIndexEntry[\"timeline\"][number],\n right: EntityMentionIndexEntry[\"timeline\"][number],\n): number {\n const timestampOrder = compareEntityTimestamps(right.timestamp, left.timestamp);\n if (timestampOrder !== 0) {\n return timestampOrder;\n }\n return right.text.localeCompare(left.text);\n}\n\nfunction jaccardSimilarity(a: string, b: string): number {\n const aTokens = new Set(tokenize(a));\n const bTokens = new Set(tokenize(b));\n if (aTokens.size === 0 || bTokens.size === 0) return 0;\n let intersection = 0;\n for (const token of aTokens) {\n if (bTokens.has(token)) intersection += 1;\n }\n const union = new Set([...aTokens, ...bTokens]).size;\n return union === 0 ? 0 : intersection / union;\n}\n\nfunction buildAliasIndex(entries: EntityMentionIndexEntry[]): Map<string, EntityMentionIndexEntry[]> {\n const index = new Map<string, EntityMentionIndexEntry[]>();\n for (const entry of entries) {\n const aliases = uniqueStrings([entry.name, ...entry.aliases]).map(normalizeEntityText).filter(Boolean);\n for (const alias of aliases) {\n const existing = index.get(alias) ?? [];\n existing.push(entry);\n index.set(alias, existing);\n }\n }\n return index;\n}\n\nasync function readNativeChunks(\n config: PluginConfig,\n recallNamespaces?: string[],\n): Promise<NativeKnowledgeChunk[]> {\n if (!config.nativeKnowledge?.enabled) return [];\n return collectNativeKnowledgeChunks({\n workspaceDir: config.workspaceDir,\n memoryDir: config.memoryDir,\n config: config.nativeKnowledge,\n recallNamespaces: resolveNamespaceCapabilities(config).namespaces ? recallNamespaces : undefined,\n defaultNamespace: config.defaultNamespace,\n }).catch(() => []);\n}\n\nasync function resolveEntityIndexStorages(\n storage: StorageManager,\n config: PluginConfig,\n recallNamespaces?: string[],\n namespaceStorage?: (namespace: string) => Promise<StorageManager>,\n): Promise<StorageManager[]> {\n if (\n !resolveNamespaceCapabilities(config).namespaces ||\n !namespaceStorage ||\n !recallNamespaces ||\n recallNamespaces.length === 0\n ) {\n return [storage];\n }\n\n const storages: StorageManager[] = [];\n const seenDirs = new Set<string>();\n for (const namespace of uniqueStrings(recallNamespaces)) {\n try {\n const scopedStorage = await namespaceStorage(namespace);\n const storageDir = path.resolve(scopedStorage.dir);\n if (seenDirs.has(storageDir)) continue;\n seenDirs.add(storageDir);\n storages.push(scopedStorage);\n } catch {\n continue;\n }\n }\n\n return storages.length > 0 ? storages : [storage];\n}\n\nfunction entityIndexStatePath(storage: StorageManager): string {\n return path.join(storage.dir, \"state\", \"entity-mention-index.json\");\n}\n\nasync function readEntityIndexState(storage: StorageManager): Promise<EntityMentionIndex | null> {\n const raw = await readFile(entityIndexStatePath(storage), \"utf-8\").catch(() => \"\");\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as Partial<EntityMentionIndex>;\n if (parsed.version !== ENTITY_INDEX_VERSION || !Array.isArray(parsed.entities)) return null;\n return parsed as EntityMentionIndex;\n } catch {\n return null;\n }\n}\n\n\nasync function readCurrentPersistedEntityIndex(\n storage: StorageManager,\n config: PluginConfig,\n recallNamespaces?: string[],\n namespaceStorage?: (namespace: string) => Promise<StorageManager>,\n): Promise<EntityMentionIndex | null> {\n if (\n resolveNamespaceCapabilities(config).namespaces &&\n namespaceStorage &&\n recallNamespaces &&\n recallNamespaces.length > 0\n ) {\n return null;\n }\n const index = await readEntityIndexState(storage);\n if (!index || index.entityStatusVersion !== storage.getMemoryStatusVersion()) {\n return null;\n }\n return index;\n}\nconst namespaceEntityIndexCache = new Map<string, EntityMentionIndex>();\nconst MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES = 32;\n\nfunction namespaceEntityIndexCacheKey(\n storages: StorageManager[],\n recallNamespaces: string[],\n): string {\n const namespaceKey = uniqueStrings(recallNamespaces).sort().join(\"\\u001f\");\n const storageKey = storages\n .map((scopedStorage) => {\n const aliases = Object.entries(scopedStorage.entityAliases)\n .sort(([left], [right]) => left.localeCompare(right));\n return (\n `${path.resolve(scopedStorage.dir)}@${scopedStorage.getMemoryStatusVersion()}` +\n `:${scopedStorage.getMemoryCorpusVersion()}:${scopedStorage.hotCacheKeyId()}:${JSON.stringify(aliases)}`\n );\n })\n .sort()\n .join(\"\\u001f\");\n return `${namespaceKey}\\u001e${storageKey}`;\n}\n\nfunction rememberNamespaceEntityIndex(key: string, index: EntityMentionIndex): void {\n if (namespaceEntityIndexCache.size >= MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES) {\n const oldestKey = namespaceEntityIndexCache.keys().next().value;\n if (typeof oldestKey === \"string\") namespaceEntityIndexCache.delete(oldestKey);\n }\n namespaceEntityIndexCache.set(key, index);\n}\n\nasync function writeEntityIndexState(storage: StorageManager, index: EntityMentionIndex): Promise<void> {\n const statePath = entityIndexStatePath(storage);\n await mkdir(path.dirname(statePath), { recursive: true });\n const nextContent = JSON.stringify(index, null, 2) + \"\\n\";\n const currentContent = await readFile(statePath, \"utf-8\").catch(() => \"\");\n if (currentContent === nextContent) return;\n await writeFile(statePath, nextContent, \"utf-8\");\n}\n\nfunction nativePseudoCanonicalId(chunk: NativeKnowledgeChunk): string {\n return `native:${createHash(\"sha256\").update(chunk.sourcePath).digest(\"hex\").slice(0, 12)}`;\n}\n\nfunction createPseudoNativeEntry(chunk: NativeKnowledgeChunk): EntityMentionIndexEntry {\n const canonicalId = nativePseudoCanonicalId(chunk);\n return {\n canonicalId,\n name: chunk.title,\n type: chunk.sourceKind,\n aliases: uniqueStrings(chunk.aliases ?? []),\n facts: [],\n structuredSections: [],\n timelineFacts: [],\n timeline: [],\n relationships: [],\n activity: [],\n factCount: 0,\n memorySnippets: [],\n nativeChunks: [\n {\n chunkId: chunk.chunkId,\n title: chunk.title,\n sourceKind: chunk.sourceKind,\n sourcePath: chunk.sourcePath,\n snippet: compactLine(chunk.content, 180),\n derivedDate: chunk.derivedDate,\n },\n ],\n };\n}\n\nfunction mergeNativeChunk(entry: EntityMentionIndexEntry, chunk: NativeKnowledgeChunk): void {\n const existing = entry.nativeChunks.find((item) => item.chunkId === chunk.chunkId);\n if (existing) return;\n entry.nativeChunks.push({\n chunkId: chunk.chunkId,\n title: chunk.title,\n sourceKind: chunk.sourceKind,\n sourcePath: chunk.sourcePath,\n snippet: compactLine(chunk.content, 180),\n derivedDate: chunk.derivedDate,\n });\n entry.aliases = uniqueStrings([...entry.aliases, ...(chunk.aliases ?? [])]);\n}\n\nfunction hasFreshNativeExplicitMention(\n index: EntityMentionIndex,\n nativeChunks: NativeKnowledgeChunk[],\n query: string,\n): boolean {\n if (nativeChunks.length === 0) return false;\n const nativeCanonicalIds = new Set(nativeChunks.map(nativePseudoCanonicalId));\n const freshNativeIndex: EntityMentionIndex = {\n ...index,\n entities: [\n ...index.entities.filter((entry) => !nativeCanonicalIds.has(entry.canonicalId)),\n ...nativeChunks.map(createPseudoNativeEntry),\n ],\n };\n return resolveLanguageIndependentExplicitCandidates(freshNativeIndex, query).length > 0;\n}\n\nasync function buildEntityMentionIndex(\n storage: StorageManager,\n config: PluginConfig,\n recallNamespaces?: string[],\n namespaceStorage?: (namespace: string) => Promise<StorageManager>,\n nativeChunksOverride?: NativeKnowledgeChunk[],\n resolvedStorages?: StorageManager[],\n): Promise<EntityMentionIndex> {\n const storages = resolvedStorages ?? await resolveEntityIndexStorages(\n storage,\n config,\n recallNamespaces,\n namespaceStorage,\n );\n const shouldPersistIndex =\n storages.length === 1 && path.resolve(storages[0]!.dir) === path.resolve(storage.dir);\n const entityStatusVersionBefore = shouldPersistIndex ? storage.getMemoryStatusVersion() : undefined;\n const [previousIndex, entityFileSets, memorySets, nativeChunks] = await Promise.all([\n shouldPersistIndex ? readEntityIndexState(storage) : Promise.resolve(null),\n Promise.all(storages.map((scopedStorage) => scopedStorage.readAllEntityFiles())),\n Promise.all(storages.map((scopedStorage) => scopedStorage.readAllMemories())),\n nativeChunksOverride ? Promise.resolve(nativeChunksOverride) : readNativeChunks(config, recallNamespaces),\n ]);\n // Pair each entity with the storage that owns it (#1534): canonical ids must\n // reflect that store's aliases and historical migration mappings, never another\n // namespace's.\n const entityRecords = entityFileSets.flatMap((set, index) =>\n set.map((entity) => ({ entity, storage: storages[index]! })),\n );\n const memories = memorySets.flat();\n\n const entities = new Map<string, EntityMentionIndexEntry>();\n for (const { entity, storage: entityStorage } of entityRecords) {\n const canonicalId =\n typeof entityStorage.normalizeEntityName === \"function\"\n ? entityStorage.normalizeEntityName(entity.name, entity.type)\n : normalizeEntityName(entity.name, entity.type, entityStorage.entityAliases);\n const rawStructuredSections = entity.structuredSections ?? [];\n const rawBeliefLedgerFactKeys = beliefLedgerFactKeys(rawStructuredSections);\n const sanitizedFacts = entity.facts\n .map((fact) => sanitizeEntityFact(fact))\n .filter(Boolean)\n .filter((fact) => !rawBeliefLedgerFactKeys.has(normalizeEntityText(fact)))\n .map((fact) => compactLine(fact, 180));\n const sanitizedTimelineFacts = entity.timeline\n .map((entry) => sanitizeEntityFact(entry.text))\n .filter(Boolean)\n .map((fact) => compactLine(fact, 180));\n entities.set(canonicalId, {\n canonicalId,\n name: entity.name,\n type: entity.type,\n aliases: uniqueStrings(entity.aliases),\n summary: entity.synthesis?.trim() || entity.summary?.trim() || undefined,\n facts: sanitizedFacts,\n timelineFacts: uniqueStrings(sanitizedTimelineFacts),\n structuredSections: rawStructuredSections.map((section) => ({\n key: section.key,\n title: section.title,\n facts: recallFactsForStructuredSection(section)\n .map((fact) => sanitizeEntityFact(fact))\n .filter(Boolean)\n .map((fact) => compactLine(fact, 180)),\n })).filter((section) => section.facts.length > 0),\n timeline: entity.timeline.map((entry) => ({ ...entry })),\n relationships: entity.relationships.map((relationship) => ({ ...relationship })),\n activity: entity.activity.map((activity) => ({ ...activity })),\n factCount: sanitizedFacts.length,\n memorySnippets: [],\n nativeChunks: [],\n });\n }\n\n for (const memory of memories) {\n const entityRef = typeof memory.frontmatter.entityRef === \"string\" ? memory.frontmatter.entityRef : \"\";\n if (!entityRef) continue;\n const entry = entities.get(entityRef);\n if (!entry) continue;\n const snippet = await readMemorySnippet(memory);\n if (!entry.memorySnippets.includes(snippet)) {\n entry.memorySnippets.push(snippet);\n }\n }\n\n const aliasIndex = buildAliasIndex([...entities.values()]);\n for (const chunk of nativeChunks) {\n const existingPseudo = entities.get(nativePseudoCanonicalId(chunk));\n if (existingPseudo) {\n mergeNativeChunk(existingPseudo, chunk);\n continue;\n }\n const candidateAliases = uniqueStrings([chunk.title, ...(chunk.aliases ?? [])]).map(normalizeEntityText).filter(Boolean);\n let matched = false;\n for (const alias of candidateAliases) {\n for (const entry of aliasIndex.get(alias) ?? []) {\n mergeNativeChunk(entry, chunk);\n matched = true;\n }\n }\n if (matched) continue;\n const pseudoEntry = createPseudoNativeEntry(chunk);\n entities.set(pseudoEntry.canonicalId, pseudoEntry);\n }\n\n const sortedEntities = [...entities.values()].sort((left, right) => left.name.localeCompare(right.name));\n const previousEntities = previousIndex ? JSON.stringify(previousIndex.entities) : \"\";\n const nextEntities = JSON.stringify(sortedEntities);\n const entityStatusVersionAfter = shouldPersistIndex ? storage.getMemoryStatusVersion() : undefined;\n const canPersistIndex = shouldPersistIndex && entityStatusVersionBefore === entityStatusVersionAfter;\n const index: EntityMentionIndex = {\n version: ENTITY_INDEX_VERSION,\n updatedAt:\n previousIndex && previousEntities === nextEntities\n ? previousIndex.updatedAt\n : new Date().toISOString(),\n entityStatusVersion: canPersistIndex ? entityStatusVersionAfter : undefined,\n entities: sortedEntities,\n };\n if (canPersistIndex) {\n await writeEntityIndexState(storage, index);\n }\n return index;\n}\n\nfunction resolveExplicitCandidates(\n index: EntityMentionIndex,\n query: string,\n): EntityCandidate[] {\n const candidates: EntityCandidate[] = [];\n for (const entry of index.entities) {\n const aliases = uniqueStrings([entry.name, ...entry.aliases]);\n let bestAlias = \"\";\n let bestScore = 0;\n for (const alias of aliases) {\n const score = scoreAliasMatch(query, alias);\n if (score > bestScore) {\n bestAlias = alias;\n bestScore = score;\n }\n }\n if (bestScore <= 0) continue;\n candidates.push({ entry, alias: bestAlias, score: bestScore, source: \"query\" });\n }\n return candidates.sort((left, right) => right.score - left.score);\n}\n\nconst EXPLICIT_ENTITY_MENTION_SCORE = 9;\n\nconst IMPLICIT_ENTITY_STOP_WORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"by\",\n \"can\",\n \"do\",\n \"for\",\n \"from\",\n \"has\",\n \"how\",\n \"i\",\n \"if\",\n \"in\",\n \"is\",\n \"it\",\n \"me\",\n \"my\",\n \"of\",\n \"on\",\n \"or\",\n \"the\",\n \"to\",\n \"was\",\n \"what\",\n \"when\",\n \"where\",\n \"who\",\n \"why\",\n \"with\",\n \"you\",\n \"your\",\n]);\n\nfunction isDistinctiveImplicitAlias(normalizedAlias: string): boolean {\n const tokens = normalizedAlias.split(/\\s+/).filter(Boolean);\n if (tokens.length > 1 && tokens.every((token) => IMPLICIT_ENTITY_STOP_WORDS.has(token))) return false;\n if (tokens.length !== 1) return true;\n const token = tokens[0]!;\n return Array.from(token).length > 1 && !IMPLICIT_ENTITY_STOP_WORDS.has(token);\n}\n\nfunction isShortLatinAlias(alias: string): boolean {\n return /^[A-Za-z]{2,3}$/.test(alias.trim());\n}\n\nfunction hasStrongShortLatinAliasMention(query: string, alias: string): boolean {\n const normalizedAlias = alias.trim();\n const titleCaseAlias = `${normalizedAlias[0]!.toUpperCase()}${normalizedAlias.slice(1).toLowerCase()}`;\n const forms = new Set([normalizedAlias, normalizedAlias.toUpperCase(), titleCaseAlias]);\n return [...forms].some((form) => {\n if (form === form.toLowerCase()) return false;\n const escaped = form.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`(?:^|[^A-Za-z0-9])${escaped}(?:$|[^A-Za-z0-9])`).test(query);\n });\n}\n\nfunction resolveLanguageIndependentExplicitCandidates(\n index: EntityMentionIndex,\n query: string,\n): EntityCandidate[] {\n const canonicalIdsByAlias = new Map<string, Set<string>>();\n for (const entry of index.entities) {\n for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {\n const normalizedAlias = normalizeEntityText(alias);\n if (!normalizedAlias) continue;\n const canonicalIds = canonicalIdsByAlias.get(normalizedAlias) ?? new Set<string>();\n canonicalIds.add(entry.canonicalId);\n canonicalIdsByAlias.set(normalizedAlias, canonicalIds);\n }\n }\n\n const candidates: EntityCandidate[] = [];\n for (const entry of index.entities) {\n let bestAlias = \"\";\n let bestScore = 0;\n for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {\n const normalizedAlias = normalizeEntityText(alias);\n const score = scoreAliasMatch(query, alias);\n if (\n !normalizedAlias ||\n !isDistinctiveImplicitAlias(normalizedAlias) ||\n (isShortLatinAlias(alias) && !hasStrongShortLatinAliasMention(query, alias)) ||\n canonicalIdsByAlias.get(normalizedAlias)?.size !== 1 ||\n score < EXPLICIT_ENTITY_MENTION_SCORE ||\n score <= bestScore\n ) {\n continue;\n }\n bestAlias = alias;\n bestScore = score;\n }\n if (bestAlias) {\n candidates.push({ entry, alias: bestAlias, score: bestScore, source: \"query\" });\n }\n }\n\n return candidates.sort(\n (left, right) => right.score - left.score || left.entry.name.localeCompare(right.entry.name),\n );\n}\n\nfunction resolveRecentTurnCandidates(\n index: EntityMentionIndex,\n transcriptEntries: TranscriptEntry[],\n recentTurns: number,\n): EntityCandidate[] {\n if (recentTurns <= 0 || transcriptEntries.length === 0) return [];\n const recentEntries = transcriptEntries.slice(-recentTurns);\n const candidates = new Map<string, EntityCandidate>();\n for (let indexOffset = recentEntries.length - 1; indexOffset >= 0; indexOffset -= 1) {\n const turn = recentEntries[indexOffset];\n const recencyBoost = recentEntries.length - indexOffset;\n const roleWeight = turn.role === \"user\" ? 2 : turn.role === \"assistant\" ? -1 : 0;\n for (const entry of index.entities) {\n const aliases = uniqueStrings([entry.name, ...entry.aliases]);\n for (const alias of aliases) {\n const score = scoreAliasMatch(turn.content, alias);\n if (score <= 0) continue;\n const current = candidates.get(entry.canonicalId);\n const weightedScore = score + Math.max(0, 6 - recencyBoost) + roleWeight;\n if (!current || weightedScore > current.score) {\n candidates.set(entry.canonicalId, {\n entry,\n alias,\n score: weightedScore,\n source: \"recent_turn\",\n });\n }\n }\n }\n }\n return [...candidates.values()].sort((left, right) => right.score - left.score);\n}\n\nasync function readMemorySnippet(memory: MemoryFile): Promise<string> {\n const content = memory.content.replace(/\\s+/g, \" \").trim();\n return compactLine(content, 180);\n}\n\nasync function buildHintSnippets(\n entry: EntityMentionIndexEntry,\n queryTokens: string[],\n mode: EntityQueryMode,\n maxSupportingFacts: number,\n requestedSectionKeys: Set<string>,\n): Promise<EntityHintSnippet[]> {\n const snippets: EntityHintSnippet[] = [];\n const aliasTokens = new Set(tokenize(uniqueStrings([entry.name, ...entry.aliases]).join(\" \")));\n if (entry.summary) {\n snippets.push({ text: compactLine(entry.summary, 180), score: 10, kind: \"summary\" });\n }\n\n if (requestedSectionKeys.size > 0) {\n for (const section of entry.structuredSections) {\n if (!requestedSectionKeys.has(normalizeEntityText(section.key).replace(/\\s+/g, \"_\"))) continue;\n for (const fact of section.facts) {\n snippets.push({ text: fact, score: mode === \"direct\" ? 8 : 9, kind: \"section\" });\n }\n }\n } else {\n for (const fact of entry.timelineFacts) {\n snippets.push({ text: fact, score: mode === \"direct\" ? 6 : 7, kind: \"fact\" });\n }\n for (const section of entry.structuredSections) {\n for (const fact of section.facts) {\n const normalizedFact = normalizeEntityText(fact);\n const hasNonAliasQueryOverlap = queryTokens.some((token) =>\n !aliasTokens.has(token) && normalizedFact.includes(token)\n );\n if (entry.timelineFacts.length > 0 && !hasNonAliasQueryOverlap) {\n continue;\n }\n snippets.push({ text: fact, score: mode === \"direct\" ? 6 : 7, kind: \"fact\" });\n }\n }\n if (entry.timelineFacts.length === 0 && entry.structuredSections.length === 0) {\n for (const fact of entry.facts) {\n if (!fact.trim()) continue;\n snippets.push({ text: fact, score: mode === \"direct\" ? 6 : 7, kind: \"fact\" });\n }\n }\n }\n\n if (requestedSectionKeys.size === 0) {\n for (const relationship of entry.relationships) {\n snippets.push({\n text: compactLine(relationLine(entry, relationship), 180),\n score: mode === \"direct\" && entry.type.toLowerCase() === \"person\" ? 6 : 4,\n kind: \"relationship\",\n });\n }\n\n for (const activity of entry.activity) {\n snippets.push({\n text: compactLine(`${activity.date}: ${activity.note}`, 180),\n score: 4,\n kind: \"activity\",\n });\n }\n\n for (const memorySnippet of entry.memorySnippets.slice(0, Math.min(maxSupportingFacts, 4))) {\n snippets.push({\n text: memorySnippet,\n score: 5,\n kind: \"memory\",\n });\n }\n\n for (const chunk of entry.nativeChunks) {\n snippets.push({\n text: compactLine(chunk.snippet, 180),\n score: 3,\n kind: \"native\",\n });\n }\n }\n\n const deduped = new Map<string, EntityHintSnippet>();\n for (const snippet of snippets) {\n const scored = scoreHintSnippet(snippet, queryTokens);\n if (!scored) continue;\n const normalized = normalizeEntityText(scored.text);\n const existing = deduped.get(normalized);\n if (!existing || scored.score > existing.score) deduped.set(normalized, scored);\n }\n\n return [...deduped.values()]\n .filter((snippet) => snippet.score > 0)\n .sort((left, right) => right.score - left.score)\n .slice(0, maxSupportingFacts);\n}\n\nfunction summarizeUncertainty(snippets: EntityHintSnippet[]): string | null {\n const direct = snippets.filter((snippet) =>\n snippet.kind === \"summary\"\n || snippet.kind === \"fact\"\n || snippet.kind === \"section\"\n || snippet.kind === \"memory\"\n );\n if (direct.length < 2) return null;\n for (let index = 0; index < direct.length; index += 1) {\n for (let compare = index + 1; compare < direct.length; compare += 1) {\n if (jaccardSimilarity(direct[index].text, direct[compare].text) < 0.2) {\n return \"Evidence is mixed across stored facts; treat the hints below as partial and verify before answering definitively.\";\n }\n }\n }\n return null;\n}\n\nfunction formatEntityHintSection(\n candidates: Array<{\n candidate: EntityCandidate;\n snippets: EntityHintSnippet[];\n uncertainty: string | null;\n }>,\n queryTokens: string[],\n mode: EntityQueryMode,\n maxRelatedEntities: number,\n maxChars: number,\n): string | null {\n if (candidates.length === 0) return null;\n const lines: string[] = [\"## entity_answer_hints\", \"\"];\n for (const { candidate, snippets, uncertainty } of candidates) {\n const hasSummary = Boolean(candidate.entry.summary?.trim());\n const preferredTopSnippets = hasSummary\n ? snippets.filter((snippet) => snippet.kind !== \"fact\")\n : snippets;\n let topSnippets = (\n preferredTopSnippets.length > 0 ? preferredTopSnippets : snippets\n ).slice(0, 3);\n const buildTimelineSnippets = (seedExcludedTexts: Set<string>): EntityHintSnippet[] => {\n const explicitTimelinePool = dedupeHintSnippetsByText(\n (candidate.entry.timeline ?? [])\n .slice()\n .sort(sortTimelineEntriesDesc)\n .map((entry) => sanitizeEntityFact(entry.text))\n .filter(Boolean)\n .map((text) => scoreHintSnippet({\n text: compactLine(text, 180),\n score: 7,\n kind: \"activity\" as const,\n }, queryTokens))\n .filter((snippet): snippet is EntityHintSnippet => snippet !== null)\n .filter((snippet) => !seedExcludedTexts.has(normalizeEntityText(snippet.text))),\n ).slice(0, 2);\n const activityTimelinePool = dedupeHintSnippetsByText(\n snippets\n .filter((snippet) => (\n snippet.kind === \"activity\" || snippet.kind === \"memory\"\n ) && !seedExcludedTexts.has(normalizeEntityText(snippet.text))),\n ).slice(0, 2);\n return explicitTimelinePool.length > 0\n ? explicitTimelinePool\n : activityTimelinePool.length > 0\n ? activityTimelinePool\n : dedupeHintSnippetsByText(\n snippets\n .filter((snippet) => (\n snippet.kind === \"fact\" || snippet.kind === \"summary\"\n ) && !seedExcludedTexts.has(normalizeEntityText(snippet.text))),\n ).slice(0, 2);\n };\n const baseTopSnippetTexts = new Set(topSnippets.map((snippet) => normalizeEntityText(snippet.text)));\n const timelinePool = mode !== \"direct\" ? buildTimelineSnippets(baseTopSnippetTexts) : [];\n if (mode !== \"direct\" && hasSummary && topSnippets.length < 2) {\n if (timelinePool.length > 0) {\n topSnippets = [...topSnippets, timelinePool[0]!].slice(0, 3);\n }\n }\n const topSnippetTexts = new Set(topSnippets.map((snippet) => normalizeEntityText(snippet.text)));\n lines.push(`- target: ${candidate.entry.name} (${candidate.entry.type})`);\n if (candidate.source === \"recent_turn\") {\n lines.push(`- resolution: carried forward from recent turns via alias \"${candidate.alias}\"`);\n } else {\n lines.push(`- resolution: matched alias \"${candidate.alias}\" in the query`);\n }\n if (uncertainty) lines.push(`- uncertainty: ${uncertainty}`);\n if (topSnippets.length > 0) {\n lines.push(\"- likely answer:\");\n for (const snippet of topSnippets) {\n lines.push(` - ${snippet.text}`);\n }\n }\n if (mode !== \"direct\") {\n const fallbackTimeline = timelinePool.filter(\n (snippet) => !topSnippetTexts.has(normalizeEntityText(snippet.text)),\n );\n if (fallbackTimeline.length > 0) {\n lines.push(\"- recent timeline:\");\n for (const snippet of fallbackTimeline) {\n lines.push(` - ${snippet.text}`);\n }\n }\n }\n const related = candidate.entry.relationships.slice(0, maxRelatedEntities).map((relationship) => relationship.target);\n if (related.length > 0) {\n lines.push(`- related entities: ${related.join(\", \")}`);\n }\n lines.push(`- support counts: facts=${candidate.entry.factCount}, memories=${candidate.entry.memorySnippets.length}, native=${candidate.entry.nativeChunks.length}`);\n lines.push(\"\");\n }\n\n let result = lines.join(\"\\n\");\n if (result.length > maxChars) {\n result = `${result.slice(0, Math.max(0, maxChars - 15)).trimEnd()}\\n\\n...(trimmed)\\n`;\n }\n return result.trim().length > 0 ? result.trimEnd() : null;\n}\n\nexport async function buildEntityRecallSection(options: BuildEntityRecallSectionOptions): Promise<string | null> {\n const prefixedMode = detectEntityQueryMode(options.query);\n const persistedIndex = prefixedMode\n ? null\n : await readCurrentPersistedEntityIndex(\n options.storage,\n options.config,\n options.recallNamespaces,\n options.namespaceStorage,\n );\n let nativeChunks: NativeKnowledgeChunk[] | undefined;\n if (\n !prefixedMode &&\n persistedIndex &&\n resolveLanguageIndependentExplicitCandidates(persistedIndex, options.query).length === 0\n ) {\n nativeChunks = await readNativeChunks(options.config, options.recallNamespaces);\n if (!hasFreshNativeExplicitMention(persistedIndex, nativeChunks, options.query)) {\n return null;\n }\n }\n const namespaceScoped =\n resolveNamespaceCapabilities(options.config).namespaces &&\n options.namespaceStorage !== undefined &&\n (options.recallNamespaces?.length ?? 0) > 0;\n const resolvedStorages = namespaceScoped\n ? await resolveEntityIndexStorages(\n options.storage,\n options.config,\n options.recallNamespaces,\n options.namespaceStorage,\n )\n : undefined;\n const namespaceCacheKey =\n resolvedStorages && options.recallNamespaces\n ? namespaceEntityIndexCacheKey(resolvedStorages, options.recallNamespaces)\n : undefined;\n let index: EntityMentionIndex | undefined = namespaceCacheKey\n ? namespaceEntityIndexCache.get(namespaceCacheKey)\n : undefined;\n if (!index) {\n index = await buildEntityMentionIndex(\n options.storage,\n options.config,\n options.recallNamespaces,\n options.namespaceStorage,\n nativeChunks,\n resolvedStorages,\n );\n if (namespaceCacheKey) rememberNamespaceEntityIndex(namespaceCacheKey, index);\n }\n const explicitCandidates = resolveExplicitCandidates(index, options.query);\n const queryCandidates = prefixedMode\n ? explicitCandidates\n : resolveLanguageIndependentExplicitCandidates(index, options.query);\n const mode = prefixedMode ?? (queryCandidates.length > 0 ? \"direct\" : null);\n if (!mode) return null;\n\n const candidates = queryCandidates.length > 0\n ? queryCandidates\n : resolveRecentTurnCandidates(index, options.transcriptEntries, options.recentTurns);\n\n if (candidates.length === 0) return null;\n\n const queryTokens = tokenize(options.query);\n const candidateLimit = queryCandidates.length === 0 && mode === \"follow_up\"\n ? 1\n : options.maxHints;\n const rankedCandidates = candidates.slice(0, candidateLimit);\n const enriched = await Promise.all(\n rankedCandidates.map(async (candidate) => {\n const requestedSectionKeys = new Set(\n resolveRequestedEntitySectionKeys(\n options.query,\n candidate.entry.type,\n candidate.entry.structuredSections,\n options.config.entitySchemas,\n ),\n );\n const snippets = await buildHintSnippets(\n candidate.entry,\n queryTokens,\n mode,\n options.maxSupportingFacts,\n requestedSectionKeys,\n );\n return {\n candidate,\n snippets,\n uncertainty: summarizeUncertainty(snippets),\n };\n }),\n );\n\n const section = formatEntityHintSection(enriched, queryTokens, mode, options.maxRelatedEntities, options.maxChars);\n if (!section) return null;\n return section;\n}\n\nexport async function readRecentEntityTranscriptEntries(\n transcriptEntriesPromise: Promise<TranscriptEntry[]>,\n recentTurns: number,\n): Promise<TranscriptEntry[]> {\n if (recentTurns <= 0) return [];\n const transcriptEntries = await transcriptEntriesPromise.catch(() => []);\n if (transcriptEntries.length === 0) return [];\n return transcriptEntries.slice(-Math.max(1, recentTurns * 2));\n}\n\nexport const entityIndexVersion = ENTITY_INDEX_VERSION;\nexport const entityRecentTranscriptLookbackHours = RECENT_TRANSCRIPT_LOOKBACK_HOURS;\n"],"mappings":"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","names":["index","token"]}
|