@remnic/core 9.28.0 → 9.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +10 -10
- package/dist/access-admin-ops-surface.js +32 -32
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +33 -33
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +32 -32
- package/dist/access-cli.js +101 -98
- package/dist/access-cli.js.map +1 -1
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +10 -10
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +43 -43
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +32 -32
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +32 -32
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +38 -38
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/access-memory-search-fanout.js +3 -3
- package/dist/{access-namespace-preflight-BiQ_-iUJ.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 +32 -32
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +32 -32
- package/dist/access-operations-batch.js +35 -35
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +37 -37
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +32 -32
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +32 -32
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +32 -32
- package/dist/access-schema.d.ts +7 -7
- package/dist/access-schema.js +4 -4
- package/dist/{access-service-CXkIgcGh.d.ts → access-service-DvPW_M5j.d.ts} +7 -7
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +32 -32
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +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 +8 -8
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +8 -8
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +2 -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-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/{catalog-Bouj8Gfg.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 +9 -9
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-GQSMYXKL.js → chunk-2AXMQWCN.js} +2 -2
- package/dist/{chunk-VYYNBJXH.js → chunk-2D7FEUCK.js} +6 -6
- package/dist/{chunk-PXQM2HOG.js → chunk-2GXM5N5A.js} +2 -2
- 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-JIF3VRKQ.js → chunk-35DL7IOI.js} +10 -10
- package/dist/{chunk-2H7OEVPO.js → chunk-3GD2HFR6.js} +2 -2
- package/dist/{chunk-KKBTBUVT.js → chunk-3JNDOAQ2.js} +5 -5
- package/dist/{chunk-4TFIRMTE.js → chunk-4A6YGWQN.js} +2 -2
- package/dist/{chunk-IKMAO55B.js → chunk-55MDBZLC.js} +2 -2
- package/dist/{chunk-RKXZ7P4V.js → chunk-5QDRGWT2.js} +3 -3
- package/dist/{chunk-IPLYGWQF.js → chunk-5W7CTZ2E.js} +6 -6
- package/dist/{chunk-ALTP3MFS.js → chunk-5ZCUDWD4.js} +2 -2
- 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-WVVK2RFM.js → chunk-7L45JFPW.js} +14 -14
- package/dist/{chunk-R372P2EH.js → chunk-ACXPX4AG.js} +2 -2
- package/dist/{chunk-7CPOZH6Y.js → chunk-ALSGMEJR.js} +5 -5
- package/dist/{chunk-JGUXPJUQ.js → chunk-AS7YMSL6.js} +2 -2
- package/dist/{chunk-DKQM5Q6Q.js → chunk-CW4AGY3G.js} +4 -4
- package/dist/{chunk-ZN4UZWMT.js → chunk-D2ANTDGO.js} +3 -3
- package/dist/{chunk-3UOSVTFR.js → chunk-D3LMYTBV.js} +9 -9
- package/dist/{chunk-FOCEI3TN.js → chunk-DRBXHRXE.js} +2 -1
- package/dist/chunk-DRBXHRXE.js.map +1 -0
- package/dist/{chunk-LIHC3T43.js → chunk-E5OBR6CJ.js} +4 -4
- package/dist/{chunk-XY7QPJDA.js → chunk-E6EE5B67.js} +2 -2
- package/dist/{chunk-TBMRQZDY.js → chunk-EP5BVCRI.js} +2 -2
- package/dist/{chunk-MJPV4LBH.js → chunk-FUYEVEX7.js} +83 -83
- package/dist/{chunk-2BEJ4XCF.js → chunk-FZRQZW4H.js} +2 -2
- package/dist/{chunk-X6ROIHFE.js → chunk-G5R3D5UP.js} +2 -2
- package/dist/{chunk-2FYNLDKJ.js → chunk-GAWOEQEQ.js} +2 -2
- package/dist/{chunk-TKBDJTXG.js → chunk-GBJ4RDFR.js} +94 -20
- package/dist/chunk-GBJ4RDFR.js.map +1 -0
- package/dist/{chunk-QH6CS6XJ.js → chunk-H24WNPA2.js} +2 -2
- package/dist/{chunk-VFNI3RPT.js → chunk-HKJCMOT6.js} +2 -2
- package/dist/{chunk-JQ7T5VDC.js → chunk-HUHX2OCX.js} +1 -1
- package/dist/chunk-HUHX2OCX.js.map +1 -0
- package/dist/{chunk-EZWWCN7I.js → chunk-IAEAFLF2.js} +2 -2
- package/dist/{chunk-NBNDVNJ2.js → chunk-IGPEJVBY.js} +3 -3
- package/dist/{chunk-MQVINOJQ.js → chunk-IYZ5K7MU.js} +3 -3
- package/dist/{chunk-Q5VJUNXA.js → chunk-JMQUBRV6.js} +105 -42
- package/dist/chunk-JMQUBRV6.js.map +1 -0
- package/dist/{chunk-2TQ2UFKH.js → chunk-JP3YPDAW.js} +57 -57
- package/dist/{chunk-P2CLYN6H.js → chunk-K5GB36ME.js} +2 -2
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- package/dist/{chunk-FBZTWUK5.js → chunk-OFHFH655.js} +8 -8
- package/dist/{chunk-GJPCP5CA.js → chunk-OP6F6L3S.js} +2 -2
- package/dist/{chunk-FGBJBYWP.js → chunk-OVRQLAYR.js} +3 -3
- package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
- package/dist/{chunk-3BSJBIZ3.js → chunk-OYJKSZIQ.js} +2 -2
- package/dist/chunk-P2BM76KT.js +528 -0
- package/dist/chunk-P2BM76KT.js.map +1 -0
- package/dist/{chunk-UR5SIN7H.js → chunk-PBUZNGMX.js} +30 -30
- package/dist/{chunk-P2OZKKYP.js → chunk-PHWUFPCO.js} +2 -2
- package/dist/{chunk-Q6YJW6KE.js → chunk-PKRIQL3V.js} +2 -2
- package/dist/{chunk-BR4UFMLO.js → chunk-PTSNLEXK.js} +3 -3
- package/dist/{chunk-AHFZXUZM.js → chunk-QDKK63Y7.js} +3 -3
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- 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-MWTMTW2T.js → chunk-SH6YO3LT.js} +3 -3
- package/dist/{chunk-IYT632D5.js → chunk-UBKEQOTD.js} +3 -3
- package/dist/{chunk-BJJAX3IZ.js → chunk-UTRO5UJU.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/{chunk-S24E4MBQ.js → chunk-VSURVXKY.js} +9 -9
- package/dist/chunk-WOCNN776.js +742 -0
- package/dist/chunk-WOCNN776.js.map +1 -0
- package/dist/{chunk-YOBNCD3Z.js → chunk-WRFBW2TT.js} +10 -10
- package/dist/{chunk-MXJ3VP6S.js → chunk-WU7TTVOD.js} +7 -7
- package/dist/{chunk-EG64LXKL.js → chunk-XOZ4ALGB.js} +3 -3
- package/dist/{chunk-2PHX3I5C.js → chunk-Z54EM5YZ.js} +10 -10
- package/dist/{cli-DJbkaZBU.d.ts → cli-CxoSOiG0.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +65 -65
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +9 -9
- 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 +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +8 -8
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -9
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/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 +1 -1
- package/dist/corpus-watermark.js +16 -16
- 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-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +8 -8
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -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-BKNGOFED.js → first-start-migration-F2QJD66E.js} +5 -5
- 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 +19 -19
- package/dist/index.js +156 -153
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +10 -10
- 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 +8 -8
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +9 -9
- package/dist/{maintenance-DveW6azo.d.ts → maintenance-Cb-PjxQd.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -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-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +15 -15
- 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 +7 -7
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +8 -8
- 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 +6 -6
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +17 -17
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +23 -23
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +15 -15
- package/dist/{orchestrator-Cvlgpe6I.d.ts → orchestrator-5GKqb_HL.d.ts} +7 -7
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +103 -100
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-BveYVaz7.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-CLWDsbYR.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-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 +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-BVf3DZ7z.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 +6 -6
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-DXLV47y2.d.ts → semantic-consolidation-BrxqnzTW.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +9 -9
- package/dist/semantic-rule-promotion.js +8 -8
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +8 -8
- package/dist/{service-DbgPTeMJ.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 +1 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/{storage-DOzTm8wG.d.ts → storage-CcH6yPk2.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +7 -7
- 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 +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{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/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/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-BA7W-_xy.d.ts → types-Dg0w9ADr.d.ts} +1 -0
- 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 +8 -8
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/capabilities.test.ts +1 -0
- package/src/capabilities.ts +7 -7
- package/src/config.test.ts +5 -0
- package/src/config.ts +1 -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/storage/entity-canonical-id-migration.ts +151 -23
- package/src/types.ts +2 -2
- package/dist/chunk-FOCEI3TN.js.map +0 -1
- package/dist/chunk-JQ7T5VDC.js.map +0 -1
- package/dist/chunk-Q5VJUNXA.js.map +0 -1
- package/dist/chunk-TKBDJTXG.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{chunk-GQSMYXKL.js.map → chunk-2AXMQWCN.js.map} +0 -0
- /package/dist/{chunk-VYYNBJXH.js.map → chunk-2D7FEUCK.js.map} +0 -0
- /package/dist/{chunk-PXQM2HOG.js.map → chunk-2GXM5N5A.js.map} +0 -0
- /package/dist/{chunk-JIF3VRKQ.js.map → chunk-35DL7IOI.js.map} +0 -0
- /package/dist/{chunk-2H7OEVPO.js.map → chunk-3GD2HFR6.js.map} +0 -0
- /package/dist/{chunk-KKBTBUVT.js.map → chunk-3JNDOAQ2.js.map} +0 -0
- /package/dist/{chunk-4TFIRMTE.js.map → chunk-4A6YGWQN.js.map} +0 -0
- /package/dist/{chunk-IKMAO55B.js.map → chunk-55MDBZLC.js.map} +0 -0
- /package/dist/{chunk-RKXZ7P4V.js.map → chunk-5QDRGWT2.js.map} +0 -0
- /package/dist/{chunk-IPLYGWQF.js.map → chunk-5W7CTZ2E.js.map} +0 -0
- /package/dist/{chunk-ALTP3MFS.js.map → chunk-5ZCUDWD4.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-WVVK2RFM.js.map → chunk-7L45JFPW.js.map} +0 -0
- /package/dist/{chunk-R372P2EH.js.map → chunk-ACXPX4AG.js.map} +0 -0
- /package/dist/{chunk-7CPOZH6Y.js.map → chunk-ALSGMEJR.js.map} +0 -0
- /package/dist/{chunk-JGUXPJUQ.js.map → chunk-AS7YMSL6.js.map} +0 -0
- /package/dist/{chunk-DKQM5Q6Q.js.map → chunk-CW4AGY3G.js.map} +0 -0
- /package/dist/{chunk-ZN4UZWMT.js.map → chunk-D2ANTDGO.js.map} +0 -0
- /package/dist/{chunk-3UOSVTFR.js.map → chunk-D3LMYTBV.js.map} +0 -0
- /package/dist/{chunk-LIHC3T43.js.map → chunk-E5OBR6CJ.js.map} +0 -0
- /package/dist/{chunk-XY7QPJDA.js.map → chunk-E6EE5B67.js.map} +0 -0
- /package/dist/{chunk-TBMRQZDY.js.map → chunk-EP5BVCRI.js.map} +0 -0
- /package/dist/{chunk-MJPV4LBH.js.map → chunk-FUYEVEX7.js.map} +0 -0
- /package/dist/{chunk-2BEJ4XCF.js.map → chunk-FZRQZW4H.js.map} +0 -0
- /package/dist/{chunk-X6ROIHFE.js.map → chunk-G5R3D5UP.js.map} +0 -0
- /package/dist/{chunk-2FYNLDKJ.js.map → chunk-GAWOEQEQ.js.map} +0 -0
- /package/dist/{chunk-QH6CS6XJ.js.map → chunk-H24WNPA2.js.map} +0 -0
- /package/dist/{chunk-VFNI3RPT.js.map → chunk-HKJCMOT6.js.map} +0 -0
- /package/dist/{chunk-EZWWCN7I.js.map → chunk-IAEAFLF2.js.map} +0 -0
- /package/dist/{chunk-NBNDVNJ2.js.map → chunk-IGPEJVBY.js.map} +0 -0
- /package/dist/{chunk-MQVINOJQ.js.map → chunk-IYZ5K7MU.js.map} +0 -0
- /package/dist/{chunk-2TQ2UFKH.js.map → chunk-JP3YPDAW.js.map} +0 -0
- /package/dist/{chunk-P2CLYN6H.js.map → chunk-K5GB36ME.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-FBZTWUK5.js.map → chunk-OFHFH655.js.map} +0 -0
- /package/dist/{chunk-GJPCP5CA.js.map → chunk-OP6F6L3S.js.map} +0 -0
- /package/dist/{chunk-FGBJBYWP.js.map → chunk-OVRQLAYR.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-3BSJBIZ3.js.map → chunk-OYJKSZIQ.js.map} +0 -0
- /package/dist/{chunk-UR5SIN7H.js.map → chunk-PBUZNGMX.js.map} +0 -0
- /package/dist/{chunk-P2OZKKYP.js.map → chunk-PHWUFPCO.js.map} +0 -0
- /package/dist/{chunk-Q6YJW6KE.js.map → chunk-PKRIQL3V.js.map} +0 -0
- /package/dist/{chunk-BR4UFMLO.js.map → chunk-PTSNLEXK.js.map} +0 -0
- /package/dist/{chunk-AHFZXUZM.js.map → chunk-QDKK63Y7.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-FCCMFVS6.js.map → chunk-RPSYDM6C.js.map} +0 -0
- /package/dist/{chunk-MWTMTW2T.js.map → chunk-SH6YO3LT.js.map} +0 -0
- /package/dist/{chunk-IYT632D5.js.map → chunk-UBKEQOTD.js.map} +0 -0
- /package/dist/{chunk-BJJAX3IZ.js.map → chunk-UTRO5UJU.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-S24E4MBQ.js.map → chunk-VSURVXKY.js.map} +0 -0
- /package/dist/{chunk-YOBNCD3Z.js.map → chunk-WRFBW2TT.js.map} +0 -0
- /package/dist/{chunk-MXJ3VP6S.js.map → chunk-WU7TTVOD.js.map} +0 -0
- /package/dist/{chunk-EG64LXKL.js.map → chunk-XOZ4ALGB.js.map} +0 -0
- /package/dist/{chunk-2PHX3I5C.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{contradiction-scan-HMF7CNKD.js.map → contradiction-scan-HYLIRMJ2.js.map} +0 -0
- /package/dist/{first-start-migration-BKNGOFED.js.map → first-start-migration-F2QJD66E.js.map} +0 -0
- /package/dist/{tier-stats-XKD7SXYY.js.map → tier-stats-OPTSBNRH.js.map} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ExtractionResult } from "./types.js";
|
|
2
|
+
import { delinearize } from "./delinearize.js";
|
|
3
|
+
import {
|
|
4
|
+
applyExtractionSourceGrounding as applyGroundingRules,
|
|
5
|
+
filterExtractionResultBySource as filterGroundingRules,
|
|
6
|
+
} from "./extraction-source-grounding-rules.js";
|
|
7
|
+
import type {
|
|
8
|
+
ExtractionGroundingRoleSources,
|
|
9
|
+
ExtractionSourceGroundingOptions,
|
|
10
|
+
} from "./extraction-source-grounding-rules.js";
|
|
11
|
+
|
|
12
|
+
export type { ExtractionGroundingRoleSources, ExtractionSourceGroundingOptions } from "./extraction-source-grounding-rules.js";
|
|
13
|
+
|
|
14
|
+
export function applyExtractionSourceGrounding(
|
|
15
|
+
result: ExtractionResult,
|
|
16
|
+
sourceText: string,
|
|
17
|
+
assertionSourceText: string = sourceText,
|
|
18
|
+
roleAssertionSources: ExtractionGroundingRoleSources | undefined,
|
|
19
|
+
messageTimestamp: Date | undefined,
|
|
20
|
+
options: ExtractionSourceGroundingOptions,
|
|
21
|
+
): ExtractionResult {
|
|
22
|
+
const sourceForGrounding = (source: string | undefined): string | undefined =>
|
|
23
|
+
source === undefined || !options.anchorTemporalExpressions
|
|
24
|
+
? source
|
|
25
|
+
: delinearize(source, result.entities, messageTimestamp ?? new Date());
|
|
26
|
+
const groundedRoleSources = roleAssertionSources === undefined
|
|
27
|
+
? undefined
|
|
28
|
+
: {
|
|
29
|
+
profile: sourceForGrounding(roleAssertionSources.profile),
|
|
30
|
+
identity: sourceForGrounding(roleAssertionSources.identity),
|
|
31
|
+
};
|
|
32
|
+
return applyGroundingRules(
|
|
33
|
+
result,
|
|
34
|
+
sourceForGrounding(sourceText) ?? sourceText,
|
|
35
|
+
sourceForGrounding(assertionSourceText) ?? assertionSourceText,
|
|
36
|
+
groundedRoleSources,
|
|
37
|
+
messageTimestamp,
|
|
38
|
+
options,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function filterExtractionResultBySource(
|
|
43
|
+
result: ExtractionResult,
|
|
44
|
+
source: string,
|
|
45
|
+
assertionSource?: string,
|
|
46
|
+
roleAssertionSources?: ExtractionGroundingRoleSources,
|
|
47
|
+
eventTimeNormalizer?: (eventTime: string) => string,
|
|
48
|
+
): ExtractionResult {
|
|
49
|
+
return filterGroundingRules(result, source, assertionSource, roleAssertionSources, eventTimeNormalizer);
|
|
50
|
+
}
|
package/src/extraction.ts
CHANGED
|
@@ -40,6 +40,7 @@ import { normalizeProcedureSteps } from "./procedural/procedure-types.js";
|
|
|
40
40
|
import { normalizeReasoningTrace } from "./reasoning-trace-types.js";
|
|
41
41
|
import { looksLikeMechanicalTelemetryTranscript } from "./telemetry-transcript.js";
|
|
42
42
|
import { buildFactProvenance, type ProvenanceTurnInput } from "./provenance.js";
|
|
43
|
+
import { applyExtractionSourceGrounding, type ExtractionGroundingRoleSources } from "./extraction-source-grounding.js";
|
|
43
44
|
import { isMemoryCategory } from "./write-envelope.js";
|
|
44
45
|
import { classifyExtractionThrownError, classifyFallbackParseFailure } from "./extraction-error-classification.js";
|
|
45
46
|
export { classifyExtractionThrownError, classifyFallbackParseFailure } from "./extraction-error-classification.js";
|
|
@@ -656,6 +657,10 @@ export class ExtractionEngine {
|
|
|
656
657
|
private async applyProactiveQuestionPass(
|
|
657
658
|
conversation: string,
|
|
658
659
|
base: ExtractionResult,
|
|
660
|
+
groundingSource: string,
|
|
661
|
+
assertionSource: string,
|
|
662
|
+
messageTimestamp?: Date,
|
|
663
|
+
roleAssertionSources?: ExtractionGroundingRoleSources,
|
|
659
664
|
): Promise<ExtractionResult> {
|
|
660
665
|
if (!resolvePipelineProcessingCapabilities(this.config).proactiveExtraction) return base;
|
|
661
666
|
const maxAdditional = Math.max(0, Math.floor(this.config.maxProactiveQuestionsPerExtraction));
|
|
@@ -670,8 +675,16 @@ export class ExtractionEngine {
|
|
|
670
675
|
proactive,
|
|
671
676
|
maxAdditional,
|
|
672
677
|
);
|
|
673
|
-
|
|
674
|
-
|
|
678
|
+
const sanitizedAdditions = this.sanitizeExtractionResult(proactiveAdditions, messageTimestamp);
|
|
679
|
+
const groundedAdditions = this.applySourceGrounding(
|
|
680
|
+
sanitizedAdditions,
|
|
681
|
+
groundingSource,
|
|
682
|
+
assertionSource,
|
|
683
|
+
roleAssertionSources,
|
|
684
|
+
messageTimestamp,
|
|
685
|
+
);
|
|
686
|
+
if (!this.hasExtractionOutputs(groundedAdditions)) return base;
|
|
687
|
+
return this.mergeProactiveExtractionPass(base, groundedAdditions, maxAdditional);
|
|
675
688
|
} catch (err) {
|
|
676
689
|
log.debug(`proactive extraction question pass failed (ignored): ${err}`);
|
|
677
690
|
return base;
|
|
@@ -875,7 +888,7 @@ export class ExtractionEngine {
|
|
|
875
888
|
if (localResponse?.content) {
|
|
876
889
|
const parsed = this.parseProactiveExtractionResultFromText(localResponse.content.trim());
|
|
877
890
|
if (parsed) {
|
|
878
|
-
return
|
|
891
|
+
return parsed;
|
|
879
892
|
}
|
|
880
893
|
}
|
|
881
894
|
if (!this.config.localLlmFallback) {
|
|
@@ -906,12 +919,10 @@ export class ExtractionEngine {
|
|
|
906
919
|
if (!fallbackResult) {
|
|
907
920
|
return { facts: [], profileUpdates: [], entities: [], questions: [] };
|
|
908
921
|
}
|
|
909
|
-
return this.
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}),
|
|
914
|
-
);
|
|
922
|
+
return this.normalizeExtractionResultPayload({
|
|
923
|
+
...fallbackResult,
|
|
924
|
+
questions: [],
|
|
925
|
+
});
|
|
915
926
|
}
|
|
916
927
|
|
|
917
928
|
private mergeProactiveExtractionPass(
|
|
@@ -1133,6 +1144,40 @@ export class ExtractionEngine {
|
|
|
1133
1144
|
return { ...result, facts };
|
|
1134
1145
|
}
|
|
1135
1146
|
|
|
1147
|
+
private applySourceGrounding(
|
|
1148
|
+
result: ExtractionResult,
|
|
1149
|
+
sourceText: string,
|
|
1150
|
+
assertionSourceText: string = sourceText,
|
|
1151
|
+
roleAssertionSources?: ExtractionGroundingRoleSources,
|
|
1152
|
+
messageTimestamp?: Date,
|
|
1153
|
+
): ExtractionResult {
|
|
1154
|
+
const capabilities = resolvePipelineProcessingCapabilities(this.config);
|
|
1155
|
+
return applyExtractionSourceGrounding(
|
|
1156
|
+
result,
|
|
1157
|
+
sourceText,
|
|
1158
|
+
assertionSourceText,
|
|
1159
|
+
roleAssertionSources,
|
|
1160
|
+
messageTimestamp,
|
|
1161
|
+
{
|
|
1162
|
+
sourceGrounding: capabilities.sourceGrounding,
|
|
1163
|
+
anchorTemporalExpressions: capabilities.delinearize,
|
|
1164
|
+
},
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
private finalizeExtractionResult(
|
|
1169
|
+
result: ExtractionResult,
|
|
1170
|
+
turns: ReadonlyArray<{
|
|
1171
|
+
content: string;
|
|
1172
|
+
sessionKey?: string;
|
|
1173
|
+
logicalSessionKey?: string;
|
|
1174
|
+
timestamp: string;
|
|
1175
|
+
turnFingerprint?: string;
|
|
1176
|
+
}>,
|
|
1177
|
+
): ExtractionResult {
|
|
1178
|
+
return this.attachProvenanceToResult(result, turns);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1136
1181
|
async extract(turns: BufferTurn[], existingEntities?: string[]): Promise<ExtractionResult> {
|
|
1137
1182
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
1138
1183
|
|
|
@@ -1158,6 +1203,24 @@ export class ExtractionEngine {
|
|
|
1158
1203
|
return `[${roleLabel}] ${t.content}`;
|
|
1159
1204
|
})
|
|
1160
1205
|
.join("\n\n");
|
|
1206
|
+
|
|
1207
|
+
const groundingSource = boundedTurns
|
|
1208
|
+
.map((turn) => turn.content)
|
|
1209
|
+
.join("\n\n");
|
|
1210
|
+
const assertionSource = boundedTurns
|
|
1211
|
+
.filter((turn) => turn.extractionContextOnly !== true)
|
|
1212
|
+
.map((turn) => turn.content)
|
|
1213
|
+
.join("\n\n");
|
|
1214
|
+
const roleAssertionSources: ExtractionGroundingRoleSources = {
|
|
1215
|
+
profile: boundedTurns
|
|
1216
|
+
.filter((turn) => turn.role === "user" && turn.extractionContextOnly !== true)
|
|
1217
|
+
.map((turn) => turn.content)
|
|
1218
|
+
.join("\n\n"),
|
|
1219
|
+
identity: boundedTurns
|
|
1220
|
+
.filter((turn) => turn.role === "assistant" && turn.extractionContextOnly !== true)
|
|
1221
|
+
.map((turn) => turn.content)
|
|
1222
|
+
.join("\n\n"),
|
|
1223
|
+
};
|
|
1161
1224
|
if (conversation.trim().length === 0) {
|
|
1162
1225
|
log.debug("extraction skipped — conversation only contained non-memory work-layer context");
|
|
1163
1226
|
return { facts: [], profileUpdates: [], entities: [], questions: [] };
|
|
@@ -1213,8 +1276,22 @@ export class ExtractionEngine {
|
|
|
1213
1276
|
this.emit({ kind: "llm_end", traceId, model: this.config.localLlmModel, operation: "extraction", durationMs });
|
|
1214
1277
|
log.debug(`extraction: used local LLM — ${localResult.facts.length} facts, ${localResult.entities.length} entities`);
|
|
1215
1278
|
const sanitized = this.sanitizeExtractionResult(localResult, messageTimestamp);
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1279
|
+
const grounded = this.applySourceGrounding(
|
|
1280
|
+
sanitized,
|
|
1281
|
+
groundingSource,
|
|
1282
|
+
assertionSource,
|
|
1283
|
+
roleAssertionSources,
|
|
1284
|
+
messageTimestamp,
|
|
1285
|
+
);
|
|
1286
|
+
const finalResult = await this.applyProactiveQuestionPass(
|
|
1287
|
+
conversation,
|
|
1288
|
+
grounded,
|
|
1289
|
+
groundingSource,
|
|
1290
|
+
assertionSource,
|
|
1291
|
+
messageTimestamp,
|
|
1292
|
+
roleAssertionSources,
|
|
1293
|
+
);
|
|
1294
|
+
return this.finalizeExtractionResult(finalResult, boundedTurns);
|
|
1218
1295
|
}
|
|
1219
1296
|
// Local failed, fall back if allowed
|
|
1220
1297
|
if (!this.config.localLlmFallback) {
|
|
@@ -1260,8 +1337,22 @@ export class ExtractionEngine {
|
|
|
1260
1337
|
this.emit({ kind: "llm_end", traceId, model: this.config.model, operation: "extraction", durationMs });
|
|
1261
1338
|
log.debug(`extraction: used direct client (${this.config.model}) — ${directResult.facts.length} facts, ${directResult.entities.length} entities`);
|
|
1262
1339
|
const sanitized = this.sanitizeExtractionResult(directResult, messageTimestamp);
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1340
|
+
const grounded = this.applySourceGrounding(
|
|
1341
|
+
sanitized,
|
|
1342
|
+
groundingSource,
|
|
1343
|
+
assertionSource,
|
|
1344
|
+
roleAssertionSources,
|
|
1345
|
+
messageTimestamp,
|
|
1346
|
+
);
|
|
1347
|
+
const finalResult = await this.applyProactiveQuestionPass(
|
|
1348
|
+
conversation,
|
|
1349
|
+
grounded,
|
|
1350
|
+
groundingSource,
|
|
1351
|
+
assertionSource,
|
|
1352
|
+
messageTimestamp,
|
|
1353
|
+
roleAssertionSources,
|
|
1354
|
+
);
|
|
1355
|
+
return this.finalizeExtractionResult(finalResult, boundedTurns);
|
|
1265
1356
|
}
|
|
1266
1357
|
// Emit error event so Opik sees the direct client failure before fallback.
|
|
1267
1358
|
// Wrapped in try/catch so a subscriber error doesn't break the fallback path.
|
|
@@ -1345,8 +1436,22 @@ export class ExtractionEngine {
|
|
|
1345
1436
|
);
|
|
1346
1437
|
const normalized = this.normalizeExtractionResultPayload(result);
|
|
1347
1438
|
const sanitized = this.sanitizeExtractionResult(normalized, messageTimestamp);
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1439
|
+
const grounded = this.applySourceGrounding(
|
|
1440
|
+
sanitized,
|
|
1441
|
+
groundingSource,
|
|
1442
|
+
assertionSource,
|
|
1443
|
+
roleAssertionSources,
|
|
1444
|
+
messageTimestamp,
|
|
1445
|
+
);
|
|
1446
|
+
const finalResult = await this.applyProactiveQuestionPass(
|
|
1447
|
+
conversation,
|
|
1448
|
+
grounded,
|
|
1449
|
+
groundingSource,
|
|
1450
|
+
assertionSource,
|
|
1451
|
+
messageTimestamp,
|
|
1452
|
+
roleAssertionSources,
|
|
1453
|
+
);
|
|
1454
|
+
return this.finalizeExtractionResult(finalResult, boundedTurns);
|
|
1350
1455
|
}
|
|
1351
1456
|
|
|
1352
1457
|
this.emit({
|
|
@@ -15,6 +15,7 @@ import { readFileSync } from "node:fs";
|
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
import { computeSupersessionKey, normalizeSupersessionKey } from "../temporal-supersession.js";
|
|
17
17
|
import type { EntityFile, MemoryFile } from "../types.js";
|
|
18
|
+
import { log } from "../logger.js";
|
|
18
19
|
import { isErrnoCode } from "../utils/errno.js";
|
|
19
20
|
import { withHeldFileLock } from "../utils/serialize-mutations.js";
|
|
20
21
|
import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
|
|
@@ -69,6 +70,14 @@ const EntityCanonicalIdMigrationStateSchema = z.object({
|
|
|
69
70
|
version: z.literal(ENTITY_CANONICAL_ID_MIGRATION_VERSION),
|
|
70
71
|
complete: z.boolean(),
|
|
71
72
|
mappings: z.record(z.string().min(1)),
|
|
73
|
+
/**
|
|
74
|
+
* Pairs the migration refused to resolve, PARKED rather than dropped.
|
|
75
|
+
* Deleting the record would strand the collision: once an operator removes
|
|
76
|
+
* the legacy file, no later scan can rediscover the mapping, so references
|
|
77
|
+
* still naming the legacy id would never be rewritten. Optional so a journal
|
|
78
|
+
* written by an older build still parses.
|
|
79
|
+
*/
|
|
80
|
+
blocked: z.record(z.string().min(1)).optional(),
|
|
72
81
|
});
|
|
73
82
|
|
|
74
83
|
type EntityCanonicalIdMigrationState = z.infer<typeof EntityCanonicalIdMigrationStateSchema>;
|
|
@@ -348,12 +357,28 @@ async function readSafeEntityEntries(entitiesDir: string): Promise<string[]> {
|
|
|
348
357
|
return entries;
|
|
349
358
|
}
|
|
350
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Legacy ids the migration cannot resolve on its own, mapped to the canonical
|
|
362
|
+
* id they collide with. Two entity files describing one entity is an ORDINARY
|
|
363
|
+
* operator state, and picking a winner would silently drop whichever side lost.
|
|
364
|
+
* So the pair is skipped and reported: reads of the legacy id keep working
|
|
365
|
+
* exactly as they did before the migration ran.
|
|
366
|
+
*/
|
|
367
|
+
export type BlockedEntityPairs = Map<string, string>;
|
|
368
|
+
|
|
351
369
|
async function discoverMappings(
|
|
352
370
|
deps: EntityCanonicalIdMigrationDependencies,
|
|
353
371
|
knownMappings: Readonly<Record<string, string>> = {},
|
|
372
|
+
blocked: BlockedEntityPairs = new Map(),
|
|
354
373
|
): Promise<Record<string, string>> {
|
|
355
374
|
const mappings: Record<string, string> = {};
|
|
356
|
-
const canonicalOwners = new Map<string, string>();
|
|
375
|
+
const canonicalOwners = new Map<string, string[]>();
|
|
376
|
+
// Blocks describe THIS scan of the directory, so they are rebuilt per pass.
|
|
377
|
+
// Accumulating them across a run would let a collision another writer has
|
|
378
|
+
// since resolved keep pruning its now-valid mapping: the entity file gets
|
|
379
|
+
// renamed while the pruned mapping skips the reference rewrite, stranding
|
|
380
|
+
// memories on a filename that no longer exists.
|
|
381
|
+
blocked.clear();
|
|
357
382
|
const entityEntries = await readSafeEntityEntries(deps.entitiesDir);
|
|
358
383
|
for (const entry of entityEntries) {
|
|
359
384
|
if (!entry.endsWith(".md")) continue;
|
|
@@ -386,18 +411,23 @@ async function discoverMappings(
|
|
|
386
411
|
if (canonicalExists) {
|
|
387
412
|
const canonicalContent = await deps.readStorageSecureFile(canonicalPath);
|
|
388
413
|
if (entityContent !== canonicalContent) {
|
|
389
|
-
|
|
414
|
+
blocked.set(legacyId, canonicalId);
|
|
415
|
+
continue;
|
|
390
416
|
}
|
|
391
417
|
}
|
|
392
|
-
|
|
393
|
-
if (previousOwner !== undefined && previousOwner !== legacyId) {
|
|
394
|
-
throw new Error(
|
|
395
|
-
`Cannot migrate legacy entity ids ${previousOwner} and ${legacyId}: both normalize to ${canonicalId}.`,
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
canonicalOwners.set(canonicalId, legacyId);
|
|
418
|
+
canonicalOwners.set(canonicalId, [...(canonicalOwners.get(canonicalId) ?? []), legacyId]);
|
|
399
419
|
mappings[legacyId] = canonicalId;
|
|
400
420
|
}
|
|
421
|
+
// A canonical id claimed by more than one legacy file has no non-arbitrary
|
|
422
|
+
// winner, and readdir order is not stable (§6) - so the "winner" would differ
|
|
423
|
+
// between hosts reading identical data. Block every claimant instead.
|
|
424
|
+
for (const [canonicalId, claimants] of canonicalOwners) {
|
|
425
|
+
if (claimants.length < 2) continue;
|
|
426
|
+
for (const legacyId of claimants) {
|
|
427
|
+
blocked.set(legacyId, canonicalId);
|
|
428
|
+
delete mappings[legacyId];
|
|
429
|
+
}
|
|
430
|
+
}
|
|
401
431
|
return mappings;
|
|
402
432
|
}
|
|
403
433
|
|
|
@@ -645,7 +675,19 @@ function mergeDiscoveredMappings(
|
|
|
645
675
|
for (const [legacyId, canonicalId] of Object.entries(discovered)) {
|
|
646
676
|
const previousMapping = merged[legacyId];
|
|
647
677
|
if (previousMapping !== undefined && previousMapping !== canonicalId) {
|
|
648
|
-
|
|
678
|
+
// A -> B collapses to A -> C once B -> C exists, so a rescan that still
|
|
679
|
+
// reads A -> B off disk is reporting the same chain, not a new target.
|
|
680
|
+
// Only a target the chain cannot reach is a real conflict.
|
|
681
|
+
let hop: string | undefined = canonicalId;
|
|
682
|
+
const seen = new Set<string>();
|
|
683
|
+
while (hop !== undefined && hop !== previousMapping && !seen.has(hop)) {
|
|
684
|
+
seen.add(hop);
|
|
685
|
+
hop = merged[hop];
|
|
686
|
+
}
|
|
687
|
+
if (hop !== previousMapping) {
|
|
688
|
+
throw new Error(`Legacy entity id ${legacyId} changed canonical target during migration.`);
|
|
689
|
+
}
|
|
690
|
+
continue;
|
|
649
691
|
}
|
|
650
692
|
if (previousMapping === undefined && wouldCreateMappingCycle(merged, legacyId, canonicalId)) continue;
|
|
651
693
|
const previousOwner = canonicalOwners.get(canonicalId);
|
|
@@ -681,6 +723,8 @@ function collapseMappings(mappings: Readonly<Record<string, string>>): Record<st
|
|
|
681
723
|
type EntityFileMigrationResult = {
|
|
682
724
|
deferred: boolean;
|
|
683
725
|
progressed: boolean;
|
|
726
|
+
/** The pair collided on content; skipped and reported, never migrated. */
|
|
727
|
+
blocked?: boolean;
|
|
684
728
|
};
|
|
685
729
|
|
|
686
730
|
async function migrateEntityFilePair(
|
|
@@ -711,7 +755,9 @@ async function migrateEntityFilePair(
|
|
|
711
755
|
deps.isEncryptedStorageFile(canonicalPath),
|
|
712
756
|
]);
|
|
713
757
|
if (legacyContent !== canonicalContent) {
|
|
714
|
-
|
|
758
|
+
// A mapping persisted by an older build, or a file changed since
|
|
759
|
+
// discovery. Same verdict as discovery: skip the pair, keep both files.
|
|
760
|
+
return { deferred: false, progressed: false, blocked: true };
|
|
715
761
|
}
|
|
716
762
|
if (legacyEncrypted && !canonicalEncrypted) {
|
|
717
763
|
if (!(await refreshMigrationLock()) || !(await refreshEntityLock())) {
|
|
@@ -792,6 +838,77 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
792
838
|
mappings: {},
|
|
793
839
|
};
|
|
794
840
|
}
|
|
841
|
+
const blocked: BlockedEntityPairs = new Map();
|
|
842
|
+
// ONE aggregated line per run, not one per pair per restart: this used to
|
|
843
|
+
// abort the daemon, so the operator needs the whole list and the remedy.
|
|
844
|
+
const finish = (): Promise<string | undefined> | string | undefined => {
|
|
845
|
+
if (blocked.size > 0) {
|
|
846
|
+
const pairs = [...blocked].map(([legacyId, canonicalId]) => `${legacyId} -> ${canonicalId}`).join(", ");
|
|
847
|
+
log.warn(
|
|
848
|
+
`entity canonical-id migration skipped ${blocked.size} unresolvable pair(s): ${pairs}. `
|
|
849
|
+
+ "Both files were kept and the legacy id still resolves; merge or delete one side to migrate it.",
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
return deps.readMigrationFingerprint?.();
|
|
853
|
+
};
|
|
854
|
+
/**
|
|
855
|
+
* Drop blocked pairs from the working set. Discovery only refuses to
|
|
856
|
+
* ADD them; a mapping persisted by an earlier run would otherwise still
|
|
857
|
+
* be applied - migrating one claimant and rewriting every reference onto
|
|
858
|
+
* the canonical file, i.e. picking the winner this fix exists to avoid,
|
|
859
|
+
* off stale state rather than what is on disk.
|
|
860
|
+
*/
|
|
861
|
+
/** @returns true when a park was promoted back into the mapping set. */
|
|
862
|
+
const pruneBlocked = async (): Promise<boolean> => {
|
|
863
|
+
const current = state;
|
|
864
|
+
if (!current) return false;
|
|
865
|
+
// THIS scan's verdict wins over the journal: normalization can change
|
|
866
|
+
// between runs, so a stale parked target would otherwise be promoted
|
|
867
|
+
// later and rewrite references onto an id that does not exist.
|
|
868
|
+
let revived = false;
|
|
869
|
+
const parked: Record<string, string> = { ...(current.blocked ?? {}) };
|
|
870
|
+
const active: Record<string, string> = {};
|
|
871
|
+
for (const [legacyId, canonicalId] of Object.entries(current.mappings)) {
|
|
872
|
+
if (!blocked.has(legacyId)) active[legacyId] = canonicalId;
|
|
873
|
+
}
|
|
874
|
+
for (const [legacyId, canonicalId] of blocked) parked[legacyId] = canonicalId;
|
|
875
|
+
// A parked pair whose legacy file is gone was resolved by keeping the
|
|
876
|
+
// canonical side. The rename is moot; the reference rewrite is not, and
|
|
877
|
+
// this record is the only thing that can still perform it.
|
|
878
|
+
// A park survives ONLY while this scan re-establishes the collision.
|
|
879
|
+
// Anything else - the scan found a real migration, or found the source
|
|
880
|
+
// needs none (already canonical under a newer normalization) - makes
|
|
881
|
+
// the record obsolete, and keeping it lets a later deletion promote a
|
|
882
|
+
// target the entity never occupied.
|
|
883
|
+
for (const [legacyId, canonicalId] of Object.entries(parked)) {
|
|
884
|
+
if (blocked.has(legacyId)) continue;
|
|
885
|
+
delete parked[legacyId];
|
|
886
|
+
if (active[legacyId] !== undefined) continue;
|
|
887
|
+
const legacyPath = deps.resolveEntityFilePath(legacyId);
|
|
888
|
+
if (legacyPath !== null && (await fileExists(legacyPath))) continue;
|
|
889
|
+
// Source gone: the rename is moot, but references still name it and
|
|
890
|
+
// this record is the only thing that can still rewrite them.
|
|
891
|
+
active[legacyId] = canonicalId;
|
|
892
|
+
revived = true;
|
|
893
|
+
}
|
|
894
|
+
// Reviving a whole chain at once yields A -> B -> C, and each rewrite
|
|
895
|
+
// surface makes a different number of passes over it - so collapse
|
|
896
|
+
// transitively before anything consumes the set.
|
|
897
|
+
const collapsed = collapseMappings(active);
|
|
898
|
+
// Parked targets follow ACTIVE moves only: hopping over a still-blocked
|
|
899
|
+
// link would jump to an id the migration has not been allowed to reach.
|
|
900
|
+
for (const [legacyId, canonicalId] of Object.entries(parked)) {
|
|
901
|
+
const moved = collapsed[canonicalId];
|
|
902
|
+
if (moved !== undefined && moved !== legacyId) parked[legacyId] = moved;
|
|
903
|
+
}
|
|
904
|
+
const same = (a: Record<string, string>, b: Record<string, string>): boolean =>
|
|
905
|
+
Object.keys(a).length === Object.keys(b).length
|
|
906
|
+
&& Object.entries(a).every(([key, value]) => b[key] === value);
|
|
907
|
+
if (same(collapsed, current.mappings) && same(parked, current.blocked ?? {})) return revived;
|
|
908
|
+
state = { ...current, mappings: collapsed, blocked: parked };
|
|
909
|
+
await writeState(deps, state);
|
|
910
|
+
return revived;
|
|
911
|
+
};
|
|
795
912
|
const previousMappings = state.mappings;
|
|
796
913
|
const collapsedMappings = collapseMappings(previousMappings);
|
|
797
914
|
const mappingsChanged =
|
|
@@ -804,11 +921,12 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
804
921
|
if (!(await lock.refresh())) throw new Error("Lost entity canonical-id migration lock.");
|
|
805
922
|
const discoveredBefore = rejectMappingCycles(
|
|
806
923
|
state.mappings,
|
|
807
|
-
await discoverMappings(deps, state.mappings),
|
|
924
|
+
await discoverMappings(deps, state.mappings, blocked),
|
|
808
925
|
);
|
|
926
|
+
await pruneBlocked();
|
|
809
927
|
const mergedBefore = collapseMappings(mergeDiscoveredMappings(state.mappings, discoveredBefore));
|
|
810
928
|
if (state.complete && Object.keys(discoveredBefore).length === 0 && !mappingsChanged) {
|
|
811
|
-
if (Object.keys(state.mappings).length === 0) return
|
|
929
|
+
if (Object.keys(state.mappings).length === 0) return finish();
|
|
812
930
|
const rewroteColdMemory = await rewriteKnownReferences(
|
|
813
931
|
deps,
|
|
814
932
|
state.mappings,
|
|
@@ -818,7 +936,7 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
818
936
|
deps.invalidateAllMemoriesCache();
|
|
819
937
|
if (rewroteColdMemory) deps.invalidateColdMemoriesCache();
|
|
820
938
|
deps.bumpMemoryStatusVersion();
|
|
821
|
-
return
|
|
939
|
+
return finish();
|
|
822
940
|
}
|
|
823
941
|
if (
|
|
824
942
|
state.complete
|
|
@@ -832,11 +950,16 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
832
950
|
if (!(await lock.refresh())) throw new Error("Lost entity canonical-id migration lock.");
|
|
833
951
|
const discoveredAfter = rejectMappingCycles(
|
|
834
952
|
state.mappings,
|
|
835
|
-
await discoverMappings(deps, state.mappings),
|
|
953
|
+
await discoverMappings(deps, state.mappings, blocked),
|
|
836
954
|
);
|
|
837
|
-
|
|
955
|
+
// Reconcile before declaring completion: this rescan can resolve a
|
|
956
|
+
// park (another writer removed the legacy file), and completing
|
|
957
|
+
// without promoting it strands its references behind a fingerprint
|
|
958
|
+
// that already reflects the deletion - so no later run revisits it.
|
|
959
|
+
const revivedInRescan = await pruneBlocked();
|
|
960
|
+
if (Object.keys(discoveredAfter).length === 0 && !revivedInRescan) {
|
|
838
961
|
await writeState(deps, { ...state, complete: true });
|
|
839
|
-
return
|
|
962
|
+
return finish();
|
|
840
963
|
}
|
|
841
964
|
state = {
|
|
842
965
|
...state,
|
|
@@ -857,9 +980,8 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
857
980
|
canonicalId,
|
|
858
981
|
() => lock.refresh(),
|
|
859
982
|
);
|
|
860
|
-
if (result.
|
|
861
|
-
|
|
862
|
-
}
|
|
983
|
+
if (result.blocked) blocked.set(legacyId, canonicalId);
|
|
984
|
+
else if (result.deferred) deferredMappings.push([legacyId, canonicalId]);
|
|
863
985
|
progressed ||= result.progressed;
|
|
864
986
|
}
|
|
865
987
|
if (deferredMappings.length === 0) break;
|
|
@@ -871,6 +993,7 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
871
993
|
}
|
|
872
994
|
pendingMappings = deferredMappings;
|
|
873
995
|
}
|
|
996
|
+
await pruneBlocked();
|
|
874
997
|
|
|
875
998
|
const rewroteColdMemory = await rewriteKnownReferences(
|
|
876
999
|
deps,
|
|
@@ -885,11 +1008,16 @@ export async function migrateLegacyEntityCanonicalIds(
|
|
|
885
1008
|
if (!(await lock.refresh())) throw new Error("Lost entity canonical-id migration lock.");
|
|
886
1009
|
const discoveredAfter = rejectMappingCycles(
|
|
887
1010
|
state.mappings,
|
|
888
|
-
await discoverMappings(deps, state.mappings),
|
|
1011
|
+
await discoverMappings(deps, state.mappings, blocked),
|
|
889
1012
|
);
|
|
890
|
-
|
|
1013
|
+
// A park resolved after the rewrite pass is promoted here, and a
|
|
1014
|
+
// promotion still has to be APPLIED. Completing on `discoveredAfter`
|
|
1015
|
+
// alone fingerprints the post-deletion corpus, so the runner never
|
|
1016
|
+
// retries and those references stay stranded.
|
|
1017
|
+
const revivedAfterRewrite = await pruneBlocked();
|
|
1018
|
+
if (Object.keys(discoveredAfter).length === 0 && !revivedAfterRewrite) {
|
|
891
1019
|
await writeState(deps, { ...state, complete: true });
|
|
892
|
-
return
|
|
1020
|
+
return finish();
|
|
893
1021
|
}
|
|
894
1022
|
state = {
|
|
895
1023
|
...state,
|
package/src/types.ts
CHANGED
|
@@ -1556,8 +1556,8 @@ export interface PluginConfig extends BoundedJsonlStateConfig {
|
|
|
1556
1556
|
profilingStorageDir: string;
|
|
1557
1557
|
/** Maximum number of trace files to keep (rolling window). */
|
|
1558
1558
|
profilingMaxTraces: number;
|
|
1559
|
-
// Extraction stability guards (P0/P1)
|
|
1560
|
-
extractionDedupeEnabled: boolean;
|
|
1559
|
+
// Extraction stability guards (P0/P1).
|
|
1560
|
+
extractionDedupeEnabled: boolean; extractionSourceGroundingEnabled: boolean;
|
|
1561
1561
|
extractionDedupeWindowMs: number;
|
|
1562
1562
|
extractionMinChars: number;
|
|
1563
1563
|
extractionMinUserTurns: number;
|