@remnic/core 9.45.4 → 9.46.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 +10 -10
- package/dist/access-admin-ops-surface.js +30 -29
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +31 -30
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +30 -29
- package/dist/access-cli.js +91 -87
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +10 -10
- package/dist/access-extraction-force-flush.js +30 -29
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +10 -10
- package/dist/access-http-lifecycle-flush.d.ts +10 -10
- package/dist/access-http-offline-stream.d.ts +10 -10
- package/dist/access-http-offline-stream.js +1 -1
- package/dist/access-http-query.js +30 -29
- package/dist/access-http.d.ts +10 -11
- package/dist/access-http.js +42 -41
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +30 -29
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +30 -29
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +36 -35
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-CWUDwB4M.d.ts → access-namespace-preflight--H6HwN85.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +30 -29
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +30 -29
- package/dist/access-offline-manifest.d.ts +8 -8
- package/dist/access-operations-batch.js +31 -30
- package/dist/access-operations.d.ts +13 -13
- package/dist/access-operations.js +35 -34
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +30 -29
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +30 -29
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +30 -29
- package/dist/access-schema.d.ts +84 -84
- package/dist/access-service-helpers.d.ts +10 -10
- package/dist/{access-service-CsU-ljFD.d.ts → access-service-loJadYd7.d.ts} +7 -7
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +30 -29
- 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-recall.d.ts +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +109 -0
- package/dist/ambient-provenance.js +22 -0
- package/dist/ambient-provenance.js.map +1 -0
- package/dist/{auto-sync-UPTUVE4X.js → auto-sync-7O6RP2RT.js} +3 -2
- package/dist/{auto-sync-UPTUVE4X.js.map → auto-sync-7O6RP2RT.js.map} +1 -1
- 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 +6 -5
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer-turn-helpers.js +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +5 -5
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-bctMURhN.d.ts → catalog-Iwbk9h5E.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 +7 -6
- 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-ER7W6H4T.js → chunk-2AD5SXO4.js} +5 -2
- package/dist/chunk-2AD5SXO4.js.map +1 -0
- package/dist/{chunk-XSFHWBQO.js → chunk-2DSUT7DZ.js} +10 -64
- package/dist/{chunk-XSFHWBQO.js.map → chunk-2DSUT7DZ.js.map} +1 -1
- package/dist/{chunk-DZPFMQZ7.js → chunk-3S63QIFQ.js} +1 -1
- package/dist/chunk-3S63QIFQ.js.map +1 -0
- package/dist/{chunk-UQWIKLQK.js → chunk-47J4EDGR.js} +9 -9
- package/dist/{chunk-5SNZSWWR.js → chunk-5LRDM4R7.js} +42 -42
- package/dist/{chunk-7YERSTN7.js → chunk-5R6S4DJZ.js} +7 -7
- package/dist/{chunk-C26TE27X.js → chunk-5VQPZ4GV.js} +3 -3
- package/dist/{chunk-U2VLVBBH.js → chunk-64BHFFKZ.js} +3 -3
- package/dist/{chunk-AJQ57VV3.js → chunk-6H744ZBH.js} +4 -4
- package/dist/chunk-6H744ZBH.js.map +1 -0
- package/dist/{chunk-7CITSYSH.js → chunk-7T4TOGMS.js} +2 -2
- package/dist/{chunk-ZMAYKGPN.js → chunk-7YQ6ESEA.js} +12 -41
- package/dist/chunk-7YQ6ESEA.js.map +1 -0
- package/dist/{chunk-YMAQDHQM.js → chunk-BDNL34CT.js} +2 -2
- package/dist/{chunk-GQL52GQ5.js → chunk-CDKHKZL5.js} +15 -12
- package/dist/chunk-CDKHKZL5.js.map +1 -0
- package/dist/{chunk-WGP57SR3.js → chunk-CK5KOVHW.js} +3 -2
- package/dist/{chunk-WGP57SR3.js.map → chunk-CK5KOVHW.js.map} +1 -1
- package/dist/{chunk-JH6BPLOP.js → chunk-E4FOAENZ.js} +4 -4
- package/dist/{chunk-ZFGZ6PZ2.js → chunk-FULKGK7P.js} +2 -2
- package/dist/{chunk-BGHFOD5A.js → chunk-HJ3SVHUW.js} +3 -3
- package/dist/{chunk-TYISDI6B.js → chunk-HXXTXLKA.js} +2 -2
- package/dist/{chunk-FZP32336.js → chunk-IDE5AR5W.js} +53 -31
- package/dist/chunk-IDE5AR5W.js.map +1 -0
- package/dist/{chunk-7SHJHPTY.js → chunk-ILBLZ5Y5.js} +2 -2
- package/dist/chunk-J7T4MX7P.js +131 -0
- package/dist/chunk-J7T4MX7P.js.map +1 -0
- package/dist/{chunk-DSUAAZZX.js → chunk-JFO5QZ7N.js} +2 -2
- package/dist/{chunk-EJHEWCGQ.js → chunk-KA47C7BF.js} +2 -2
- package/dist/{chunk-NUEQKLNB.js → chunk-KMWYZTIE.js} +2 -2
- package/dist/{chunk-TQ4GD737.js → chunk-L7G72WY4.js} +2 -2
- package/dist/{chunk-CLB32OHM.js → chunk-LI7OE7G6.js} +2 -2
- package/dist/{chunk-TN76AKO3.js → chunk-M2INOSTA.js} +2 -2
- package/dist/{chunk-DYVMXPCF.js → chunk-M32URQXV.js} +665 -614
- package/dist/chunk-M32URQXV.js.map +1 -0
- package/dist/{chunk-WQIHRA5F.js → chunk-N3LL5NEU.js} +2 -2
- package/dist/{chunk-HFPASSFV.js → chunk-P2OTGMTR.js} +2 -2
- package/dist/{chunk-Y7HRYCNW.js → chunk-PFJXPOD4.js} +2 -2
- package/dist/{chunk-MDISBSYA.js → chunk-PKCLQ7KM.js} +43 -143
- package/dist/chunk-PKCLQ7KM.js.map +1 -0
- package/dist/chunk-QW27DOHG.js +84 -0
- package/dist/chunk-QW27DOHG.js.map +1 -0
- package/dist/{chunk-ZI32MKDW.js → chunk-RCU25Z66.js} +32 -35
- package/dist/chunk-RCU25Z66.js.map +1 -0
- package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-QCECHYZL.js → chunk-RVO6TCTU.js} +6 -6
- package/dist/{chunk-D3I2MCN7.js → chunk-RVPTS4U5.js} +3 -3
- package/dist/{chunk-W3IC7QOY.js → chunk-RVYVMQK4.js} +3 -3
- package/dist/chunk-S2HLHAZ4.js +16 -0
- package/dist/chunk-S2HLHAZ4.js.map +1 -0
- package/dist/{chunk-2MRHJNWL.js → chunk-ST5IEK3H.js} +2 -2
- package/dist/{chunk-O4KMGRXE.js → chunk-SXWHN7GC.js} +2 -2
- package/dist/{chunk-KXEFRMCF.js → chunk-T6JRMVOV.js} +2 -2
- package/dist/{chunk-R5RFK3CB.js → chunk-U6JGQ37L.js} +2 -2
- package/dist/{chunk-UV72DEZD.js → chunk-UYUYZ4WY.js} +36 -10
- package/dist/chunk-UYUYZ4WY.js.map +1 -0
- package/dist/{chunk-EITZHSX6.js → chunk-V5FE3UAI.js} +2 -2
- package/dist/chunk-VL35ZFSZ.js +102 -0
- package/dist/chunk-VL35ZFSZ.js.map +1 -0
- package/dist/{chunk-NTOIP2E6.js → chunk-W2ZSNIBP.js} +2 -2
- package/dist/{chunk-QVSBTCVP.js → chunk-WHWDBTCJ.js} +2 -2
- package/dist/{chunk-5CEECY6P.js → chunk-WOC6DXP5.js} +3 -3
- package/dist/{chunk-XTAUXTDO.js → chunk-XBMJ35IP.js} +2 -2
- package/dist/{chunk-VOUOLGIP.js → chunk-YRFAYOFQ.js} +11 -13
- package/dist/chunk-YRFAYOFQ.js.map +1 -0
- package/dist/{chunk-P7NGM24P.js → chunk-YWCOJOUI.js} +2 -2
- package/dist/{chunk-6NNNURLK.js → chunk-Z54EM5YZ.js} +4 -4
- package/dist/{chunk-ULVR5KG7.js → chunk-ZDAYWJV6.js} +2 -2
- package/dist/chunk-ZDAYWJV6.js.map +1 -0
- package/dist/{cli-BBHDtG36.d.ts → cli-D_RcqXfZ.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +61 -60
- package/dist/compat/checks.js +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +6 -5
- 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/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +6 -5
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +6 -5
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +8 -7
- 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 +17 -16
- 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-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +6 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- package/dist/external-wiki-access.d.ts +10 -10
- package/dist/external-wiki-access.js +33 -32
- package/dist/external-wiki-cli.js +4 -90
- package/dist/external-wiki-cli.js.map +1 -1
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +10 -10
- package/dist/external-wiki-search.js +2 -2
- package/dist/external-wiki.d.ts +1 -5
- package/dist/external-wiki.js +1 -3
- 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-prompt.d.ts +36 -0
- package/dist/extraction-prompt.js +16 -0
- package/dist/extraction-prompt.js.map +1 -0
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +6 -14
- package/dist/extraction.js +13 -10
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-F2QJD66E.js → first-start-migration-ZSHEFEI3.js} +10 -12
- package/dist/{first-start-migration-F2QJD66E.js.map → first-start-migration-ZSHEFEI3.js.map} +1 -1
- 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 +701 -697
- package/dist/index.js +133 -128
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +2 -2
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +6 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +6 -5
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +7 -6
- package/dist/{maintenance-D2mveyCd.d.ts → maintenance-DQrL93Uu.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-snapshot.d.ts +10 -0
- package/dist/memory-snapshot.js +8 -0
- package/dist/memory-snapshot.js.map +1 -0
- 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 +16 -15
- 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 +3 -3
- package/dist/namespaces/storage.js +6 -5
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +18 -17
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +22 -21
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +11 -10
- package/dist/{orchestrator-DJYlwiUv.d.ts → orchestrator-LPGegii3.d.ts} +8 -8
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +93 -89
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CNjY4wk3.d.ts → pipeline-1h2GpiHP.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-C0UDZidt.d.ts → qmd-UdwoF71D.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/qmd.js +4 -4
- 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/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/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-BJzp2F5A.d.ts → scope-profiles-APjhSe-w.d.ts} +1 -1
- package/dist/sdk-compat.js.map +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 +14 -14
- 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-D4KAZO2G.d.ts → semantic-consolidation-CrySDbk3.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +7 -6
- package/dist/semantic-rule-promotion.js +6 -5
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +6 -5
- package/dist/{service-BeDxSqE-.d.ts → service-DJ0LDyuN.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/source-agent-qualifier.d.ts +4 -1
- package/dist/source-agent-qualifier.js +10 -9
- package/dist/{storage-DfjxusTE.d.ts → storage-y340tYKb.d.ts} +5 -2
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +5 -4
- package/dist/summarizer.d.ts +1 -1
- 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-migration.js +1 -1
- 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/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-yX_FwERf.d.ts → types-D_Au9qJO.d.ts} +13 -2
- 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 +6 -5
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -12
- package/src/access-http-offline-stream.ts +1 -0
- package/src/access-http.ts +0 -57
- package/src/access-operations-batch.ts +1 -1
- package/src/access-service-observe-lcm-parity.test.ts +45 -20
- package/src/access-service.ts +3 -4
- package/src/ambient-provenance.test.ts +510 -0
- package/src/ambient-provenance.ts +229 -0
- package/src/buffer-turn-helpers.ts +17 -1
- package/src/compat/checks.test.ts +45 -1
- package/src/compat/checks.ts +16 -16
- package/src/external-wiki-cli.ts +28 -20
- package/src/external-wiki-search.test.ts +68 -2
- package/src/external-wiki.ts +12 -38
- package/src/extraction-prompt.ts +142 -0
- package/src/extraction.ts +37 -148
- package/src/index.ts +1 -5
- package/src/maintenance/first-start-migration.ts +11 -11
- package/src/meetings/memory-gen.test.ts +51 -0
- package/src/meetings/memory-gen.ts +36 -8
- package/src/meetings/summary-extractor.ts +4 -2
- package/src/memory-snapshot.ts +15 -0
- package/src/orchestration/recall-internal.ts +5 -148
- package/src/orchestration/recall-profile-storage.ts +194 -0
- package/src/orchestration/recall-search-pipeline.ts +13 -182
- package/src/orchestration/recall-search-prefilter.ts +254 -0
- package/src/orchestration/session-context.ts +1 -1
- package/src/orchestrator.ts +1 -1
- package/src/sdk-compat.ts +2 -4
- package/src/source-agent-qualifier.ts +3 -0
- package/src/storage-contract/cache-coherence.test.ts +99 -0
- package/src/storage-fact-hash-index-defer.test.ts +14 -7
- package/src/storage.ts +47 -48
- package/src/testing/subjects/first-start-tier-migration.test.ts +75 -0
- package/src/testing/subjects/recall-profile-storage.test.ts +362 -0
- package/src/testing/subjects/recall-search-prefilter.test.ts +365 -0
- package/src/tier-migration.ts +10 -12
- package/src/types.ts +2 -2
- package/src/wearables/memory-gen.test.ts +82 -0
- package/src/wearables/memory-gen.ts +54 -5
- package/src/wearables/trust.ts +19 -2
- package/dist/chunk-AJQ57VV3.js.map +0 -1
- package/dist/chunk-DYVMXPCF.js.map +0 -1
- package/dist/chunk-DZPFMQZ7.js.map +0 -1
- package/dist/chunk-ER7W6H4T.js.map +0 -1
- package/dist/chunk-FZP32336.js.map +0 -1
- package/dist/chunk-GQL52GQ5.js.map +0 -1
- package/dist/chunk-MDISBSYA.js.map +0 -1
- package/dist/chunk-ULVR5KG7.js.map +0 -1
- package/dist/chunk-UV72DEZD.js.map +0 -1
- package/dist/chunk-VOUOLGIP.js.map +0 -1
- package/dist/chunk-ZI32MKDW.js.map +0 -1
- package/dist/chunk-ZMAYKGPN.js.map +0 -1
- package/dist/legacy-hook-compat.d.ts +0 -3
- package/dist/legacy-hook-compat.js +0 -36
- package/dist/legacy-hook-compat.js.map +0 -1
- package/src/legacy-hook-compat.test.ts +0 -20
- package/src/legacy-hook-compat.ts +0 -45
- /package/dist/{chunk-7RZJWZ46.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-UQWIKLQK.js.map → chunk-47J4EDGR.js.map} +0 -0
- /package/dist/{chunk-5SNZSWWR.js.map → chunk-5LRDM4R7.js.map} +0 -0
- /package/dist/{chunk-7YERSTN7.js.map → chunk-5R6S4DJZ.js.map} +0 -0
- /package/dist/{chunk-C26TE27X.js.map → chunk-5VQPZ4GV.js.map} +0 -0
- /package/dist/{chunk-U2VLVBBH.js.map → chunk-64BHFFKZ.js.map} +0 -0
- /package/dist/{chunk-7CITSYSH.js.map → chunk-7T4TOGMS.js.map} +0 -0
- /package/dist/{chunk-YMAQDHQM.js.map → chunk-BDNL34CT.js.map} +0 -0
- /package/dist/{chunk-JH6BPLOP.js.map → chunk-E4FOAENZ.js.map} +0 -0
- /package/dist/{chunk-ZFGZ6PZ2.js.map → chunk-FULKGK7P.js.map} +0 -0
- /package/dist/{chunk-BGHFOD5A.js.map → chunk-HJ3SVHUW.js.map} +0 -0
- /package/dist/{chunk-TYISDI6B.js.map → chunk-HXXTXLKA.js.map} +0 -0
- /package/dist/{chunk-7SHJHPTY.js.map → chunk-ILBLZ5Y5.js.map} +0 -0
- /package/dist/{chunk-DSUAAZZX.js.map → chunk-JFO5QZ7N.js.map} +0 -0
- /package/dist/{chunk-EJHEWCGQ.js.map → chunk-KA47C7BF.js.map} +0 -0
- /package/dist/{chunk-NUEQKLNB.js.map → chunk-KMWYZTIE.js.map} +0 -0
- /package/dist/{chunk-TQ4GD737.js.map → chunk-L7G72WY4.js.map} +0 -0
- /package/dist/{chunk-CLB32OHM.js.map → chunk-LI7OE7G6.js.map} +0 -0
- /package/dist/{chunk-TN76AKO3.js.map → chunk-M2INOSTA.js.map} +0 -0
- /package/dist/{chunk-WQIHRA5F.js.map → chunk-N3LL5NEU.js.map} +0 -0
- /package/dist/{chunk-HFPASSFV.js.map → chunk-P2OTGMTR.js.map} +0 -0
- /package/dist/{chunk-Y7HRYCNW.js.map → chunk-PFJXPOD4.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-QCECHYZL.js.map → chunk-RVO6TCTU.js.map} +0 -0
- /package/dist/{chunk-D3I2MCN7.js.map → chunk-RVPTS4U5.js.map} +0 -0
- /package/dist/{chunk-W3IC7QOY.js.map → chunk-RVYVMQK4.js.map} +0 -0
- /package/dist/{chunk-2MRHJNWL.js.map → chunk-ST5IEK3H.js.map} +0 -0
- /package/dist/{chunk-O4KMGRXE.js.map → chunk-SXWHN7GC.js.map} +0 -0
- /package/dist/{chunk-KXEFRMCF.js.map → chunk-T6JRMVOV.js.map} +0 -0
- /package/dist/{chunk-R5RFK3CB.js.map → chunk-U6JGQ37L.js.map} +0 -0
- /package/dist/{chunk-EITZHSX6.js.map → chunk-V5FE3UAI.js.map} +0 -0
- /package/dist/{chunk-NTOIP2E6.js.map → chunk-W2ZSNIBP.js.map} +0 -0
- /package/dist/{chunk-QVSBTCVP.js.map → chunk-WHWDBTCJ.js.map} +0 -0
- /package/dist/{chunk-5CEECY6P.js.map → chunk-WOC6DXP5.js.map} +0 -0
- /package/dist/{chunk-XTAUXTDO.js.map → chunk-XBMJ35IP.js.map} +0 -0
- /package/dist/{chunk-P7NGM24P.js.map → chunk-YWCOJOUI.js.map} +0 -0
- /package/dist/{chunk-6NNNURLK.js.map → chunk-Z54EM5YZ.js.map} +0 -0
|
@@ -34,7 +34,13 @@ import { RerankCache, rerankLocalOrNoop, reorderByRankedKeys } from "../rerank.j
|
|
|
34
34
|
import type { SearchBackend, SearchDegradation, SearchExecutionOptions, SearchQueryOptions } from "../search/port.js";
|
|
35
35
|
import { SecureStoreLockedError } from "../secure-store/index.js";
|
|
36
36
|
import { isPathInsideStorageRoot } from "../storage-paths.js";
|
|
37
|
-
import { extractTagsFromPrompt, isTemporalQuery, queryByDateRangeAsync, queryByTagsAsync, readIndexSnapshotAsync, recencyWindowFromPrompt
|
|
37
|
+
import { extractTagsFromPrompt, isTemporalQuery, queryByDateRangeAsync, queryByTagsAsync, readIndexSnapshotAsync, recencyWindowFromPrompt } from "../temporal-index.js";
|
|
38
|
+
import {
|
|
39
|
+
buildQueryAwarePrefilter as buildQueryAwarePrefilterHelper,
|
|
40
|
+
fetchActiveArtifactsForNamespace as fetchActiveArtifactsForNamespaceHelper,
|
|
41
|
+
searchEmbeddingFallback as searchEmbeddingFallbackHelper,
|
|
42
|
+
searchQueryAwareFallback as searchQueryAwareFallbackHelper,
|
|
43
|
+
} from "./recall-search-prefilter.js";
|
|
38
44
|
import { shouldFilterSupersededFromRecall } from "../temporal-supersession.js";
|
|
39
45
|
import { isValidAsOf, isValidityExpiredNow } from "../temporal-validity.js";
|
|
40
46
|
import type { TrustStageResultItem } from "../trust-score-stage.js";
|
|
@@ -49,7 +55,6 @@ import {
|
|
|
49
55
|
} from "../recall-memory-map.js";
|
|
50
56
|
import { type UtilityRuntimeValues, applyUtilityRankingRuntimeDelta } from "../utility-runtime.js";
|
|
51
57
|
import {
|
|
52
|
-
computeArtifactCandidateFetchLimit,
|
|
53
58
|
lifecycleRecallScoreAdjustment,
|
|
54
59
|
shouldFilterLifecycleRecallCandidate,
|
|
55
60
|
computeQmdHybridFetchLimit,
|
|
@@ -247,158 +252,17 @@ export class RecallSearchPipelineCoordinator {
|
|
|
247
252
|
prompt: string,
|
|
248
253
|
targetCount: number,
|
|
249
254
|
): Promise<MemoryFile[]> {
|
|
250
|
-
|
|
251
|
-
let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
|
|
252
|
-
const maxFetchLimit = Math.min(800, Math.max(fetchLimit, targetCount * 8));
|
|
253
|
-
const MAX_ATTEMPTS = 4;
|
|
254
|
-
let bestFiltered: MemoryFile[] = [];
|
|
255
|
-
|
|
256
|
-
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
|
|
257
|
-
const rawResults = await storage.searchArtifacts(prompt, fetchLimit);
|
|
258
|
-
const sourceIds = Array.from(
|
|
259
|
-
new Set(
|
|
260
|
-
rawResults
|
|
261
|
-
.map((a) => a.frontmatter.sourceMemoryId)
|
|
262
|
-
.filter(
|
|
263
|
-
(id): id is string => typeof id === "string" && id.length > 0,
|
|
264
|
-
),
|
|
265
|
-
),
|
|
266
|
-
);
|
|
267
|
-
const sourceStatus =
|
|
268
|
-
sourceIds.length > 0
|
|
269
|
-
? await this.deps.resolveArtifactSourceStatuses(storage, sourceIds)
|
|
270
|
-
: new Map<string, "active" | "superseded" | "archived" | "missing">();
|
|
271
|
-
|
|
272
|
-
const filtered: MemoryFile[] = [];
|
|
273
|
-
for (const artifact of rawResults) {
|
|
274
|
-
const sourceId = artifact.frontmatter.sourceMemoryId;
|
|
275
|
-
if (!sourceId) {
|
|
276
|
-
filtered.push(artifact);
|
|
277
|
-
if (filtered.length >= targetCount) break;
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
const status = sourceStatus.get(sourceId) ?? "missing";
|
|
281
|
-
if (status !== "active") continue;
|
|
282
|
-
filtered.push(artifact);
|
|
283
|
-
if (filtered.length >= targetCount) break;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (filtered.length >= targetCount) return filtered.slice(0, targetCount);
|
|
287
|
-
if (filtered.length > bestFiltered.length) {
|
|
288
|
-
bestFiltered = filtered;
|
|
289
|
-
}
|
|
290
|
-
if (rawResults.length === 0) return filtered;
|
|
291
|
-
if (rawResults.length < fetchLimit && filtered.length > 0)
|
|
292
|
-
return filtered;
|
|
293
|
-
if (fetchLimit >= maxFetchLimit) return filtered;
|
|
294
|
-
|
|
295
|
-
const growth = Math.max(targetCount * 2, 12);
|
|
296
|
-
fetchLimit = Math.min(maxFetchLimit, fetchLimit + growth);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return bestFiltered;
|
|
255
|
+
return fetchActiveArtifactsForNamespaceHelper(this.deps, namespace, prompt, targetCount);
|
|
300
256
|
}
|
|
301
257
|
|
|
302
258
|
async buildQueryAwarePrefilter(
|
|
303
259
|
prompt: string,
|
|
304
260
|
recallNamespaces: string[],
|
|
305
261
|
): Promise<QueryAwarePrefilter> {
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
candidatePaths: null,
|
|
309
|
-
temporalFromDate: null,
|
|
310
|
-
matchedTags: [],
|
|
311
|
-
expandedTags: [],
|
|
312
|
-
combination: "none",
|
|
313
|
-
filteredToFullSearch: false,
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const temporalFromDate = isTemporalQuery(prompt)
|
|
318
|
-
? recencyWindowFromPrompt(prompt, Date.now())
|
|
319
|
-
: null;
|
|
320
|
-
// Read the temporal + tag prefilter indexes as ONE consistent snapshot
|
|
321
|
-
// (issue #1911, Codex Medium) so a concurrent async index mutation can't be
|
|
322
|
-
// observed half-applied (new temporal row, tag membership not yet written),
|
|
323
|
-
// which would drop the current memory from the tag prefilter.
|
|
324
|
-
const [rawTemporal, tagSignals] = await readIndexSnapshotAsync(
|
|
325
|
-
this.deps.config.memoryDir,
|
|
326
|
-
() =>
|
|
327
|
-
Promise.all([
|
|
328
|
-
temporalFromDate
|
|
329
|
-
? queryByDateRangeAsync(this.deps.config.memoryDir, temporalFromDate)
|
|
330
|
-
: Promise.resolve<Set<string> | null>(null),
|
|
331
|
-
resolvePromptTagPrefilterAsync(this.deps.config.memoryDir, prompt).catch(
|
|
332
|
-
() => ({
|
|
333
|
-
matchedTags: extractTagsFromPrompt(prompt),
|
|
334
|
-
expandedTags: extractTagsFromPrompt(prompt),
|
|
335
|
-
paths: null,
|
|
336
|
-
}),
|
|
337
|
-
),
|
|
338
|
-
]),
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
const temporalCandidates = this.deps.scopeQueryAwarePaths(
|
|
342
|
-
rawTemporal,
|
|
343
|
-
recallNamespaces,
|
|
344
|
-
);
|
|
345
|
-
const tagCandidates = this.deps.scopeQueryAwarePaths(
|
|
346
|
-
tagSignals.paths,
|
|
347
|
-
recallNamespaces,
|
|
348
|
-
);
|
|
349
|
-
const maxCandidates = this.deps.config.queryAwareIndexingMaxCandidates;
|
|
350
|
-
|
|
351
|
-
let candidatePaths: Set<string> | null = null;
|
|
352
|
-
let combination: QueryAwarePrefilter["combination"] = "none";
|
|
353
|
-
let filteredToFullSearch = false;
|
|
354
|
-
|
|
355
|
-
if (
|
|
356
|
-
tagSignals.matchedTags.length > 0 &&
|
|
357
|
-
tagCandidates !== null &&
|
|
358
|
-
tagCandidates.size === 0
|
|
359
|
-
) {
|
|
360
|
-
candidatePaths = tagCandidates;
|
|
361
|
-
combination = "tag";
|
|
362
|
-
} else if (temporalCandidates !== null && tagCandidates !== null) {
|
|
363
|
-
const intersection = new Set(
|
|
364
|
-
Array.from(temporalCandidates).filter((memoryPath) =>
|
|
365
|
-
tagCandidates.has(memoryPath),
|
|
366
|
-
),
|
|
367
|
-
);
|
|
368
|
-
if (intersection.size > 0) {
|
|
369
|
-
candidatePaths = intersection;
|
|
370
|
-
combination = "intersection";
|
|
371
|
-
} else {
|
|
372
|
-
candidatePaths = new Set([...temporalCandidates, ...tagCandidates]);
|
|
373
|
-
combination = "union";
|
|
374
|
-
}
|
|
375
|
-
} else if (temporalCandidates !== null) {
|
|
376
|
-
candidatePaths = temporalCandidates;
|
|
377
|
-
combination = "temporal";
|
|
378
|
-
} else if (tagCandidates !== null) {
|
|
379
|
-
candidatePaths = tagCandidates;
|
|
380
|
-
combination = "tag";
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (
|
|
384
|
-
candidatePaths &&
|
|
385
|
-
maxCandidates > 0 &&
|
|
386
|
-
candidatePaths.size > maxCandidates
|
|
387
|
-
) {
|
|
388
|
-
filteredToFullSearch = true;
|
|
389
|
-
candidatePaths = null;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return {
|
|
393
|
-
candidatePaths,
|
|
394
|
-
temporalFromDate,
|
|
395
|
-
matchedTags: tagSignals.matchedTags,
|
|
396
|
-
expandedTags: tagSignals.expandedTags,
|
|
397
|
-
combination,
|
|
398
|
-
filteredToFullSearch,
|
|
399
|
-
};
|
|
262
|
+
return buildQueryAwarePrefilterHelper(this.deps, prompt, recallNamespaces);
|
|
400
263
|
}
|
|
401
264
|
|
|
265
|
+
|
|
402
266
|
async fetchQmdMemoryResultsWithArtifactTopUp(
|
|
403
267
|
prompt: string,
|
|
404
268
|
qmdFetchLimit: number,
|
|
@@ -654,26 +518,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
654
518
|
query: string,
|
|
655
519
|
limit: number,
|
|
656
520
|
): Promise<QmdSearchResult[]> {
|
|
657
|
-
|
|
658
|
-
if (!(await this.deps.embeddingFallback.isAvailable())) return [];
|
|
659
|
-
const hits = await this.deps.embeddingFallback.search(query, limit);
|
|
660
|
-
if (hits.length === 0) return [];
|
|
661
|
-
|
|
662
|
-
const results: QmdSearchResult[] = [];
|
|
663
|
-
for (const hit of hits) {
|
|
664
|
-
const fullPath = path.isAbsolute(hit.path)
|
|
665
|
-
? hit.path
|
|
666
|
-
: path.join(this.deps.config.memoryDir, hit.path);
|
|
667
|
-
const memory = await this.deps.storage.readMemoryByPath(fullPath);
|
|
668
|
-
if (!memory) continue;
|
|
669
|
-
results.push({
|
|
670
|
-
docid: hit.id,
|
|
671
|
-
path: fullPath,
|
|
672
|
-
score: hit.score,
|
|
673
|
-
snippet: memory.content.slice(0, 400).replace(/\n/g, " "),
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
return results;
|
|
521
|
+
return searchEmbeddingFallbackHelper(this.deps, query, limit);
|
|
677
522
|
}
|
|
678
523
|
|
|
679
524
|
/**
|
|
@@ -686,24 +531,10 @@ export class RecallSearchPipelineCoordinator {
|
|
|
686
531
|
queryAwarePrefilter?: QueryAwarePrefilter,
|
|
687
532
|
abortSignal?: AbortSignal,
|
|
688
533
|
): Promise<QmdSearchResult[]> {
|
|
689
|
-
|
|
690
|
-
const cappedLimit = Math.max(0, limit);
|
|
691
|
-
if (cappedLimit === 0 || queryAwarePrefilter?.candidatePaths?.size === 0) return [];
|
|
692
|
-
|
|
693
|
-
const candidatePaths = queryAwarePrefilter?.candidatePaths;
|
|
694
|
-
const scopedSeedResults = (
|
|
695
|
-
candidatePaths?.size
|
|
696
|
-
? await this.deps.searchScopedMemoryCandidates(
|
|
697
|
-
candidatePaths,
|
|
698
|
-
prompt,
|
|
699
|
-
candidatePaths.size,
|
|
700
|
-
{ allowArchived: true },
|
|
701
|
-
)
|
|
702
|
-
: []
|
|
703
|
-
).filter((result) => !isGenericRecallExcludedPath(result.path, this.deps.config, "qmd"));
|
|
704
|
-
return scopedSeedResults.slice(0, cappedLimit);
|
|
534
|
+
return searchQueryAwareFallbackHelper(this.deps, prompt, limit, queryAwarePrefilter, abortSignal);
|
|
705
535
|
}
|
|
706
536
|
|
|
537
|
+
|
|
707
538
|
async applyColdFallbackPipeline(options: {
|
|
708
539
|
prompt: string;
|
|
709
540
|
recallNamespaces: string[];
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolveIndexingCapabilities, resolveMemoryLifecycleCapabilities } from "../capabilities.js";
|
|
3
|
+
import type { EmbeddingFallback } from "../embedding-fallback.js";
|
|
4
|
+
import type { StorageManager } from "../index.js";
|
|
5
|
+
import type { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
6
|
+
import {
|
|
7
|
+
computeArtifactCandidateFetchLimit,
|
|
8
|
+
throwIfRecallAborted,
|
|
9
|
+
type QueryAwarePrefilter,
|
|
10
|
+
} from "../orchestrator.js";
|
|
11
|
+
import {
|
|
12
|
+
extractTagsFromPrompt,
|
|
13
|
+
isTemporalQuery,
|
|
14
|
+
queryByDateRangeAsync,
|
|
15
|
+
readIndexSnapshotAsync,
|
|
16
|
+
recencyWindowFromPrompt,
|
|
17
|
+
resolvePromptTagPrefilterAsync,
|
|
18
|
+
} from "../temporal-index.js";
|
|
19
|
+
import type { MemoryFile, PluginConfig, QmdSearchResult } from "../types.js";
|
|
20
|
+
import { isGenericRecallExcludedPath } from "./generic-recall-paths.js";
|
|
21
|
+
|
|
22
|
+
export interface PrefilterAndArtifactDeps {
|
|
23
|
+
readonly config: PluginConfig;
|
|
24
|
+
readonly storageRouter: NamespaceStorageRouter;
|
|
25
|
+
readonly storage: StorageManager;
|
|
26
|
+
readonly embeddingFallback: EmbeddingFallback;
|
|
27
|
+
resolveArtifactSourceStatuses(
|
|
28
|
+
storage: StorageManager,
|
|
29
|
+
sourceIds: string[],
|
|
30
|
+
): Promise<Map<string, "active" | "superseded" | "archived" | "missing">>;
|
|
31
|
+
scopeQueryAwarePaths(
|
|
32
|
+
paths: Set<string> | null,
|
|
33
|
+
recallNamespaces: string[],
|
|
34
|
+
): Set<string> | null;
|
|
35
|
+
searchScopedMemoryCandidates(
|
|
36
|
+
candidatePaths: Set<string>,
|
|
37
|
+
query: string,
|
|
38
|
+
limit: number,
|
|
39
|
+
options?: {
|
|
40
|
+
allowArchived?: boolean;
|
|
41
|
+
},
|
|
42
|
+
): Promise<QmdSearchResult[]>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function fetchActiveArtifactsForNamespace(
|
|
46
|
+
deps: Pick<PrefilterAndArtifactDeps, "storageRouter" | "resolveArtifactSourceStatuses">,
|
|
47
|
+
namespace: string,
|
|
48
|
+
prompt: string,
|
|
49
|
+
targetCount: number,
|
|
50
|
+
): Promise<MemoryFile[]> {
|
|
51
|
+
const storage = await deps.storageRouter.storageFor(namespace);
|
|
52
|
+
let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
|
|
53
|
+
const maxFetchLimit = Math.min(800, Math.max(fetchLimit, targetCount * 8));
|
|
54
|
+
const MAX_ATTEMPTS = 4;
|
|
55
|
+
let bestFiltered: MemoryFile[] = [];
|
|
56
|
+
|
|
57
|
+
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
|
|
58
|
+
const rawResults = await storage.searchArtifacts(prompt, fetchLimit);
|
|
59
|
+
const sourceIds = Array.from(
|
|
60
|
+
new Set(
|
|
61
|
+
rawResults
|
|
62
|
+
.map((a) => a.frontmatter.sourceMemoryId)
|
|
63
|
+
.filter(
|
|
64
|
+
(id): id is string => typeof id === "string" && id.length > 0,
|
|
65
|
+
),
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
const sourceStatus =
|
|
69
|
+
sourceIds.length > 0
|
|
70
|
+
? await deps.resolveArtifactSourceStatuses(storage, sourceIds)
|
|
71
|
+
: new Map<string, "active" | "superseded" | "archived" | "missing">();
|
|
72
|
+
|
|
73
|
+
const filtered: MemoryFile[] = [];
|
|
74
|
+
for (const artifact of rawResults) {
|
|
75
|
+
const sourceId = artifact.frontmatter.sourceMemoryId;
|
|
76
|
+
if (!sourceId) {
|
|
77
|
+
filtered.push(artifact);
|
|
78
|
+
if (filtered.length >= targetCount) break;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const status = sourceStatus.get(sourceId) ?? "missing";
|
|
82
|
+
if (status !== "active") continue;
|
|
83
|
+
filtered.push(artifact);
|
|
84
|
+
if (filtered.length >= targetCount) break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (filtered.length >= targetCount) return filtered.slice(0, targetCount);
|
|
88
|
+
if (filtered.length > bestFiltered.length) {
|
|
89
|
+
bestFiltered = filtered;
|
|
90
|
+
}
|
|
91
|
+
if (rawResults.length === 0) return filtered;
|
|
92
|
+
if (rawResults.length < fetchLimit && filtered.length > 0)
|
|
93
|
+
return filtered;
|
|
94
|
+
if (fetchLimit >= maxFetchLimit) return filtered;
|
|
95
|
+
|
|
96
|
+
const growth = Math.max(targetCount * 2, 12);
|
|
97
|
+
fetchLimit = Math.min(maxFetchLimit, fetchLimit + growth);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return bestFiltered;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function buildQueryAwarePrefilter(
|
|
104
|
+
deps: Pick<PrefilterAndArtifactDeps, "config" | "scopeQueryAwarePaths">,
|
|
105
|
+
prompt: string,
|
|
106
|
+
recallNamespaces: string[],
|
|
107
|
+
): Promise<QueryAwarePrefilter> {
|
|
108
|
+
if (!resolveIndexingCapabilities(deps.config).queryAwareIndexing || !prompt.trim()) {
|
|
109
|
+
return {
|
|
110
|
+
candidatePaths: null,
|
|
111
|
+
temporalFromDate: null,
|
|
112
|
+
matchedTags: [],
|
|
113
|
+
expandedTags: [],
|
|
114
|
+
combination: "none",
|
|
115
|
+
filteredToFullSearch: false,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const temporalFromDate = isTemporalQuery(prompt)
|
|
120
|
+
? recencyWindowFromPrompt(prompt, Date.now())
|
|
121
|
+
: null;
|
|
122
|
+
// Read the temporal + tag prefilter indexes as ONE consistent snapshot
|
|
123
|
+
// (issue #1911, Codex Medium) so a concurrent async index mutation can't be
|
|
124
|
+
// observed half-applied (new temporal row, tag membership not yet written),
|
|
125
|
+
// which would drop the current memory from the tag prefilter.
|
|
126
|
+
const [rawTemporal, tagSignals] = await readIndexSnapshotAsync(
|
|
127
|
+
deps.config.memoryDir,
|
|
128
|
+
() =>
|
|
129
|
+
Promise.all([
|
|
130
|
+
temporalFromDate
|
|
131
|
+
? queryByDateRangeAsync(deps.config.memoryDir, temporalFromDate)
|
|
132
|
+
: Promise.resolve<Set<string> | null>(null),
|
|
133
|
+
resolvePromptTagPrefilterAsync(deps.config.memoryDir, prompt).catch(
|
|
134
|
+
() => ({
|
|
135
|
+
matchedTags: extractTagsFromPrompt(prompt),
|
|
136
|
+
expandedTags: extractTagsFromPrompt(prompt),
|
|
137
|
+
paths: null,
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
140
|
+
]),
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const temporalCandidates = deps.scopeQueryAwarePaths(
|
|
144
|
+
rawTemporal,
|
|
145
|
+
recallNamespaces,
|
|
146
|
+
);
|
|
147
|
+
const tagCandidates = deps.scopeQueryAwarePaths(
|
|
148
|
+
tagSignals.paths,
|
|
149
|
+
recallNamespaces,
|
|
150
|
+
);
|
|
151
|
+
const maxCandidates = deps.config.queryAwareIndexingMaxCandidates;
|
|
152
|
+
|
|
153
|
+
let candidatePaths: Set<string> | null = null;
|
|
154
|
+
let combination: QueryAwarePrefilter["combination"] = "none";
|
|
155
|
+
let filteredToFullSearch = false;
|
|
156
|
+
|
|
157
|
+
if (
|
|
158
|
+
tagSignals.matchedTags.length > 0 &&
|
|
159
|
+
tagCandidates !== null &&
|
|
160
|
+
tagCandidates.size === 0
|
|
161
|
+
) {
|
|
162
|
+
candidatePaths = tagCandidates;
|
|
163
|
+
combination = "tag";
|
|
164
|
+
} else if (temporalCandidates !== null && tagCandidates !== null) {
|
|
165
|
+
const intersection = new Set(
|
|
166
|
+
Array.from(temporalCandidates).filter((memoryPath) =>
|
|
167
|
+
tagCandidates.has(memoryPath),
|
|
168
|
+
),
|
|
169
|
+
);
|
|
170
|
+
if (intersection.size > 0) {
|
|
171
|
+
candidatePaths = intersection;
|
|
172
|
+
combination = "intersection";
|
|
173
|
+
} else {
|
|
174
|
+
candidatePaths = new Set([...temporalCandidates, ...tagCandidates]);
|
|
175
|
+
combination = "union";
|
|
176
|
+
}
|
|
177
|
+
} else if (temporalCandidates !== null) {
|
|
178
|
+
candidatePaths = temporalCandidates;
|
|
179
|
+
combination = "temporal";
|
|
180
|
+
} else if (tagCandidates !== null) {
|
|
181
|
+
candidatePaths = tagCandidates;
|
|
182
|
+
combination = "tag";
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
candidatePaths &&
|
|
187
|
+
maxCandidates > 0 &&
|
|
188
|
+
candidatePaths.size > maxCandidates
|
|
189
|
+
) {
|
|
190
|
+
filteredToFullSearch = true;
|
|
191
|
+
candidatePaths = null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
candidatePaths,
|
|
196
|
+
temporalFromDate,
|
|
197
|
+
matchedTags: tagSignals.matchedTags,
|
|
198
|
+
expandedTags: tagSignals.expandedTags,
|
|
199
|
+
combination,
|
|
200
|
+
filteredToFullSearch,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export async function searchEmbeddingFallback(
|
|
205
|
+
deps: Pick<PrefilterAndArtifactDeps, "config" | "embeddingFallback" | "storage">,
|
|
206
|
+
query: string,
|
|
207
|
+
limit: number,
|
|
208
|
+
): Promise<QmdSearchResult[]> {
|
|
209
|
+
if (!resolveMemoryLifecycleCapabilities(deps.config).embeddingFallback) return [];
|
|
210
|
+
if (!(await deps.embeddingFallback.isAvailable())) return [];
|
|
211
|
+
const hits = await deps.embeddingFallback.search(query, limit);
|
|
212
|
+
if (hits.length === 0) return [];
|
|
213
|
+
|
|
214
|
+
const results: QmdSearchResult[] = [];
|
|
215
|
+
for (const hit of hits) {
|
|
216
|
+
const fullPath = path.isAbsolute(hit.path)
|
|
217
|
+
? hit.path
|
|
218
|
+
: path.join(deps.config.memoryDir, hit.path);
|
|
219
|
+
const memory = await deps.storage.readMemoryByPath(fullPath);
|
|
220
|
+
if (!memory) continue;
|
|
221
|
+
results.push({
|
|
222
|
+
docid: hit.id,
|
|
223
|
+
path: fullPath,
|
|
224
|
+
score: hit.score,
|
|
225
|
+
snippet: memory.content.slice(0, 400).replace(/\n/g, " "),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return results;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export async function searchQueryAwareFallback(
|
|
232
|
+
deps: Pick<PrefilterAndArtifactDeps, "config" | "searchScopedMemoryCandidates">,
|
|
233
|
+
prompt: string,
|
|
234
|
+
limit: number,
|
|
235
|
+
queryAwarePrefilter?: QueryAwarePrefilter,
|
|
236
|
+
abortSignal?: AbortSignal,
|
|
237
|
+
): Promise<QmdSearchResult[]> {
|
|
238
|
+
throwIfRecallAborted(abortSignal);
|
|
239
|
+
const cappedLimit = Math.max(0, limit);
|
|
240
|
+
if (cappedLimit === 0 || queryAwarePrefilter?.candidatePaths?.size === 0) return [];
|
|
241
|
+
|
|
242
|
+
const candidatePaths = queryAwarePrefilter?.candidatePaths;
|
|
243
|
+
const scopedSeedResults = (
|
|
244
|
+
candidatePaths?.size
|
|
245
|
+
? await deps.searchScopedMemoryCandidates(
|
|
246
|
+
candidatePaths,
|
|
247
|
+
prompt,
|
|
248
|
+
candidatePaths.size,
|
|
249
|
+
{ allowArchived: true },
|
|
250
|
+
)
|
|
251
|
+
: []
|
|
252
|
+
).filter((result) => !isGenericRecallExcludedPath(result.path, deps.config, "qmd"));
|
|
253
|
+
return scopedSeedResults.slice(0, cappedLimit);
|
|
254
|
+
}
|
|
@@ -306,7 +306,7 @@ export class SessionContextCoordinator {
|
|
|
306
306
|
* Register a peer ID for a session so recall can inject the peer's
|
|
307
307
|
* profile into context (issue #679 PR 3/5). Pass `null` to clear.
|
|
308
308
|
*
|
|
309
|
-
* Connectors and the `
|
|
309
|
+
* Connectors and the `before_prompt_build` hook call this when the
|
|
310
310
|
* session's counter-party is known. The ID is validated against
|
|
311
311
|
* `PEER_ID_PATTERN` before storing.
|
|
312
312
|
*
|
package/src/orchestrator.ts
CHANGED
|
@@ -656,7 +656,7 @@ export class Orchestrator {
|
|
|
656
656
|
|
|
657
657
|
/**
|
|
658
658
|
* Per-session workspace selections keyed by sessionKey.
|
|
659
|
-
* Set by the
|
|
659
|
+
* Set by the before_prompt_build hook so recall() uses the correct
|
|
660
660
|
* agent workspace for BOOT.md injection. Cleared after each recall.
|
|
661
661
|
* Using a Map prevents concurrent sessions from overwriting each other.
|
|
662
662
|
*/
|
package/src/sdk-compat.ts
CHANGED
|
@@ -64,10 +64,8 @@ export function detectSdkCapabilities(api: Record<string, unknown>): SdkCapabili
|
|
|
64
64
|
// - registerMemoryCapability (capability-based SDKs, ≥2026.4.5; the
|
|
65
65
|
// deprecated registerMemoryPromptSection may be absent)
|
|
66
66
|
// - registrationMode (explicit registration lifecycle signal)
|
|
67
|
-
//
|
|
68
|
-
// expose it
|
|
69
|
-
// legacy before_agent_start hook to be registered on new SDKs that only
|
|
70
|
-
// expose registerMemoryCapability, silently breaking memory injection.
|
|
67
|
+
// Runtime version alone is not authoritative because some transitional
|
|
68
|
+
// builds expose it without the modern prompt-hook surfaces.
|
|
71
69
|
const hasNewHookSystem =
|
|
72
70
|
hasRegisterMemoryPromptSection || hasRegisterMemoryCapability || hasRegistrationMode;
|
|
73
71
|
|
|
@@ -48,6 +48,9 @@ export interface ExtractionGroundingContext {
|
|
|
48
48
|
roleAssertionSources?: ExtractionGroundingRoleSources;
|
|
49
49
|
messageTimestamp: Date | undefined;
|
|
50
50
|
sourceConnector?: string;
|
|
51
|
+
/** Input came from an always-on recorder (issue #2294); the proactive
|
|
52
|
+
* second pass reads it so its prompts carry the same media warning. */
|
|
53
|
+
ambientCapture?: boolean;
|
|
51
54
|
scopeClassificationEnabled?: boolean;
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -435,3 +435,102 @@ test("citation path lookup resolves collection-prefixed QMD paths", async () =>
|
|
|
435
435
|
await rm(dir, { recursive: true, force: true });
|
|
436
436
|
}
|
|
437
437
|
});
|
|
438
|
+
test("memory snapshots ignore object key order", async () => {
|
|
439
|
+
const { createMemorySnapshot } = await import("../memory-snapshot.js");
|
|
440
|
+
type SnapshotInput = Parameters<typeof createMemorySnapshot>[0];
|
|
441
|
+
const first = {
|
|
442
|
+
content: "payload",
|
|
443
|
+
frontmatter: { z: 1, nested: { y: 2, x: 3 } },
|
|
444
|
+
} as unknown as SnapshotInput;
|
|
445
|
+
const second = {
|
|
446
|
+
frontmatter: { nested: { x: 3, y: 2 }, z: 1 },
|
|
447
|
+
content: "payload",
|
|
448
|
+
} as unknown as SnapshotInput;
|
|
449
|
+
assert.equal(createMemorySnapshot(first), createMemorySnapshot(second));
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
test("tier move: caller-only mutation is not persisted by moveMemoryToPath", async () => {
|
|
453
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-caller-mut-"));
|
|
454
|
+
try {
|
|
455
|
+
resetStaticCaches();
|
|
456
|
+
const storage = new StorageManager(dir);
|
|
457
|
+
await storage.ensureDirectories();
|
|
458
|
+
|
|
459
|
+
const { id } = await storage.writeMemory("fact", "original disk content");
|
|
460
|
+
const memories = await storage.readAllMemories();
|
|
461
|
+
const memory = memories.find((m) => m.frontmatter.id === id);
|
|
462
|
+
assert.ok(memory, "memory must exist");
|
|
463
|
+
|
|
464
|
+
memory.content = "caller mutated unpersisted content";
|
|
465
|
+
|
|
466
|
+
const targetPath = storage.buildTierMemoryPath(memory, "cold");
|
|
467
|
+
await storage.moveMemoryToPath(memory, targetPath);
|
|
468
|
+
|
|
469
|
+
const onDisk = await readFile(targetPath, "utf8");
|
|
470
|
+
assert.ok(onDisk.includes("original disk content"), "Moved file on disk must retain original content");
|
|
471
|
+
assert.ok(!onDisk.includes("caller mutated unpersisted content"), "Moved file on disk must not carry caller's unpersisted content mutation");
|
|
472
|
+
} finally {
|
|
473
|
+
resetStaticCaches();
|
|
474
|
+
await rm(dir, { recursive: true, force: true });
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test("tier move: stale on-disk mutation fails snapshot check during move", async () => {
|
|
479
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-stale-disk-"));
|
|
480
|
+
try {
|
|
481
|
+
resetStaticCaches();
|
|
482
|
+
const storage = new StorageManager(dir);
|
|
483
|
+
await storage.ensureDirectories();
|
|
484
|
+
|
|
485
|
+
const { id } = await storage.writeMemory("fact", "unmodified content");
|
|
486
|
+
const memories = await storage.readAllMemories();
|
|
487
|
+
const memory = memories.find((m) => m.frontmatter.id === id);
|
|
488
|
+
assert.ok(memory, "memory must exist");
|
|
489
|
+
|
|
490
|
+
const diskContent = await readFile(memory.path, "utf8");
|
|
491
|
+
await writeFile(memory.path, diskContent.replace("unmodified content", "external edit on disk"));
|
|
492
|
+
|
|
493
|
+
const targetPath = storage.buildTierMemoryPath(memory, "cold");
|
|
494
|
+
await assert.rejects(
|
|
495
|
+
async () => {
|
|
496
|
+
await storage.moveMemoryToPath(memory, targetPath);
|
|
497
|
+
},
|
|
498
|
+
(err: Error) => {
|
|
499
|
+
return err.message.includes("changed before its tier move");
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
} finally {
|
|
503
|
+
resetStaticCaches();
|
|
504
|
+
await rm(dir, { recursive: true, force: true });
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test("tier move: cold-to-hot move invalidates cold cache and cannot remain in readAllColdMemories", async () => {
|
|
509
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-cold-to-hot-"));
|
|
510
|
+
try {
|
|
511
|
+
resetStaticCaches();
|
|
512
|
+
const storage = new StorageManager(dir);
|
|
513
|
+
await storage.ensureDirectories();
|
|
514
|
+
|
|
515
|
+
const { id } = await storage.writeMemory("fact", "demoted to cold then promoted");
|
|
516
|
+
const memories = await storage.readAllMemories();
|
|
517
|
+
const memory = memories.find((m) => m.frontmatter.id === id);
|
|
518
|
+
assert.ok(memory, "memory must exist");
|
|
519
|
+
|
|
520
|
+
const { targetPath: coldPath } = await storage.migrateMemoryToTier(memory, "cold");
|
|
521
|
+
|
|
522
|
+
const coldMemories = await storage.readAllColdMemories();
|
|
523
|
+
const coldMem = coldMemories.find((m) => m.frontmatter.id === id);
|
|
524
|
+
assert.ok(coldMem, "memory must be present in cold tier read");
|
|
525
|
+
|
|
526
|
+
const { changed } = await storage.migrateMemoryToTier(coldMem, "hot");
|
|
527
|
+
assert.equal(changed, true, "migration from cold to hot must succeed");
|
|
528
|
+
|
|
529
|
+
const coldMemoriesAfter = await storage.readAllColdMemories();
|
|
530
|
+
const foundInCold = coldMemoriesAfter.some((m) => m.frontmatter.id === id);
|
|
531
|
+
assert.equal(foundInCold, false, "promoted memory must not remain in readAllColdMemories cache");
|
|
532
|
+
} finally {
|
|
533
|
+
resetStaticCaches();
|
|
534
|
+
await rm(dir, { recursive: true, force: true });
|
|
535
|
+
}
|
|
536
|
+
});
|