@remnic/core 9.50.0 → 9.50.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +10 -10
- package/dist/access-admin-ops-surface.js +17 -17
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +18 -18
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +17 -17
- package/dist/access-cli.js +42 -42
- 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 +17 -17
- 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-query.js +17 -17
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +23 -23
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +17 -17
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +17 -17
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +21 -21
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-DuDU301-.d.ts → access-namespace-preflight-Dj2QolFE.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +17 -17
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +17 -17
- package/dist/access-offline-manifest.d.ts +8 -8
- package/dist/access-operations-batch.js +18 -18
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +20 -20
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +17 -17
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +17 -17
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +17 -17
- package/dist/{access-service--_3T_v23.d.ts → access-service-DesbnTSa.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +10 -10
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +17 -17
- 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/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +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 -6
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-merge-KXTRZ23Z.js → capsule-merge-XMFBXVDP.js} +4 -4
- package/dist/{catalog-DjUmUIal.d.ts → catalog-D-G7RgXR.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 -7
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-N3CXAYPJ.js → chunk-2HGUDBRJ.js} +2 -2
- package/dist/{chunk-FV7YQTN3.js → chunk-2S72LWKX.js} +2 -2
- package/dist/{chunk-NKL25FCF.js → chunk-4MBPIL4V.js} +2 -2
- package/dist/{chunk-PWIMF7LP.js → chunk-5C2HNJMO.js} +12 -12
- package/dist/{chunk-ZN4EYMKJ.js → chunk-67QG75MJ.js} +2 -2
- package/dist/{chunk-JI62YGPI.js → chunk-6QPHF6RR.js} +2 -2
- package/dist/{chunk-4EABKPZS.js → chunk-75XOWNRS.js} +4 -4
- package/dist/{chunk-O76MWTVS.js → chunk-7BAYBYY5.js} +2 -2
- package/dist/{chunk-4JWJMRPJ.js → chunk-7PKFPLLZ.js} +2 -2
- package/dist/{chunk-24BKGKGO.js → chunk-BOFVT6P3.js} +5 -5
- package/dist/{chunk-SHYIMIX5.js → chunk-ESG7Z255.js} +2 -2
- package/dist/{chunk-P26YHAQH.js → chunk-EWMTOVMY.js} +51 -27
- package/dist/chunk-EWMTOVMY.js.map +1 -0
- package/dist/{chunk-WPZX7MEA.js → chunk-FXX6RQYC.js} +3 -3
- package/dist/{chunk-S75UQ3T3.js → chunk-GDDGZVFI.js} +2 -2
- package/dist/{chunk-S2SJEOTM.js → chunk-GFIKG4FR.js} +2 -2
- package/dist/{chunk-7NDM2PNK.js → chunk-GZICBRWK.js} +2 -2
- package/dist/{chunk-X4IDNPOS.js → chunk-HAEU3ZW7.js} +2 -2
- package/dist/{chunk-RBPH3GZV.js → chunk-IK6X5QPO.js} +26 -29
- package/dist/chunk-IK6X5QPO.js.map +1 -0
- package/dist/{chunk-GKEYXXKX.js → chunk-IXXABW5A.js} +2 -2
- package/dist/{chunk-GGBSF2X7.js → chunk-JB6D7EFB.js} +2 -2
- package/dist/{chunk-E633OXMH.js → chunk-JPHEOE6Z.js} +8 -8
- package/dist/{chunk-6XGEBQ3R.js → chunk-KDG2KTWW.js} +3 -3
- package/dist/{chunk-7BLWBSRL.js → chunk-LEJPSMKM.js} +2 -2
- package/dist/{chunk-JDCQK3C5.js → chunk-M4A44LUA.js} +2 -2
- package/dist/{chunk-ZDAYWJV6.js → chunk-NO37MR45.js} +3 -3
- package/dist/{chunk-PWLB4TRK.js → chunk-OQAL6SIR.js} +2 -2
- package/dist/{chunk-QWLW3VQH.js → chunk-PLKFO2HJ.js} +2 -2
- package/dist/{chunk-EURCX6PS.js → chunk-PWN32TAG.js} +2 -2
- package/dist/{chunk-ELQCS47S.js → chunk-PYKKWQZ2.js} +3 -3
- package/dist/{chunk-P4QOYG52.js → chunk-QN7NTKRC.js} +1 -1
- package/dist/{chunk-7VWZ4LRW.js → chunk-QW3WFHKU.js} +2 -2
- package/dist/{chunk-PNRA7FAD.js → chunk-RZRUV6N2.js} +104 -62
- package/dist/chunk-RZRUV6N2.js.map +1 -0
- package/dist/{chunk-3LD4N2TF.js → chunk-S3AYIQCU.js} +68 -82
- package/dist/chunk-S3AYIQCU.js.map +1 -0
- package/dist/{chunk-ZJIFYUJI.js → chunk-SV3PSA7Y.js} +2 -2
- package/dist/{chunk-LQKXVQZR.js → chunk-TQFHQPWD.js} +5 -5
- package/dist/{chunk-GSEPRIZC.js → chunk-TS4AJ2GI.js} +2 -2
- package/dist/{chunk-VFS3MK5F.js → chunk-V5H6OJCR.js} +2 -2
- package/dist/{chunk-T35UJI5R.js → chunk-V7X767RT.js} +18 -18
- package/dist/{chunk-4S3ECH3U.js → chunk-VJXY5ZCT.js} +2 -2
- package/dist/{chunk-PLCHU56K.js → chunk-YQ4IQ2GA.js} +2 -2
- package/dist/{chunk-LTOAJXZB.js → chunk-Z3RHPGSY.js} +3 -3
- package/dist/{chunk-5XCN4XBU.js → chunk-ZQOCRIGA.js} +3 -3
- package/dist/{cli-BLNmNEMT.d.ts → cli-D4vvtxjY.d.ts} +5 -5
- package/dist/cli.d.ts +12 -12
- package/dist/cli.js +34 -34
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +6 -6
- 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 -6
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +7 -7
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/consolidation-undo.js +3 -3
- 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 -8
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +8 -8
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/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 -6
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +8 -8
- package/dist/explicit-capture.js +4 -4
- package/dist/external-wiki-access.d.ts +10 -10
- package/dist/external-wiki-access.js +18 -18
- 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/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +17 -18
- package/dist/extraction.js +10 -10
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-GJ42LCBW.js → forget-UJDJHG6R.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +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 +42 -42
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- 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 -6
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +6 -6
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +7 -7
- package/dist/{maintenance-DKbKZi3u.d.ts → maintenance-ClmUVpGI.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 +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 +7 -7
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +6 -6
- 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 +9 -9
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +14 -14
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +11 -11
- package/dist/{orchestrator-BRwD7ceU.d.ts → orchestrator-qJ07zI8H.d.ts} +8 -12
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +42 -42
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-DC-1C9T8.d.ts → pipeline-WFCxhHOn.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-DdeCEZdb.d.ts → qmd-5tzkQ44y.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-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-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- 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/{scope-profiles-BXVq4Jv0.d.ts → scope-profiles--vfXPl3X.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- 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-CGYxfa8F.d.ts → semantic-consolidation-BBDuP9nJ.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +7 -7
- package/dist/semantic-rule-promotion.js +6 -6
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +6 -6
- package/dist/{service-CBDBQFCN.d.ts → service-B8DtbpCM.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +9 -9
- package/dist/{storage-V--MQi7w.d.ts → storage-BkYN1RIy.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +5 -5
- 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-supersession.js +1 -1
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-D_a6Sqjz.d.ts → types-u2s9j1uD.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +6 -6
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/connectors/index.ts +40 -112
- package/src/dependency-revalidation-routing.test.ts +165 -0
- package/src/extraction.ts +46 -31
- package/src/orchestration/dependency-propagation.test.ts +89 -8
- package/src/orchestration/dependency-propagation.ts +60 -27
- package/src/orchestration/dependency-revalidation.test.ts +119 -0
- package/src/orchestration/dependency-revalidation.ts +31 -82
- package/src/orchestrator.ts +5 -7
- package/src/runtime/daemon-health.ts +53 -0
- package/src/runtime/http-transport.ts +25 -0
- package/src/testing/subjects/dependency-propagation.test.ts +367 -0
- package/dist/chunk-3LD4N2TF.js.map +0 -1
- package/dist/chunk-P26YHAQH.js.map +0 -1
- package/dist/chunk-PNRA7FAD.js.map +0 -1
- package/dist/chunk-RBPH3GZV.js.map +0 -1
- /package/dist/{capsule-merge-KXTRZ23Z.js.map → capsule-merge-XMFBXVDP.js.map} +0 -0
- /package/dist/{chunk-N3CXAYPJ.js.map → chunk-2HGUDBRJ.js.map} +0 -0
- /package/dist/{chunk-FV7YQTN3.js.map → chunk-2S72LWKX.js.map} +0 -0
- /package/dist/{chunk-NKL25FCF.js.map → chunk-4MBPIL4V.js.map} +0 -0
- /package/dist/{chunk-PWIMF7LP.js.map → chunk-5C2HNJMO.js.map} +0 -0
- /package/dist/{chunk-ZN4EYMKJ.js.map → chunk-67QG75MJ.js.map} +0 -0
- /package/dist/{chunk-JI62YGPI.js.map → chunk-6QPHF6RR.js.map} +0 -0
- /package/dist/{chunk-4EABKPZS.js.map → chunk-75XOWNRS.js.map} +0 -0
- /package/dist/{chunk-O76MWTVS.js.map → chunk-7BAYBYY5.js.map} +0 -0
- /package/dist/{chunk-4JWJMRPJ.js.map → chunk-7PKFPLLZ.js.map} +0 -0
- /package/dist/{chunk-24BKGKGO.js.map → chunk-BOFVT6P3.js.map} +0 -0
- /package/dist/{chunk-SHYIMIX5.js.map → chunk-ESG7Z255.js.map} +0 -0
- /package/dist/{chunk-WPZX7MEA.js.map → chunk-FXX6RQYC.js.map} +0 -0
- /package/dist/{chunk-S75UQ3T3.js.map → chunk-GDDGZVFI.js.map} +0 -0
- /package/dist/{chunk-S2SJEOTM.js.map → chunk-GFIKG4FR.js.map} +0 -0
- /package/dist/{chunk-7NDM2PNK.js.map → chunk-GZICBRWK.js.map} +0 -0
- /package/dist/{chunk-X4IDNPOS.js.map → chunk-HAEU3ZW7.js.map} +0 -0
- /package/dist/{chunk-GKEYXXKX.js.map → chunk-IXXABW5A.js.map} +0 -0
- /package/dist/{chunk-GGBSF2X7.js.map → chunk-JB6D7EFB.js.map} +0 -0
- /package/dist/{chunk-E633OXMH.js.map → chunk-JPHEOE6Z.js.map} +0 -0
- /package/dist/{chunk-6XGEBQ3R.js.map → chunk-KDG2KTWW.js.map} +0 -0
- /package/dist/{chunk-7BLWBSRL.js.map → chunk-LEJPSMKM.js.map} +0 -0
- /package/dist/{chunk-JDCQK3C5.js.map → chunk-M4A44LUA.js.map} +0 -0
- /package/dist/{chunk-ZDAYWJV6.js.map → chunk-NO37MR45.js.map} +0 -0
- /package/dist/{chunk-PWLB4TRK.js.map → chunk-OQAL6SIR.js.map} +0 -0
- /package/dist/{chunk-QWLW3VQH.js.map → chunk-PLKFO2HJ.js.map} +0 -0
- /package/dist/{chunk-EURCX6PS.js.map → chunk-PWN32TAG.js.map} +0 -0
- /package/dist/{chunk-ELQCS47S.js.map → chunk-PYKKWQZ2.js.map} +0 -0
- /package/dist/{chunk-P4QOYG52.js.map → chunk-QN7NTKRC.js.map} +0 -0
- /package/dist/{chunk-7VWZ4LRW.js.map → chunk-QW3WFHKU.js.map} +0 -0
- /package/dist/{chunk-ZJIFYUJI.js.map → chunk-SV3PSA7Y.js.map} +0 -0
- /package/dist/{chunk-LQKXVQZR.js.map → chunk-TQFHQPWD.js.map} +0 -0
- /package/dist/{chunk-GSEPRIZC.js.map → chunk-TS4AJ2GI.js.map} +0 -0
- /package/dist/{chunk-VFS3MK5F.js.map → chunk-V5H6OJCR.js.map} +0 -0
- /package/dist/{chunk-T35UJI5R.js.map → chunk-V7X767RT.js.map} +0 -0
- /package/dist/{chunk-4S3ECH3U.js.map → chunk-VJXY5ZCT.js.map} +0 -0
- /package/dist/{chunk-PLCHU56K.js.map → chunk-YQ4IQ2GA.js.map} +0 -0
- /package/dist/{chunk-LTOAJXZB.js.map → chunk-Z3RHPGSY.js.map} +0 -0
- /package/dist/{chunk-5XCN4XBU.js.map → chunk-ZQOCRIGA.js.map} +0 -0
- /package/dist/{forget-GJ42LCBW.js.map → forget-UJDJHG6R.js.map} +0 -0
|
@@ -79,7 +79,7 @@ function config(overrides: Record<string, unknown> = {}): PluginConfig {
|
|
|
79
79
|
|
|
80
80
|
function fixture(
|
|
81
81
|
initial: MemoryFile[],
|
|
82
|
-
verdicts: Verdict[] | Error | ((signal?: AbortSignal) => Promise<
|
|
82
|
+
verdicts: Verdict[] | Error | ((signal?: AbortSignal) => Promise<{ verdicts: Verdict[] }>),
|
|
83
83
|
): Fixture {
|
|
84
84
|
const memories = new Map(initial.map((item) => [item.frontmatter.id, item]));
|
|
85
85
|
const calls: Fixture["calls"] = { revalidate: [], supersede: [], frontmatter: [] };
|
|
@@ -267,13 +267,24 @@ test("disabled propagation is an immediate no-op for boolean and string false",
|
|
|
267
267
|
},
|
|
268
268
|
);
|
|
269
269
|
|
|
270
|
-
assert.deepEqual(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
270
|
+
assert.deepEqual(
|
|
271
|
+
{
|
|
272
|
+
dependentsFound: result.dependentsFound,
|
|
273
|
+
invalidated: result.invalidated,
|
|
274
|
+
stillValid: result.stillValid,
|
|
275
|
+
uncertain: result.uncertain,
|
|
276
|
+
skipped: result.skipped,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
dependentsFound: 0,
|
|
280
|
+
invalidated: 0,
|
|
281
|
+
stillValid: 0,
|
|
282
|
+
uncertain: 0,
|
|
283
|
+
skipped: "disabled",
|
|
284
|
+
},
|
|
285
|
+
);
|
|
286
|
+
assert.equal(result.route, null);
|
|
287
|
+
assert.equal(typeof result.durationMs, "number");
|
|
277
288
|
assert.equal(fixtureValue.calls.revalidate.length, 0);
|
|
278
289
|
}
|
|
279
290
|
});
|
|
@@ -295,6 +306,12 @@ test("invalidated verdict supersedes the dependent and persists dependency front
|
|
|
295
306
|
);
|
|
296
307
|
|
|
297
308
|
assert.equal(result.invalidated, 1);
|
|
309
|
+
assert.equal(result.dependentsFound, 1);
|
|
310
|
+
assert.equal(result.stillValid, 0);
|
|
311
|
+
assert.equal(result.uncertain, 0);
|
|
312
|
+
assert.equal(result.skipped, null);
|
|
313
|
+
assert.equal(result.route, "fast-completion");
|
|
314
|
+
assert.equal(typeof result.durationMs, "number");
|
|
298
315
|
assert.deepEqual(fixtureValue.calls.supersede, [
|
|
299
316
|
{
|
|
300
317
|
id: "dep",
|
|
@@ -387,6 +404,12 @@ test("LLM errors skip the event and perform zero writes", async () => {
|
|
|
387
404
|
},
|
|
388
405
|
);
|
|
389
406
|
|
|
407
|
+
assert.equal(result.dependentsFound, 1);
|
|
408
|
+
assert.equal(result.invalidated, 0);
|
|
409
|
+
assert.equal(result.stillValid, 0);
|
|
410
|
+
assert.equal(result.uncertain, 0);
|
|
411
|
+
assert.equal(result.route, "fast-completion");
|
|
412
|
+
assert.equal(typeof result.durationMs, "number");
|
|
390
413
|
assert.equal(result.skipped, "llm_error");
|
|
391
414
|
assert.equal(fixtureValue.calls.supersede.length, 0);
|
|
392
415
|
assert.equal(fixtureValue.calls.frontmatter.length, 0);
|
|
@@ -411,11 +434,69 @@ test("LLM timeout aborts the batch and performs zero writes", async () => {
|
|
|
411
434
|
},
|
|
412
435
|
);
|
|
413
436
|
|
|
437
|
+
assert.equal(result.dependentsFound, 1);
|
|
438
|
+
assert.equal(result.route, "fast-completion");
|
|
439
|
+
assert.equal(typeof result.durationMs, "number");
|
|
414
440
|
assert.equal(result.skipped, "timeout");
|
|
415
441
|
assert.equal(fixtureValue.calls.supersede.length, 0);
|
|
416
442
|
assert.equal(fixtureValue.calls.frontmatter.length, 0);
|
|
417
443
|
});
|
|
418
444
|
|
|
445
|
+
test("a completion that ignores AbortSignal returns at the shared deadline", async (t) => {
|
|
446
|
+
t.mock.timers.enable({ apis: ["setTimeout", "Date"], now: 0 });
|
|
447
|
+
try {
|
|
448
|
+
const old = memory("old", { links: [{ targetId: "dep", linkType: "supports" }] });
|
|
449
|
+
const fixtureValue = fixture([old, memory("dep")], () => new Promise<never>(() => {}));
|
|
450
|
+
const resultPromise = propagateInvalidation(
|
|
451
|
+
deps(fixtureValue, { dependencyPropagation: { timeoutMs: 20 } }),
|
|
452
|
+
{
|
|
453
|
+
oldMemory: old,
|
|
454
|
+
replacementId: "new",
|
|
455
|
+
replacementContent: "replacement",
|
|
456
|
+
cause: "contradiction",
|
|
457
|
+
namespaceScope: "namespace-a",
|
|
458
|
+
},
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
await Promise.resolve();
|
|
462
|
+
t.mock.timers.tick(20);
|
|
463
|
+
const result = await resultPromise;
|
|
464
|
+
|
|
465
|
+
assert.equal(result.dependentsFound, 1);
|
|
466
|
+
assert.equal(result.invalidated, 0);
|
|
467
|
+
assert.equal(result.stillValid, 0);
|
|
468
|
+
assert.equal(result.uncertain, 0);
|
|
469
|
+
assert.equal(result.skipped, "timeout");
|
|
470
|
+
assert.equal(result.route, "fast-completion");
|
|
471
|
+
assert.equal(result.durationMs, 20);
|
|
472
|
+
assert.equal(fixtureValue.calls.supersede.length, 0);
|
|
473
|
+
assert.equal(fixtureValue.calls.frontmatter.length, 0);
|
|
474
|
+
} finally {
|
|
475
|
+
t.mock.timers.reset();
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
test("a zero timeout disables the deadline", async () => {
|
|
480
|
+
const old = memory("old", { links: [{ targetId: "dep", linkType: "supports" }] });
|
|
481
|
+
const fixtureValue = fixture([old, memory("dep")], () =>
|
|
482
|
+
new Promise((resolve) => setTimeout(() => resolve({
|
|
483
|
+
verdicts: [{ memoryId: "dep", verdict: "invalidated" }],
|
|
484
|
+
}), 5)),
|
|
485
|
+
);
|
|
486
|
+
const result = await propagateInvalidation(
|
|
487
|
+
deps(fixtureValue, { dependencyPropagation: { timeoutMs: 0 } }),
|
|
488
|
+
{
|
|
489
|
+
oldMemory: old,
|
|
490
|
+
replacementId: "new",
|
|
491
|
+
replacementContent: "replacement",
|
|
492
|
+
cause: "contradiction",
|
|
493
|
+
namespaceScope: "namespace-a",
|
|
494
|
+
},
|
|
495
|
+
);
|
|
496
|
+
assert.equal(result.invalidated, 1);
|
|
497
|
+
assert.equal(result.skipped, null);
|
|
498
|
+
});
|
|
499
|
+
|
|
419
500
|
test("dryRun computes invalidation verdicts without writing", async () => {
|
|
420
501
|
const old = memory("old", { links: [{ targetId: "dep", linkType: "supports" }] });
|
|
421
502
|
const fixtureValue = fixture([old, memory("dep")], [{ memoryId: "dep", verdict: "invalidated" }]);
|
|
@@ -34,6 +34,8 @@ export interface PropagationResult {
|
|
|
34
34
|
stillValid: number;
|
|
35
35
|
uncertain: number;
|
|
36
36
|
skipped: "disabled" | "no_dependents" | "llm_error" | "timeout" | null;
|
|
37
|
+
route: "fast-completion" | null;
|
|
38
|
+
durationMs: number;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
function propagationConfig(config: PluginConfig): DependencyPropagationConfig {
|
|
@@ -96,8 +98,13 @@ export function findDependents(
|
|
|
96
98
|
});
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
function emptyResult(
|
|
100
|
-
|
|
101
|
+
function emptyResult(
|
|
102
|
+
skipped: PropagationResult["skipped"],
|
|
103
|
+
durationMs: number,
|
|
104
|
+
route: PropagationResult["route"] = null,
|
|
105
|
+
dependentsFound = 0,
|
|
106
|
+
): PropagationResult {
|
|
107
|
+
return { dependentsFound, invalidated: 0, stillValid: 0, uncertain: 0, skipped, route, durationMs };
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
function logResult(event: PropagationEvent, result: PropagationResult): void {
|
|
@@ -111,6 +118,8 @@ function logResult(event: PropagationEvent, result: PropagationResult): void {
|
|
|
111
118
|
stillValid: result.stillValid,
|
|
112
119
|
uncertain: result.uncertain,
|
|
113
120
|
skipped: result.skipped,
|
|
121
|
+
route: result.route,
|
|
122
|
+
durationMs: result.durationMs,
|
|
114
123
|
})}`,
|
|
115
124
|
);
|
|
116
125
|
}
|
|
@@ -136,16 +145,17 @@ export async function propagateInvalidation(
|
|
|
136
145
|
deps: { storage: StorageManager; extraction: ExtractionEngine; config: PluginConfig },
|
|
137
146
|
event: PropagationEvent,
|
|
138
147
|
): Promise<PropagationResult> {
|
|
148
|
+
const startedAt = Date.now();
|
|
139
149
|
const config = propagationConfig(deps.config);
|
|
140
150
|
if (!isEnabled(config.enabled)) {
|
|
141
|
-
const result = emptyResult("disabled");
|
|
151
|
+
const result = emptyResult("disabled", Date.now() - startedAt);
|
|
142
152
|
logResult(event, result);
|
|
143
153
|
return result;
|
|
144
154
|
}
|
|
145
155
|
|
|
146
156
|
const maxDependents = config.maxDependents;
|
|
147
157
|
if (maxDependents <= 0) {
|
|
148
|
-
const result = emptyResult("no_dependents");
|
|
158
|
+
const result = emptyResult("no_dependents", Date.now() - startedAt);
|
|
149
159
|
logResult(event, result);
|
|
150
160
|
return result;
|
|
151
161
|
}
|
|
@@ -155,7 +165,7 @@ export async function propagateInvalidation(
|
|
|
155
165
|
memories = await deps.storage.readAllMemories();
|
|
156
166
|
} catch (error) {
|
|
157
167
|
log.warn(`dependency propagation discovery failed for ${event.oldMemory.frontmatter.id}: ${error}`);
|
|
158
|
-
const result = emptyResult("llm_error");
|
|
168
|
+
const result = emptyResult("llm_error", Date.now() - startedAt);
|
|
159
169
|
logResult(event, result);
|
|
160
170
|
return result;
|
|
161
171
|
}
|
|
@@ -171,46 +181,67 @@ export async function propagateInvalidation(
|
|
|
171
181
|
const dependents = discovered.slice(0, Math.max(0, Math.floor(maxDependents)));
|
|
172
182
|
|
|
173
183
|
if (dependents.length === 0) {
|
|
174
|
-
const result = emptyResult("no_dependents");
|
|
184
|
+
const result = emptyResult("no_dependents", Date.now() - startedAt);
|
|
175
185
|
logResult(event, result);
|
|
176
186
|
return result;
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
const controller = new AbortController();
|
|
180
190
|
const timeoutMs = config.timeoutMs;
|
|
181
|
-
|
|
182
|
-
|
|
191
|
+
let timedOut = false;
|
|
192
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
193
|
+
const deadline = Number.isFinite(timeoutMs) && timeoutMs > 0
|
|
194
|
+
? new Promise<never>((_, reject) => {
|
|
195
|
+
timeout = setTimeout(() => {
|
|
196
|
+
timedOut = true;
|
|
197
|
+
const error = new PropagationTimeoutError();
|
|
198
|
+
controller.abort(error);
|
|
199
|
+
reject(error);
|
|
200
|
+
}, timeoutMs);
|
|
201
|
+
})
|
|
183
202
|
: undefined;
|
|
203
|
+
const revalidation = Promise.resolve().then(() => deps.extraction.revalidateDependents(
|
|
204
|
+
{ id: event.oldMemory.frontmatter.id, content: event.oldMemory.content },
|
|
205
|
+
event.replacementId && event.replacementContent !== null
|
|
206
|
+
? { id: event.replacementId, content: event.replacementContent }
|
|
207
|
+
: null,
|
|
208
|
+
dependents.map((memory) => ({
|
|
209
|
+
id: memory.frontmatter.id,
|
|
210
|
+
category: memory.frontmatter.category,
|
|
211
|
+
content: memory.content,
|
|
212
|
+
})),
|
|
213
|
+
controller.signal,
|
|
214
|
+
));
|
|
184
215
|
|
|
185
216
|
let verdicts: Array<{ memoryId: string; verdict: "still_valid" | "invalidated" | "uncertain"; reason?: string }>;
|
|
186
217
|
try {
|
|
187
|
-
const response =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
controller.signal,
|
|
198
|
-
);
|
|
199
|
-
verdicts = response.verdicts;
|
|
200
|
-
if (controller.signal.aborted) {
|
|
201
|
-
if (timeout !== undefined) clearTimeout(timeout);
|
|
202
|
-
const result = emptyResult("timeout");
|
|
218
|
+
const response = deadline
|
|
219
|
+
? await Promise.race([revalidation, deadline])
|
|
220
|
+
: await revalidation;
|
|
221
|
+
if (timedOut || controller.signal.aborted) {
|
|
222
|
+
const result = emptyResult(
|
|
223
|
+
"timeout",
|
|
224
|
+
Date.now() - startedAt,
|
|
225
|
+
"fast-completion",
|
|
226
|
+
dependents.length,
|
|
227
|
+
);
|
|
203
228
|
logResult(event, result);
|
|
204
229
|
return result;
|
|
205
230
|
}
|
|
231
|
+
verdicts = response.verdicts;
|
|
206
232
|
} catch (error) {
|
|
207
|
-
const result = emptyResult(
|
|
233
|
+
const result = emptyResult(
|
|
234
|
+
timedOut || isTimeoutError(error, controller.signal) ? "timeout" : "llm_error",
|
|
235
|
+
Date.now() - startedAt,
|
|
236
|
+
"fast-completion",
|
|
237
|
+
dependents.length,
|
|
238
|
+
);
|
|
208
239
|
log.warn(`dependency propagation revalidation failed for ${event.oldMemory.frontmatter.id}: ${error}`);
|
|
209
240
|
logResult(event, result);
|
|
210
|
-
if (timeout !== undefined) clearTimeout(timeout);
|
|
211
241
|
return result;
|
|
242
|
+
} finally {
|
|
243
|
+
clearTimeout(timeout!);
|
|
212
244
|
}
|
|
213
|
-
if (timeout !== undefined) clearTimeout(timeout);
|
|
214
245
|
|
|
215
246
|
let invalidated = 0;
|
|
216
247
|
let stillValid = 0;
|
|
@@ -257,6 +288,8 @@ export async function propagateInvalidation(
|
|
|
257
288
|
stillValid,
|
|
258
289
|
uncertain,
|
|
259
290
|
skipped: null,
|
|
291
|
+
route: "fast-completion",
|
|
292
|
+
durationMs: Date.now() - startedAt,
|
|
260
293
|
};
|
|
261
294
|
logResult(event, result);
|
|
262
295
|
return result;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
revalidateDependentsViaLlm,
|
|
6
|
+
type RevalidationDeps,
|
|
7
|
+
} from "./dependency-revalidation.js";
|
|
8
|
+
|
|
9
|
+
type Dependent = { id: string; category: string; content: string };
|
|
10
|
+
type CompletionOptions = {
|
|
11
|
+
operation?: string;
|
|
12
|
+
priority?: "background" | "recall-critical";
|
|
13
|
+
timeoutMs?: number;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
temperature?: number;
|
|
16
|
+
maxTokens?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type CompletionCall = {
|
|
20
|
+
messages: Array<{ role: string; content: string }>;
|
|
21
|
+
options: CompletionOptions;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const superseded = { id: "old", content: "old supporting fact" };
|
|
25
|
+
const replacement = { id: "new", content: "new supporting fact" };
|
|
26
|
+
|
|
27
|
+
function dependents(count: number): Dependent[] {
|
|
28
|
+
return Array.from({ length: count }, (_, index) => ({
|
|
29
|
+
id: `dependent-${String(index + 1).padStart(2, "0")}`,
|
|
30
|
+
category: index % 2 === 0 ? "fact" : "decision",
|
|
31
|
+
content: `dependent claim ${index + 1}`,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function makeDeps(payload: unknown, calls: CompletionCall[]): RevalidationDeps {
|
|
36
|
+
return {
|
|
37
|
+
fastChatCompletion: async (messages, options) => {
|
|
38
|
+
calls.push({ messages, options });
|
|
39
|
+
return { content: JSON.stringify(payload) };
|
|
40
|
+
},
|
|
41
|
+
parseJsonObject: (raw) => JSON.parse(raw ?? "null") as unknown,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
test("revalidation uses only the injected fast completion seam", async () => {
|
|
46
|
+
const calls: CompletionCall[] = [];
|
|
47
|
+
const signal = new AbortController().signal;
|
|
48
|
+
const requested = dependents(1);
|
|
49
|
+
|
|
50
|
+
await revalidateDependentsViaLlm(
|
|
51
|
+
makeDeps({ verdicts: [{ memoryId: requested[0]!.id, verdict: "still_valid" }] }, calls),
|
|
52
|
+
superseded,
|
|
53
|
+
replacement,
|
|
54
|
+
requested,
|
|
55
|
+
{ signal, timeoutMs: 37 },
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const call = calls[0];
|
|
59
|
+
assert.ok(call);
|
|
60
|
+
assert.equal(call.options.operation, "dependency_revalidation");
|
|
61
|
+
assert.equal(call.options.priority, "background");
|
|
62
|
+
assert.equal(call.options.timeoutMs, 37);
|
|
63
|
+
assert.equal(call.options.signal, signal);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("revalidation normalizes one verdict per dependent for one, five, and ten dependents", async () => {
|
|
67
|
+
for (const count of [1, 5, 10]) {
|
|
68
|
+
const requested = dependents(count);
|
|
69
|
+
const calls: CompletionCall[] = [];
|
|
70
|
+
const result = await revalidateDependentsViaLlm(
|
|
71
|
+
makeDeps(
|
|
72
|
+
{
|
|
73
|
+
verdicts: [
|
|
74
|
+
...requested.map((dependent) => ({ memoryId: dependent.id, verdict: "invalidated" })),
|
|
75
|
+
{ memoryId: "unknown-id", verdict: "invalidated" },
|
|
76
|
+
{ memoryId: requested[0]!.id, verdict: "still_valid" },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
calls,
|
|
80
|
+
),
|
|
81
|
+
superseded,
|
|
82
|
+
replacement,
|
|
83
|
+
requested,
|
|
84
|
+
{ timeoutMs: 37 },
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
assert.equal(result.verdicts.length, count);
|
|
88
|
+
assert.deepEqual(
|
|
89
|
+
result.verdicts.map((verdict) => verdict.memoryId),
|
|
90
|
+
requested.map((dependent) => dependent.id),
|
|
91
|
+
);
|
|
92
|
+
assert.equal(new Set(result.verdicts.map((verdict) => verdict.memoryId)).size, count);
|
|
93
|
+
assert.equal(calls.length, 1);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("revalidation rejects empty completion output", async () => {
|
|
98
|
+
for (const content of [null, "", " "]) {
|
|
99
|
+
const deps: RevalidationDeps = {
|
|
100
|
+
fastChatCompletion: async () => content === null ? null : { content },
|
|
101
|
+
parseJsonObject: (raw) => JSON.parse(raw ?? "null") as unknown,
|
|
102
|
+
};
|
|
103
|
+
await assert.rejects(
|
|
104
|
+
revalidateDependentsViaLlm(deps, superseded, replacement, dependents(1)),
|
|
105
|
+
/no dependency revalidation output/,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("revalidation defaults invalid verdict enums to uncertain", async () => {
|
|
111
|
+
const requested = dependents(1);
|
|
112
|
+
const result = await revalidateDependentsViaLlm(
|
|
113
|
+
makeDeps({ verdicts: [{ memoryId: requested[0]!.id, verdict: "approved" }] }, []),
|
|
114
|
+
superseded,
|
|
115
|
+
replacement,
|
|
116
|
+
requested,
|
|
117
|
+
);
|
|
118
|
+
assert.deepEqual(result.verdicts, [{ memoryId: requested[0]!.id, verdict: "uncertain" }]);
|
|
119
|
+
});
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* Extracted from ExtractionEngine to keep extraction.ts under its ratchet
|
|
5
5
|
* ceiling. The ExtractionEngine.revalidateDependents method delegates here.
|
|
6
6
|
*/
|
|
7
|
-
import type { LocalLlmClient } from "../local-llm.js";
|
|
8
|
-
import type { FallbackLlmClient, FallbackLlmOptions } from "../fallback-llm.js";
|
|
9
7
|
|
|
10
8
|
export interface RevalidationVerdict {
|
|
11
9
|
memoryId: string;
|
|
@@ -13,18 +11,20 @@ export interface RevalidationVerdict {
|
|
|
13
11
|
reason?: string;
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
temperature: number;
|
|
25
|
-
maxTokens: number;
|
|
14
|
+
export type RevalidationFastChatCompletion = (
|
|
15
|
+
messages: Array<{ role: "system" | "user" | "assistant"; content: string }>,
|
|
16
|
+
options: {
|
|
17
|
+
temperature?: number;
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
operation?: string;
|
|
21
|
+
priority?: "background" | "recall-critical";
|
|
26
22
|
signal?: AbortSignal;
|
|
27
|
-
}
|
|
23
|
+
},
|
|
24
|
+
) => Promise<{ content: string } | null>;
|
|
25
|
+
|
|
26
|
+
export interface RevalidationDeps {
|
|
27
|
+
fastChatCompletion: RevalidationFastChatCompletion;
|
|
28
28
|
parseJsonObject: (raw: string | null) => unknown;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -95,78 +95,27 @@ export async function revalidateDependentsViaLlm(
|
|
|
95
95
|
superseded: { id: string; content: string },
|
|
96
96
|
replacement: { id: string; content: string } | null,
|
|
97
97
|
dependents: Array<{ id: string; category: string; content: string }>,
|
|
98
|
-
signal?: AbortSignal,
|
|
98
|
+
options: { signal?: AbortSignal; timeoutMs?: number } = {},
|
|
99
99
|
): Promise<{ verdicts: RevalidationVerdict[] }> {
|
|
100
100
|
const { input, instructionText } = buildPrompt(superseded, replacement, dependents);
|
|
101
101
|
const maxTokens = Math.max(1024, dependents.length * 256);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
rawContent = response?.content ?? null;
|
|
120
|
-
if (!rawContent && !deps.config.localLlmFallback) {
|
|
121
|
-
throw new Error("local LLM returned no dependency revalidation output");
|
|
122
|
-
}
|
|
123
|
-
} catch (error) {
|
|
124
|
-
if (!deps.config.localLlmFallback || signal?.aborted) throw error;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (rawContent === null && !deps.shouldUseDirectClient) {
|
|
129
|
-
const response = await deps.fallbackLlm.chatCompletion(
|
|
130
|
-
[
|
|
131
|
-
{ role: "system", content: instructionText },
|
|
132
|
-
{ role: "user", content: input },
|
|
133
|
-
],
|
|
134
|
-
deps.withGatewayAgent({ temperature: 0.2, maxTokens, signal }),
|
|
135
|
-
);
|
|
136
|
-
rawContent = response?.content ?? null;
|
|
137
|
-
if (!rawContent) throw new Error("fallback LLM returned no dependency revalidation output");
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (rawContent === null && deps.shouldUseDirectClient) {
|
|
141
|
-
const chatClient = deps.client as unknown as {
|
|
142
|
-
chat: {
|
|
143
|
-
completions: {
|
|
144
|
-
create(
|
|
145
|
-
request: {
|
|
146
|
-
model: string;
|
|
147
|
-
messages: Array<{ role: string; content: string }>;
|
|
148
|
-
max_tokens?: number;
|
|
149
|
-
},
|
|
150
|
-
options?: { signal?: AbortSignal },
|
|
151
|
-
): Promise<{ choices?: Array<{ message?: { content?: string } }> }>;
|
|
152
|
-
};
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
const response = await chatClient.chat.completions.create(
|
|
156
|
-
{
|
|
157
|
-
model: deps.config.model,
|
|
158
|
-
messages: [
|
|
159
|
-
{ role: "system", content: instructionText },
|
|
160
|
-
{ role: "user", content: input },
|
|
161
|
-
],
|
|
162
|
-
max_tokens: maxTokens,
|
|
163
|
-
},
|
|
164
|
-
{ signal },
|
|
165
|
-
);
|
|
166
|
-
rawContent = response.choices?.[0]?.message?.content ?? null;
|
|
167
|
-
if (!rawContent?.trim()) {
|
|
168
|
-
throw new Error("direct client returned no dependency revalidation output");
|
|
169
|
-
}
|
|
102
|
+
const response = await deps.fastChatCompletion(
|
|
103
|
+
[
|
|
104
|
+
{ role: "system", content: instructionText },
|
|
105
|
+
{ role: "user", content: input },
|
|
106
|
+
],
|
|
107
|
+
{
|
|
108
|
+
temperature: 0.2,
|
|
109
|
+
maxTokens,
|
|
110
|
+
operation: "dependency_revalidation",
|
|
111
|
+
priority: "background",
|
|
112
|
+
timeoutMs: options.timeoutMs,
|
|
113
|
+
signal: options.signal,
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
const rawContent = response?.content ?? null;
|
|
117
|
+
if (!rawContent?.trim()) {
|
|
118
|
+
throw new Error("fast completion returned no dependency revalidation output");
|
|
170
119
|
}
|
|
171
120
|
|
|
172
121
|
return { verdicts: normalizeVerdicts(deps.parseJsonObject(rawContent), dependents) };
|
package/src/orchestrator.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { SmartBuffer } from "./buffer.js";
|
|
|
24
24
|
import { chunkContent, type ChunkingConfig } from "./chunking.js";
|
|
25
25
|
import { semanticChunkContent, type SemanticChunkResult } from "./semantic-chunking.js";
|
|
26
26
|
import { ExtractionEngine } from "./extraction.js";
|
|
27
|
+
import type { RevalidationFastChatCompletion } from "./orchestration/dependency-revalidation.js";
|
|
27
28
|
import { detectPassiveCorrections } from "./correction/passive-correction-detector.js";
|
|
28
29
|
import { capturePassiveCorrections, type PassiveCaptureConfig } from "./correction/passive-capture.js";
|
|
29
30
|
import { createCorrectionService } from "./correction/correction-access-wiring.js";
|
|
@@ -1684,6 +1685,7 @@ export class Orchestrator {
|
|
|
1684
1685
|
this.localLlm,
|
|
1685
1686
|
config.gatewayConfig,
|
|
1686
1687
|
this.modelRegistry,
|
|
1688
|
+
this.fastChatCompletion.bind(this),
|
|
1687
1689
|
);
|
|
1688
1690
|
this.lifecyclePolicyCoordinator = new LifecyclePolicyCoordinator({
|
|
1689
1691
|
config,
|
|
@@ -1881,21 +1883,17 @@ export class Orchestrator {
|
|
|
1881
1883
|
);
|
|
1882
1884
|
}
|
|
1883
1885
|
|
|
1884
|
-
/**
|
|
1885
|
-
* Execute a fast-tier LLM chat completion.
|
|
1886
|
-
* When gateway model source is active and fastGatewayAgentId is configured,
|
|
1887
|
-
* routes through the gateway chain. Otherwise uses the local fast LLM.
|
|
1888
|
-
*/
|
|
1886
|
+
/** Execute a fast-tier completion through the gateway when configured, otherwise the local fast LLM. */
|
|
1889
1887
|
private async fastChatCompletion(
|
|
1890
1888
|
messages: Array<{ role: string; content: string }>,
|
|
1891
|
-
options:
|
|
1889
|
+
options: Parameters<RevalidationFastChatCompletion>[1],
|
|
1892
1890
|
): Promise<{ content: string } | null> {
|
|
1893
1891
|
if (this._fastGatewayLlm && this.config.modelSource === "gateway") {
|
|
1894
1892
|
const agentId =
|
|
1895
1893
|
this.config.fastGatewayAgentId || this.config.gatewayAgentId || undefined;
|
|
1896
1894
|
const result = await this._fastGatewayLlm.chatCompletion(
|
|
1897
1895
|
messages as Array<{ role: "system" | "user" | "assistant"; content: string }>,
|
|
1898
|
-
{
|
|
1896
|
+
{ ...options, agentId },
|
|
1899
1897
|
);
|
|
1900
1898
|
return result ? { content: result.content } : null;
|
|
1901
1899
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { launchProcessSync } from "./child-process.js";
|
|
2
|
+
import { mergeEnv } from "./env.js";
|
|
3
|
+
import { httpProtocolForHost } from "./http-transport.js";
|
|
4
|
+
|
|
5
|
+
const HEALTH_EXIT_OK = 0;
|
|
6
|
+
const HEALTH_EXIT_UNAUTHORIZED = 2;
|
|
7
|
+
|
|
8
|
+
export function checkDaemonHealth(
|
|
9
|
+
host: string,
|
|
10
|
+
port: number,
|
|
11
|
+
authToken?: string,
|
|
12
|
+
allowInsecureHttp = false,
|
|
13
|
+
): boolean {
|
|
14
|
+
try {
|
|
15
|
+
const safePort = Math.trunc(Number(port));
|
|
16
|
+
if (!Number.isFinite(safePort) || safePort < 1 || safePort > 65535) return false;
|
|
17
|
+
|
|
18
|
+
const bareHost = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
19
|
+
const script = [
|
|
20
|
+
"const env = process['env'];",
|
|
21
|
+
"const protocol = env.REMNIC_HEALTH_PROTOCOL;",
|
|
22
|
+
"if (protocol !== 'http' && protocol !== 'https') process.exit(1);",
|
|
23
|
+
"const transport = require(protocol);",
|
|
24
|
+
"const headers = {};",
|
|
25
|
+
"if (env.REMNIC_HEALTH_TOKEN) headers['authorization'] = 'Bearer ' + env.REMNIC_HEALTH_TOKEN;",
|
|
26
|
+
"const req = transport.get({",
|
|
27
|
+
" host: env.REMNIC_HEALTH_HOST,",
|
|
28
|
+
" port: parseInt(env.REMNIC_HEALTH_PORT, 10),",
|
|
29
|
+
" path: '/engram/v1/health', headers, timeout: 3000,",
|
|
30
|
+
"}, (res) => { process.exit(res.statusCode === 200 ? 0 : res.statusCode === 401 ? 2 : 1); });",
|
|
31
|
+
"req.on('error', () => process.exit(1));",
|
|
32
|
+
"req.on('timeout', () => { req.destroy(); process.exit(1); });",
|
|
33
|
+
].join("\n");
|
|
34
|
+
const env: NodeJS.ProcessEnv = mergeEnv({
|
|
35
|
+
REMNIC_HEALTH_HOST: bareHost,
|
|
36
|
+
REMNIC_HEALTH_PORT: String(safePort),
|
|
37
|
+
REMNIC_HEALTH_PROTOCOL: httpProtocolForHost(host, allowInsecureHttp),
|
|
38
|
+
});
|
|
39
|
+
if (authToken) env.REMNIC_HEALTH_TOKEN = authToken;
|
|
40
|
+
|
|
41
|
+
const launchOptions = { timeout: 4000, env };
|
|
42
|
+
const result = launchProcessSync(process.execPath, ["-e", script], launchOptions);
|
|
43
|
+
if (result.status === HEALTH_EXIT_OK) return true;
|
|
44
|
+
if (result.status !== HEALTH_EXIT_UNAUTHORIZED) return false;
|
|
45
|
+
|
|
46
|
+
console.error("[remnic/connectors] health probe got 401 — retrying after token cache TTL...");
|
|
47
|
+
launchProcessSync(process.execPath, ["-e", "setTimeout(() => {}, 6000)"], { timeout: 7000, env: {} });
|
|
48
|
+
const retry = launchProcessSync(process.execPath, ["-e", script], launchOptions);
|
|
49
|
+
return retry.status === HEALTH_EXIT_OK;
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
|
|
3
|
+
function normalizedIp(host: string): string {
|
|
4
|
+
const value = host.trim().replace(/^\[/, "").replace(/\]\.?$/, "").replace(/\.$/, "");
|
|
5
|
+
if (isIP(value) === 4) return value;
|
|
6
|
+
if (isIP(value) !== 6) return "";
|
|
7
|
+
return new URL(`http://[${value}]/`).hostname.slice(1, -1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function isLoopbackHost(host: string): boolean {
|
|
11
|
+
const normalized = host.trim().replace(/^\[/, "").replace(/\]\.?$/, "").replace(/\.$/, "").toLowerCase();
|
|
12
|
+
if (normalized === "localhost" || normalized.endsWith(".localhost")) return true;
|
|
13
|
+
|
|
14
|
+
const ip = normalizedIp(normalized);
|
|
15
|
+
if (ip === "::1") return true;
|
|
16
|
+
if (isIP(ip) === 4) return ip.startsWith("127.");
|
|
17
|
+
if (!ip.startsWith("::ffff:")) return false;
|
|
18
|
+
|
|
19
|
+
const [high, low] = ip.slice("::ffff:".length).split(":");
|
|
20
|
+
return Number.parseInt(high, 16) >>> 8 === 127 || (high === "0" && Number.parseInt(low, 16) >>> 8 === 127);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function httpProtocolForHost(host: string, allowInsecureHttp = false): "http" | "https" {
|
|
24
|
+
return isLoopbackHost(host) || allowInsecureHttp ? "http" : "https";
|
|
25
|
+
}
|