@remnic/core 9.45.3 → 9.45.5
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/abort-error.d.ts +2 -1
- package/dist/abort-error.js +3 -1
- package/dist/access-admin-ops-surface.d.ts +14 -10
- package/dist/access-admin-ops-surface.js +84 -75
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +14 -10
- package/dist/access-authorization-probe.js +85 -76
- package/dist/access-boundary.d.ts +15 -11
- package/dist/access-boundary.js +84 -75
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +191 -177
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +16 -0
- package/dist/access-coding-context-resolution.js +13 -0
- package/dist/access-coding-context-resolution.js.map +1 -0
- package/dist/access-extraction-force-flush.d.ts +14 -10
- package/dist/access-extraction-force-flush.js +84 -75
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-lcm-compaction.d.ts +16 -12
- package/dist/access-http-lcm-compaction.js +3 -3
- package/dist/access-http-lifecycle-flush.d.ts +14 -10
- package/dist/access-http-lifecycle-flush.js +2 -2
- package/dist/access-http-offline-stream.d.ts +123 -0
- package/dist/access-http-offline-stream.js +10 -0
- package/dist/access-http-offline-stream.js.map +1 -0
- package/dist/access-http-query.js +84 -75
- package/dist/access-http.d.ts +15 -11
- package/dist/access-http.js +104 -90
- package/dist/access-identity-continuity-surface.d.ts +9 -8
- package/dist/access-identity-continuity-surface.js +84 -75
- package/dist/access-lcm-surface.d.ts +14 -10
- package/dist/access-lcm-surface.js +84 -75
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +14 -10
- package/dist/access-mcp.js +95 -82
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-5yZ4g6F8.d.ts → access-namespace-preflight-CWUDwB4M.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +84 -75
- package/dist/access-observe-helpers.d.ts +1 -0
- package/dist/access-observe-helpers.js +1 -1
- package/dist/access-observe-write-surface.d.ts +16 -10
- package/dist/access-observe-write-surface.js +84 -75
- package/dist/access-offline-manifest.d.ts +104 -0
- package/dist/access-offline-manifest.js +45 -0
- package/dist/access-offline-manifest.js.map +1 -0
- package/dist/access-operations-batch.js +86 -77
- package/dist/access-operations.d.ts +18 -14
- package/dist/access-operations.js +91 -79
- package/dist/access-recall-concurrency.d.ts +16 -26
- package/dist/access-recall-concurrency.js +86 -76
- package/dist/access-recall-response.d.ts +18 -14
- package/dist/access-recall-response.js +84 -75
- package/dist/access-recall-surface.d.ts +29 -24
- package/dist/access-recall-surface.js +84 -75
- package/dist/access-schema.d.ts +84 -84
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CiJRsgAB.d.ts → access-service-CNN89xyn.d.ts} +25 -16
- package/dist/access-service-helpers.d.ts +14 -10
- package/dist/access-service.d.ts +14 -10
- package/dist/access-service.js +84 -75
- package/dist/access-surface-catalog.d.ts +14 -10
- package/dist/access-surface-catalog.js +4 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +4 -3
- package/dist/action-confidence.d.ts +2 -1
- package/dist/active-memory-bridge.d.ts +2 -1
- package/dist/active-recall.d.ts +2 -1
- package/dist/active-recall.js +10 -8
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-5OE5QOZB.js → auto-sync-UPTUVE4X.js} +6 -6
- package/dist/behavior-learner.d.ts +2 -1
- package/dist/behavior-learner.js +1 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +9 -8
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +24 -22
- package/dist/buffer-surprise-report.d.ts +2 -1
- package/dist/buffer-turn-helpers.d.ts +2 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/buffer.js +12 -11
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-merge-IDWJPCWK.js → capsule-merge-Q6AR3XL7.js} +67 -54
- package/dist/capsule-merge-Q6AR3XL7.js.map +1 -0
- package/dist/{catalog-scBmy0sO.d.ts → catalog-bctMURhN.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +28 -26
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +2 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-E5UK4VPE.js → chunk-2FSTB6BJ.js} +5 -5
- package/dist/{chunk-5ZE7QHTK.js → chunk-2X2T2UVE.js} +5 -5
- package/dist/{chunk-P4DRWEYC.js → chunk-3COYXTGM.js} +2 -2
- package/dist/{chunk-5IVLTFOV.js → chunk-44N6ESJ4.js} +2 -2
- package/dist/{chunk-DL7ZD3JH.js → chunk-4FBVAGV3.js} +14 -9
- package/dist/chunk-4FBVAGV3.js.map +1 -0
- package/dist/{chunk-WOCNN776.js → chunk-4POAMKV6.js} +100 -41
- package/dist/chunk-4POAMKV6.js.map +1 -0
- package/dist/{chunk-HO3QBJEY.js → chunk-5546W5SI.js} +2 -2
- package/dist/{chunk-AAIUERNB.js → chunk-5QJQHBLE.js} +6 -6
- package/dist/{chunk-6CZPDBJS.js → chunk-5U7ID3EZ.js} +3 -3
- package/dist/{chunk-RN7DY3FC.js → chunk-6ISC4AVB.js} +31 -12
- package/dist/chunk-6ISC4AVB.js.map +1 -0
- package/dist/chunk-773TRRGT.js +36 -0
- package/dist/chunk-773TRRGT.js.map +1 -0
- package/dist/chunk-7T4TOGMS.js +242 -0
- package/dist/chunk-7T4TOGMS.js.map +1 -0
- package/dist/{chunk-DLVPUX7U.js → chunk-7YKVM5H3.js} +8 -6
- package/dist/chunk-7YKVM5H3.js.map +1 -0
- package/dist/chunk-7YQ6ESEA.js +322 -0
- package/dist/chunk-7YQ6ESEA.js.map +1 -0
- package/dist/{chunk-DNWXFTLD.js → chunk-A4IJCD2Z.js} +2 -2
- package/dist/{chunk-3CE77VAP.js → chunk-A4JMGKCD.js} +87 -74
- package/dist/chunk-A4JMGKCD.js.map +1 -0
- package/dist/chunk-A5KNZSNA.js +26 -0
- package/dist/chunk-A5KNZSNA.js.map +1 -0
- package/dist/{chunk-PKNLM44P.js → chunk-AC5OWJLV.js} +9 -9
- package/dist/{chunk-LZ4LDKHZ.js → chunk-AMAUBUKY.js} +6 -6
- package/dist/{chunk-CUM2BBPN.js → chunk-AUMWZSE7.js} +19 -10
- package/dist/chunk-AUMWZSE7.js.map +1 -0
- package/dist/{chunk-BUE5E2HL.js → chunk-BGLY7EEM.js} +5 -314
- package/dist/chunk-BGLY7EEM.js.map +1 -0
- package/dist/chunk-BIPBQQFI.js +44 -0
- package/dist/chunk-BIPBQQFI.js.map +1 -0
- package/dist/{chunk-S5SLVSVY.js → chunk-BQIFZ2MP.js} +5 -5
- package/dist/chunk-BTTPKDIL.js +34 -0
- package/dist/{chunk-PVGDJXVK.js.map → chunk-BTTPKDIL.js.map} +1 -1
- package/dist/chunk-CK5KOVHW.js +69 -0
- package/dist/chunk-CK5KOVHW.js.map +1 -0
- package/dist/{chunk-Q6IP2ARR.js → chunk-CSOYVTRX.js} +2 -2
- package/dist/{chunk-XOQSEF7X.js → chunk-CVILPI77.js} +6 -6
- package/dist/{chunk-VWAXN2BN.js → chunk-CX4ZUMC6.js} +91 -83
- package/dist/chunk-CX4ZUMC6.js.map +1 -0
- package/dist/{chunk-NVRYW264.js → chunk-DAJPRXBR.js} +16 -13
- package/dist/chunk-DAJPRXBR.js.map +1 -0
- package/dist/{chunk-J7VGGECD.js → chunk-DZPFMQZ7.js} +1 -1
- package/dist/chunk-DZPFMQZ7.js.map +1 -0
- package/dist/{chunk-4LMA77JH.js → chunk-E5XQIWAL.js} +3 -3
- package/dist/{chunk-WUNIWKY4.js → chunk-ELIL2A37.js} +6 -6
- package/dist/{chunk-OQ5PRDDS.js → chunk-ERZ2R42X.js} +6 -6
- package/dist/{chunk-U7GW7NE7.js → chunk-FIK3CQNA.js} +10 -10
- package/dist/{chunk-D3J5SLQK.js → chunk-FR27HBBA.js} +81 -20
- package/dist/chunk-FR27HBBA.js.map +1 -0
- package/dist/{chunk-E6PNLPGJ.js → chunk-FUCYDRE5.js} +838 -480
- package/dist/chunk-FUCYDRE5.js.map +1 -0
- package/dist/{chunk-HZFHQ4AQ.js → chunk-G7A5HLUS.js} +23 -17
- package/dist/chunk-G7A5HLUS.js.map +1 -0
- package/dist/{chunk-33PLLLL7.js → chunk-GFCVUY6G.js} +6 -6
- package/dist/{chunk-HREE4JHI.js → chunk-GODSPTOT.js} +477 -278
- package/dist/chunk-GODSPTOT.js.map +1 -0
- package/dist/{chunk-S2NCTZGJ.js → chunk-GRUYA45P.js} +15 -15
- package/dist/chunk-GRUYA45P.js.map +1 -0
- package/dist/{chunk-VUPTKTDV.js → chunk-GUAL4PQH.js} +3 -3
- package/dist/{chunk-CINZGPSJ.js → chunk-GUMZC2BO.js} +2 -2
- package/dist/{chunk-H24WNPA2.js → chunk-GWFSVJ4P.js} +3 -3
- package/dist/{chunk-7XC2HX75.js → chunk-GYPQL6XN.js} +157 -16
- package/dist/chunk-GYPQL6XN.js.map +1 -0
- package/dist/{chunk-TSH56VPU.js → chunk-HAYSYUAB.js} +2 -2
- package/dist/{chunk-PDLBLTOK.js → chunk-HC3PBX23.js} +9 -9
- package/dist/{chunk-TDHTVMPG.js → chunk-HFPASSFV.js} +7 -2
- package/dist/chunk-HFPASSFV.js.map +1 -0
- package/dist/chunk-J2WC5LF4.js +395 -0
- package/dist/chunk-J2WC5LF4.js.map +1 -0
- package/dist/{chunk-KXB4VXHY.js → chunk-JIYDRBVZ.js} +2 -2
- package/dist/chunk-JV3C2MNQ.js +74 -0
- package/dist/chunk-JV3C2MNQ.js.map +1 -0
- package/dist/{chunk-HLPD7B7P.js → chunk-JZH4LWHB.js} +2 -2
- package/dist/{chunk-AV5ZEH4M.js → chunk-KVJRXN2E.js} +2 -2
- package/dist/{chunk-WFTIGIIS.js → chunk-L6CQ7WIW.js} +5 -5
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- package/dist/{chunk-EJUEXZHX.js → chunk-LLJMAULE.js} +2 -2
- package/dist/{chunk-N5Z4EVOR.js → chunk-LNEWDF2A.js} +36 -11
- package/dist/chunk-LNEWDF2A.js.map +1 -0
- package/dist/{chunk-QN25OCUF.js → chunk-LPYDOLSM.js} +5 -5
- package/dist/{chunk-AS7YMSL6.js → chunk-M23RF3LJ.js} +4 -4
- package/dist/{chunk-OAEQLRCY.js → chunk-MO4HSXHZ.js} +5 -5
- package/dist/{chunk-ECK75GDJ.js → chunk-N3LL5NEU.js} +43 -24
- package/dist/chunk-N3LL5NEU.js.map +1 -0
- package/dist/chunk-NEF7LR5J.js +29 -0
- package/dist/chunk-NEF7LR5J.js.map +1 -0
- package/dist/{chunk-3F2LKUMU.js → chunk-NIS256NW.js} +2 -2
- package/dist/{chunk-YIAA2X3D.js → chunk-NK5RGJ65.js} +3 -3
- package/dist/chunk-NLDVVWCL.js +84 -0
- package/dist/chunk-NLDVVWCL.js.map +1 -0
- package/dist/{chunk-4J7G5SY4.js → chunk-NZBZ7IS2.js} +72 -24
- package/dist/chunk-NZBZ7IS2.js.map +1 -0
- package/dist/{chunk-3TBLDMJA.js → chunk-O4KMGRXE.js} +5 -2
- package/dist/chunk-O4KMGRXE.js.map +1 -0
- package/dist/{chunk-7TWUCYER.js → chunk-PNRA7FAD.js} +7 -7
- package/dist/{chunk-5I4M26Q7.js → chunk-QBSFOKY6.js} +4 -4
- package/dist/{chunk-E53DSZEN.js → chunk-QR6G5KF4.js} +3 -3
- package/dist/{chunk-CJ2ZR7UA.js → chunk-QUENPGWZ.js} +261 -211
- package/dist/chunk-QUENPGWZ.js.map +1 -0
- package/dist/{chunk-4UH4BTGK.js → chunk-QVJPH7SH.js} +84 -84
- package/dist/{chunk-UYLMNVY6.js → chunk-R3KHKU7M.js} +16 -9
- package/dist/chunk-R3KHKU7M.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-WDISJRMG.js → chunk-RMMVQQA6.js} +2 -2
- package/dist/{chunk-JVLCVFQ4.js → chunk-RNHVVMFN.js} +3 -3
- package/dist/{chunk-QJAQNXWI.js → chunk-RVO6TCTU.js} +81 -84
- package/dist/chunk-RVO6TCTU.js.map +1 -0
- package/dist/chunk-S2HLHAZ4.js +16 -0
- package/dist/chunk-S2HLHAZ4.js.map +1 -0
- package/dist/{chunk-KWMXR7XS.js → chunk-S2V7RUCL.js} +8 -1
- package/dist/{chunk-KWMXR7XS.js.map → chunk-S2V7RUCL.js.map} +1 -1
- package/dist/{chunk-5SM35XZR.js → chunk-S5NZBKKQ.js} +2 -2
- package/dist/{chunk-VNA7W7QF.js → chunk-SVH57F5Z.js} +12 -4
- package/dist/chunk-SVH57F5Z.js.map +1 -0
- package/dist/{chunk-WIPEXG6R.js → chunk-SXIMQLGV.js} +2 -2
- package/dist/{chunk-RVLJEII5.js → chunk-SYUBB3WM.js} +256 -187
- package/dist/chunk-SYUBB3WM.js.map +1 -0
- package/dist/{chunk-VCD4PSK2.js → chunk-TQZ4DVBC.js} +7 -4
- package/dist/chunk-TQZ4DVBC.js.map +1 -0
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-YV32N67O.js → chunk-URS5GSM7.js} +1 -1
- package/dist/chunk-URS5GSM7.js.map +1 -0
- package/dist/{chunk-4B77XSG5.js → chunk-UV72DEZD.js} +5 -5
- package/dist/{chunk-BJKPPZ6Z.js → chunk-UW66OZTD.js} +2 -2
- package/dist/{chunk-XYTOI63Z.js → chunk-V2TNYF6Q.js} +19 -11
- package/dist/chunk-V2TNYF6Q.js.map +1 -0
- package/dist/{chunk-S2BBISHU.js → chunk-VANZKHTN.js} +3 -3
- package/dist/chunk-VHFXP27N.js +250 -0
- package/dist/chunk-VHFXP27N.js.map +1 -0
- package/dist/chunk-VL35ZFSZ.js +102 -0
- package/dist/chunk-VL35ZFSZ.js.map +1 -0
- package/dist/{chunk-3Y224NYC.js → chunk-VYISFWVX.js} +2 -2
- package/dist/{chunk-JE7EK33X.js → chunk-W2V7UESE.js} +2 -2
- package/dist/{chunk-TIHMZFIV.js → chunk-W3IC7QOY.js} +3 -3
- package/dist/{chunk-NRV4Y3PM.js → chunk-W4FBGYGK.js} +1 -1
- package/dist/{chunk-P2BM76KT.js → chunk-WAS4HV46.js} +174 -43
- package/dist/chunk-WAS4HV46.js.map +1 -0
- package/dist/{chunk-57QKLRBV.js → chunk-WB7JSQCP.js} +2 -1
- package/dist/chunk-WB7JSQCP.js.map +1 -0
- package/dist/{chunk-A5OJCXZL.js → chunk-WZ3TOIDW.js} +15 -4
- package/dist/chunk-WZ3TOIDW.js.map +1 -0
- package/dist/{chunk-MU7ZHSZE.js → chunk-WZFAPHIK.js} +2 -2
- package/dist/{chunk-T2TTP3KU.js → chunk-X4IDNPOS.js} +2 -2
- package/dist/{chunk-UVIKWC7M.js → chunk-XAGYS7X6.js} +17 -17
- package/dist/{chunk-BLAKS3CP.js → chunk-XL3TATMJ.js} +3 -3
- package/dist/{chunk-W4XJFLAL.js → chunk-XPRJSHNI.js} +2 -2
- package/dist/{chunk-5TFP4CUL.js → chunk-XQ3HXAQH.js} +14 -11
- package/dist/chunk-XQ3HXAQH.js.map +1 -0
- package/dist/{chunk-E6EE5B67.js → chunk-YK6BDDHP.js} +4 -4
- package/dist/{chunk-ES36HTSC.js → chunk-YLHM5BQQ.js} +3 -3
- package/dist/{chunk-ULARSG5Z.js → chunk-YN6ASZUG.js} +10 -8
- package/dist/{chunk-ULARSG5Z.js.map → chunk-YN6ASZUG.js.map} +1 -1
- package/dist/{chunk-VOUOLGIP.js → chunk-YRFAYOFQ.js} +11 -13
- package/dist/chunk-YRFAYOFQ.js.map +1 -0
- package/dist/{chunk-IKKWIPYN.js → chunk-YYQAKIDJ.js} +37 -1
- package/dist/chunk-YYQAKIDJ.js.map +1 -0
- package/dist/{chunk-GF22HWS2.js → chunk-Z54EM5YZ.js} +4 -4
- package/dist/{chunk-64UDOIMI.js → chunk-ZLQ37WJX.js} +2 -2
- package/dist/{cli-BUGN3d6_.d.ts → cli-BHBswmUa.d.ts} +5 -5
- package/dist/cli.d.ts +16 -12
- package/dist/cli.js +138 -123
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +25 -23
- package/dist/compounding/preference-consolidator.d.ts +2 -1
- package/dist/compression-optimizer.d.ts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +10 -8
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +24 -22
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +27 -25
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/consolidation-undo.js +10 -7
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/contradiction/index.d.ts +3 -2
- package/dist/converge-config.d.ts +2 -1
- package/dist/convergence-refresh.d.ts +4 -3
- package/dist/convergence-refresh.js +28 -26
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/indexer.d.ts +2 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/corpus-watermark.d.ts +2 -1
- package/dist/corpus-watermark.js +43 -41
- package/dist/day-summary.d.ts +2 -1
- package/dist/delinearize.d.ts +2 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer-wiring.js +2 -2
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-retrieval-boundaries.js +1 -1
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +25 -23
- package/dist/entity-schema.d.ts +2 -1
- package/dist/explicit-capture.d.ts +9 -8
- package/dist/explicit-capture.js +11 -9
- package/dist/external-wiki-access.d.ts +127 -0
- package/dist/external-wiki-access.js +187 -0
- package/dist/external-wiki-access.js.map +1 -0
- package/dist/external-wiki-cli.d.ts +13 -0
- package/dist/external-wiki-cli.js +10 -0
- package/dist/external-wiki-cli.js.map +1 -0
- package/dist/external-wiki-collection-registration.d.ts +39 -0
- package/dist/external-wiki-collection-registration.js +79 -0
- package/dist/external-wiki-collection-registration.js.map +1 -0
- package/dist/external-wiki-collection.d.ts +50 -0
- package/dist/external-wiki-collection.js +387 -0
- package/dist/external-wiki-collection.js.map +1 -0
- package/dist/external-wiki-config.d.ts +13 -0
- package/dist/external-wiki-config.js +13 -0
- package/dist/external-wiki-config.js.map +1 -0
- package/dist/external-wiki-guard.d.ts +11 -0
- package/dist/external-wiki-guard.js +18 -0
- package/dist/external-wiki-guard.js.map +1 -0
- package/dist/external-wiki-mcp-tools.d.ts +123 -0
- package/dist/external-wiki-mcp-tools.js +8 -0
- package/dist/external-wiki-mcp-tools.js.map +1 -0
- package/dist/external-wiki-search.d.ts +42 -0
- package/dist/external-wiki-search.js +11 -0
- package/dist/external-wiki-search.js.map +1 -0
- package/dist/external-wiki.d.ts +39 -0
- package/dist/external-wiki.js +14 -0
- package/dist/external-wiki.js.map +1 -0
- package/dist/extraction-error-classification.d.ts +2 -1
- package/dist/extraction-faithfulness.d.ts +2 -1
- package/dist/extraction-judge-telemetry.d.ts +2 -1
- package/dist/extraction-judge-training.d.ts +2 -1
- package/dist/extraction-judge.d.ts +2 -1
- package/dist/extraction-liveness.d.ts +2 -1
- package/dist/extraction-source-grounding-helpers.d.ts +5 -3
- package/dist/extraction-source-grounding-helpers.js +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.js +2 -2
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction-source-grounding.js +5 -5
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +46 -43
- package/dist/fallback-llm.d.ts +2 -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 +2 -1
- package/dist/graph-dashboard-key.d.ts +2 -1
- package/dist/graph-dashboard-parser.d.ts +2 -1
- package/dist/graph-edge-reinforcement.d.ts +2 -1
- package/dist/graph-snapshot.d.ts +2 -1
- package/dist/graph.d.ts +2 -1
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/importance.d.ts +2 -1
- package/dist/importers/index.d.ts +2 -1
- package/dist/in-flight-reads.d.ts +2 -1
- package/dist/index.d.ts +443 -430
- package/dist/index.js +304 -269
- package/dist/intent.d.ts +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +7 -7
- package/dist/lcm/tools.d.ts +2 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/live-connectors-runner.d.ts +2 -1
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +25 -23
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +25 -23
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +27 -25
- package/dist/{maintenance-LbuS2rUA.d.ts → maintenance-CoRikzIt.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +14 -10
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +2 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -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 +3 -2
- package/dist/models-json.d.ts +2 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +41 -39
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +18 -18
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +24 -22
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +11 -9
- package/dist/offline-sync.d.ts +29 -3
- package/dist/offline-sync.js +6 -2
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +46 -44
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-doctor-replica.js +3 -3
- package/dist/operator-toolkit.d.ts +4 -3
- package/dist/operator-toolkit.js +60 -55
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +37 -33
- package/dist/{orchestrator-rHiWt32X.d.ts → orchestrator-BJeq7Pw1.d.ts} +14 -7
- package/dist/orchestrator.d.ts +9 -8
- package/dist/orchestrator.js +200 -186
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-W_97O8BV.d.ts → pipeline-CNjY4wk3.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/policy-runtime.js +1 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/provenance.js +2 -2
- package/dist/{qmd-LWtMofAf.d.ts → qmd-C0UDZidt.d.ts} +9 -7
- package/dist/qmd-preflight.d.ts +5 -4
- package/dist/qmd-preflight.js +2 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +4 -3
- package/dist/qmd.js +8 -8
- package/dist/recall-concurrency-config.d.ts +2 -1
- package/dist/recall-disclosure-escalation.d.ts +2 -1
- package/dist/recall-explain-renderer.d.ts +2 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -1
- package/dist/recall-planner-llm.d.ts +2 -1
- package/dist/recall-state.d.ts +2 -1
- package/dist/recall-tag-filter.d.ts +2 -1
- package/dist/recall-timings.d.ts +2 -1
- package/dist/recall-xray-cli.d.ts +2 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +8 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +12 -2
- package/dist/reconcile/cursor.js +46 -7
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +9 -2
- package/dist/reconcile/manifest.js +15 -268
- package/dist/reconcile/manifest.js.map +1 -1
- package/dist/reconcile/plan.d.ts +4 -1
- package/dist/reconcile/plan.js +4 -4
- package/dist/replay/normalizers/chatgpt.d.ts +2 -1
- package/dist/replay/normalizers/claude.d.ts +2 -1
- package/dist/replay/normalizers/openclaw.d.ts +2 -1
- package/dist/replay/normalizers/shared.d.ts +2 -1
- package/dist/replay/runner.d.ts +2 -1
- package/dist/replay/types.d.ts +2 -1
- package/dist/replica-divergence.d.ts +2 -1
- package/dist/replica-divergence.js +2 -2
- package/dist/replica-peers-config.d.ts +2 -1
- package/dist/resolve-auth-token.d.ts +2 -1
- package/dist/resume-bundles.js +12 -10
- package/dist/retrieval-agents.d.ts +4 -3
- package/dist/retrieval-agents.js +2 -2
- package/dist/retrieval-tiers.d.ts +2 -1
- package/dist/routing/engine.d.ts +2 -1
- package/dist/routing/store.d.ts +2 -1
- package/dist/salvage-envelope.d.ts +2 -1
- package/dist/schemas.d.ts +54 -54
- package/dist/{scope-profiles-BiQKOE-p.d.ts → scope-profiles-BJzp2F5A.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/embed-helper.js +3 -3
- package/dist/search/factory.d.ts +4 -2
- package/dist/search/factory.js +20 -18
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +20 -20
- package/dist/search/lancedb-backend.d.ts +2 -1
- package/dist/search/lancedb-backend.js +4 -4
- package/dist/search/meilisearch-backend.d.ts +2 -1
- package/dist/search/meilisearch-backend.js +4 -4
- package/dist/search/noop-backend.d.ts +2 -1
- package/dist/search/orama-backend.d.ts +2 -1
- package/dist/search/orama-backend.js +4 -4
- package/dist/search/port.d.ts +18 -1
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-dHYCyqgh.d.ts → semantic-consolidation-D4KAZO2G.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +26 -24
- package/dist/semantic-rule-promotion.js +24 -22
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +25 -23
- package/dist/{service-DJG3KCQ4.d.ts → service-DWC4tq7p.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -1
- package/dist/session-observer-state.d.ts +2 -1
- package/dist/shared-context/manager.d.ts +10 -9
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +43 -40
- package/dist/{storage-F9FVh-w9.d.ts → storage-DPGjB-8e.d.ts} +28 -13
- package/dist/storage.d.ts +3 -2
- package/dist/storage.js +26 -24
- package/dist/summarizer.d.ts +2 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +2 -1
- package/dist/temporal-supersession.d.ts +3 -2
- package/dist/temporal-timeline-recall.d.ts +2 -1
- package/dist/temporal-validity.d.ts +2 -1
- package/dist/threading.d.ts +2 -1
- package/dist/tier-migration.d.ts +3 -2
- package/dist/tier-migration.js +1 -1
- package/dist/tier-routing.d.ts +2 -1
- package/dist/tool-scoped-memory.d.ts +5 -1
- package/dist/tool-scoped-memory.js +3 -1
- package/dist/topics.d.ts +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/{types-rEwubvim.d.ts → types-yX_FwERf.d.ts} +8 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/verified-recall.js +25 -23
- package/dist/write-envelope.d.ts +2 -1
- package/package.json +2 -2
- package/src/abort-error.ts +17 -0
- package/src/access-admin-ops-surface.ts +1 -0
- package/src/access-boundary.ts +1 -0
- package/src/access-coding-context-resolution.ts +42 -0
- package/src/access-extraction-force-flush.ts +38 -2
- package/src/access-http-lcm-compaction.ts +5 -2
- package/src/access-http-offline-stream.ts +80 -0
- package/src/access-http.test.ts +310 -3
- package/src/access-http.ts +84 -77
- package/src/access-mcp-output-schemas.ts +36 -0
- package/src/access-mcp.test.ts +95 -1
- package/src/access-mcp.ts +7 -9
- package/src/access-observe-helpers.ts +64 -22
- package/src/access-observe-write-surface.ts +8 -0
- package/src/access-offline-manifest.ts +54 -0
- package/src/access-operations-batch.ts +3 -3
- package/src/access-operations.ts +13 -7
- package/src/access-recall-concurrency.ts +3 -27
- package/src/access-recall-surface.ts +3 -0
- package/src/access-service-health.test.ts +32 -7
- package/src/access-service-namespace.test.ts +55 -0
- package/src/access-service-observe-idempotency.test.ts +34 -2
- package/src/access-service-observe-lcm-parity.test.ts +183 -23
- package/src/access-service-observe-scope.test.ts +160 -1
- package/src/access-service-offline-file-content.test.ts +345 -1
- package/src/access-service.ts +88 -62
- package/src/access-surface-catalog.ts +4 -0
- package/src/admin/admin-surfaces.ts +2 -0
- package/src/binary-lifecycle/pipeline.test.ts +106 -1
- package/src/binary-lifecycle/pipeline.ts +3 -0
- package/src/coding/git-context.test.ts +47 -0
- package/src/coding/git-context.ts +129 -27
- package/src/config.test.ts +24 -0
- package/src/config.ts +9 -12
- package/src/connector-provenance.test.ts +101 -0
- package/src/consolidation-undo.ts +3 -0
- package/src/convergence-refresh.ts +14 -2
- package/src/correction/correction-access-wiring.ts +9 -7
- package/src/correction/correction-executor.test.ts +206 -2
- package/src/correction/correction-executor.ts +29 -20
- package/src/correction/correction-planner.test.ts +36 -0
- package/src/correction/correction-planner.ts +9 -15
- package/src/correction/correction-service.ts +3 -1
- package/src/correction/correction-storage-integration.test.ts +77 -0
- package/src/correction/correction-surfaces.test.ts +41 -28
- package/src/correction/passive-capture.test.ts +59 -0
- package/src/correction/passive-capture.ts +4 -1
- package/src/entity-retrieval-boundaries.ts +17 -4
- package/src/entity-retrieval.ts +27 -6
- package/src/external-wiki-access.test.ts +65 -0
- package/src/external-wiki-access.ts +31 -0
- package/src/external-wiki-cli.ts +100 -0
- package/src/external-wiki-collection-registration.test.ts +163 -0
- package/src/external-wiki-collection-registration.ts +101 -0
- package/src/external-wiki-collection.test.ts +502 -0
- package/src/external-wiki-collection.ts +503 -0
- package/src/external-wiki-config.test.ts +135 -0
- package/src/external-wiki-config.ts +100 -0
- package/src/external-wiki-guard.ts +83 -0
- package/src/external-wiki-mcp-tools.ts +23 -0
- package/src/external-wiki-search.test.ts +367 -0
- package/src/external-wiki-search.ts +362 -0
- package/src/external-wiki.test.ts +240 -0
- package/src/external-wiki.ts +427 -0
- package/src/extraction-scope-source-agent.test.ts +21 -0
- package/src/extraction-source-grounding-helpers.ts +243 -53
- package/src/extraction-source-grounding-rules.ts +133 -39
- package/src/extraction-source-grounding.test.ts +363 -33
- package/src/extraction-timeout.test.ts +1 -0
- package/src/extraction-watermark.test.ts +150 -7
- package/src/extraction.ts +8 -1
- package/src/index.ts +9 -5
- package/src/maintenance/first-start-migration.ts +11 -11
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-snapshot.ts +15 -0
- package/src/offline-sync.test.ts +194 -0
- package/src/offline-sync.ts +217 -13
- package/src/orchestration/external-wiki-recall-guard.test.ts +94 -0
- package/src/orchestration/extraction-persist.ts +19 -2
- package/src/orchestration/extraction-run-helpers.ts +37 -19
- package/src/orchestration/extraction-run.test.ts +171 -2
- package/src/orchestration/extraction-run.ts +11 -13
- package/src/orchestration/extraction-watermark.ts +106 -17
- package/src/orchestration/generic-recall-paths.ts +14 -0
- package/src/orchestration/orchestrator-helpers.ts +2 -0
- package/src/orchestration/orchestrator-init.ts +9 -0
- package/src/orchestration/recall-internal-deps.ts +6 -0
- package/src/orchestration/recall-internal.ts +154 -33
- package/src/orchestration/recall-rerank-coordinator.ts +60 -25
- package/src/orchestration/recall-search-pipeline.test.ts +75 -1
- package/src/orchestration/recall-search-pipeline.ts +50 -10
- package/src/orchestrator-convergence-refresh.test.ts +36 -2
- package/src/orchestrator.ts +13 -3
- package/src/page-versioning.ts +5 -19
- package/src/procedural/procedure-recall.ts +5 -1
- package/src/provenance-surfaces.test.ts +3 -0
- package/src/qmd-client.test.ts +78 -17
- package/src/qmd.test.ts +24 -0
- package/src/qmd.ts +224 -315
- package/src/recall-explain-renderer.ts +3 -0
- package/src/recall-rerank-coordinator.test.ts +61 -0
- package/src/recall-xray-renderer.test.ts +6 -0
- package/src/recall-xray.test.ts +88 -1
- package/src/recall-xray.ts +15 -0
- package/src/reconcile/cursor.test.ts +48 -0
- package/src/reconcile/cursor.ts +58 -11
- package/src/reconcile/manifest.test.ts +4 -0
- package/src/reconcile/manifest.ts +41 -51
- package/src/reconcile/plan.test.ts +4 -0
- package/src/reconcile/plan.ts +28 -16
- package/src/search/factory.ts +6 -6
- package/src/search/port.ts +25 -9
- package/src/secure-store/secure-fs.ts +20 -12
- package/src/secure-store/secure-store.test.ts +41 -2
- package/src/spaces/index.test.ts +61 -2
- package/src/spaces/index.ts +44 -18
- package/src/storage/entity-alias-config.ts +97 -0
- package/src/storage/entity-canonical-id-lock.ts +53 -23
- package/src/storage/entity-canonical-id-migration.ts +53 -22
- package/src/storage/entity-canonical-id-references.ts +3 -0
- package/src/storage/entity-id-safety.ts +7 -0
- package/src/storage/entity-store.ts +6 -2
- package/src/storage/memory-frontmatter-metadata.ts +4 -9
- package/src/storage/memory-migration-serialization.ts +10 -15
- package/src/storage/tombstone-blocked-capture-mutation.ts +52 -64
- package/src/storage/tombstone-blocked-capture-sync.ts +244 -199
- package/src/storage-contract/cache-coherence.test.ts +99 -0
- package/src/storage-deletion-revisions.test.ts +91 -0
- package/src/storage-fact-hash-index-defer.test.ts +460 -170
- package/src/storage.ts +572 -284
- package/src/testing/subjects/first-start-tier-migration.test.ts +75 -0
- package/src/tier-migration.ts +10 -12
- package/src/tool-scoped-memory.ts +10 -0
- package/src/transfer/capsule-import.ts +13 -0
- package/src/transfer/capsule-merge.ts +13 -0
- package/src/trust-score-recall-paths.test.ts +75 -1
- package/src/types.ts +7 -3
- package/dist/capsule-merge-IDWJPCWK.js.map +0 -1
- package/dist/chunk-3CE77VAP.js.map +0 -1
- package/dist/chunk-3TBLDMJA.js.map +0 -1
- package/dist/chunk-4J7G5SY4.js.map +0 -1
- package/dist/chunk-57QKLRBV.js.map +0 -1
- package/dist/chunk-5TFP4CUL.js.map +0 -1
- package/dist/chunk-7XC2HX75.js.map +0 -1
- package/dist/chunk-A5OJCXZL.js.map +0 -1
- package/dist/chunk-BUE5E2HL.js.map +0 -1
- package/dist/chunk-CJ2ZR7UA.js.map +0 -1
- package/dist/chunk-CUM2BBPN.js.map +0 -1
- package/dist/chunk-D3J5SLQK.js.map +0 -1
- package/dist/chunk-DL7ZD3JH.js.map +0 -1
- package/dist/chunk-DLVPUX7U.js.map +0 -1
- package/dist/chunk-E6PNLPGJ.js.map +0 -1
- package/dist/chunk-ECK75GDJ.js.map +0 -1
- package/dist/chunk-HREE4JHI.js.map +0 -1
- package/dist/chunk-HZFHQ4AQ.js.map +0 -1
- package/dist/chunk-IKKWIPYN.js.map +0 -1
- package/dist/chunk-J7VGGECD.js.map +0 -1
- package/dist/chunk-N5Z4EVOR.js.map +0 -1
- package/dist/chunk-NVRYW264.js.map +0 -1
- package/dist/chunk-P2BM76KT.js.map +0 -1
- package/dist/chunk-PVGDJXVK.js +0 -21
- package/dist/chunk-QJAQNXWI.js.map +0 -1
- package/dist/chunk-RN7DY3FC.js.map +0 -1
- package/dist/chunk-RVLJEII5.js.map +0 -1
- package/dist/chunk-S2NCTZGJ.js.map +0 -1
- package/dist/chunk-TDHTVMPG.js.map +0 -1
- package/dist/chunk-UYLMNVY6.js.map +0 -1
- package/dist/chunk-VCD4PSK2.js.map +0 -1
- package/dist/chunk-VNA7W7QF.js.map +0 -1
- package/dist/chunk-VOUOLGIP.js.map +0 -1
- package/dist/chunk-VWAXN2BN.js.map +0 -1
- package/dist/chunk-WOCNN776.js.map +0 -1
- package/dist/chunk-XYTOI63Z.js.map +0 -1
- package/dist/chunk-YV32N67O.js.map +0 -1
- /package/dist/{auto-sync-5OE5QOZB.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
- /package/dist/{chunk-E5UK4VPE.js.map → chunk-2FSTB6BJ.js.map} +0 -0
- /package/dist/{chunk-5ZE7QHTK.js.map → chunk-2X2T2UVE.js.map} +0 -0
- /package/dist/{chunk-P4DRWEYC.js.map → chunk-3COYXTGM.js.map} +0 -0
- /package/dist/{chunk-5IVLTFOV.js.map → chunk-44N6ESJ4.js.map} +0 -0
- /package/dist/{chunk-HO3QBJEY.js.map → chunk-5546W5SI.js.map} +0 -0
- /package/dist/{chunk-AAIUERNB.js.map → chunk-5QJQHBLE.js.map} +0 -0
- /package/dist/{chunk-6CZPDBJS.js.map → chunk-5U7ID3EZ.js.map} +0 -0
- /package/dist/{chunk-DNWXFTLD.js.map → chunk-A4IJCD2Z.js.map} +0 -0
- /package/dist/{chunk-PKNLM44P.js.map → chunk-AC5OWJLV.js.map} +0 -0
- /package/dist/{chunk-LZ4LDKHZ.js.map → chunk-AMAUBUKY.js.map} +0 -0
- /package/dist/{chunk-S5SLVSVY.js.map → chunk-BQIFZ2MP.js.map} +0 -0
- /package/dist/{chunk-Q6IP2ARR.js.map → chunk-CSOYVTRX.js.map} +0 -0
- /package/dist/{chunk-XOQSEF7X.js.map → chunk-CVILPI77.js.map} +0 -0
- /package/dist/{chunk-4LMA77JH.js.map → chunk-E5XQIWAL.js.map} +0 -0
- /package/dist/{chunk-WUNIWKY4.js.map → chunk-ELIL2A37.js.map} +0 -0
- /package/dist/{chunk-OQ5PRDDS.js.map → chunk-ERZ2R42X.js.map} +0 -0
- /package/dist/{chunk-U7GW7NE7.js.map → chunk-FIK3CQNA.js.map} +0 -0
- /package/dist/{chunk-33PLLLL7.js.map → chunk-GFCVUY6G.js.map} +0 -0
- /package/dist/{chunk-VUPTKTDV.js.map → chunk-GUAL4PQH.js.map} +0 -0
- /package/dist/{chunk-CINZGPSJ.js.map → chunk-GUMZC2BO.js.map} +0 -0
- /package/dist/{chunk-H24WNPA2.js.map → chunk-GWFSVJ4P.js.map} +0 -0
- /package/dist/{chunk-TSH56VPU.js.map → chunk-HAYSYUAB.js.map} +0 -0
- /package/dist/{chunk-PDLBLTOK.js.map → chunk-HC3PBX23.js.map} +0 -0
- /package/dist/{chunk-KXB4VXHY.js.map → chunk-JIYDRBVZ.js.map} +0 -0
- /package/dist/{chunk-HLPD7B7P.js.map → chunk-JZH4LWHB.js.map} +0 -0
- /package/dist/{chunk-AV5ZEH4M.js.map → chunk-KVJRXN2E.js.map} +0 -0
- /package/dist/{chunk-WFTIGIIS.js.map → chunk-L6CQ7WIW.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-EJUEXZHX.js.map → chunk-LLJMAULE.js.map} +0 -0
- /package/dist/{chunk-QN25OCUF.js.map → chunk-LPYDOLSM.js.map} +0 -0
- /package/dist/{chunk-AS7YMSL6.js.map → chunk-M23RF3LJ.js.map} +0 -0
- /package/dist/{chunk-OAEQLRCY.js.map → chunk-MO4HSXHZ.js.map} +0 -0
- /package/dist/{chunk-3F2LKUMU.js.map → chunk-NIS256NW.js.map} +0 -0
- /package/dist/{chunk-YIAA2X3D.js.map → chunk-NK5RGJ65.js.map} +0 -0
- /package/dist/{chunk-7TWUCYER.js.map → chunk-PNRA7FAD.js.map} +0 -0
- /package/dist/{chunk-5I4M26Q7.js.map → chunk-QBSFOKY6.js.map} +0 -0
- /package/dist/{chunk-E53DSZEN.js.map → chunk-QR6G5KF4.js.map} +0 -0
- /package/dist/{chunk-4UH4BTGK.js.map → chunk-QVJPH7SH.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-WDISJRMG.js.map → chunk-RMMVQQA6.js.map} +0 -0
- /package/dist/{chunk-JVLCVFQ4.js.map → chunk-RNHVVMFN.js.map} +0 -0
- /package/dist/{chunk-5SM35XZR.js.map → chunk-S5NZBKKQ.js.map} +0 -0
- /package/dist/{chunk-WIPEXG6R.js.map → chunk-SXIMQLGV.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-BJKPPZ6Z.js.map → chunk-UW66OZTD.js.map} +0 -0
- /package/dist/{chunk-S2BBISHU.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-3Y224NYC.js.map → chunk-VYISFWVX.js.map} +0 -0
- /package/dist/{chunk-JE7EK33X.js.map → chunk-W2V7UESE.js.map} +0 -0
- /package/dist/{chunk-TIHMZFIV.js.map → chunk-W3IC7QOY.js.map} +0 -0
- /package/dist/{chunk-NRV4Y3PM.js.map → chunk-W4FBGYGK.js.map} +0 -0
- /package/dist/{chunk-MU7ZHSZE.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-T2TTP3KU.js.map → chunk-X4IDNPOS.js.map} +0 -0
- /package/dist/{chunk-UVIKWC7M.js.map → chunk-XAGYS7X6.js.map} +0 -0
- /package/dist/{chunk-BLAKS3CP.js.map → chunk-XL3TATMJ.js.map} +0 -0
- /package/dist/{chunk-W4XJFLAL.js.map → chunk-XPRJSHNI.js.map} +0 -0
- /package/dist/{chunk-E6EE5B67.js.map → chunk-YK6BDDHP.js.map} +0 -0
- /package/dist/{chunk-ES36HTSC.js.map → chunk-YLHM5BQQ.js.map} +0 -0
- /package/dist/{chunk-GF22HWS2.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-64UDOIMI.js.map → chunk-ZLQ37WJX.js.map} +0 -0
package/src/qmd.ts
CHANGED
|
@@ -1,39 +1,35 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { abortError, isAbortError, throwIfAborted } from "./abort-error.js";
|
|
4
5
|
import { log } from "./logger.js";
|
|
5
6
|
import { clearQmdResultCaches, getCachedQmdSearch, setCachedQmdSearch } from "./memory-cache.js";
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import type { QmdSearchExplain, QmdSearchResult } from "./types.js";
|
|
12
|
-
import {
|
|
13
|
-
resolveEnsureCollectionArgs,
|
|
14
|
-
type SearchBackend,
|
|
15
|
-
type SearchDegradation,
|
|
16
|
-
type SearchExecutionOptions,
|
|
17
|
-
type SearchQueryOptions,
|
|
18
|
-
} from "./search/port.js";
|
|
19
|
-
import { launchProcess, type CommandChildProcess } from "./runtime/child-process.js";
|
|
20
|
-
import { mergeEnv } from "./runtime/env.js";
|
|
21
|
-
import {
|
|
8
|
+
QMD_PROBE_RETRY_BACKOFF_MS,
|
|
9
|
+
QMD_PROBE_TIMEOUT_MS,
|
|
10
|
+
QMD_SUPPORTED_VERSION,
|
|
11
|
+
type QmdProbeFailureKind,
|
|
22
12
|
classifyProbeFailure,
|
|
23
13
|
compareQmdVersions,
|
|
24
14
|
getQmdPostInstallProbeTargets,
|
|
25
15
|
parseQmdVersion,
|
|
26
16
|
parseQmdVersionOutput,
|
|
27
|
-
QMD_PROBE_RETRY_BACKOFF_MS,
|
|
28
|
-
QMD_PROBE_TIMEOUT_MS,
|
|
29
|
-
QMD_SUPPORTED_VERSION,
|
|
30
17
|
qmdVersionToString,
|
|
31
18
|
resolveQmdCapabilities,
|
|
32
19
|
shouldAutoUpgradeQmd,
|
|
33
20
|
versionAtLeast,
|
|
34
|
-
type QmdProbeFailureKind,
|
|
35
21
|
} from "./qmd-preflight.js";
|
|
36
|
-
import {
|
|
22
|
+
import { EMPTY_QMD_STATUS, type QmdStatusReport, embedQmdFiles, fetchQmdStatus } from "./qmd-status.js";
|
|
23
|
+
import { type CommandChildProcess, launchProcess } from "./runtime/child-process.js";
|
|
24
|
+
import { mergeEnv } from "./runtime/env.js";
|
|
25
|
+
import {
|
|
26
|
+
type SearchBackend,
|
|
27
|
+
type SearchDegradation,
|
|
28
|
+
type SearchExecutionOptions,
|
|
29
|
+
type SearchQueryOptions,
|
|
30
|
+
resolveEnsureCollectionArgs,
|
|
31
|
+
} from "./search/port.js";
|
|
32
|
+
import type { QmdSearchExplain, QmdSearchResult } from "./types.js";
|
|
37
33
|
// Re-export version-check / probe-preflight helpers (moved to qmd-preflight.ts,
|
|
38
34
|
// issue #1841) so existing imports from "./qmd.js" keep resolving.
|
|
39
35
|
export {
|
|
@@ -53,6 +49,7 @@ export interface QmdClientOptions {
|
|
|
53
49
|
updateMinIntervalMs?: number;
|
|
54
50
|
qmdPath?: string;
|
|
55
51
|
daemonUrl?: string;
|
|
52
|
+
qmdStrictPath?: boolean;
|
|
56
53
|
daemonRecheckIntervalMs?: number;
|
|
57
54
|
qmdSupportedVersion?: string;
|
|
58
55
|
qmdAutoUpgradeEnabled?: boolean;
|
|
@@ -224,7 +221,12 @@ function sleep(ms: number): Promise<void> {
|
|
|
224
221
|
function errorMessage(err: unknown): string {
|
|
225
222
|
if (typeof err === "string") return err;
|
|
226
223
|
if (err instanceof Error) return err.message;
|
|
227
|
-
if (
|
|
224
|
+
if (
|
|
225
|
+
err &&
|
|
226
|
+
typeof err === "object" &&
|
|
227
|
+
"message" in err &&
|
|
228
|
+
typeof (err as { message?: unknown }).message === "string"
|
|
229
|
+
) {
|
|
228
230
|
return (err as { message: string }).message;
|
|
229
231
|
}
|
|
230
232
|
return String(err);
|
|
@@ -339,12 +341,11 @@ function normalizeStructuredSearches(value: unknown): QmdStructuredSearch[] {
|
|
|
339
341
|
}
|
|
340
342
|
|
|
341
343
|
function buildSyntheticHydeQuery(query: string, intent?: string): string {
|
|
342
|
-
const base =
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
: base;
|
|
344
|
+
const base =
|
|
345
|
+
intent && intent.trim().length > 0
|
|
346
|
+
? `A relevant Remnic memory for ${intent.trim()} would answer: ${query.trim()}`
|
|
347
|
+
: `A relevant Remnic memory would answer: ${query.trim()}`;
|
|
348
|
+
return base.length > QMD_STRUCTURED_HYDE_MAX_CHARS ? base.slice(0, QMD_STRUCTURED_HYDE_MAX_CHARS) : base;
|
|
348
349
|
}
|
|
349
350
|
|
|
350
351
|
/**
|
|
@@ -360,7 +361,7 @@ function buildSyntheticHydeQuery(query: string, intent?: string): string {
|
|
|
360
361
|
export function buildDefaultStructuredSearches(
|
|
361
362
|
query: string,
|
|
362
363
|
options?: SearchQueryOptions,
|
|
363
|
-
strategy: QmdSearchStrategy = "hybrid"
|
|
364
|
+
strategy: QmdSearchStrategy = "hybrid"
|
|
364
365
|
): QmdStructuredSearch[] {
|
|
365
366
|
const explicit = normalizeStructuredSearches(options?.structuredSearches);
|
|
366
367
|
if (explicit.length > 0) return explicit;
|
|
@@ -370,11 +371,7 @@ export function buildDefaultStructuredSearches(
|
|
|
370
371
|
if (strategy === "lex") return [lex];
|
|
371
372
|
const vec: QmdStructuredSearch = { type: "vec", query: trimmed };
|
|
372
373
|
if (strategy === "lex-vec") return [lex, vec];
|
|
373
|
-
return [
|
|
374
|
-
lex,
|
|
375
|
-
vec,
|
|
376
|
-
{ type: "hyde", query: buildSyntheticHydeQuery(trimmed, options?.intent) },
|
|
377
|
-
];
|
|
374
|
+
return [lex, vec, { type: "hyde", query: buildSyntheticHydeQuery(trimmed, options?.intent) }];
|
|
378
375
|
}
|
|
379
376
|
|
|
380
377
|
function parseExplainScores(value: unknown): number[] | undefined {
|
|
@@ -389,24 +386,21 @@ export function parseQmdExplain(value: unknown): QmdSearchExplain | undefined {
|
|
|
389
386
|
const rrf =
|
|
390
387
|
typeof candidate.rrf === "number"
|
|
391
388
|
? candidate.rrf
|
|
392
|
-
: candidate.rrf &&
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
389
|
+
: candidate.rrf &&
|
|
390
|
+
typeof candidate.rrf === "object" &&
|
|
391
|
+
typeof (candidate.rrf as Record<string, unknown>).totalScore === "number"
|
|
392
|
+
? ((candidate.rrf as Record<string, unknown>).totalScore as number)
|
|
393
|
+
: undefined;
|
|
396
394
|
const rrfObj =
|
|
397
|
-
candidate.rrf && typeof candidate.rrf === "object"
|
|
398
|
-
? (candidate.rrf as Record<string, unknown>)
|
|
399
|
-
: undefined;
|
|
395
|
+
candidate.rrf && typeof candidate.rrf === "object" ? (candidate.rrf as Record<string, unknown>) : undefined;
|
|
400
396
|
const parsed: QmdSearchExplain = {
|
|
401
397
|
ftsScores: parseExplainScores(candidate.ftsScores),
|
|
402
398
|
vectorScores: parseExplainScores(candidate.vectorScores),
|
|
403
399
|
rrf,
|
|
404
400
|
rrfRank: typeof rrfObj?.rank === "number" ? rrfObj.rank : undefined,
|
|
405
|
-
rrfPositionScore:
|
|
406
|
-
typeof rrfObj?.positionScore === "number" ? rrfObj.positionScore : undefined,
|
|
401
|
+
rrfPositionScore: typeof rrfObj?.positionScore === "number" ? rrfObj.positionScore : undefined,
|
|
407
402
|
rrfBaseScore: typeof rrfObj?.baseScore === "number" ? rrfObj.baseScore : undefined,
|
|
408
|
-
rrfTopRankBonus:
|
|
409
|
-
typeof rrfObj?.topRankBonus === "number" ? rrfObj.topRankBonus : undefined,
|
|
403
|
+
rrfTopRankBonus: typeof rrfObj?.topRankBonus === "number" ? rrfObj.topRankBonus : undefined,
|
|
410
404
|
rerankScore: typeof candidate.rerankScore === "number" ? candidate.rerankScore : undefined,
|
|
411
405
|
blendedScore: typeof candidate.blendedScore === "number" ? candidate.blendedScore : undefined,
|
|
412
406
|
};
|
|
@@ -481,9 +475,9 @@ const QMD_MUTEX = new AsyncMutex();
|
|
|
481
475
|
function runQmd(
|
|
482
476
|
args: string[],
|
|
483
477
|
timeoutMs: number = QMD_TIMEOUT_MS,
|
|
484
|
-
qmdPath
|
|
478
|
+
qmdPath = "qmd",
|
|
485
479
|
signal?: AbortSignal,
|
|
486
|
-
runtimeEnv?: QmdRuntimeEnv
|
|
480
|
+
runtimeEnv?: QmdRuntimeEnv
|
|
487
481
|
): Promise<{ stdout: string; stderr: string }> {
|
|
488
482
|
// Serialize all qmd calls. This avoids SQLite lock contention when multiple
|
|
489
483
|
// channels/agents trigger QMD operations at nearly the same time.
|
|
@@ -538,7 +532,7 @@ function runQmdOnce(
|
|
|
538
532
|
timeoutMs: number,
|
|
539
533
|
qmdPath: string,
|
|
540
534
|
signal?: AbortSignal,
|
|
541
|
-
runtimeEnv?: QmdRuntimeEnv
|
|
535
|
+
runtimeEnv?: QmdRuntimeEnv
|
|
542
536
|
): Promise<{ stdout: string; stderr: string }> {
|
|
543
537
|
const isVersionCheck = args.length === 1 && args[0] === "--version";
|
|
544
538
|
return runCommandWithTimeout(qmdPath, args, {
|
|
@@ -559,7 +553,7 @@ function runCommandWithTimeout(
|
|
|
559
553
|
env?: QmdRuntimeEnv;
|
|
560
554
|
label?: string;
|
|
561
555
|
isSuccessExitCode?: (code: number | null) => boolean;
|
|
562
|
-
}
|
|
556
|
+
}
|
|
563
557
|
): Promise<{ stdout: string; stderr: string }> {
|
|
564
558
|
const label = options.label ?? `${command} ${args.join(" ")}`;
|
|
565
559
|
const isSuccessExitCode = options.isSuccessExitCode ?? ((code: number | null) => code === 0);
|
|
@@ -587,7 +581,7 @@ function runCommandWithTimeout(
|
|
|
587
581
|
reject(
|
|
588
582
|
Object.assign(new Error(`${label} timed out after ${options.timeoutMs}ms`), {
|
|
589
583
|
timedOut: true as const,
|
|
590
|
-
})
|
|
584
|
+
})
|
|
591
585
|
);
|
|
592
586
|
}, options.timeoutMs);
|
|
593
587
|
const onAbort = () => {
|
|
@@ -624,11 +618,7 @@ function runCommandWithTimeout(
|
|
|
624
618
|
if (isSuccessExitCode(code)) {
|
|
625
619
|
resolve({ stdout, stderr });
|
|
626
620
|
} else {
|
|
627
|
-
reject(
|
|
628
|
-
new Error(
|
|
629
|
-
`${label} failed (code ${code}): ${truncateForLog(stderr || stdout)}`,
|
|
630
|
-
),
|
|
631
|
-
);
|
|
621
|
+
reject(new Error(`${label} failed (code ${code}): ${truncateForLog(stderr || stdout)}`));
|
|
632
622
|
}
|
|
633
623
|
});
|
|
634
624
|
});
|
|
@@ -638,7 +628,7 @@ function runProcessCommand(
|
|
|
638
628
|
command: string,
|
|
639
629
|
args: string[],
|
|
640
630
|
timeoutMs: number,
|
|
641
|
-
signal?: AbortSignal
|
|
631
|
+
signal?: AbortSignal
|
|
642
632
|
): Promise<{ stdout: string; stderr: string }> {
|
|
643
633
|
return runCommandWithTimeout(command, args, {
|
|
644
634
|
timeoutMs,
|
|
@@ -743,7 +733,7 @@ class QmdDaemonSession {
|
|
|
743
733
|
capabilities: {},
|
|
744
734
|
clientInfo: { name: "openclaw-remnic", version: "1.0.0" },
|
|
745
735
|
},
|
|
746
|
-
60_000
|
|
736
|
+
60_000
|
|
747
737
|
);
|
|
748
738
|
if (!result) {
|
|
749
739
|
// Null result (non-timeout failure) — kill and let the next probe respawn.
|
|
@@ -778,8 +768,8 @@ class QmdDaemonSession {
|
|
|
778
768
|
async callTool(
|
|
779
769
|
name: string,
|
|
780
770
|
args: Record<string, unknown>,
|
|
781
|
-
timeoutMs
|
|
782
|
-
signal?: AbortSignal
|
|
771
|
+
timeoutMs = 30_000,
|
|
772
|
+
signal?: AbortSignal
|
|
783
773
|
): Promise<unknown> {
|
|
784
774
|
if (!this.child || this.child.killed || !this.initialized) {
|
|
785
775
|
throw new Error("QMD mcp process not running");
|
|
@@ -833,7 +823,7 @@ class QmdDaemonSession {
|
|
|
833
823
|
method: string,
|
|
834
824
|
params: Record<string, unknown>,
|
|
835
825
|
timeoutMs: number,
|
|
836
|
-
signal?: AbortSignal
|
|
826
|
+
signal?: AbortSignal
|
|
837
827
|
): Promise<unknown> {
|
|
838
828
|
return new Promise((resolve, reject) => {
|
|
839
829
|
throwIfAborted(signal, `QMD mcp ${method} aborted before request`);
|
|
@@ -953,10 +943,7 @@ const QMD_RESULT_LINE_RE = /^#([0-9a-fA-F]+)\s+(\d+)%\s+(.+)/;
|
|
|
953
943
|
*/
|
|
954
944
|
const QMD_PATH_TITLE_RE = /^(.+?\.[a-zA-Z]{2,10})\s+-\s+(.*)$/;
|
|
955
945
|
|
|
956
|
-
function parseQmdMarkdownResultText(
|
|
957
|
-
text: string,
|
|
958
|
-
transport: QmdSearchResult["transport"],
|
|
959
|
-
): QmdSearchResult[] {
|
|
946
|
+
function parseQmdMarkdownResultText(text: string, transport: QmdSearchResult["transport"]): QmdSearchResult[] {
|
|
960
947
|
const results: QmdSearchResult[] = [];
|
|
961
948
|
for (const line of text.split("\n")) {
|
|
962
949
|
const m = QMD_RESULT_LINE_RE.exec(line.trim());
|
|
@@ -969,17 +956,14 @@ function parseQmdMarkdownResultText(
|
|
|
969
956
|
docid: m[1],
|
|
970
957
|
path: pathTitleSplit[1] ?? "unknown",
|
|
971
958
|
snippet: "",
|
|
972
|
-
score: parseInt(m[2], 10) / 100,
|
|
959
|
+
score: Number.parseInt(m[2], 10) / 100,
|
|
973
960
|
transport,
|
|
974
961
|
});
|
|
975
962
|
}
|
|
976
963
|
return results;
|
|
977
964
|
}
|
|
978
965
|
|
|
979
|
-
function parseMcpSearchResult(
|
|
980
|
-
result: unknown,
|
|
981
|
-
transport: QmdSearchResult["transport"] = "daemon",
|
|
982
|
-
): QmdSearchResult[] {
|
|
966
|
+
function parseMcpSearchResult(result: unknown, transport: QmdSearchResult["transport"] = "daemon"): QmdSearchResult[] {
|
|
983
967
|
const resultObj = result as Record<string, unknown> | null;
|
|
984
968
|
if (!resultObj) return [];
|
|
985
969
|
const results: QmdSearchResult[] = [];
|
|
@@ -988,16 +972,17 @@ function parseMcpSearchResult(
|
|
|
988
972
|
const d = doc as Record<string, unknown>;
|
|
989
973
|
results.push({
|
|
990
974
|
docid: typeof d.docid === "string" ? d.docid.replace(/^#/, "") : "",
|
|
991
|
-
path:
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
975
|
+
path:
|
|
976
|
+
typeof d.file === "string"
|
|
977
|
+
? d.file
|
|
978
|
+
: typeof d.path === "string"
|
|
979
|
+
? d.path
|
|
980
|
+
: typeof d.docid === "string"
|
|
981
|
+
? d.docid.replace(/^#/, "")
|
|
982
|
+
: "unknown",
|
|
996
983
|
snippet: typeof d.snippet === "string" ? d.snippet : "",
|
|
997
984
|
score: typeof d.score === "number" ? d.score : 0,
|
|
998
|
-
line: typeof d.line === "number" && Number.isFinite(d.line)
|
|
999
|
-
? Math.max(1, Math.floor(d.line))
|
|
1000
|
-
: undefined,
|
|
985
|
+
line: typeof d.line === "number" && Number.isFinite(d.line) ? Math.max(1, Math.floor(d.line)) : undefined,
|
|
1001
986
|
explain: parseQmdExplain(d.explain),
|
|
1002
987
|
transport,
|
|
1003
988
|
});
|
|
@@ -1036,7 +1021,7 @@ function parseMcpSearchResult(
|
|
|
1036
1021
|
|
|
1037
1022
|
function parseQmdSearchStdout(
|
|
1038
1023
|
stdout: string,
|
|
1039
|
-
transport: QmdSearchResult["transport"] = "subprocess"
|
|
1024
|
+
transport: QmdSearchResult["transport"] = "subprocess"
|
|
1040
1025
|
): QmdSearchResult[] {
|
|
1041
1026
|
const trimmedOut = stdout.trim();
|
|
1042
1027
|
if (!trimmedOut || trimmedOut === "No results found.") return [];
|
|
@@ -1045,19 +1030,14 @@ function parseQmdSearchStdout(
|
|
|
1045
1030
|
return parsed.map(
|
|
1046
1031
|
(entry: Record<string, unknown>): QmdSearchResult => ({
|
|
1047
1032
|
docid: (entry.docid as string) ?? "",
|
|
1048
|
-
path:
|
|
1049
|
-
(entry.file as string) ??
|
|
1050
|
-
(entry.path as string) ??
|
|
1051
|
-
(entry.docid as string) ??
|
|
1052
|
-
"unknown",
|
|
1033
|
+
path: (entry.file as string) ?? (entry.path as string) ?? (entry.docid as string) ?? "unknown",
|
|
1053
1034
|
snippet: (entry.snippet as string) ?? "",
|
|
1054
1035
|
score: typeof entry.score === "number" ? entry.score : 0,
|
|
1055
|
-
line:
|
|
1056
|
-
? Math.max(1, Math.floor(entry.line))
|
|
1057
|
-
: undefined,
|
|
1036
|
+
line:
|
|
1037
|
+
typeof entry.line === "number" && Number.isFinite(entry.line) ? Math.max(1, Math.floor(entry.line)) : undefined,
|
|
1058
1038
|
explain: parseQmdExplain(entry.explain),
|
|
1059
1039
|
transport,
|
|
1060
|
-
})
|
|
1040
|
+
})
|
|
1061
1041
|
);
|
|
1062
1042
|
}
|
|
1063
1043
|
|
|
@@ -1072,15 +1052,11 @@ function stableRuntimeEnvKey(runtimeEnv: QmdRuntimeEnv): string {
|
|
|
1072
1052
|
return JSON.stringify(
|
|
1073
1053
|
Object.keys(runtimeEnv)
|
|
1074
1054
|
.sort()
|
|
1075
|
-
.map((key) => [key, runtimeEnv[key]])
|
|
1055
|
+
.map((key) => [key, runtimeEnv[key]])
|
|
1076
1056
|
);
|
|
1077
1057
|
}
|
|
1078
1058
|
|
|
1079
|
-
function recordAutoUpgradeStatus(
|
|
1080
|
-
state: QmdGlobalState,
|
|
1081
|
-
targetKey: string,
|
|
1082
|
-
status: string,
|
|
1083
|
-
): void {
|
|
1059
|
+
function recordAutoUpgradeStatus(state: QmdGlobalState, targetKey: string, status: string): void {
|
|
1084
1060
|
state.lastAutoUpgradeStatusByTarget[targetKey] = status;
|
|
1085
1061
|
state.lastAutoUpgradeStatus = status;
|
|
1086
1062
|
}
|
|
@@ -1089,7 +1065,7 @@ function retainSharedDaemonSession(
|
|
|
1089
1065
|
qmdPath: string,
|
|
1090
1066
|
runtimeEnv: QmdRuntimeEnv = {},
|
|
1091
1067
|
indexName?: string,
|
|
1092
|
-
cliVersion?: string | null
|
|
1068
|
+
cliVersion?: string | null
|
|
1093
1069
|
): QmdDaemonSession {
|
|
1094
1070
|
const normalizedPath = qmdPath.trim() || "qmd";
|
|
1095
1071
|
const normalizedIndex = indexName?.trim() || "";
|
|
@@ -1174,6 +1150,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1174
1150
|
private readonly qmdSearchStrategy: QmdSearchStrategy;
|
|
1175
1151
|
private readonly qmdSubprocessStrategy: QmdSubprocessStrategy;
|
|
1176
1152
|
private readonly qmdFallbackPaths: string[];
|
|
1153
|
+
private readonly qmdStrictPath: boolean;
|
|
1177
1154
|
private readonly daemonTimeoutMs: number;
|
|
1178
1155
|
private readonly qmdRuntimeEnv: QmdRuntimeEnv;
|
|
1179
1156
|
private qmdPathSource: "auto-path" | "auto-fallback" | "configured" = "auto-path";
|
|
@@ -1195,7 +1172,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1195
1172
|
constructor(
|
|
1196
1173
|
private readonly collection: string,
|
|
1197
1174
|
private readonly maxResults: number,
|
|
1198
|
-
opts?: QmdClientOptions
|
|
1175
|
+
opts?: QmdClientOptions
|
|
1199
1176
|
) {
|
|
1200
1177
|
this.slowLog = opts?.slowLog;
|
|
1201
1178
|
this.updateTimeoutMs = opts?.updateTimeoutMs ?? 120_000;
|
|
@@ -1208,12 +1185,10 @@ export class QmdClient implements SearchBackend {
|
|
|
1208
1185
|
this.qmdAutoUpgradeEnabled = opts?.qmdAutoUpgradeEnabled === true;
|
|
1209
1186
|
this.qmdAutoUpgradeCheckIntervalMs = Math.max(
|
|
1210
1187
|
60_000,
|
|
1211
|
-
Math.floor(opts?.qmdAutoUpgradeCheckIntervalMs ?? QMD_AUTO_UPGRADE_CHECK_INTERVAL_MS)
|
|
1188
|
+
Math.floor(opts?.qmdAutoUpgradeCheckIntervalMs ?? QMD_AUTO_UPGRADE_CHECK_INTERVAL_MS)
|
|
1212
1189
|
);
|
|
1213
1190
|
this.qmdChunkStrategy =
|
|
1214
|
-
opts?.qmdChunkStrategy === "auto" || opts?.qmdChunkStrategy === "regex"
|
|
1215
|
-
? opts.qmdChunkStrategy
|
|
1216
|
-
: undefined;
|
|
1191
|
+
opts?.qmdChunkStrategy === "auto" || opts?.qmdChunkStrategy === "regex" ? opts.qmdChunkStrategy : undefined;
|
|
1217
1192
|
this.qmdCandidateLimit =
|
|
1218
1193
|
typeof opts?.qmdCandidateLimit === "number" &&
|
|
1219
1194
|
Number.isFinite(opts.qmdCandidateLimit) &&
|
|
@@ -1222,19 +1197,13 @@ export class QmdClient implements SearchBackend {
|
|
|
1222
1197
|
: undefined;
|
|
1223
1198
|
this.qmdQueryRerankEnabled = opts?.qmdQueryRerankEnabled !== false;
|
|
1224
1199
|
this.qmdIndexName = opts?.qmdIndexName?.trim() || undefined;
|
|
1225
|
-
// Default "hybrid" preserves the historical lex+vec+hyde daemon plan. Issue #1335.
|
|
1226
1200
|
this.qmdSearchStrategy =
|
|
1227
|
-
opts?.qmdSearchStrategy === "lex" || opts?.qmdSearchStrategy === "lex-vec"
|
|
1228
|
-
? opts.qmdSearchStrategy
|
|
1229
|
-
: "hybrid";
|
|
1230
|
-
// Default "query" keeps `qmd query` (LLM expansion + rerank) per gotcha #7. Issue #1335.
|
|
1201
|
+
opts?.qmdSearchStrategy === "lex" || opts?.qmdSearchStrategy === "lex-vec" ? opts.qmdSearchStrategy : "hybrid";
|
|
1231
1202
|
this.qmdSubprocessStrategy = opts?.qmdSubprocessStrategy === "search" ? "search" : "query";
|
|
1232
1203
|
this.qmdFallbackPaths = opts?.qmdFallbackPaths
|
|
1233
1204
|
? opts.qmdFallbackPaths.map((candidate) => candidate.trim()).filter(Boolean)
|
|
1234
1205
|
: QMD_FALLBACK_PATHS;
|
|
1235
|
-
|
|
1236
|
-
// Floor of 1000ms avoids absurdly small values; callers wanting CPU-only HyDE
|
|
1237
|
-
// headroom can raise this (e.g. 20000) without code changes.
|
|
1206
|
+
this.qmdStrictPath = opts?.qmdStrictPath === true;
|
|
1238
1207
|
this.daemonTimeoutMs =
|
|
1239
1208
|
typeof opts?.qmdDaemonTimeoutMs === "number" && Number.isFinite(opts.qmdDaemonTimeoutMs)
|
|
1240
1209
|
? Math.max(1_000, Math.floor(opts.qmdDaemonTimeoutMs))
|
|
@@ -1248,7 +1217,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1248
1217
|
this.daemonRecheckIntervalMs = opts?.daemonRecheckIntervalMs ?? 15_000;
|
|
1249
1218
|
}
|
|
1250
1219
|
|
|
1251
|
-
private qmdPath
|
|
1220
|
+
private qmdPath = "qmd";
|
|
1252
1221
|
|
|
1253
1222
|
private buildRuntimeEnv(opts?: QmdClientOptions): QmdRuntimeEnv {
|
|
1254
1223
|
const env: QmdRuntimeEnv = {};
|
|
@@ -1304,10 +1273,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1304
1273
|
private async probeDaemon(): Promise<boolean> {
|
|
1305
1274
|
this.lastDaemonCheckAtMs = Date.now();
|
|
1306
1275
|
const normalizedPath = this.qmdPath.trim() || "qmd";
|
|
1307
|
-
const daemonIndexName =
|
|
1308
|
-
this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection
|
|
1309
|
-
? this.qmdIndexName
|
|
1310
|
-
: undefined;
|
|
1276
|
+
const daemonIndexName = this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection ? this.qmdIndexName : undefined;
|
|
1311
1277
|
const daemonSessionPath = `${normalizedPath}\0${daemonIndexName ?? ""}\0${this.cliVersion ?? ""}`;
|
|
1312
1278
|
if (!this.daemonSession || this.daemonSessionPath !== daemonSessionPath) {
|
|
1313
1279
|
await releaseSharedDaemonSession(this.daemonSession);
|
|
@@ -1315,7 +1281,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1315
1281
|
normalizedPath,
|
|
1316
1282
|
this.qmdRuntimeEnv,
|
|
1317
1283
|
daemonIndexName,
|
|
1318
|
-
this.cliVersion
|
|
1284
|
+
this.cliVersion
|
|
1319
1285
|
);
|
|
1320
1286
|
this.daemonSessionPath = daemonSessionPath;
|
|
1321
1287
|
}
|
|
@@ -1329,7 +1295,9 @@ export class QmdClient implements SearchBackend {
|
|
|
1329
1295
|
]);
|
|
1330
1296
|
if (!ok) {
|
|
1331
1297
|
const loading = this.daemonSession.isLoading();
|
|
1332
|
-
log.debug(
|
|
1298
|
+
log.debug(
|
|
1299
|
+
`QMD daemon: stdio session not ready within ${PROBE_QUICK_TIMEOUT_MS}ms probe window${loading ? " (still loading)" : ""}`
|
|
1300
|
+
);
|
|
1333
1301
|
this.daemonAvailable = false;
|
|
1334
1302
|
return false;
|
|
1335
1303
|
}
|
|
@@ -1344,15 +1312,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1344
1312
|
}
|
|
1345
1313
|
}
|
|
1346
1314
|
|
|
1347
|
-
|
|
1348
|
-
* Run a single `qmd --version` probe against `qmdPath`. Extracted as its own
|
|
1349
|
-
* method so tests can inject a fake probe runner that exercises the preflight
|
|
1350
|
-
* retry/classification paths without spawning a real qmd binary. Issue #1841.
|
|
1351
|
-
*/
|
|
1352
|
-
private runVersionProbe(
|
|
1353
|
-
qmdPath: string,
|
|
1354
|
-
signal?: AbortSignal,
|
|
1355
|
-
): Promise<{ stdout: string; stderr: string }> {
|
|
1315
|
+
private runVersionProbe(qmdPath: string, signal?: AbortSignal): Promise<{ stdout: string; stderr: string }> {
|
|
1356
1316
|
return runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, qmdPath, signal, this.qmdRuntimeEnv);
|
|
1357
1317
|
}
|
|
1358
1318
|
|
|
@@ -1361,18 +1321,19 @@ export class QmdClient implements SearchBackend {
|
|
|
1361
1321
|
allowAutoUpgrade?: boolean;
|
|
1362
1322
|
preserveStateOnFailure?: boolean;
|
|
1363
1323
|
signal?: AbortSignal;
|
|
1364
|
-
} = {}
|
|
1324
|
+
} = {}
|
|
1365
1325
|
): Promise<boolean> {
|
|
1366
|
-
const priorState =
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1326
|
+
const priorState =
|
|
1327
|
+
options.preserveStateOnFailure === true
|
|
1328
|
+
? {
|
|
1329
|
+
available: this.available,
|
|
1330
|
+
qmdPath: this.qmdPath,
|
|
1331
|
+
qmdPathSource: this.qmdPathSource,
|
|
1332
|
+
cliVersion: this.cliVersion,
|
|
1333
|
+
lastCliProbeError: this.lastCliProbeError,
|
|
1334
|
+
qmdCapabilities: this.qmdCapabilities,
|
|
1335
|
+
}
|
|
1336
|
+
: null;
|
|
1376
1337
|
const restorePriorState = (): void => {
|
|
1377
1338
|
if (!priorState) return;
|
|
1378
1339
|
this.available = priorState.available;
|
|
@@ -1395,7 +1356,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1395
1356
|
const recordProbeSuccess = async (
|
|
1396
1357
|
result: { stdout: string; stderr: string },
|
|
1397
1358
|
qmdPath: string,
|
|
1398
|
-
source: typeof this.qmdPathSource
|
|
1359
|
+
source: typeof this.qmdPathSource
|
|
1399
1360
|
): Promise<void> => {
|
|
1400
1361
|
this.available = true;
|
|
1401
1362
|
this.qmdPath = qmdPath;
|
|
@@ -1430,15 +1391,9 @@ export class QmdClient implements SearchBackend {
|
|
|
1430
1391
|
failureKind = classifyProbeFailure(err);
|
|
1431
1392
|
// Never retry a hard misconfiguration (missing/not-executable) — only
|
|
1432
1393
|
// transient slowness. (Caller cancellation is handled above.)
|
|
1433
|
-
if (
|
|
1434
|
-
failureKind === "transient" &&
|
|
1435
|
-
attempt < QMD_PROBE_RETRY_BACKOFF_MS.length
|
|
1436
|
-
) {
|
|
1394
|
+
if (failureKind === "transient" && attempt < QMD_PROBE_RETRY_BACKOFF_MS.length) {
|
|
1437
1395
|
try {
|
|
1438
|
-
await sleepWithSignal(
|
|
1439
|
-
QMD_PROBE_RETRY_BACKOFF_MS[attempt] ?? 500,
|
|
1440
|
-
options.signal,
|
|
1441
|
-
);
|
|
1396
|
+
await sleepWithSignal(QMD_PROBE_RETRY_BACKOFF_MS[attempt] ?? 500, options.signal);
|
|
1442
1397
|
} catch {
|
|
1443
1398
|
// Aborted mid-backoff: caller cancelled — stop, emit no warning.
|
|
1444
1399
|
callerCancelled = true;
|
|
@@ -1454,29 +1409,34 @@ export class QmdClient implements SearchBackend {
|
|
|
1454
1409
|
if (!callerCancelled) {
|
|
1455
1410
|
if (failureKind === "transient") {
|
|
1456
1411
|
this.logCliProbeWarning(
|
|
1457
|
-
`QMD: qmdPath ${configuredPath} version check timed out (host may be under load); retried ${retries} time${retries === 1 ? "" : "s"}
|
|
1412
|
+
`QMD: qmdPath ${configuredPath} version check timed out (host may be under load); retried ${retries} time${retries === 1 ? "" : "s"}`
|
|
1458
1413
|
);
|
|
1459
1414
|
} else if (failureKind === "missing") {
|
|
1460
1415
|
this.logCliProbeWarning(
|
|
1461
|
-
`QMD: configured qmdPath not found or not executable (${configuredPath}): ${this.lastCliProbeError}
|
|
1416
|
+
`QMD: configured qmdPath not found or not executable (${configuredPath}): ${this.lastCliProbeError}`
|
|
1462
1417
|
);
|
|
1463
1418
|
} else {
|
|
1464
1419
|
// Preserve the historical generic message for exit-code/other failures.
|
|
1465
|
-
this.logCliProbeWarning(
|
|
1466
|
-
`QMD: configured qmdPath failed (${configuredPath}): ${this.lastCliProbeError}`,
|
|
1467
|
-
);
|
|
1420
|
+
this.logCliProbeWarning(`QMD: configured qmdPath failed (${configuredPath}): ${this.lastCliProbeError}`);
|
|
1468
1421
|
}
|
|
1469
1422
|
}
|
|
1470
1423
|
}
|
|
1424
|
+
if (this.configuredQmdPath && this.qmdStrictPath) {
|
|
1425
|
+
if (priorState) {
|
|
1426
|
+
restorePriorState();
|
|
1427
|
+
} else {
|
|
1428
|
+
this.available = false;
|
|
1429
|
+
restoreConfiguredProbeFailure();
|
|
1430
|
+
}
|
|
1431
|
+
return false;
|
|
1432
|
+
}
|
|
1471
1433
|
|
|
1472
|
-
// Try PATH first
|
|
1473
1434
|
try {
|
|
1474
1435
|
const result = await this.runVersionProbe("qmd", options.signal);
|
|
1475
1436
|
await recordProbeSuccess(result, "qmd", "auto-path");
|
|
1476
1437
|
return true;
|
|
1477
1438
|
} catch (err) {
|
|
1478
1439
|
markProbeFailure(err);
|
|
1479
|
-
// Try fallback paths
|
|
1480
1440
|
for (const fallbackPath of this.qmdFallbackPaths) {
|
|
1481
1441
|
try {
|
|
1482
1442
|
const result = await this.runVersionProbe(fallbackPath, options.signal);
|
|
@@ -1485,7 +1445,6 @@ export class QmdClient implements SearchBackend {
|
|
|
1485
1445
|
return true;
|
|
1486
1446
|
} catch (fallbackErr) {
|
|
1487
1447
|
markProbeFailure(fallbackErr);
|
|
1488
|
-
// Continue to next fallback
|
|
1489
1448
|
}
|
|
1490
1449
|
}
|
|
1491
1450
|
if (priorState) {
|
|
@@ -1504,10 +1463,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1504
1463
|
const targetKey = this.autoUpgradeTargetKey();
|
|
1505
1464
|
const now = Date.now();
|
|
1506
1465
|
const lastCheckAtMs = state.lastAutoUpgradeCheckByTargetMs[targetKey];
|
|
1507
|
-
if (
|
|
1508
|
-
Number.isFinite(lastCheckAtMs) &&
|
|
1509
|
-
now - lastCheckAtMs < this.qmdAutoUpgradeCheckIntervalMs
|
|
1510
|
-
) {
|
|
1466
|
+
if (Number.isFinite(lastCheckAtMs) && now - lastCheckAtMs < this.qmdAutoUpgradeCheckIntervalMs) {
|
|
1511
1467
|
return;
|
|
1512
1468
|
}
|
|
1513
1469
|
state.lastAutoUpgradeCheckByTargetMs[targetKey] = now;
|
|
@@ -1525,7 +1481,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1525
1481
|
recordAutoUpgradeStatus(
|
|
1526
1482
|
state,
|
|
1527
1483
|
targetKey,
|
|
1528
|
-
`current: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}
|
|
1484
|
+
`current: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}`
|
|
1529
1485
|
);
|
|
1530
1486
|
return;
|
|
1531
1487
|
}
|
|
@@ -1533,7 +1489,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1533
1489
|
const status = `skipped: configured qmdPath=${this.qmdPath}`;
|
|
1534
1490
|
recordAutoUpgradeStatus(state, targetKey, status);
|
|
1535
1491
|
log.warn(
|
|
1536
|
-
`QMD auto-upgrade skipped because qmdPath is explicitly configured (${this.qmdPath}); install ${QMD_PACKAGE_NAME}@${this.qmdSupportedVersion} manually for that path
|
|
1492
|
+
`QMD auto-upgrade skipped because qmdPath is explicitly configured (${this.qmdPath}); install ${QMD_PACKAGE_NAME}@${this.qmdSupportedVersion} manually for that path.`
|
|
1537
1493
|
);
|
|
1538
1494
|
return;
|
|
1539
1495
|
}
|
|
@@ -1541,13 +1497,9 @@ export class QmdClient implements SearchBackend {
|
|
|
1541
1497
|
const packageSpec = `${QMD_PACKAGE_NAME}@${this.qmdSupportedVersion}`;
|
|
1542
1498
|
try {
|
|
1543
1499
|
log.warn(
|
|
1544
|
-
`QMD auto-upgrade: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}; running npm install -g ${packageSpec}
|
|
1545
|
-
);
|
|
1546
|
-
await runProcessCommand(
|
|
1547
|
-
"npm",
|
|
1548
|
-
["install", "-g", packageSpec],
|
|
1549
|
-
QMD_AUTO_UPGRADE_TIMEOUT_MS,
|
|
1500
|
+
`QMD auto-upgrade: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}; running npm install -g ${packageSpec}`
|
|
1550
1501
|
);
|
|
1502
|
+
await runProcessCommand("npm", ["install", "-g", packageSpec], QMD_AUTO_UPGRADE_TIMEOUT_MS);
|
|
1551
1503
|
const postInstall = await this.probePostInstallQmdVersion(supported);
|
|
1552
1504
|
this.qmdPath = postInstall.qmdPath;
|
|
1553
1505
|
this.qmdPathSource = postInstall.source;
|
|
@@ -1568,7 +1520,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1568
1520
|
recordAutoUpgradeStatus(
|
|
1569
1521
|
state,
|
|
1570
1522
|
targetKey,
|
|
1571
|
-
`upgraded: installed=${this.cliVersion ?? "unknown"} target=${this.qmdSupportedVersion}
|
|
1523
|
+
`upgraded: installed=${this.cliVersion ?? "unknown"} target=${this.qmdSupportedVersion}`
|
|
1572
1524
|
);
|
|
1573
1525
|
} catch (err) {
|
|
1574
1526
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1591,7 +1543,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1591
1543
|
QMD_PROBE_TIMEOUT_MS,
|
|
1592
1544
|
candidate.qmdPath,
|
|
1593
1545
|
undefined,
|
|
1594
|
-
this.qmdRuntimeEnv
|
|
1546
|
+
this.qmdRuntimeEnv
|
|
1595
1547
|
);
|
|
1596
1548
|
const postInstall = {
|
|
1597
1549
|
...candidate,
|
|
@@ -1623,8 +1575,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1623
1575
|
private logCliProbeWarning(message: string): void {
|
|
1624
1576
|
const state = getGlobalQmdState();
|
|
1625
1577
|
const now = Date.now();
|
|
1626
|
-
const canWarn =
|
|
1627
|
-
state.lastCliWarnAtMs === null || now - state.lastCliWarnAtMs >= QMD_CLI_WARN_THROTTLE_MS;
|
|
1578
|
+
const canWarn = state.lastCliWarnAtMs === null || now - state.lastCliWarnAtMs >= QMD_CLI_WARN_THROTTLE_MS;
|
|
1628
1579
|
if (!canWarn) {
|
|
1629
1580
|
log.debug(message);
|
|
1630
1581
|
return;
|
|
@@ -1667,8 +1618,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1667
1618
|
.join(",");
|
|
1668
1619
|
const globalState = getGlobalQmdState();
|
|
1669
1620
|
const autoUpgradeStatus =
|
|
1670
|
-
globalState.lastAutoUpgradeStatusByTarget[this.autoUpgradeTargetKey()] ??
|
|
1671
|
-
globalState.lastAutoUpgradeStatus;
|
|
1621
|
+
globalState.lastAutoUpgradeStatusByTarget[this.autoUpgradeTargetKey()] ?? globalState.lastAutoUpgradeStatus;
|
|
1672
1622
|
const probeError = this.lastCliProbeError ? ` cliProbeError=${this.lastCliProbeError}` : "";
|
|
1673
1623
|
return `cli=${this.available} daemon=${this.daemonAvailable} session=${!!this.daemonSession} cliPath=${cliPath} cliPathSource=${this.qmdPathSource} cliVersion=${cliVersion} supportedVersion=${status.supportedVersion} upgradeAvailable=${status.upgradeAvailable} qmdFeatures=${enabledFeatures || "none"}${autoUpgradeStatus ? ` autoUpgrade=${autoUpgradeStatus}` : ""}${probeError}`;
|
|
1674
1624
|
}
|
|
@@ -1729,6 +1679,18 @@ export class QmdClient implements SearchBackend {
|
|
|
1729
1679
|
return fetchQmdStatus((args, timeoutMs) => this.runQmdCommand(args, timeoutMs), this.collection, QMD_TIMEOUT_MS);
|
|
1730
1680
|
}
|
|
1731
1681
|
|
|
1682
|
+
async collectionStatus(collection: string): Promise<Pick<QmdStatusReport, "totalFiles">> {
|
|
1683
|
+
if (!this.isAvailable() || !this.qmdCapabilities.safeStatusDeviceProbe) {
|
|
1684
|
+
return { totalFiles: null };
|
|
1685
|
+
}
|
|
1686
|
+
const report = await fetchQmdStatus(
|
|
1687
|
+
(args, timeoutMs) => this.runQmdCommand(args, timeoutMs),
|
|
1688
|
+
collection,
|
|
1689
|
+
QMD_TIMEOUT_MS
|
|
1690
|
+
);
|
|
1691
|
+
return { totalFiles: report.totalFiles };
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1732
1694
|
isDaemonMode(): boolean {
|
|
1733
1695
|
return this.daemonAvailable;
|
|
1734
1696
|
}
|
|
@@ -1764,24 +1726,26 @@ export class QmdClient implements SearchBackend {
|
|
|
1764
1726
|
}
|
|
1765
1727
|
this.daemonTransientFailures += 1;
|
|
1766
1728
|
if (this.daemonTransientFailures >= QmdClient.DAEMON_MAX_TRANSIENT_FAILURES) {
|
|
1767
|
-
log.debug(
|
|
1729
|
+
log.debug(
|
|
1730
|
+
`QMD daemon ${label} failed after ${durationMs}ms (${this.daemonTransientFailures} consecutive failures, invalidating): ${err}`
|
|
1731
|
+
);
|
|
1768
1732
|
this.daemonSession?.invalidate();
|
|
1769
1733
|
this.daemonAvailable = false;
|
|
1770
1734
|
this.daemonTransientFailures = 0;
|
|
1771
1735
|
} else {
|
|
1772
|
-
log.debug(
|
|
1736
|
+
log.debug(
|
|
1737
|
+
`QMD daemon ${label} failed after ${durationMs}ms (transient ${this.daemonTransientFailures}/${QmdClient.DAEMON_MAX_TRANSIENT_FAILURES}): ${err}`
|
|
1738
|
+
);
|
|
1773
1739
|
}
|
|
1774
1740
|
}
|
|
1775
1741
|
|
|
1776
1742
|
private async runQmdCommand(
|
|
1777
1743
|
args: string[],
|
|
1778
1744
|
timeoutMs: number,
|
|
1779
|
-
signal?: AbortSignal
|
|
1745
|
+
signal?: AbortSignal
|
|
1780
1746
|
): Promise<{ stdout: string; stderr: string }> {
|
|
1781
1747
|
const commandArgs =
|
|
1782
|
-
this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection
|
|
1783
|
-
? ["--index", this.qmdIndexName, ...args]
|
|
1784
|
-
: args;
|
|
1748
|
+
this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection ? ["--index", this.qmdIndexName, ...args] : args;
|
|
1785
1749
|
return runQmd(commandArgs, timeoutMs, this.qmdPath, signal, this.qmdRuntimeEnv);
|
|
1786
1750
|
}
|
|
1787
1751
|
|
|
@@ -1887,10 +1851,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1887
1851
|
}
|
|
1888
1852
|
}
|
|
1889
1853
|
|
|
1890
|
-
private addResolvedSearchOptionsToMcpArgs(
|
|
1891
|
-
args: Record<string, unknown>,
|
|
1892
|
-
options?: SearchQueryOptions,
|
|
1893
|
-
): void {
|
|
1854
|
+
private addResolvedSearchOptionsToMcpArgs(args: Record<string, unknown>, options?: SearchQueryOptions): void {
|
|
1894
1855
|
if (options?.intent) {
|
|
1895
1856
|
args.intent = options.intent;
|
|
1896
1857
|
}
|
|
@@ -1922,7 +1883,7 @@ export class QmdClient implements SearchBackend {
|
|
|
1922
1883
|
collection?: string,
|
|
1923
1884
|
maxResults?: number,
|
|
1924
1885
|
options?: SearchQueryOptions,
|
|
1925
|
-
execution?: SearchExecutionOptions
|
|
1886
|
+
execution?: SearchExecutionOptions
|
|
1926
1887
|
): Promise<QmdSearchResult[]> {
|
|
1927
1888
|
const trimmed = query.trim();
|
|
1928
1889
|
if (!trimmed) return [];
|
|
@@ -2004,7 +1965,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2004
1965
|
(degradation) => {
|
|
2005
1966
|
subprocessDegraded = true;
|
|
2006
1967
|
this.notifyDegradation(execution?.onDegradation, degradation.code, degradation.detail);
|
|
2007
|
-
}
|
|
1968
|
+
}
|
|
2008
1969
|
);
|
|
2009
1970
|
// Never cache a degraded empty result: a 60s TTL hit would serve the
|
|
2010
1971
|
// failure as a genuine no-matches WITHOUT re-reporting the degradation
|
|
@@ -2018,7 +1979,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2018
1979
|
async searchGlobal(
|
|
2019
1980
|
query: string,
|
|
2020
1981
|
maxResults?: number,
|
|
2021
|
-
execution?: SearchExecutionOptions
|
|
1982
|
+
execution?: SearchExecutionOptions
|
|
2022
1983
|
): Promise<QmdSearchResult[]> {
|
|
2023
1984
|
const trimmed = query.trim();
|
|
2024
1985
|
if (!trimmed) return [];
|
|
@@ -2063,13 +2024,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2063
2024
|
}
|
|
2064
2025
|
|
|
2065
2026
|
// Subprocess fallback (only reached when daemon is unavailable and not loading)
|
|
2066
|
-
return this.searchGlobalViaSubprocess(
|
|
2067
|
-
trimmed,
|
|
2068
|
-
n,
|
|
2069
|
-
searchOptions,
|
|
2070
|
-
execution?.signal,
|
|
2071
|
-
execution?.onDegradation,
|
|
2072
|
-
);
|
|
2027
|
+
return this.searchGlobalViaSubprocess(trimmed, n, searchOptions, execution?.signal, execution?.onDegradation);
|
|
2073
2028
|
}
|
|
2074
2029
|
|
|
2075
2030
|
/**
|
|
@@ -2079,7 +2034,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2079
2034
|
query: string,
|
|
2080
2035
|
collection?: string,
|
|
2081
2036
|
maxResults?: number,
|
|
2082
|
-
execution?: SearchExecutionOptions
|
|
2037
|
+
execution?: SearchExecutionOptions
|
|
2083
2038
|
): Promise<QmdSearchResult[]> {
|
|
2084
2039
|
const trimmed = query.trim();
|
|
2085
2040
|
if (!trimmed) return [];
|
|
@@ -2129,7 +2084,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2129
2084
|
query: string,
|
|
2130
2085
|
collection?: string,
|
|
2131
2086
|
maxResults?: number,
|
|
2132
|
-
execution?: SearchExecutionOptions
|
|
2087
|
+
execution?: SearchExecutionOptions
|
|
2133
2088
|
): Promise<QmdSearchResult[]> {
|
|
2134
2089
|
const trimmed = query.trim();
|
|
2135
2090
|
if (!trimmed) return [];
|
|
@@ -2180,7 +2135,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2180
2135
|
query: string,
|
|
2181
2136
|
collection?: string,
|
|
2182
2137
|
maxResults?: number,
|
|
2183
|
-
execution?: SearchExecutionOptions
|
|
2138
|
+
execution?: SearchExecutionOptions
|
|
2184
2139
|
): Promise<QmdSearchResult[]> {
|
|
2185
2140
|
const n = maxResults ?? this.maxResults;
|
|
2186
2141
|
const trimmed = query.trim();
|
|
@@ -2205,9 +2160,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2205
2160
|
}
|
|
2206
2161
|
|
|
2207
2162
|
// Sort by score descending, take top N
|
|
2208
|
-
return [...merged.values()]
|
|
2209
|
-
.sort((a, b) => b.score - a.score)
|
|
2210
|
-
.slice(0, n);
|
|
2163
|
+
return [...merged.values()].sort((a, b) => b.score - a.score).slice(0, n);
|
|
2211
2164
|
}
|
|
2212
2165
|
|
|
2213
2166
|
private async searchViaDaemon(
|
|
@@ -2215,7 +2168,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2215
2168
|
collection: string | undefined,
|
|
2216
2169
|
maxResults: number,
|
|
2217
2170
|
options?: SearchQueryOptions,
|
|
2218
|
-
signal?: AbortSignal
|
|
2171
|
+
signal?: AbortSignal
|
|
2219
2172
|
): Promise<QmdSearchResult[] | null> {
|
|
2220
2173
|
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
2221
2174
|
|
|
@@ -2249,7 +2202,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2249
2202
|
|
|
2250
2203
|
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
2251
2204
|
log.warn(
|
|
2252
|
-
`SLOW QMD daemon query: durationMs=${durationMs} collection=${collection ?? "global"} maxResults=${maxResults} queryChars=${query.length} v2=${v2}
|
|
2205
|
+
`SLOW QMD daemon query: durationMs=${durationMs} collection=${collection ?? "global"} maxResults=${maxResults} queryChars=${query.length} v2=${v2}`
|
|
2253
2206
|
);
|
|
2254
2207
|
}
|
|
2255
2208
|
|
|
@@ -2279,7 +2232,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2279
2232
|
query: string,
|
|
2280
2233
|
collection: string,
|
|
2281
2234
|
maxResults: number,
|
|
2282
|
-
signal?: AbortSignal
|
|
2235
|
+
signal?: AbortSignal
|
|
2283
2236
|
): Promise<QmdSearchResult[] | null> {
|
|
2284
2237
|
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
2285
2238
|
|
|
@@ -2297,7 +2250,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2297
2250
|
limit: maxResults,
|
|
2298
2251
|
},
|
|
2299
2252
|
this.daemonTimeoutMs,
|
|
2300
|
-
signal
|
|
2253
|
+
signal
|
|
2301
2254
|
);
|
|
2302
2255
|
} else {
|
|
2303
2256
|
// QMD v1: dedicated `search` tool for BM25
|
|
@@ -2305,7 +2258,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2305
2258
|
"search",
|
|
2306
2259
|
{ query, limit: maxResults, collection },
|
|
2307
2260
|
this.daemonTimeoutMs,
|
|
2308
|
-
signal
|
|
2261
|
+
signal
|
|
2309
2262
|
);
|
|
2310
2263
|
}
|
|
2311
2264
|
const durationMs = Date.now() - startedAtMs;
|
|
@@ -2332,7 +2285,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2332
2285
|
query: string,
|
|
2333
2286
|
collection: string,
|
|
2334
2287
|
maxResults: number,
|
|
2335
|
-
signal?: AbortSignal
|
|
2288
|
+
signal?: AbortSignal
|
|
2336
2289
|
): Promise<QmdSearchResult[] | null> {
|
|
2337
2290
|
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
2338
2291
|
|
|
@@ -2350,7 +2303,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2350
2303
|
limit: maxResults,
|
|
2351
2304
|
},
|
|
2352
2305
|
this.daemonTimeoutMs,
|
|
2353
|
-
signal
|
|
2306
|
+
signal
|
|
2354
2307
|
);
|
|
2355
2308
|
} else {
|
|
2356
2309
|
// QMD v1: dedicated `vsearch` tool for vector search
|
|
@@ -2358,7 +2311,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2358
2311
|
"vsearch",
|
|
2359
2312
|
{ query, limit: maxResults, collection },
|
|
2360
2313
|
this.daemonTimeoutMs,
|
|
2361
|
-
signal
|
|
2314
|
+
signal
|
|
2362
2315
|
);
|
|
2363
2316
|
}
|
|
2364
2317
|
const durationMs = Date.now() - startedAtMs;
|
|
@@ -2390,7 +2343,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2390
2343
|
private notifyDegradation(
|
|
2391
2344
|
onDegradation: SearchExecutionOptions["onDegradation"],
|
|
2392
2345
|
code: SearchDegradation["code"],
|
|
2393
|
-
detail?: string
|
|
2346
|
+
detail?: string
|
|
2394
2347
|
): void {
|
|
2395
2348
|
if (!onDegradation) return;
|
|
2396
2349
|
try {
|
|
@@ -2437,7 +2390,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2437
2390
|
maxResults: number,
|
|
2438
2391
|
options?: SearchQueryOptions,
|
|
2439
2392
|
signal?: AbortSignal,
|
|
2440
|
-
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2393
|
+
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2441
2394
|
): Promise<QmdSearchResult[]> {
|
|
2442
2395
|
if (this.available === false) return [];
|
|
2443
2396
|
|
|
@@ -2462,7 +2415,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2462
2415
|
const durationMs = Date.now() - startedAtMs;
|
|
2463
2416
|
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
2464
2417
|
log.warn(
|
|
2465
|
-
`SLOW QMD query: durationMs=${durationMs} collection=${collection} maxResults=${maxResults} queryChars=${query.length}
|
|
2418
|
+
`SLOW QMD query: durationMs=${durationMs} collection=${collection} maxResults=${maxResults} queryChars=${query.length}`
|
|
2466
2419
|
);
|
|
2467
2420
|
}
|
|
2468
2421
|
|
|
@@ -2485,7 +2438,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2485
2438
|
collection: string,
|
|
2486
2439
|
maxResults: number,
|
|
2487
2440
|
signal?: AbortSignal,
|
|
2488
|
-
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2441
|
+
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2489
2442
|
): Promise<QmdSearchResult[]> {
|
|
2490
2443
|
if (this.available === false) return [];
|
|
2491
2444
|
const startedAtMs = Date.now();
|
|
@@ -2512,7 +2465,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2512
2465
|
collection: string,
|
|
2513
2466
|
maxResults: number,
|
|
2514
2467
|
signal?: AbortSignal,
|
|
2515
|
-
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2468
|
+
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2516
2469
|
): Promise<QmdSearchResult[]> {
|
|
2517
2470
|
if (this.available === false) return [];
|
|
2518
2471
|
const startedAtMs = Date.now();
|
|
@@ -2520,7 +2473,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2520
2473
|
const { stdout } = await this.runQmdCommand(
|
|
2521
2474
|
["vsearch", query, "-c", collection, "--json", "-n", String(maxResults)],
|
|
2522
2475
|
QMD_TIMEOUT_MS,
|
|
2523
|
-
signal
|
|
2476
|
+
signal
|
|
2524
2477
|
);
|
|
2525
2478
|
log.debug(`QMD vsearch: ${Date.now() - startedAtMs}ms`);
|
|
2526
2479
|
return parseQmdSearchStdout(stdout);
|
|
@@ -2540,7 +2493,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2540
2493
|
maxResults: number,
|
|
2541
2494
|
options?: SearchQueryOptions,
|
|
2542
2495
|
signal?: AbortSignal,
|
|
2543
|
-
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2496
|
+
onDegradation?: SearchExecutionOptions["onDegradation"]
|
|
2544
2497
|
): Promise<QmdSearchResult[]> {
|
|
2545
2498
|
if (this.available === false) return [];
|
|
2546
2499
|
|
|
@@ -2563,7 +2516,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2563
2516
|
const durationMs = Date.now() - startedAtMs;
|
|
2564
2517
|
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
2565
2518
|
log.warn(
|
|
2566
|
-
`SLOW QMD global ${bm25 ? "search" : "query"}: durationMs=${durationMs} maxResults=${maxResults} queryChars=${query.length}
|
|
2519
|
+
`SLOW QMD global ${bm25 ? "search" : "query"}: durationMs=${durationMs} maxResults=${maxResults} queryChars=${query.length}`
|
|
2567
2520
|
);
|
|
2568
2521
|
}
|
|
2569
2522
|
|
|
@@ -2580,40 +2533,26 @@ export class QmdClient implements SearchBackend {
|
|
|
2580
2533
|
}
|
|
2581
2534
|
|
|
2582
2535
|
async update(execution?: SearchExecutionOptions): Promise<void> {
|
|
2583
|
-
await this.runUpdateForCollection(
|
|
2584
|
-
this.collection,
|
|
2585
|
-
{ perCollectionThrottle: false },
|
|
2586
|
-
execution?.signal,
|
|
2587
|
-
);
|
|
2536
|
+
await this.runUpdateForCollection(this.collection, { perCollectionThrottle: false }, execution?.signal);
|
|
2588
2537
|
}
|
|
2589
2538
|
|
|
2590
2539
|
async updateStrict(execution?: SearchExecutionOptions): Promise<void> {
|
|
2591
2540
|
await this.runUpdateForCollection(
|
|
2592
2541
|
this.collection,
|
|
2593
2542
|
{ perCollectionThrottle: false, strict: true },
|
|
2594
|
-
execution?.signal
|
|
2543
|
+
execution?.signal
|
|
2595
2544
|
);
|
|
2596
2545
|
}
|
|
2597
2546
|
|
|
2598
|
-
async updateCollection(
|
|
2599
|
-
collection:
|
|
2600
|
-
execution?: SearchExecutionOptions,
|
|
2601
|
-
): Promise<void> {
|
|
2602
|
-
await this.runUpdateForCollection(
|
|
2603
|
-
collection,
|
|
2604
|
-
{ perCollectionThrottle: true },
|
|
2605
|
-
execution?.signal,
|
|
2606
|
-
);
|
|
2547
|
+
async updateCollection(collection: string, execution?: SearchExecutionOptions): Promise<void> {
|
|
2548
|
+
await this.runUpdateForCollection(collection, { perCollectionThrottle: true }, execution?.signal);
|
|
2607
2549
|
}
|
|
2608
2550
|
|
|
2609
|
-
async updateCollectionStrict(
|
|
2610
|
-
collection: string,
|
|
2611
|
-
execution?: SearchExecutionOptions,
|
|
2612
|
-
): Promise<void> {
|
|
2551
|
+
async updateCollectionStrict(collection: string, execution?: SearchExecutionOptions): Promise<void> {
|
|
2613
2552
|
await this.runUpdateForCollection(
|
|
2614
2553
|
collection,
|
|
2615
2554
|
{ perCollectionThrottle: true, strict: true, force: true },
|
|
2616
|
-
execution?.signal
|
|
2555
|
+
execution?.signal
|
|
2617
2556
|
);
|
|
2618
2557
|
}
|
|
2619
2558
|
|
|
@@ -2624,7 +2563,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2624
2563
|
private async runUpdateForCollection(
|
|
2625
2564
|
collection: string,
|
|
2626
2565
|
options: { perCollectionThrottle: boolean; strict?: boolean; force?: boolean },
|
|
2627
|
-
signal?: AbortSignal
|
|
2566
|
+
signal?: AbortSignal
|
|
2628
2567
|
): Promise<void> {
|
|
2629
2568
|
if (this.available === false) {
|
|
2630
2569
|
if (options.strict) {
|
|
@@ -2642,61 +2581,40 @@ export class QmdClient implements SearchBackend {
|
|
|
2642
2581
|
const globalState = getGlobalQmdState();
|
|
2643
2582
|
const now = Date.now();
|
|
2644
2583
|
if (!options.force && options.perCollectionThrottle) {
|
|
2645
|
-
if (
|
|
2646
|
-
globalState.lastGlobalUpdateFailAtMs &&
|
|
2647
|
-
now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS
|
|
2648
|
-
) {
|
|
2584
|
+
if (globalState.lastGlobalUpdateFailAtMs && now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
2649
2585
|
log.debug("QMD update: suppressed by global failure backoff");
|
|
2650
2586
|
if (options.strict) throw new Error("QMD update skipped by global failure backoff");
|
|
2651
2587
|
return;
|
|
2652
2588
|
}
|
|
2653
2589
|
const lastCollectionRun = globalState.lastUpdateByCollectionMs[name];
|
|
2654
|
-
if (
|
|
2655
|
-
Number.isFinite(lastCollectionRun) &&
|
|
2656
|
-
now - lastCollectionRun < this.updateMinIntervalMs
|
|
2657
|
-
) {
|
|
2590
|
+
if (Number.isFinite(lastCollectionRun) && now - lastCollectionRun < this.updateMinIntervalMs) {
|
|
2658
2591
|
log.debug(`QMD update: suppressed by per-collection min-interval gate (${name})`);
|
|
2659
2592
|
if (options.strict) throw new Error("QMD update skipped by per-collection min-interval gate");
|
|
2660
2593
|
return;
|
|
2661
2594
|
}
|
|
2662
2595
|
const lastCollectionFail = globalState.lastUpdateFailByCollectionMs[name];
|
|
2663
|
-
if (
|
|
2664
|
-
Number.isFinite(lastCollectionFail) &&
|
|
2665
|
-
now - lastCollectionFail < QMD_UPDATE_BACKOFF_MS
|
|
2666
|
-
) {
|
|
2596
|
+
if (Number.isFinite(lastCollectionFail) && now - lastCollectionFail < QMD_UPDATE_BACKOFF_MS) {
|
|
2667
2597
|
log.debug(`QMD update: suppressed by per-collection failure backoff (${name})`);
|
|
2668
2598
|
if (options.strict) throw new Error("QMD update skipped by per-collection failure backoff");
|
|
2669
2599
|
return;
|
|
2670
2600
|
}
|
|
2671
2601
|
} else if (!options.force) {
|
|
2672
|
-
if (
|
|
2673
|
-
this.lastUpdateRunAtMs &&
|
|
2674
|
-
now - this.lastUpdateRunAtMs < this.updateMinIntervalMs
|
|
2675
|
-
) {
|
|
2602
|
+
if (this.lastUpdateRunAtMs && now - this.lastUpdateRunAtMs < this.updateMinIntervalMs) {
|
|
2676
2603
|
log.debug("QMD update: suppressed due to min-interval gate");
|
|
2677
2604
|
if (options.strict) throw new Error("QMD update skipped by min-interval gate");
|
|
2678
2605
|
return;
|
|
2679
2606
|
}
|
|
2680
|
-
if (
|
|
2681
|
-
this._lastUpdateFailAtMs &&
|
|
2682
|
-
now - this._lastUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS
|
|
2683
|
-
) {
|
|
2607
|
+
if (this._lastUpdateFailAtMs && now - this._lastUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
2684
2608
|
log.debug("QMD update: suppressed due to recent failures (backoff)");
|
|
2685
2609
|
if (options.strict) throw new Error("QMD update skipped by recent failure backoff");
|
|
2686
2610
|
return;
|
|
2687
2611
|
}
|
|
2688
|
-
if (
|
|
2689
|
-
globalState.lastGlobalUpdateRunAtMs &&
|
|
2690
|
-
now - globalState.lastGlobalUpdateRunAtMs < this.updateMinIntervalMs
|
|
2691
|
-
) {
|
|
2612
|
+
if (globalState.lastGlobalUpdateRunAtMs && now - globalState.lastGlobalUpdateRunAtMs < this.updateMinIntervalMs) {
|
|
2692
2613
|
log.debug("QMD update: suppressed by global min-interval gate");
|
|
2693
2614
|
if (options.strict) throw new Error("QMD update skipped by global min-interval gate");
|
|
2694
2615
|
return;
|
|
2695
2616
|
}
|
|
2696
|
-
if (
|
|
2697
|
-
globalState.lastGlobalUpdateFailAtMs &&
|
|
2698
|
-
now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS
|
|
2699
|
-
) {
|
|
2617
|
+
if (globalState.lastGlobalUpdateFailAtMs && now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
2700
2618
|
log.debug("QMD update: suppressed by global failure backoff");
|
|
2701
2619
|
if (options.strict) throw new Error("QMD update skipped by global failure backoff");
|
|
2702
2620
|
return;
|
|
@@ -2706,7 +2624,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2706
2624
|
if (!globalState.warnedGlobalUpdateBehavior) {
|
|
2707
2625
|
globalState.warnedGlobalUpdateBehavior = true;
|
|
2708
2626
|
log.warn(
|
|
2709
|
-
"QMD update runs globally across collections in current CLI versions; Engram now rate-limits update calls to reduce gateway load."
|
|
2627
|
+
"QMD update runs globally across collections in current CLI versions; Engram now rate-limits update calls to reduce gateway load."
|
|
2710
2628
|
);
|
|
2711
2629
|
}
|
|
2712
2630
|
const startedAtMs = Date.now();
|
|
@@ -2774,7 +2692,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2774
2692
|
this.collection,
|
|
2775
2693
|
filePaths,
|
|
2776
2694
|
300_000,
|
|
2777
|
-
this.buildEmbedArgs(this.collection)
|
|
2695
|
+
this.buildEmbedArgs(this.collection)
|
|
2778
2696
|
);
|
|
2779
2697
|
if (result.ok) clearQmdResultCaches();
|
|
2780
2698
|
return result.ok;
|
|
@@ -2782,7 +2700,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2782
2700
|
|
|
2783
2701
|
private async runEmbedForCollection(
|
|
2784
2702
|
collection: string,
|
|
2785
|
-
options: { perCollectionThrottle: boolean; strict?: boolean }
|
|
2703
|
+
options: { perCollectionThrottle: boolean; strict?: boolean }
|
|
2786
2704
|
): Promise<void> {
|
|
2787
2705
|
if (this.available === false) {
|
|
2788
2706
|
if (options.strict) throw new Error("QMD unavailable");
|
|
@@ -2796,53 +2714,35 @@ export class QmdClient implements SearchBackend {
|
|
|
2796
2714
|
const globalState = getGlobalQmdState();
|
|
2797
2715
|
const now = Date.now();
|
|
2798
2716
|
if (options.perCollectionThrottle) {
|
|
2799
|
-
if (
|
|
2800
|
-
globalState.lastGlobalEmbedFailAtMs &&
|
|
2801
|
-
now - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS
|
|
2802
|
-
) {
|
|
2717
|
+
if (globalState.lastGlobalEmbedFailAtMs && now - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
2803
2718
|
log.debug(`QMD embed: suppressed by global failure backoff (${name})`);
|
|
2804
2719
|
if (options.strict) throw new Error("QMD embed skipped by global failure backoff");
|
|
2805
2720
|
return;
|
|
2806
2721
|
}
|
|
2807
2722
|
const lastCollectionRun = globalState.lastEmbedByCollectionMs[name];
|
|
2808
|
-
if (
|
|
2809
|
-
Number.isFinite(lastCollectionRun) &&
|
|
2810
|
-
now - lastCollectionRun < this.updateMinIntervalMs
|
|
2811
|
-
) {
|
|
2723
|
+
if (Number.isFinite(lastCollectionRun) && now - lastCollectionRun < this.updateMinIntervalMs) {
|
|
2812
2724
|
log.debug(`QMD embed: suppressed by per-collection min-interval gate (${name})`);
|
|
2813
2725
|
if (options.strict) throw new Error("QMD embed skipped by per-collection min-interval gate");
|
|
2814
2726
|
return;
|
|
2815
2727
|
}
|
|
2816
2728
|
const lastCollectionFail = globalState.lastEmbedFailByCollectionMs[name];
|
|
2817
|
-
if (
|
|
2818
|
-
Number.isFinite(lastCollectionFail) &&
|
|
2819
|
-
now - lastCollectionFail < QMD_EMBED_BACKOFF_MS
|
|
2820
|
-
) {
|
|
2729
|
+
if (Number.isFinite(lastCollectionFail) && now - lastCollectionFail < QMD_EMBED_BACKOFF_MS) {
|
|
2821
2730
|
log.debug(`QMD embed: suppressed by per-collection failure backoff (${name})`);
|
|
2822
2731
|
if (options.strict) throw new Error("QMD embed skipped by per-collection failure backoff");
|
|
2823
2732
|
return;
|
|
2824
2733
|
}
|
|
2825
2734
|
} else {
|
|
2826
|
-
if (
|
|
2827
|
-
this.lastEmbedFailAtMs &&
|
|
2828
|
-
now - this.lastEmbedFailAtMs < QMD_EMBED_BACKOFF_MS
|
|
2829
|
-
) {
|
|
2735
|
+
if (this.lastEmbedFailAtMs && now - this.lastEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
2830
2736
|
log.debug("QMD embed: suppressed due to recent failures (backoff)");
|
|
2831
2737
|
if (options.strict) throw new Error("QMD embed skipped by recent failure backoff");
|
|
2832
2738
|
return;
|
|
2833
2739
|
}
|
|
2834
|
-
if (
|
|
2835
|
-
globalState.lastGlobalEmbedRunAtMs &&
|
|
2836
|
-
now - globalState.lastGlobalEmbedRunAtMs < this.updateMinIntervalMs
|
|
2837
|
-
) {
|
|
2740
|
+
if (globalState.lastGlobalEmbedRunAtMs && now - globalState.lastGlobalEmbedRunAtMs < this.updateMinIntervalMs) {
|
|
2838
2741
|
log.debug("QMD embed: suppressed by global min-interval gate");
|
|
2839
2742
|
if (options.strict) throw new Error("QMD embed skipped by global min-interval gate");
|
|
2840
2743
|
return;
|
|
2841
2744
|
}
|
|
2842
|
-
if (
|
|
2843
|
-
globalState.lastGlobalEmbedFailAtMs &&
|
|
2844
|
-
now - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS
|
|
2845
|
-
) {
|
|
2745
|
+
if (globalState.lastGlobalEmbedFailAtMs && now - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
2846
2746
|
log.debug("QMD embed: suppressed by global failure backoff");
|
|
2847
2747
|
if (options.strict) throw new Error("QMD embed skipped by global failure backoff");
|
|
2848
2748
|
return;
|
|
@@ -2904,14 +2804,37 @@ export class QmdClient implements SearchBackend {
|
|
|
2904
2804
|
}
|
|
2905
2805
|
}
|
|
2906
2806
|
|
|
2807
|
+
supportsAdditionalCollections(): boolean {
|
|
2808
|
+
return true;
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
async collectionRoot(collection: string, execution?: SearchExecutionOptions): Promise<string | null> {
|
|
2812
|
+
const { stdout } = await this.runQmdCommand(
|
|
2813
|
+
["collection", "show", collection],
|
|
2814
|
+
QMD_TIMEOUT_MS,
|
|
2815
|
+
execution?.signal
|
|
2816
|
+
);
|
|
2817
|
+
const match = stdout.match(/^\s*Path:\s*(.+?)\s*$/m);
|
|
2818
|
+
return match?.[1]?.trim() || null;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
async excludeCollectionFromGlobalSearch(collection: string, execution?: SearchExecutionOptions): Promise<void> {
|
|
2822
|
+
await this.runQmdCommand(["collection", "exclude", collection], QMD_TIMEOUT_MS, execution?.signal);
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
async deleteCollection(collection: string, execution?: SearchExecutionOptions): Promise<boolean> {
|
|
2826
|
+
if (collection === this.collection) {
|
|
2827
|
+
throw new Error("Refusing to delete the primary QMD collection");
|
|
2828
|
+
}
|
|
2829
|
+
await this.runQmdCommand(["collection", "remove", collection], QMD_TIMEOUT_MS, execution?.signal);
|
|
2830
|
+
return true;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2907
2833
|
async checkCollection(
|
|
2908
2834
|
collectionOrExecution?: string | SearchExecutionOptions,
|
|
2909
|
-
execution?: SearchExecutionOptions
|
|
2835
|
+
execution?: SearchExecutionOptions
|
|
2910
2836
|
): Promise<"present" | "missing" | "unknown" | "skipped"> {
|
|
2911
|
-
const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(
|
|
2912
|
-
collectionOrExecution,
|
|
2913
|
-
execution,
|
|
2914
|
-
);
|
|
2837
|
+
const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(collectionOrExecution, execution);
|
|
2915
2838
|
if (this.available === false && !this.daemonAvailable) return "unknown";
|
|
2916
2839
|
// If only daemon is available (no CLI), skip collection check
|
|
2917
2840
|
if (this.available === false) return "skipped";
|
|
@@ -2919,10 +2842,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2919
2842
|
try {
|
|
2920
2843
|
const { stdout } = await this.runQmdCommand(["collection", "list"], QMD_TIMEOUT_MS, effectiveExecution?.signal);
|
|
2921
2844
|
// Parse text output: "openclaw-engram (qmd://openclaw-engram/)"
|
|
2922
|
-
const collectionRegex = new RegExp(
|
|
2923
|
-
`^${escapeRegExp(targetCollection)}\\s+\\(qmd://`,
|
|
2924
|
-
"m",
|
|
2925
|
-
);
|
|
2845
|
+
const collectionRegex = new RegExp(`^${escapeRegExp(targetCollection)}\\s+\\(qmd://`, "m");
|
|
2926
2846
|
if (collectionRegex.test(stdout)) {
|
|
2927
2847
|
return "present";
|
|
2928
2848
|
}
|
|
@@ -2931,7 +2851,7 @@ export class QmdClient implements SearchBackend {
|
|
|
2931
2851
|
// Treat command/probe failures as unknown so callers do not disable features
|
|
2932
2852
|
// permanently after a transient CLI or daemon hiccup.
|
|
2933
2853
|
log.debug(
|
|
2934
|
-
`QMD collection check unavailable for "${targetCollection}" (will not disable features): ${err instanceof Error ? err.message : String(err)}
|
|
2854
|
+
`QMD collection check unavailable for "${targetCollection}" (will not disable features): ${err instanceof Error ? err.message : String(err)}`
|
|
2935
2855
|
);
|
|
2936
2856
|
return "unknown";
|
|
2937
2857
|
}
|
|
@@ -2940,12 +2860,9 @@ export class QmdClient implements SearchBackend {
|
|
|
2940
2860
|
async ensureCollection(
|
|
2941
2861
|
memoryDir: string,
|
|
2942
2862
|
collectionOrExecution?: string | SearchExecutionOptions,
|
|
2943
|
-
execution?: SearchExecutionOptions
|
|
2863
|
+
execution?: SearchExecutionOptions
|
|
2944
2864
|
): Promise<"present" | "missing" | "unknown" | "skipped"> {
|
|
2945
|
-
const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(
|
|
2946
|
-
collectionOrExecution,
|
|
2947
|
-
execution,
|
|
2948
|
-
);
|
|
2865
|
+
const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(collectionOrExecution, execution);
|
|
2949
2866
|
const targetCollection = collection ?? this.collection;
|
|
2950
2867
|
const collectionState = await this.checkCollection(targetCollection, effectiveExecution);
|
|
2951
2868
|
if (collectionState !== "missing") return collectionState;
|
|
@@ -2954,37 +2871,29 @@ export class QmdClient implements SearchBackend {
|
|
|
2954
2871
|
await this.runQmdCommand(
|
|
2955
2872
|
["collection", "add", memoryDir, "--name", targetCollection],
|
|
2956
2873
|
QMD_TIMEOUT_MS,
|
|
2957
|
-
effectiveExecution?.signal
|
|
2958
|
-
);
|
|
2959
|
-
log.info(
|
|
2960
|
-
`QMD collection "${targetCollection}" auto-created at ${memoryDir}`,
|
|
2874
|
+
effectiveExecution?.signal
|
|
2961
2875
|
);
|
|
2876
|
+
log.info(`QMD collection "${targetCollection}" auto-created at ${memoryDir}`);
|
|
2962
2877
|
return "present";
|
|
2963
2878
|
} catch (err) {
|
|
2964
2879
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2965
2880
|
if (isCallerCancellation(err, effectiveExecution?.signal)) {
|
|
2966
2881
|
log.debug(
|
|
2967
|
-
`QMD collection auto-create for "${targetCollection}" was cancelled; keeping collection state unknown
|
|
2882
|
+
`QMD collection auto-create for "${targetCollection}" was cancelled; keeping collection state unknown`
|
|
2968
2883
|
);
|
|
2969
2884
|
return "unknown";
|
|
2970
2885
|
}
|
|
2971
2886
|
const postCreateState = await this.checkCollection(targetCollection, effectiveExecution);
|
|
2972
2887
|
if (postCreateState === "present") {
|
|
2973
|
-
log.info(
|
|
2974
|
-
`QMD collection "${targetCollection}" is present after auto-create failure; continuing`,
|
|
2975
|
-
);
|
|
2888
|
+
log.info(`QMD collection "${targetCollection}" is present after auto-create failure; continuing`);
|
|
2976
2889
|
return "present";
|
|
2977
2890
|
}
|
|
2978
2891
|
if (/\balready exists\b|\bexists already\b/i.test(msg)) {
|
|
2979
|
-
log.info(
|
|
2980
|
-
`QMD collection "${targetCollection}" already exists after concurrent auto-create; continuing`,
|
|
2981
|
-
);
|
|
2892
|
+
log.info(`QMD collection "${targetCollection}" already exists after concurrent auto-create; continuing`);
|
|
2982
2893
|
return "present";
|
|
2983
2894
|
}
|
|
2984
2895
|
if (postCreateState !== "missing") return postCreateState;
|
|
2985
|
-
log.warn(
|
|
2986
|
-
`QMD collection "${targetCollection}" not found and auto-create failed: ${msg}`,
|
|
2987
|
-
);
|
|
2896
|
+
log.warn(`QMD collection "${targetCollection}" not found and auto-create failed: ${msg}`);
|
|
2988
2897
|
return "missing";
|
|
2989
2898
|
}
|
|
2990
2899
|
}
|