@remnic/core 9.27.0 → 9.28.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 +43 -38
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +13 -10
- package/dist/access-authorization-probe.js +44 -39
- package/dist/access-boundary.d.ts +13 -10
- package/dist/access-boundary.js +43 -38
- package/dist/access-cli.js +100 -94
- 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 +53 -48
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +43 -38
- package/dist/access-lcm-surface.d.ts +13 -10
- package/dist/access-lcm-surface.js +43 -38
- package/dist/access-mcp.d.ts +13 -10
- package/dist/access-mcp.js +48 -43
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-wRSZEO5V.d.ts → access-namespace-preflight-BiQ_-iUJ.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +43 -38
- package/dist/access-observe-write-surface.d.ts +13 -10
- package/dist/access-observe-write-surface.js +43 -38
- package/dist/access-operations-batch.js +45 -40
- package/dist/access-operations.d.ts +16 -13
- package/dist/access-operations.js +47 -42
- package/dist/access-recall-concurrency.d.ts +13 -10
- package/dist/access-recall-concurrency.js +43 -38
- package/dist/access-recall-response.d.ts +13 -10
- package/dist/access-recall-response.js +43 -38
- package/dist/access-recall-surface.d.ts +13 -10
- package/dist/access-recall-surface.js +43 -38
- package/dist/access-schema.d.ts +80 -80
- package/dist/access-schema.js +4 -4
- package/dist/{access-service-B4-Fu9x2.d.ts → access-service-CXkIgcGh.d.ts} +12 -8
- package/dist/access-service.d.ts +13 -10
- package/dist/access-service.js +43 -38
- 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-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 +7 -7
- package/dist/adapters/registry.js +3 -3
- 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 +12 -10
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-BLLxZ5L5.d.ts → catalog-Bouj8Gfg.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 +13 -11
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-7RZJWZ46.js → chunk-227UFSEQ.js} +5 -5
- package/dist/{chunk-UT3OQPFA.js → chunk-2BEJ4XCF.js} +2 -2
- package/dist/{chunk-EOLC6EXV.js → chunk-2FYNLDKJ.js} +24 -3
- package/dist/chunk-2FYNLDKJ.js.map +1 -0
- package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-6NNNURLK.js → chunk-2PHX3I5C.js} +8 -8
- package/dist/{chunk-HORJVJ6K.js → chunk-2TQ2UFKH.js} +65 -60
- package/dist/chunk-2TQ2UFKH.js.map +1 -0
- package/dist/{chunk-RPA2RX5P.js → chunk-3BSJBIZ3.js} +2 -2
- package/dist/{chunk-JCVQV6QX.js → chunk-3UOSVTFR.js} +11 -11
- package/dist/{chunk-AJ7QCSIS.js → chunk-7CPOZH6Y.js} +2 -2
- package/dist/{chunk-MEBQFQ26.js → chunk-AHFZXUZM.js} +7 -5
- package/dist/chunk-AHFZXUZM.js.map +1 -0
- package/dist/{chunk-U3TH5Q2Q.js → chunk-ALTP3MFS.js} +2 -2
- package/dist/{chunk-77CNV7DY.js → chunk-BLAKS3CP.js} +4 -4
- package/dist/{chunk-XQ4EH6DI.js → chunk-BR4UFMLO.js} +2 -2
- package/dist/chunk-CVILPI77.js +432 -0
- package/dist/chunk-CVILPI77.js.map +1 -0
- package/dist/{chunk-WEAO45M4.js → chunk-DKQM5Q6Q.js} +2 -2
- package/dist/{chunk-CSXHRAJJ.js → chunk-EG64LXKL.js} +3 -3
- package/dist/{chunk-PTN6UAUA.js → chunk-ES36HTSC.js} +4 -4
- package/dist/{chunk-5BRT4Z2I.js → chunk-EZWWCN7I.js} +2 -2
- package/dist/{chunk-XKGPIWGI.js → chunk-FBZTWUK5.js} +5 -5
- package/dist/{chunk-GJJBPI6I.js → chunk-FOCEI3TN.js} +6 -3
- package/dist/chunk-FOCEI3TN.js.map +1 -0
- package/dist/{chunk-FRVTCCGD.js → chunk-GJPCP5CA.js} +2 -2
- package/dist/{chunk-CI26JDZA.js → chunk-GQSMYXKL.js} +6 -4
- package/dist/{chunk-CI26JDZA.js.map → chunk-GQSMYXKL.js.map} +1 -1
- 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-VDX2J7OX.js → chunk-IPLYGWQF.js} +6 -6
- package/dist/{chunk-YSGBD3QN.js → chunk-IYT632D5.js} +3 -3
- package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
- package/dist/{chunk-RSYJV25N.js → chunk-JIF3VRKQ.js} +8 -8
- package/dist/{chunk-V25OWXAC.js → chunk-JQ7T5VDC.js} +1 -1
- package/dist/chunk-JQ7T5VDC.js.map +1 -0
- package/dist/{chunk-EUSLKI4X.js → chunk-KKBTBUVT.js} +2 -2
- package/dist/{chunk-RNY3BO35.js → chunk-LIHC3T43.js} +2 -2
- package/dist/{chunk-RGJBM7Z3.js → chunk-MJPV4LBH.js} +79 -79
- package/dist/{chunk-RGJBM7Z3.js.map → chunk-MJPV4LBH.js.map} +1 -1
- package/dist/{chunk-UGH6VPPO.js → chunk-MWTMTW2T.js} +2 -2
- package/dist/{chunk-MG6MNSP4.js → chunk-MXJ3VP6S.js} +6 -6
- package/dist/{chunk-XKO7BM2C.js → chunk-NBNDVNJ2.js} +186 -25
- package/dist/chunk-NBNDVNJ2.js.map +1 -0
- package/dist/{chunk-M5EPMNS4.js → chunk-P2CLYN6H.js} +2 -2
- package/dist/{chunk-BNGPHGVZ.js → chunk-PXQM2HOG.js} +13 -6
- package/dist/{chunk-BNGPHGVZ.js.map → chunk-PXQM2HOG.js.map} +1 -1
- package/dist/{chunk-CIQXI47W.js → chunk-Q5VJUNXA.js} +1192 -268
- package/dist/chunk-Q5VJUNXA.js.map +1 -0
- package/dist/{chunk-KGTD2KZJ.js → chunk-Q6YJW6KE.js} +2 -2
- package/dist/{chunk-X3SQYAPP.js → chunk-R372P2EH.js} +2 -2
- package/dist/{chunk-4MJZTF42.js → chunk-RKXZ7P4V.js} +3 -3
- package/dist/chunk-RMMVQQA6.js +70 -0
- package/dist/chunk-RMMVQQA6.js.map +1 -0
- package/dist/{chunk-2RAC4JIG.js → chunk-S24E4MBQ.js} +14 -14
- package/dist/chunk-S24E4MBQ.js.map +1 -0
- package/dist/{chunk-RYHWZ52A.js → chunk-S2BBISHU.js} +4 -4
- package/dist/{chunk-LLISELSY.js → chunk-TBMRQZDY.js} +2 -2
- package/dist/{chunk-FMLKOL2Z.js → chunk-TC3VNKGX.js} +4 -4
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-NUWMZIYZ.js → chunk-UR5SIN7H.js} +53 -35
- package/dist/chunk-UR5SIN7H.js.map +1 -0
- package/dist/{chunk-JDOJZTFF.js → chunk-VFNI3RPT.js} +2 -2
- package/dist/chunk-VNA7W7QF.js +134 -0
- package/dist/chunk-VNA7W7QF.js.map +1 -0
- package/dist/{chunk-EYJSW2RV.js → chunk-VYYNBJXH.js} +5 -5
- package/dist/chunk-WNIUPHWV.js +152 -0
- package/dist/chunk-WNIUPHWV.js.map +1 -0
- package/dist/chunk-WRJVB3C2.js +118 -0
- package/dist/chunk-WRJVB3C2.js.map +1 -0
- package/dist/{chunk-BHLN7L7M.js → chunk-WVVK2RFM.js} +6 -6
- package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-HEXSNYJD.js → chunk-YOBNCD3Z.js} +6 -6
- package/dist/chunk-YXZG5TVN.js +40 -0
- package/dist/chunk-YXZG5TVN.js.map +1 -0
- package/dist/{chunk-4DJQYKMN.js → chunk-ZIKENA2C.js} +2 -2
- package/dist/chunk-ZIKENA2C.js.map +1 -0
- package/dist/{chunk-SK3EYPKC.js → chunk-ZN4UZWMT.js} +2 -2
- package/dist/{cli-Bz7X7dGx.d.ts → cli-DJbkaZBU.d.ts} +5 -5
- package/dist/cli.d.ts +14 -12
- package/dist/cli.js +79 -74
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +12 -10
- 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 +12 -10
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +12 -10
- 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/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 +25 -21
- package/dist/day-summary.d.ts +1 -1
- 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/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 +13 -10
- 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/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.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-BKNGOFED.js} +4 -4
- 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 +409 -407
- package/dist/index.js +147 -141
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +9 -9
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +12 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -10
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +13 -11
- package/dist/{maintenance-DgnD2z8S.d.ts → maintenance-DveW6azo.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 +22 -20
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +12 -10
- 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 +3 -3
- package/dist/operator-doctor-corpus.d.ts +22 -3
- package/dist/operator-doctor-corpus.js +32 -22
- 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 +33 -27
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +17 -15
- package/dist/{orchestrator-rIHmHpv1.d.ts → orchestrator-Cvlgpe6I.d.ts} +7 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +99 -93
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-Bq5zU6Bp.d.ts → pipeline-BveYVaz7.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-CLWDsbYR.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 +76 -76
- package/dist/{scope-profiles-D0-ff4xT.d.ts → scope-profiles-BVf3DZ7z.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +13 -13
- 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-DXLV47y2.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +13 -11
- package/dist/semantic-rule-promotion.js +12 -10
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +12 -10
- package/dist/{service-cTvil7D_.d.ts → service-DbgPTeMJ.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/signal.d.ts +1 -1
- package/dist/{storage-C9ibpTme.d.ts → storage-DOzTm8wG.d.ts} +13 -19
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +13 -10
- package/dist/summarizer.d.ts +1 -1
- 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/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +3 -3
- 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-BA7W-_xy.d.ts} +53 -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 +12 -10
- 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/cli.ts +9 -7
- package/src/config.ts +2 -1
- 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/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 +3 -3
- 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-V25OWXAC.js.map +0 -1
- package/dist/chunk-XKO7BM2C.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-7RZJWZ46.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-UT3OQPFA.js.map → chunk-2BEJ4XCF.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-6NNNURLK.js.map → chunk-2PHX3I5C.js.map} +0 -0
- /package/dist/{chunk-RPA2RX5P.js.map → chunk-3BSJBIZ3.js.map} +0 -0
- /package/dist/{chunk-JCVQV6QX.js.map → chunk-3UOSVTFR.js.map} +0 -0
- /package/dist/{chunk-AJ7QCSIS.js.map → chunk-7CPOZH6Y.js.map} +0 -0
- /package/dist/{chunk-U3TH5Q2Q.js.map → chunk-ALTP3MFS.js.map} +0 -0
- /package/dist/{chunk-77CNV7DY.js.map → chunk-BLAKS3CP.js.map} +0 -0
- /package/dist/{chunk-XQ4EH6DI.js.map → chunk-BR4UFMLO.js.map} +0 -0
- /package/dist/{chunk-WEAO45M4.js.map → chunk-DKQM5Q6Q.js.map} +0 -0
- /package/dist/{chunk-CSXHRAJJ.js.map → chunk-EG64LXKL.js.map} +0 -0
- /package/dist/{chunk-PTN6UAUA.js.map → chunk-ES36HTSC.js.map} +0 -0
- /package/dist/{chunk-5BRT4Z2I.js.map → chunk-EZWWCN7I.js.map} +0 -0
- /package/dist/{chunk-XKGPIWGI.js.map → chunk-FBZTWUK5.js.map} +0 -0
- /package/dist/{chunk-FRVTCCGD.js.map → chunk-GJPCP5CA.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-IPLYGWQF.js.map} +0 -0
- /package/dist/{chunk-YSGBD3QN.js.map → chunk-IYT632D5.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-RSYJV25N.js.map → chunk-JIF3VRKQ.js.map} +0 -0
- /package/dist/{chunk-EUSLKI4X.js.map → chunk-KKBTBUVT.js.map} +0 -0
- /package/dist/{chunk-RNY3BO35.js.map → chunk-LIHC3T43.js.map} +0 -0
- /package/dist/{chunk-UGH6VPPO.js.map → chunk-MWTMTW2T.js.map} +0 -0
- /package/dist/{chunk-MG6MNSP4.js.map → chunk-MXJ3VP6S.js.map} +0 -0
- /package/dist/{chunk-M5EPMNS4.js.map → chunk-P2CLYN6H.js.map} +0 -0
- /package/dist/{chunk-KGTD2KZJ.js.map → chunk-Q6YJW6KE.js.map} +0 -0
- /package/dist/{chunk-X3SQYAPP.js.map → chunk-R372P2EH.js.map} +0 -0
- /package/dist/{chunk-4MJZTF42.js.map → chunk-RKXZ7P4V.js.map} +0 -0
- /package/dist/{chunk-RYHWZ52A.js.map → chunk-S2BBISHU.js.map} +0 -0
- /package/dist/{chunk-LLISELSY.js.map → chunk-TBMRQZDY.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-JDOJZTFF.js.map → chunk-VFNI3RPT.js.map} +0 -0
- /package/dist/{chunk-EYJSW2RV.js.map → chunk-VYYNBJXH.js.map} +0 -0
- /package/dist/{chunk-BHLN7L7M.js.map → chunk-WVVK2RFM.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-HEXSNYJD.js.map → chunk-YOBNCD3Z.js.map} +0 -0
- /package/dist/{chunk-SK3EYPKC.js.map → chunk-ZN4UZWMT.js.map} +0 -0
- /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-BKNGOFED.js.map} +0 -0
package/src/entity-retrieval.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { collectNativeKnowledgeChunks, type NativeKnowledgeChunk } from "./nativ
|
|
|
7
7
|
import { compareEntityTimestamps, normalizeEntityName, type StorageManager } from "./storage.js";
|
|
8
8
|
import { normalizeEntityText, resolveRequestedEntitySectionKeys } from "./entity-schema.js";
|
|
9
9
|
import type { EntityStructuredSection, MemoryFile, PluginConfig, TranscriptEntry } from "./types.js";
|
|
10
|
+
import { containsPhrase } from "./entity-retrieval-boundaries.js";
|
|
10
11
|
|
|
11
12
|
const ENTITY_INDEX_VERSION = 3;
|
|
12
13
|
const RECENT_TRANSCRIPT_LOOKBACK_HOURS = 24;
|
|
@@ -51,6 +52,7 @@ type EntityMentionIndexEntry = {
|
|
|
51
52
|
type EntityMentionIndex = {
|
|
52
53
|
version: number;
|
|
53
54
|
updatedAt: string;
|
|
55
|
+
entityStatusVersion?: number;
|
|
54
56
|
entities: EntityMentionIndexEntry[];
|
|
55
57
|
};
|
|
56
58
|
|
|
@@ -89,12 +91,6 @@ function uniqueStrings(values: string[]): string[] {
|
|
|
89
91
|
return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))];
|
|
90
92
|
}
|
|
91
93
|
|
|
92
|
-
function containsPhrase(haystack: string, needle: string): boolean {
|
|
93
|
-
if (!needle) return false;
|
|
94
|
-
const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95
|
-
return new RegExp(`(^|\\b)${escaped}(\\b|$)`, "i").test(haystack);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
94
|
function compactLine(value: string, maxLength: number = 220): string {
|
|
99
95
|
const normalized = value.replace(/\s+/g, " ").trim();
|
|
100
96
|
if (normalized.length <= maxLength) return normalized;
|
|
@@ -383,6 +379,57 @@ async function readEntityIndexState(storage: StorageManager): Promise<EntityMent
|
|
|
383
379
|
}
|
|
384
380
|
}
|
|
385
381
|
|
|
382
|
+
|
|
383
|
+
async function readCurrentPersistedEntityIndex(
|
|
384
|
+
storage: StorageManager,
|
|
385
|
+
config: PluginConfig,
|
|
386
|
+
recallNamespaces?: string[],
|
|
387
|
+
namespaceStorage?: (namespace: string) => Promise<StorageManager>,
|
|
388
|
+
): Promise<EntityMentionIndex | null> {
|
|
389
|
+
if (
|
|
390
|
+
resolveNamespaceCapabilities(config).namespaces &&
|
|
391
|
+
namespaceStorage &&
|
|
392
|
+
recallNamespaces &&
|
|
393
|
+
recallNamespaces.length > 0
|
|
394
|
+
) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
const index = await readEntityIndexState(storage);
|
|
398
|
+
if (!index || index.entityStatusVersion !== storage.getMemoryStatusVersion()) {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
return index;
|
|
402
|
+
}
|
|
403
|
+
const namespaceEntityIndexCache = new Map<string, EntityMentionIndex>();
|
|
404
|
+
const MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES = 32;
|
|
405
|
+
|
|
406
|
+
function namespaceEntityIndexCacheKey(
|
|
407
|
+
storages: StorageManager[],
|
|
408
|
+
recallNamespaces: string[],
|
|
409
|
+
): string {
|
|
410
|
+
const namespaceKey = uniqueStrings(recallNamespaces).sort().join("\u001f");
|
|
411
|
+
const storageKey = storages
|
|
412
|
+
.map((scopedStorage) => {
|
|
413
|
+
const aliases = Object.entries(scopedStorage.entityAliases)
|
|
414
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
415
|
+
return (
|
|
416
|
+
`${path.resolve(scopedStorage.dir)}@${scopedStorage.getMemoryStatusVersion()}` +
|
|
417
|
+
`:${scopedStorage.getMemoryCorpusVersion()}:${scopedStorage.hotCacheKeyId()}:${JSON.stringify(aliases)}`
|
|
418
|
+
);
|
|
419
|
+
})
|
|
420
|
+
.sort()
|
|
421
|
+
.join("\u001f");
|
|
422
|
+
return `${namespaceKey}\u001e${storageKey}`;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function rememberNamespaceEntityIndex(key: string, index: EntityMentionIndex): void {
|
|
426
|
+
if (namespaceEntityIndexCache.size >= MAX_NAMESPACE_ENTITY_INDEX_CACHE_ENTRIES) {
|
|
427
|
+
const oldestKey = namespaceEntityIndexCache.keys().next().value;
|
|
428
|
+
if (typeof oldestKey === "string") namespaceEntityIndexCache.delete(oldestKey);
|
|
429
|
+
}
|
|
430
|
+
namespaceEntityIndexCache.set(key, index);
|
|
431
|
+
}
|
|
432
|
+
|
|
386
433
|
async function writeEntityIndexState(storage: StorageManager, index: EntityMentionIndex): Promise<void> {
|
|
387
434
|
const statePath = entityIndexStatePath(storage);
|
|
388
435
|
await mkdir(path.dirname(statePath), { recursive: true });
|
|
@@ -438,13 +485,32 @@ function mergeNativeChunk(entry: EntityMentionIndexEntry, chunk: NativeKnowledge
|
|
|
438
485
|
entry.aliases = uniqueStrings([...entry.aliases, ...(chunk.aliases ?? [])]);
|
|
439
486
|
}
|
|
440
487
|
|
|
488
|
+
function hasFreshNativeExplicitMention(
|
|
489
|
+
index: EntityMentionIndex,
|
|
490
|
+
nativeChunks: NativeKnowledgeChunk[],
|
|
491
|
+
query: string,
|
|
492
|
+
): boolean {
|
|
493
|
+
if (nativeChunks.length === 0) return false;
|
|
494
|
+
const nativeCanonicalIds = new Set(nativeChunks.map(nativePseudoCanonicalId));
|
|
495
|
+
const freshNativeIndex: EntityMentionIndex = {
|
|
496
|
+
...index,
|
|
497
|
+
entities: [
|
|
498
|
+
...index.entities.filter((entry) => !nativeCanonicalIds.has(entry.canonicalId)),
|
|
499
|
+
...nativeChunks.map(createPseudoNativeEntry),
|
|
500
|
+
],
|
|
501
|
+
};
|
|
502
|
+
return resolveLanguageIndependentExplicitCandidates(freshNativeIndex, query).length > 0;
|
|
503
|
+
}
|
|
504
|
+
|
|
441
505
|
async function buildEntityMentionIndex(
|
|
442
506
|
storage: StorageManager,
|
|
443
507
|
config: PluginConfig,
|
|
444
508
|
recallNamespaces?: string[],
|
|
445
509
|
namespaceStorage?: (namespace: string) => Promise<StorageManager>,
|
|
510
|
+
nativeChunksOverride?: NativeKnowledgeChunk[],
|
|
511
|
+
resolvedStorages?: StorageManager[],
|
|
446
512
|
): Promise<EntityMentionIndex> {
|
|
447
|
-
const storages = await resolveEntityIndexStorages(
|
|
513
|
+
const storages = resolvedStorages ?? await resolveEntityIndexStorages(
|
|
448
514
|
storage,
|
|
449
515
|
config,
|
|
450
516
|
recallNamespaces,
|
|
@@ -452,23 +518,27 @@ async function buildEntityMentionIndex(
|
|
|
452
518
|
);
|
|
453
519
|
const shouldPersistIndex =
|
|
454
520
|
storages.length === 1 && path.resolve(storages[0]!.dir) === path.resolve(storage.dir);
|
|
521
|
+
const entityStatusVersionBefore = shouldPersistIndex ? storage.getMemoryStatusVersion() : undefined;
|
|
455
522
|
const [previousIndex, entityFileSets, memorySets, nativeChunks] = await Promise.all([
|
|
456
523
|
shouldPersistIndex ? readEntityIndexState(storage) : Promise.resolve(null),
|
|
457
524
|
Promise.all(storages.map((scopedStorage) => scopedStorage.readAllEntityFiles())),
|
|
458
525
|
Promise.all(storages.map((scopedStorage) => scopedStorage.readAllMemories())),
|
|
459
|
-
readNativeChunks(config, recallNamespaces),
|
|
526
|
+
nativeChunksOverride ? Promise.resolve(nativeChunksOverride) : readNativeChunks(config, recallNamespaces),
|
|
460
527
|
]);
|
|
461
|
-
// Pair each entity with the
|
|
462
|
-
//
|
|
528
|
+
// Pair each entity with the storage that owns it (#1534): canonical ids must
|
|
529
|
+
// reflect that store's aliases and historical migration mappings, never another
|
|
463
530
|
// namespace's.
|
|
464
531
|
const entityRecords = entityFileSets.flatMap((set, index) =>
|
|
465
|
-
set.map((entity) => ({ entity,
|
|
532
|
+
set.map((entity) => ({ entity, storage: storages[index]! })),
|
|
466
533
|
);
|
|
467
534
|
const memories = memorySets.flat();
|
|
468
535
|
|
|
469
536
|
const entities = new Map<string, EntityMentionIndexEntry>();
|
|
470
|
-
for (const { entity,
|
|
471
|
-
const canonicalId =
|
|
537
|
+
for (const { entity, storage: entityStorage } of entityRecords) {
|
|
538
|
+
const canonicalId =
|
|
539
|
+
typeof entityStorage.normalizeEntityName === "function"
|
|
540
|
+
? entityStorage.normalizeEntityName(entity.name, entity.type)
|
|
541
|
+
: normalizeEntityName(entity.name, entity.type, entityStorage.entityAliases);
|
|
472
542
|
const rawStructuredSections = entity.structuredSections ?? [];
|
|
473
543
|
const rawBeliefLedgerFactKeys = beliefLedgerFactKeys(rawStructuredSections);
|
|
474
544
|
const sanitizedFacts = entity.facts
|
|
@@ -539,15 +609,18 @@ async function buildEntityMentionIndex(
|
|
|
539
609
|
const sortedEntities = [...entities.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
540
610
|
const previousEntities = previousIndex ? JSON.stringify(previousIndex.entities) : "";
|
|
541
611
|
const nextEntities = JSON.stringify(sortedEntities);
|
|
612
|
+
const entityStatusVersionAfter = shouldPersistIndex ? storage.getMemoryStatusVersion() : undefined;
|
|
613
|
+
const canPersistIndex = shouldPersistIndex && entityStatusVersionBefore === entityStatusVersionAfter;
|
|
542
614
|
const index: EntityMentionIndex = {
|
|
543
615
|
version: ENTITY_INDEX_VERSION,
|
|
544
616
|
updatedAt:
|
|
545
617
|
previousIndex && previousEntities === nextEntities
|
|
546
618
|
? previousIndex.updatedAt
|
|
547
619
|
: new Date().toISOString(),
|
|
620
|
+
entityStatusVersion: canPersistIndex ? entityStatusVersionAfter : undefined,
|
|
548
621
|
entities: sortedEntities,
|
|
549
622
|
};
|
|
550
|
-
if (
|
|
623
|
+
if (canPersistIndex) {
|
|
551
624
|
await writeEntityIndexState(storage, index);
|
|
552
625
|
}
|
|
553
626
|
return index;
|
|
@@ -575,6 +648,114 @@ function resolveExplicitCandidates(
|
|
|
575
648
|
return candidates.sort((left, right) => right.score - left.score);
|
|
576
649
|
}
|
|
577
650
|
|
|
651
|
+
const EXPLICIT_ENTITY_MENTION_SCORE = 9;
|
|
652
|
+
|
|
653
|
+
const IMPLICIT_ENTITY_STOP_WORDS = new Set([
|
|
654
|
+
"a",
|
|
655
|
+
"an",
|
|
656
|
+
"and",
|
|
657
|
+
"are",
|
|
658
|
+
"as",
|
|
659
|
+
"at",
|
|
660
|
+
"be",
|
|
661
|
+
"by",
|
|
662
|
+
"can",
|
|
663
|
+
"do",
|
|
664
|
+
"for",
|
|
665
|
+
"from",
|
|
666
|
+
"has",
|
|
667
|
+
"how",
|
|
668
|
+
"i",
|
|
669
|
+
"if",
|
|
670
|
+
"in",
|
|
671
|
+
"is",
|
|
672
|
+
"it",
|
|
673
|
+
"me",
|
|
674
|
+
"my",
|
|
675
|
+
"of",
|
|
676
|
+
"on",
|
|
677
|
+
"or",
|
|
678
|
+
"the",
|
|
679
|
+
"to",
|
|
680
|
+
"was",
|
|
681
|
+
"what",
|
|
682
|
+
"when",
|
|
683
|
+
"where",
|
|
684
|
+
"who",
|
|
685
|
+
"why",
|
|
686
|
+
"with",
|
|
687
|
+
"you",
|
|
688
|
+
"your",
|
|
689
|
+
]);
|
|
690
|
+
|
|
691
|
+
function isDistinctiveImplicitAlias(normalizedAlias: string): boolean {
|
|
692
|
+
const tokens = normalizedAlias.split(/\s+/).filter(Boolean);
|
|
693
|
+
if (tokens.length > 1 && tokens.every((token) => IMPLICIT_ENTITY_STOP_WORDS.has(token))) return false;
|
|
694
|
+
if (tokens.length !== 1) return true;
|
|
695
|
+
const token = tokens[0]!;
|
|
696
|
+
return Array.from(token).length > 1 && !IMPLICIT_ENTITY_STOP_WORDS.has(token);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function isShortLatinAlias(alias: string): boolean {
|
|
700
|
+
return /^[A-Za-z]{2,3}$/.test(alias.trim());
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function hasStrongShortLatinAliasMention(query: string, alias: string): boolean {
|
|
704
|
+
const normalizedAlias = alias.trim();
|
|
705
|
+
const titleCaseAlias = `${normalizedAlias[0]!.toUpperCase()}${normalizedAlias.slice(1).toLowerCase()}`;
|
|
706
|
+
const forms = new Set([normalizedAlias, normalizedAlias.toUpperCase(), titleCaseAlias]);
|
|
707
|
+
return [...forms].some((form) => {
|
|
708
|
+
if (form === form.toLowerCase()) return false;
|
|
709
|
+
const escaped = form.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
710
|
+
return new RegExp(`(?:^|[^A-Za-z0-9])${escaped}(?:$|[^A-Za-z0-9])`).test(query);
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function resolveLanguageIndependentExplicitCandidates(
|
|
715
|
+
index: EntityMentionIndex,
|
|
716
|
+
query: string,
|
|
717
|
+
): EntityCandidate[] {
|
|
718
|
+
const canonicalIdsByAlias = new Map<string, Set<string>>();
|
|
719
|
+
for (const entry of index.entities) {
|
|
720
|
+
for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {
|
|
721
|
+
const normalizedAlias = normalizeEntityText(alias);
|
|
722
|
+
if (!normalizedAlias) continue;
|
|
723
|
+
const canonicalIds = canonicalIdsByAlias.get(normalizedAlias) ?? new Set<string>();
|
|
724
|
+
canonicalIds.add(entry.canonicalId);
|
|
725
|
+
canonicalIdsByAlias.set(normalizedAlias, canonicalIds);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const candidates: EntityCandidate[] = [];
|
|
730
|
+
for (const entry of index.entities) {
|
|
731
|
+
let bestAlias = "";
|
|
732
|
+
let bestScore = 0;
|
|
733
|
+
for (const alias of uniqueStrings([entry.name, ...entry.aliases])) {
|
|
734
|
+
const normalizedAlias = normalizeEntityText(alias);
|
|
735
|
+
const score = scoreAliasMatch(query, alias);
|
|
736
|
+
if (
|
|
737
|
+
!normalizedAlias ||
|
|
738
|
+
!isDistinctiveImplicitAlias(normalizedAlias) ||
|
|
739
|
+
(isShortLatinAlias(alias) && !hasStrongShortLatinAliasMention(query, alias)) ||
|
|
740
|
+
canonicalIdsByAlias.get(normalizedAlias)?.size !== 1 ||
|
|
741
|
+
score < EXPLICIT_ENTITY_MENTION_SCORE ||
|
|
742
|
+
score <= bestScore
|
|
743
|
+
) {
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
bestAlias = alias;
|
|
747
|
+
bestScore = score;
|
|
748
|
+
}
|
|
749
|
+
if (bestAlias) {
|
|
750
|
+
candidates.push({ entry, alias: bestAlias, score: bestScore, source: "query" });
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
return candidates.sort(
|
|
755
|
+
(left, right) => right.score - left.score || left.entry.name.localeCompare(right.entry.name),
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
578
759
|
function resolveRecentTurnCandidates(
|
|
579
760
|
index: EntityMentionIndex,
|
|
580
761
|
transcriptEntries: TranscriptEntry[],
|
|
@@ -825,26 +1006,71 @@ function formatEntityHintSection(
|
|
|
825
1006
|
}
|
|
826
1007
|
|
|
827
1008
|
export async function buildEntityRecallSection(options: BuildEntityRecallSectionOptions): Promise<string | null> {
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
1009
|
+
const prefixedMode = detectEntityQueryMode(options.query);
|
|
1010
|
+
const persistedIndex = prefixedMode
|
|
1011
|
+
? null
|
|
1012
|
+
: await readCurrentPersistedEntityIndex(
|
|
1013
|
+
options.storage,
|
|
1014
|
+
options.config,
|
|
1015
|
+
options.recallNamespaces,
|
|
1016
|
+
options.namespaceStorage,
|
|
1017
|
+
);
|
|
1018
|
+
let nativeChunks: NativeKnowledgeChunk[] | undefined;
|
|
1019
|
+
if (
|
|
1020
|
+
!prefixedMode &&
|
|
1021
|
+
persistedIndex &&
|
|
1022
|
+
resolveLanguageIndependentExplicitCandidates(persistedIndex, options.query).length === 0
|
|
1023
|
+
) {
|
|
1024
|
+
nativeChunks = await readNativeChunks(options.config, options.recallNamespaces);
|
|
1025
|
+
if (!hasFreshNativeExplicitMention(persistedIndex, nativeChunks, options.query)) {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
const namespaceScoped =
|
|
1030
|
+
resolveNamespaceCapabilities(options.config).namespaces &&
|
|
1031
|
+
options.namespaceStorage !== undefined &&
|
|
1032
|
+
(options.recallNamespaces?.length ?? 0) > 0;
|
|
1033
|
+
const resolvedStorages = namespaceScoped
|
|
1034
|
+
? await resolveEntityIndexStorages(
|
|
1035
|
+
options.storage,
|
|
1036
|
+
options.config,
|
|
1037
|
+
options.recallNamespaces,
|
|
1038
|
+
options.namespaceStorage,
|
|
1039
|
+
)
|
|
1040
|
+
: undefined;
|
|
1041
|
+
const namespaceCacheKey =
|
|
1042
|
+
resolvedStorages && options.recallNamespaces
|
|
1043
|
+
? namespaceEntityIndexCacheKey(resolvedStorages, options.recallNamespaces)
|
|
1044
|
+
: undefined;
|
|
1045
|
+
let index: EntityMentionIndex | undefined = namespaceCacheKey
|
|
1046
|
+
? namespaceEntityIndexCache.get(namespaceCacheKey)
|
|
1047
|
+
: undefined;
|
|
1048
|
+
if (!index) {
|
|
1049
|
+
index = await buildEntityMentionIndex(
|
|
1050
|
+
options.storage,
|
|
1051
|
+
options.config,
|
|
1052
|
+
options.recallNamespaces,
|
|
1053
|
+
options.namespaceStorage,
|
|
1054
|
+
nativeChunks,
|
|
1055
|
+
resolvedStorages,
|
|
1056
|
+
);
|
|
1057
|
+
if (namespaceCacheKey) rememberNamespaceEntityIndex(namespaceCacheKey, index);
|
|
1058
|
+
}
|
|
839
1059
|
const explicitCandidates = resolveExplicitCandidates(index, options.query);
|
|
840
|
-
const
|
|
1060
|
+
const queryCandidates = prefixedMode
|
|
841
1061
|
? explicitCandidates
|
|
1062
|
+
: resolveLanguageIndependentExplicitCandidates(index, options.query);
|
|
1063
|
+
const mode = prefixedMode ?? (queryCandidates.length > 0 ? "direct" : null);
|
|
1064
|
+
if (!mode) return null;
|
|
1065
|
+
|
|
1066
|
+
const candidates = queryCandidates.length > 0
|
|
1067
|
+
? queryCandidates
|
|
842
1068
|
: resolveRecentTurnCandidates(index, options.transcriptEntries, options.recentTurns);
|
|
843
1069
|
|
|
844
1070
|
if (candidates.length === 0) return null;
|
|
845
1071
|
|
|
846
1072
|
const queryTokens = tokenize(options.query);
|
|
847
|
-
const candidateLimit =
|
|
1073
|
+
const candidateLimit = queryCandidates.length === 0 && mode === "follow_up"
|
|
848
1074
|
? 1
|
|
849
1075
|
: options.maxHints;
|
|
850
1076
|
const rankedCandidates = candidates.slice(0, candidateLimit);
|
package/src/entity-schema.ts
CHANGED
|
@@ -44,8 +44,9 @@ const DEFAULT_ENTITY_SCHEMAS: Record<string, EntitySchemaDefinition> = {
|
|
|
44
44
|
|
|
45
45
|
export function normalizeEntityText(value: string): string {
|
|
46
46
|
return value
|
|
47
|
+
.normalize("NFC")
|
|
47
48
|
.toLowerCase()
|
|
48
|
-
.replace(/[
|
|
49
|
+
.replace(/[^\p{L}\p{M}\p{N}]+/gu, " ")
|
|
49
50
|
.trim();
|
|
50
51
|
}
|
|
51
52
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
2
|
+
import { isErrnoCode } from "./utils/errno.js";
|
|
3
|
+
import { assertPathInsideRoot } from "./utils/path-containment.js";
|
|
4
|
+
import { getMemoryProjectionPath, initializeMemoryProjectionDb } from "./memory-projection-store.js";
|
|
5
|
+
import { type BetterSqlite3Database, openBetterSqlite3 } from "./runtime/better-sqlite.js";
|
|
6
|
+
|
|
7
|
+
const PROJECTION_WRITE_BUSY_TIMEOUT_MS = 100;
|
|
8
|
+
const PROJECTION_WRITE_RETRY_COUNT = 4;
|
|
9
|
+
const PROJECTION_WRITE_RETRY_DELAY_MS = 100;
|
|
10
|
+
|
|
11
|
+
function isSqliteBusyError(error: unknown): boolean {
|
|
12
|
+
const messages: string[] = [];
|
|
13
|
+
const seen = new Set<unknown>();
|
|
14
|
+
let current: unknown = error;
|
|
15
|
+
while (current !== null && typeof current === "object" && !seen.has(current)) {
|
|
16
|
+
seen.add(current);
|
|
17
|
+
if (current instanceof Error) messages.push(current.message);
|
|
18
|
+
if (!("cause" in current)) break;
|
|
19
|
+
current = current.cause;
|
|
20
|
+
}
|
|
21
|
+
const lower = messages.join("\n").toLowerCase();
|
|
22
|
+
return lower.includes("database is locked") || lower.includes("sqlite_busy");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function validateProjectionPath(
|
|
26
|
+
memoryDir: string,
|
|
27
|
+
projectionPath: string,
|
|
28
|
+
): Promise<boolean> {
|
|
29
|
+
let projectionStat;
|
|
30
|
+
try {
|
|
31
|
+
projectionStat = await lstat(projectionPath);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (isErrnoCode(error, "ENOENT")) return false;
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
if (projectionStat.isSymbolicLink() || !projectionStat.isFile()) {
|
|
37
|
+
throw new Error(`Refusing memory projection rewrite through unsafe database path: ${projectionPath}.`);
|
|
38
|
+
}
|
|
39
|
+
const [memoryRoot, projectionReal] = await Promise.all([
|
|
40
|
+
realpath(memoryDir),
|
|
41
|
+
realpath(projectionPath),
|
|
42
|
+
]);
|
|
43
|
+
assertPathInsideRoot(memoryRoot, projectionReal, projectionPath);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function rewriteProjectedEntityReferenceRows(
|
|
48
|
+
memoryDir: string,
|
|
49
|
+
entries: ReadonlyArray<readonly [string, string]>,
|
|
50
|
+
memoryId?: string,
|
|
51
|
+
): Promise<void> {
|
|
52
|
+
if (memoryId !== undefined && memoryId.length === 0) {
|
|
53
|
+
throw new Error("Projection memoryId must not be empty.");
|
|
54
|
+
}
|
|
55
|
+
const scopedMemory = memoryId !== undefined;
|
|
56
|
+
const validEntries = entries.filter(
|
|
57
|
+
([previousEntityRef, nextEntityRef]) =>
|
|
58
|
+
previousEntityRef.length > 0 && nextEntityRef.length > 0 && previousEntityRef !== nextEntityRef,
|
|
59
|
+
);
|
|
60
|
+
if (validEntries.length === 0) return;
|
|
61
|
+
|
|
62
|
+
const projectionPath = getMemoryProjectionPath(memoryDir);
|
|
63
|
+
if (!(await validateProjectionPath(memoryDir, projectionPath))) return;
|
|
64
|
+
|
|
65
|
+
let lastError: unknown;
|
|
66
|
+
for (let attempt = 0; attempt < PROJECTION_WRITE_RETRY_COUNT; attempt += 1) {
|
|
67
|
+
if (!(await validateProjectionPath(memoryDir, projectionPath))) return;
|
|
68
|
+
let db: BetterSqlite3Database | null = null;
|
|
69
|
+
try {
|
|
70
|
+
db = openBetterSqlite3(projectionPath, { fileMustExist: true });
|
|
71
|
+
db.pragma(`busy_timeout = ${PROJECTION_WRITE_BUSY_TIMEOUT_MS}`);
|
|
72
|
+
initializeMemoryProjectionDb(db);
|
|
73
|
+
const updateCurrent = db.prepare(
|
|
74
|
+
scopedMemory
|
|
75
|
+
? "UPDATE memory_current SET entity_ref = ? WHERE memory_id = ? AND entity_ref = ?"
|
|
76
|
+
: "UPDATE memory_current SET entity_ref = ? WHERE entity_ref = ?",
|
|
77
|
+
);
|
|
78
|
+
const updateMentions = db.prepare(
|
|
79
|
+
scopedMemory
|
|
80
|
+
? `
|
|
81
|
+
UPDATE memory_entity_mentions
|
|
82
|
+
SET entity_ref = ?
|
|
83
|
+
WHERE memory_id = ? AND entity_ref = ? AND mention_source = 'frontmatter.entityRef'
|
|
84
|
+
`
|
|
85
|
+
: `
|
|
86
|
+
UPDATE memory_entity_mentions
|
|
87
|
+
SET entity_ref = ?
|
|
88
|
+
WHERE entity_ref = ? AND mention_source = 'frontmatter.entityRef'
|
|
89
|
+
`,
|
|
90
|
+
);
|
|
91
|
+
const rewrite = db.transaction(() => {
|
|
92
|
+
for (const [previousEntityRef, nextEntityRef] of validEntries) {
|
|
93
|
+
const params = scopedMemory
|
|
94
|
+
? [nextEntityRef, memoryId, previousEntityRef]
|
|
95
|
+
: [nextEntityRef, previousEntityRef];
|
|
96
|
+
updateCurrent.run(...params);
|
|
97
|
+
updateMentions.run(...params);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
rewrite();
|
|
101
|
+
return;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
lastError = error;
|
|
104
|
+
if (!isSqliteBusyError(error) || attempt === PROJECTION_WRITE_RETRY_COUNT - 1) {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
const { promise, resolve } = Promise.withResolvers<void>();
|
|
108
|
+
setTimeout(resolve, PROJECTION_WRITE_RETRY_DELAY_MS);
|
|
109
|
+
await promise;
|
|
110
|
+
} finally {
|
|
111
|
+
db?.close();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
throw lastError instanceof Error ? lastError : new Error("Projection rewrite failed.");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function rewriteProjectedMemoryEntityReference(
|
|
119
|
+
memoryDir: string,
|
|
120
|
+
memoryId: string,
|
|
121
|
+
previousEntityRef: string,
|
|
122
|
+
nextEntityRef: string,
|
|
123
|
+
): Promise<void> {
|
|
124
|
+
await rewriteProjectedEntityReferenceRows(memoryDir, [[previousEntityRef, nextEntityRef]], memoryId);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export async function rewriteProjectedEntityReferences(
|
|
128
|
+
memoryDir: string,
|
|
129
|
+
replacements: Readonly<Record<string, string>>,
|
|
130
|
+
): Promise<void> {
|
|
131
|
+
await rewriteProjectedEntityReferenceRows(memoryDir, Object.entries(replacements));
|
|
132
|
+
}
|
|
@@ -284,6 +284,7 @@ export class NamespaceStorageRouter {
|
|
|
284
284
|
root = await this.defaultNamespaceRoot();
|
|
285
285
|
const cached = this.cache.get(ns);
|
|
286
286
|
if (cached && cached.dir === root) {
|
|
287
|
+
await this.applySecureStoreConfig(cached);
|
|
287
288
|
this.notifyResolved(ns, root);
|
|
288
289
|
return cached;
|
|
289
290
|
}
|
|
@@ -291,6 +292,7 @@ export class NamespaceStorageRouter {
|
|
|
291
292
|
const cached = this.cache.get(ns);
|
|
292
293
|
root = await this.namespaceRoot(ns);
|
|
293
294
|
if (cached && cached.dir === root) {
|
|
295
|
+
await this.applySecureStoreConfig(cached);
|
|
294
296
|
this.notifyResolved(ns, root);
|
|
295
297
|
return cached;
|
|
296
298
|
}
|
|
@@ -335,7 +337,7 @@ export class NamespaceStorageRouter {
|
|
|
335
337
|
// recovery paths (e.g. the CLI lifecycle-ledger rebuild) refuse an encrypted
|
|
336
338
|
// ledger they could actually rewrite, and namespace writes could silently
|
|
337
339
|
// fall back to plaintext. Mirror the orchestrator's setup exactly.
|
|
338
|
-
this.applySecureStoreConfig(sm);
|
|
340
|
+
await this.applySecureStoreConfig(sm);
|
|
339
341
|
this.cache.set(ns, sm);
|
|
340
342
|
// #2019: let the orchestrator wire write-triggered prioritized embedding on
|
|
341
343
|
// every router-created namespace storage, not just the primary default store.
|
|
@@ -478,12 +480,12 @@ export class NamespaceStorageRouter {
|
|
|
478
480
|
* root keyring id — exactly the id the orchestrator and `secure-store unlock`
|
|
479
481
|
* register under. No-op when secure-store is disabled.
|
|
480
482
|
*/
|
|
481
|
-
private applySecureStoreConfig(sm: StorageManager): void {
|
|
483
|
+
private async applySecureStoreConfig(sm: StorageManager): Promise<void> {
|
|
482
484
|
if (!resolveRecallAuxiliaryCapabilities(this.config).secureStore) return;
|
|
483
485
|
sm.setSecureStoreRequired(true);
|
|
484
486
|
const existingKey = keyring.getKey(secureStoreDir(this.config.memoryDir));
|
|
485
487
|
if (existingKey) {
|
|
486
|
-
sm.
|
|
488
|
+
await sm.setSecureStoreKeyAndWait(existingKey, this.config.secureStoreEncryptOnWrite);
|
|
487
489
|
}
|
|
488
490
|
}
|
|
489
491
|
|
|
@@ -23,7 +23,9 @@ import {
|
|
|
23
23
|
computeCorpusWatermarks,
|
|
24
24
|
resolveCorpusNamespaceRoots,
|
|
25
25
|
} from "./corpus-watermark.js";
|
|
26
|
+
import { summarizeReplicaDivergence } from "./operator-doctor-replica.js";
|
|
26
27
|
import type { OperatorDoctorCheck } from "./operator-toolkit.js";
|
|
28
|
+
import type { ResolveSecretRefFn } from "./resolve-auth-token.js";
|
|
27
29
|
import type { PluginConfig } from "./types.js";
|
|
28
30
|
|
|
29
31
|
const DIGEST_PREFIX_LENGTH = 12;
|
|
@@ -93,3 +95,42 @@ export async function summarizeCorpusWatermark(
|
|
|
93
95
|
details: { corpus: watermarks },
|
|
94
96
|
};
|
|
95
97
|
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Extract the watermark array this check stores under `details.corpus` (issue
|
|
101
|
+
* #2149). The replica-divergence doctor check reuses the local watermark set
|
|
102
|
+
* computed here rather than rescanning the corpus, and consumes it through this
|
|
103
|
+
* helper so the `details.corpus` shape stays owned by the module that produces it.
|
|
104
|
+
*/
|
|
105
|
+
export function corpusWatermarksFromCheck(check: OperatorDoctorCheck): CorpusWatermark[] {
|
|
106
|
+
const details = check.details;
|
|
107
|
+
if (!details || typeof details !== "object" || !("corpus" in details) || !Array.isArray(details.corpus)) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
// This check always stores a CorpusWatermark[] under `corpus` (guarded above).
|
|
111
|
+
return details.corpus as CorpusWatermark[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Build the corpus-watermark and replica-divergence doctor checks together.
|
|
116
|
+
*
|
|
117
|
+
* They are paired deliberately: the replica comparison consumes the corpus
|
|
118
|
+
* check's watermarks (one scan, not two) AND its completeness — an incomplete
|
|
119
|
+
* local census must not let the replica check certify convergence. The pairing
|
|
120
|
+
* lives HERE, next to the corpus check + `corpusWatermarksFromCheck` it consumes
|
|
121
|
+
* and the `PluginConfig` it needs, so the sibling replica module stays a light
|
|
122
|
+
* tsup DTS entry free of the heavy `PluginConfig` type graph (round 6, coderabbit).
|
|
123
|
+
*/
|
|
124
|
+
export async function summarizeCorpusAndReplica(
|
|
125
|
+
config: PluginConfig,
|
|
126
|
+
storageFactory: (dir: string) => CorpusStorage,
|
|
127
|
+
resolveSecretRef?: ResolveSecretRefFn | null,
|
|
128
|
+
): Promise<OperatorDoctorCheck[]> {
|
|
129
|
+
const watermarkCheck = await summarizeCorpusWatermark(config, storageFactory);
|
|
130
|
+
const replicaCheck = await summarizeReplicaDivergence(
|
|
131
|
+
config.replicaPeers,
|
|
132
|
+
corpusWatermarksFromCheck(watermarkCheck),
|
|
133
|
+
{ resolveSecretRef, localCensusComplete: watermarkCheck.status === "ok" },
|
|
134
|
+
);
|
|
135
|
+
return [watermarkCheck, replicaCheck];
|
|
136
|
+
}
|