@remnic/core 9.69.39 → 9.69.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +16 -14
- package/dist/access-admin-ops-surface.js +37 -37
- package/dist/access-authorization-probe.d.ts +16 -14
- package/dist/access-authorization-probe.js +38 -38
- package/dist/access-boundary.d.ts +16 -14
- package/dist/access-boundary.js +37 -37
- package/dist/access-cli.js +98 -97
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +16 -14
- package/dist/access-extraction-force-flush.js +37 -37
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-briefing.d.ts +16 -14
- package/dist/access-http-briefing.js +38 -38
- package/dist/access-http-lcm-compaction.d.ts +16 -14
- package/dist/access-http-lifecycle-flush.d.ts +16 -14
- package/dist/access-http-offline-stream.d.ts +16 -14
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +39 -39
- package/dist/access-http.d.ts +17 -15
- package/dist/access-http.js +53 -53
- package/dist/access-identity-continuity-surface.d.ts +13 -12
- package/dist/access-identity-continuity-surface.js +37 -37
- package/dist/access-lcm-surface.d.ts +16 -14
- package/dist/access-lcm-surface.js +37 -37
- package/dist/access-mcp.d.ts +16 -14
- package/dist/access-mcp.js +45 -45
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-DY4z6L5X.d.ts → access-namespace-preflight-CKBumJ8W.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +37 -37
- package/dist/access-observe-transcript.d.ts +13 -12
- package/dist/access-observe-write-category.d.ts +1 -1
- package/dist/access-observe-write-category.js +2 -2
- package/dist/access-observe-write-surface.d.ts +16 -14
- package/dist/access-observe-write-surface.js +37 -37
- package/dist/access-offline-manifest.d.ts +37 -13
- package/dist/access-offline-manifest.js +7 -3
- package/dist/access-operations-batch.js +39 -39
- package/dist/access-operations.d.ts +16 -14
- package/dist/access-operations.js +44 -44
- package/dist/access-recall-concurrency.d.ts +16 -14
- package/dist/access-recall-concurrency.js +37 -37
- package/dist/access-recall-response.d.ts +16 -14
- package/dist/access-recall-response.js +37 -37
- package/dist/access-recall-surface.d.ts +16 -14
- package/dist/access-recall-surface.js +37 -37
- package/dist/access-schema.d.ts +5 -3
- package/dist/access-schema.js +1 -1
- package/dist/{access-service-MY4bsr_Q.d.ts → access-service-DJ3qogNt.d.ts} +8 -8
- package/dist/access-service-helpers.d.ts +16 -14
- package/dist/access-service.d.ts +16 -14
- package/dist/access-service.js +37 -37
- package/dist/access-surface-catalog.d.ts +16 -14
- package/dist/access-surface-catalog.js +39 -39
- package/dist/access-wearables-meetings-surface.d.ts +6 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +6 -5
- package/dist/active-recall.js.map +1 -1
- package/dist/activity/digest.d.ts +1 -1
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-RP4C6ZPF.js → auto-sync-D6BAPIJV.js} +5 -5
- package/dist/background-generation-config.d.ts +1 -1
- package/dist/background-generation-config.js +3 -1
- package/dist/background-generation.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +13 -12
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +15 -15
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +5 -5
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +3 -2
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-CW87xGx8.d.ts → catalog-BHXkBVhg.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +19 -18
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-B36GUU6T.js → chunk-23HFXQ5J.js} +36 -3
- package/dist/chunk-23HFXQ5J.js.map +1 -0
- package/dist/{chunk-YFTNZMGR.js → chunk-27NO2KVB.js} +31 -8
- package/dist/chunk-27NO2KVB.js.map +1 -0
- package/dist/{chunk-JTQR6L2N.js → chunk-2SKMZUOW.js} +2 -2
- package/dist/{chunk-GG5FHZJJ.js → chunk-2SNCQHJZ.js} +2 -2
- package/dist/{chunk-O76F5QPP.js → chunk-3QEVOQF5.js} +2 -2
- package/dist/{chunk-3N3PBBEH.js → chunk-3XPN7AVY.js} +2 -2
- package/dist/{chunk-X4TD4O2F.js → chunk-46Z3VGWF.js} +2 -2
- package/dist/{chunk-2ZTDRNCS.js → chunk-4CMXI55L.js} +2 -2
- package/dist/{chunk-FWWWUPOE.js → chunk-5LYSEZOF.js} +18 -9
- package/dist/chunk-5LYSEZOF.js.map +1 -0
- package/dist/{chunk-IQEJIOEU.js → chunk-62HFZNCJ.js} +17 -10
- package/dist/chunk-62HFZNCJ.js.map +1 -0
- package/dist/{chunk-YKREX63Z.js → chunk-6L2II3KS.js} +5 -3
- package/dist/chunk-6L2II3KS.js.map +1 -0
- package/dist/{chunk-MUTVRKKY.js → chunk-7D6SER6A.js} +8 -8
- package/dist/{chunk-WBM2MVBK.js → chunk-7Z54NXVS.js} +2 -2
- package/dist/{chunk-ACY4ZPF7.js → chunk-AEOOGXMQ.js} +10 -5
- package/dist/chunk-AEOOGXMQ.js.map +1 -0
- package/dist/{chunk-UHRZ324M.js → chunk-BGRTZOJB.js} +3 -3
- package/dist/{chunk-ZEGL7YCC.js → chunk-BXIJSPCL.js} +2 -2
- package/dist/{chunk-JKKII6GX.js → chunk-BYQX4IOG.js} +2 -2
- package/dist/{chunk-WIWLX65T.js → chunk-C5R73BON.js} +2 -2
- package/dist/{chunk-BD7JTBYP.js → chunk-D7MAYFQP.js} +2 -2
- package/dist/{chunk-TNZNSMVJ.js → chunk-DAZANIYU.js} +249 -295
- package/dist/chunk-DAZANIYU.js.map +1 -0
- package/dist/{chunk-LMLGBG6H.js → chunk-DFVSJFHK.js} +2 -2
- package/dist/{chunk-3NPNBVFR.js → chunk-ES5BUPYB.js} +2 -2
- package/dist/{chunk-MVAQ2WM3.js → chunk-G2XZFGYN.js} +6 -2
- package/dist/chunk-G2XZFGYN.js.map +1 -0
- package/dist/{chunk-TNSCIPBQ.js → chunk-G6NQ3L4T.js} +2 -2
- package/dist/{chunk-5N4MZLEH.js → chunk-GO5LOHCD.js} +2 -2
- package/dist/{chunk-AECJY3GJ.js → chunk-GSSDHAYH.js} +2 -2
- package/dist/{chunk-TSP5WH72.js → chunk-HJUP3K6L.js} +2 -2
- package/dist/{chunk-AAZEKXUP.js → chunk-ICNJ6J46.js} +2 -2
- package/dist/{chunk-6EHM2AV7.js → chunk-IMBQFHRV.js} +2 -2
- package/dist/{chunk-4RZLTZVM.js → chunk-IOPIGX7Y.js} +1 -1
- package/dist/{chunk-EYKIDK33.js → chunk-IS2IDFJP.js} +13 -13
- package/dist/{chunk-VJIE4D2I.js → chunk-J4WGTN2N.js} +2 -2
- package/dist/{chunk-NXGSONWM.js → chunk-J7FVMLBR.js} +2 -2
- package/dist/{chunk-VSL63CFJ.js → chunk-JAJIMTFB.js} +6 -6
- package/dist/{chunk-4JVQRFZD.js → chunk-JOP7W24J.js} +9 -9
- package/dist/{chunk-YUW66UAH.js → chunk-JUDT33RX.js} +2 -2
- package/dist/{chunk-QHT7MOUF.js → chunk-K4A6UVPB.js} +22 -11
- package/dist/chunk-K4A6UVPB.js.map +1 -0
- package/dist/{chunk-D545Z7UH.js → chunk-K4JKAXMO.js} +2 -2
- package/dist/{chunk-BV4ZKIZH.js → chunk-K75A5XWU.js} +3 -2
- package/dist/{chunk-3CBI2ZSA.js → chunk-KG2OOAFF.js} +20 -12
- package/dist/chunk-KG2OOAFF.js.map +1 -0
- package/dist/{chunk-M6HBPLBA.js → chunk-KOTG3RXE.js} +2 -2
- package/dist/{chunk-CWTCMZGE.js → chunk-KTOXQMW3.js} +119 -3
- package/dist/chunk-KTOXQMW3.js.map +1 -0
- package/dist/{chunk-OB3XMWX5.js → chunk-KVO2BTA4.js} +2 -2
- package/dist/{chunk-GI4ZBWPQ.js → chunk-KY236SP5.js} +3 -3
- package/dist/{chunk-4BCHFSC7.js → chunk-LFVZD5EC.js} +3 -3
- package/dist/{chunk-O4M4BDIJ.js → chunk-LKFVVN7R.js} +2 -2
- package/dist/{chunk-IYKZJVL5.js → chunk-MDIEES23.js} +1 -1
- package/dist/chunk-MDIEES23.js.map +1 -0
- package/dist/{chunk-4RX5O34R.js → chunk-MJC7UKH7.js} +2 -2
- package/dist/{chunk-CZTPU65V.js → chunk-MVG3KXON.js} +63 -16
- package/dist/chunk-MVG3KXON.js.map +1 -0
- package/dist/{chunk-YDVAM7S4.js → chunk-NETQXOPY.js} +2 -2
- package/dist/chunk-NETQXOPY.js.map +1 -0
- package/dist/{chunk-UZZ7SQT3.js → chunk-NVVZPBKI.js} +2 -2
- package/dist/{chunk-BLDBT6HZ.js → chunk-PJRKLB4Z.js} +18 -2
- package/dist/chunk-PJRKLB4Z.js.map +1 -0
- package/dist/{chunk-VBSNUH4J.js → chunk-PKUJNICO.js} +2 -2
- package/dist/{chunk-OPBFP4TF.js → chunk-QE6YVNP5.js} +7 -7
- package/dist/{chunk-WKDFJXW5.js → chunk-QM2SPLKQ.js} +1 -1
- package/dist/chunk-QM2SPLKQ.js.map +1 -0
- package/dist/{chunk-ENBPQEVU.js → chunk-QPVNK2VE.js} +2 -2
- package/dist/{chunk-RLJHJQUY.js → chunk-QS5Q5RBV.js} +2 -2
- package/dist/{chunk-3EKVN2OP.js → chunk-RDLPFM7I.js} +2 -2
- package/dist/{chunk-F4EHXVP7.js → chunk-RJQAP333.js} +2 -2
- package/dist/{chunk-QTQ6XKGT.js → chunk-RLU2Y5GV.js} +4 -4
- package/dist/chunk-RLU2Y5GV.js.map +1 -0
- package/dist/{chunk-5SPCMAUC.js → chunk-ROEFLU37.js} +4 -4
- package/dist/{chunk-UZEHHXYC.js → chunk-SFHLQPBF.js} +22 -22
- package/dist/chunk-SK7D34OL.js +68 -0
- package/dist/chunk-SK7D34OL.js.map +1 -0
- package/dist/{chunk-ZBW7A667.js → chunk-SUEOG2S4.js} +2 -2
- package/dist/{chunk-Q7CLGFA7.js → chunk-TEMKBSV6.js} +2 -2
- package/dist/{chunk-LQNRVPTV.js → chunk-THTF2W7M.js} +151 -118
- package/dist/chunk-THTF2W7M.js.map +1 -0
- package/dist/{chunk-GMIQV6DD.js → chunk-TO36VPZI.js} +2 -2
- package/dist/{chunk-6YAIN5XJ.js → chunk-TZ44E732.js} +44 -6
- package/dist/chunk-TZ44E732.js.map +1 -0
- package/dist/{chunk-JXN77SGO.js → chunk-U2VDCFXW.js} +1 -1
- package/dist/chunk-U2VDCFXW.js.map +1 -0
- package/dist/{chunk-LPYYY4AP.js → chunk-UZ6JYPJ6.js} +500 -218
- package/dist/chunk-UZ6JYPJ6.js.map +1 -0
- package/dist/{chunk-FXHOZGSE.js → chunk-V2ZA4YWE.js} +2 -2
- package/dist/{chunk-XH3HGI2N.js → chunk-VHKXRYQN.js} +2 -2
- package/dist/{chunk-GAS7KYC7.js → chunk-VKWFNPBH.js} +2 -2
- package/dist/{chunk-6H2G7RFT.js → chunk-VNQRRUNS.js} +11 -10
- package/dist/chunk-VNQRRUNS.js.map +1 -0
- package/dist/{chunk-IL6ODG6M.js → chunk-VQWBUPSJ.js} +2 -2
- package/dist/{chunk-5YCNDC3C.js → chunk-VQYWKCDR.js} +2 -2
- package/dist/{chunk-54NX5EG4.js → chunk-W23JARAQ.js} +2 -2
- package/dist/{chunk-YQNNHLCG.js → chunk-WPGR3RW4.js} +2 -2
- package/dist/{chunk-FNHLI2RE.js → chunk-WZYHPAG5.js} +3 -3
- package/dist/{chunk-5HYUUFMQ.js → chunk-XCPNH2MG.js} +259 -10
- package/dist/chunk-XCPNH2MG.js.map +1 -0
- package/dist/{chunk-TA4C3XB7.js → chunk-XM46Y66S.js} +2 -2
- package/dist/{chunk-PCOVEDPK.js → chunk-YRIFXXMI.js} +3 -3
- package/dist/{chunk-TRLOFIQC.js → chunk-YTK5MVNF.js} +2 -2
- package/dist/{chunk-Q432REND.js → chunk-YTZN2UZO.js} +2 -2
- package/dist/{chunk-6AGWBKQU.js → chunk-Z4GUX2M6.js} +2 -2
- package/dist/{chunk-AENM6GKU.js → chunk-ZAEPD4C2.js} +2 -2
- package/dist/{chunk-KQW3YGEN.js → chunk-ZRMMXWYI.js} +2 -2
- package/dist/{chunk-P4ZAEYKG.js → chunk-ZX3AYNNV.js} +6 -3
- package/dist/chunk-ZX3AYNNV.js.map +1 -0
- package/dist/{chunk-MCRVQ5YQ.js → chunk-ZZCR2QYL.js} +2 -2
- package/dist/{cli-DGq0MNpO.d.ts → cli-BWri5-am.d.ts} +5 -5
- package/dist/cli.d.ts +18 -16
- package/dist/cli.js +75 -74
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +14 -14
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +15 -15
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +6 -5
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +15 -15
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +15 -15
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +6 -5
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +17 -17
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +17 -17
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/deep-recall-http-glue.d.ts +16 -14
- package/dist/deep-recall-http-glue.js +2 -2
- package/dist/deep-recall-mcp-tools.d.ts +16 -14
- package/dist/deep-recall-policy-llm.d.ts +4 -3
- package/dist/deep-recall-policy-llm.js +3 -3
- package/dist/deep-recall-seeds.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-Cq1ekOwV.d.ts → dependency-propagation-delivery-ueZlKTQB.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +15 -15
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +13 -12
- package/dist/external-wiki-access.d.ts +16 -14
- package/dist/external-wiki-access.js +38 -38
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +16 -14
- package/dist/extraction-error-classification.d.ts +14 -3
- package/dist/extraction-error-classification.js +5 -3
- package/dist/extraction-faithfulness.d.ts +4 -3
- package/dist/extraction-faithfulness.js +3 -3
- package/dist/extraction-judge-telemetry.d.ts +4 -3
- package/dist/extraction-judge-training.d.ts +4 -3
- package/dist/extraction-judge.d.ts +4 -3
- package/dist/extraction-judge.js +3 -3
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction-span-config.d.ts +1 -1
- package/dist/extraction-span-materialize.d.ts +1 -1
- package/dist/extraction.d.ts +4 -4
- package/dist/extraction.js +25 -23
- package/dist/fallback-llm-codex-subscription.d.ts +52 -7
- package/dist/fallback-llm-codex-subscription.js +17 -1
- package/dist/fallback-llm.d.ts +25 -28
- package/dist/fallback-llm.js +4 -3
- package/dist/{generic-recall-paths-BcySh_f9.d.ts → generic-recall-paths-CpyVmA88.d.ts} +1 -1
- package/dist/graph-append-error.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-jsonl.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/importers/test-utils.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-DWOb4wz9.d.ts → index-BvUA4S7M.d.ts} +3 -3
- package/dist/index.d.ts +79 -39
- package/dist/index.js +119 -103
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +3 -3
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm-BsJGulur.d.ts +247 -0
- package/dist/local-llm-config.d.ts +4 -1
- package/dist/local-llm-config.js +4 -2
- package/dist/local-llm-helpers.d.ts +18 -69
- package/dist/local-llm-helpers.js +1 -1
- package/dist/local-llm.d.ts +3 -170
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +3 -3
- package/dist/location/index.js +17 -17
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +15 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +15 -15
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +16 -16
- package/dist/{maintenance-CW9wCzMP.d.ts → maintenance-CYubtIRr.d.ts} +9 -3
- package/dist/mcp-memory-inspector-app.d.ts +16 -14
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-controller.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +16 -14
- package/dist/memory-subject.d.ts +16 -14
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +16 -16
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +12 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +15 -15
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +18 -18
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +29 -28
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +26 -26
- package/dist/{orchestrator-ComHLm49.d.ts → orchestrator-BWDRJ_0d.d.ts} +24 -11
- package/dist/orchestrator.d.ts +13 -12
- package/dist/orchestrator.js +101 -98
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CiYcqqhl.d.ts → pipeline-7JMn2yMH.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +2 -2
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-CuK4_Cb1.d.ts → public-http-CJWs3mo9.d.ts} +1 -1
- package/dist/{qmd-qXD4vatU.d.ts → qmd-CxCH9G9m.d.ts} +2 -2
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/qmd.js +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-navigate-access.d.ts +1 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +1 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +1 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +3 -2
- package/dist/recall-planner-llm.js +4 -3
- package/dist/recall-planner-llm.js.map +1 -1
- package/dist/recall-state-view-admission.d.ts +13 -3
- package/dist/recall-state-view-admission.js +8 -8
- package/dist/recall-state-view-anchors.d.ts +1 -1
- package/dist/recall-state-view-anchors.js +2 -2
- package/dist/recall-state-view-inject.js +2 -2
- package/dist/recall-state-view-render.js +2 -2
- package/dist/recall-state-view-widen.js +2 -2
- package/dist/recall-state-view-wire.js +3 -3
- package/dist/recall-state-view.d.ts +1 -0
- package/dist/recall-state-view.js +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +7 -6
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-BT9rqC3w.d.ts → scope-profiles-BGAUqhBR.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +2 -2
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/{semantic-consolidation-CmZi7thY.d.ts → semantic-consolidation-CCeRD9pV.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +16 -16
- package/dist/semantic-rule-promotion.js +15 -15
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +15 -15
- package/dist/{service-CLkA7AQB.d.ts → service-BwpzRduk.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +18 -18
- package/dist/standup/build.js +15 -15
- package/dist/{storage-wvX01lht.d.ts → storage-BprAGBG0.d.ts} +2 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +14 -14
- package/dist/subject-config.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +18 -17
- package/dist/support-passport/index.js +40 -40
- package/dist/task-llm-config.d.ts +16 -0
- package/dist/task-llm-config.js +12 -0
- package/dist/task-llm-config.js.map +1 -0
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +15 -15
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-Cyr32ABj.d.ts → types-nJV23pa3.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +15 -15
- package/dist/who-knows-cli.d.ts +16 -14
- package/dist/who-knows-cli.js +16 -16
- package/dist/who-knows.d.ts +16 -14
- package/dist/who-knows.js +15 -15
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-category-alias.test.ts +93 -0
- package/src/access-offline-manifest.ts +52 -2
- package/src/access-schema.ts +9 -4
- package/src/activity/config.test.ts +61 -0
- package/src/activity/config.ts +40 -1
- package/src/activity/timeline/analysis-provider.ts +8 -2
- package/src/activity/timeline/analysis-run.test.ts +82 -0
- package/src/activity/timeline/publish-cli.test.ts +30 -0
- package/src/activity/timeline/publish-cli.ts +7 -0
- package/src/activity/timeline/query.ts +8 -1
- package/src/activity/timeline/regenerate.test.ts +82 -2
- package/src/activity/timeline/regenerate.ts +7 -1
- package/src/activity/vault-frontmatter.test.ts +99 -1
- package/src/activity/vault-frontmatter.ts +131 -0
- package/src/activity/vault-publish.ts +6 -0
- package/src/activity/vault-publisher.test.ts +172 -0
- package/src/activity/vault-publisher.ts +69 -15
- package/src/activity/vault-region.test.ts +7 -2
- package/src/activity/vault-region.ts +7 -3
- package/src/background-generation-config.ts +32 -6
- package/src/background-generation.test.ts +10 -1
- package/src/cli/timeline-publish-commands.ts +9 -0
- package/src/config.test.ts +170 -43
- package/src/config.ts +17 -5
- package/src/extraction-error-classification.ts +36 -1
- package/src/extraction-timeout.test.ts +110 -1
- package/src/extraction.test.ts +19 -1
- package/src/extraction.ts +23 -21
- package/src/fallback-llm-codex-subscription.ts +193 -7
- package/src/fallback-llm-parse-failure.test.ts +156 -0
- package/src/fallback-llm.test.ts +58 -0
- package/src/fallback-llm.ts +187 -186
- package/src/index.ts +1 -0
- package/src/local-llm-config.ts +11 -10
- package/src/local-llm-headers-timeout.test.ts +30 -0
- package/src/local-llm-helpers.ts +28 -0
- package/src/local-llm.ts +8 -19
- package/src/namespaces/search.test.ts +51 -1
- package/src/namespaces/search.ts +48 -3
- package/src/orchestration/extraction-persist-promotion.test.ts +228 -2
- package/src/orchestration/extraction-persist-promotion.ts +17 -14
- package/src/orchestration/orchestrator-helpers.test.ts +104 -0
- package/src/orchestration/orchestrator-init.ts +366 -106
- package/src/orchestration/recall-internal.ts +5 -11
- package/src/orchestration/semantic-merge-promotion-payload.ts +62 -6
- package/src/orchestration/startup-collection-checks.ts +85 -0
- package/src/orchestrator-flush.test.ts +7 -0
- package/src/orchestrator-init.test.ts +1539 -0
- package/src/orchestrator.ts +7 -0
- package/src/qmd.ts +21 -10
- package/src/recall-state-view-admission.ts +11 -1
- package/src/recall-state-view-cron-intent.test.ts +268 -0
- package/src/recall-state-view-widen.test.ts +14 -5
- package/src/recall-state-view-widen.ts +8 -1
- package/src/recall-state-view.ts +5 -2
- package/src/reconcile-identity-cache.test.ts +82 -1
- package/src/search/port.ts +1 -1
- package/src/storage/cas-revision-store.test.ts +4 -0
- package/src/storage/cas-revision-store.ts +104 -12
- package/src/storage-frontmatter-cas.test.ts +19 -17
- package/src/summarizer.ts +5 -1
- package/src/task-llm-config.test.ts +124 -0
- package/src/task-llm-config.ts +88 -0
- package/src/testing/subjects/startup-discovery-lifecycle.test.ts +273 -0
- package/src/types.ts +1 -0
- package/dist/chunk-3CBI2ZSA.js.map +0 -1
- package/dist/chunk-5HYUUFMQ.js.map +0 -1
- package/dist/chunk-6H2G7RFT.js.map +0 -1
- package/dist/chunk-6YAIN5XJ.js.map +0 -1
- package/dist/chunk-ACY4ZPF7.js.map +0 -1
- package/dist/chunk-B36GUU6T.js.map +0 -1
- package/dist/chunk-BLDBT6HZ.js.map +0 -1
- package/dist/chunk-CWTCMZGE.js.map +0 -1
- package/dist/chunk-CZTPU65V.js.map +0 -1
- package/dist/chunk-FWWWUPOE.js.map +0 -1
- package/dist/chunk-IQEJIOEU.js.map +0 -1
- package/dist/chunk-IYKZJVL5.js.map +0 -1
- package/dist/chunk-JXN77SGO.js.map +0 -1
- package/dist/chunk-LPYYY4AP.js.map +0 -1
- package/dist/chunk-LQNRVPTV.js.map +0 -1
- package/dist/chunk-MVAQ2WM3.js.map +0 -1
- package/dist/chunk-P4ZAEYKG.js.map +0 -1
- package/dist/chunk-QHT7MOUF.js.map +0 -1
- package/dist/chunk-QTQ6XKGT.js.map +0 -1
- package/dist/chunk-TNZNSMVJ.js.map +0 -1
- package/dist/chunk-WKDFJXW5.js.map +0 -1
- package/dist/chunk-YDVAM7S4.js.map +0 -1
- package/dist/chunk-YFTNZMGR.js.map +0 -1
- package/dist/chunk-YKREX63Z.js.map +0 -1
- /package/dist/{auto-sync-RP4C6ZPF.js.map → auto-sync-D6BAPIJV.js.map} +0 -0
- /package/dist/{chunk-JTQR6L2N.js.map → chunk-2SKMZUOW.js.map} +0 -0
- /package/dist/{chunk-GG5FHZJJ.js.map → chunk-2SNCQHJZ.js.map} +0 -0
- /package/dist/{chunk-O76F5QPP.js.map → chunk-3QEVOQF5.js.map} +0 -0
- /package/dist/{chunk-3N3PBBEH.js.map → chunk-3XPN7AVY.js.map} +0 -0
- /package/dist/{chunk-X4TD4O2F.js.map → chunk-46Z3VGWF.js.map} +0 -0
- /package/dist/{chunk-2ZTDRNCS.js.map → chunk-4CMXI55L.js.map} +0 -0
- /package/dist/{chunk-MUTVRKKY.js.map → chunk-7D6SER6A.js.map} +0 -0
- /package/dist/{chunk-WBM2MVBK.js.map → chunk-7Z54NXVS.js.map} +0 -0
- /package/dist/{chunk-UHRZ324M.js.map → chunk-BGRTZOJB.js.map} +0 -0
- /package/dist/{chunk-ZEGL7YCC.js.map → chunk-BXIJSPCL.js.map} +0 -0
- /package/dist/{chunk-JKKII6GX.js.map → chunk-BYQX4IOG.js.map} +0 -0
- /package/dist/{chunk-WIWLX65T.js.map → chunk-C5R73BON.js.map} +0 -0
- /package/dist/{chunk-BD7JTBYP.js.map → chunk-D7MAYFQP.js.map} +0 -0
- /package/dist/{chunk-LMLGBG6H.js.map → chunk-DFVSJFHK.js.map} +0 -0
- /package/dist/{chunk-3NPNBVFR.js.map → chunk-ES5BUPYB.js.map} +0 -0
- /package/dist/{chunk-TNSCIPBQ.js.map → chunk-G6NQ3L4T.js.map} +0 -0
- /package/dist/{chunk-5N4MZLEH.js.map → chunk-GO5LOHCD.js.map} +0 -0
- /package/dist/{chunk-AECJY3GJ.js.map → chunk-GSSDHAYH.js.map} +0 -0
- /package/dist/{chunk-TSP5WH72.js.map → chunk-HJUP3K6L.js.map} +0 -0
- /package/dist/{chunk-AAZEKXUP.js.map → chunk-ICNJ6J46.js.map} +0 -0
- /package/dist/{chunk-6EHM2AV7.js.map → chunk-IMBQFHRV.js.map} +0 -0
- /package/dist/{chunk-4RZLTZVM.js.map → chunk-IOPIGX7Y.js.map} +0 -0
- /package/dist/{chunk-EYKIDK33.js.map → chunk-IS2IDFJP.js.map} +0 -0
- /package/dist/{chunk-VJIE4D2I.js.map → chunk-J4WGTN2N.js.map} +0 -0
- /package/dist/{chunk-NXGSONWM.js.map → chunk-J7FVMLBR.js.map} +0 -0
- /package/dist/{chunk-VSL63CFJ.js.map → chunk-JAJIMTFB.js.map} +0 -0
- /package/dist/{chunk-4JVQRFZD.js.map → chunk-JOP7W24J.js.map} +0 -0
- /package/dist/{chunk-YUW66UAH.js.map → chunk-JUDT33RX.js.map} +0 -0
- /package/dist/{chunk-D545Z7UH.js.map → chunk-K4JKAXMO.js.map} +0 -0
- /package/dist/{chunk-BV4ZKIZH.js.map → chunk-K75A5XWU.js.map} +0 -0
- /package/dist/{chunk-M6HBPLBA.js.map → chunk-KOTG3RXE.js.map} +0 -0
- /package/dist/{chunk-OB3XMWX5.js.map → chunk-KVO2BTA4.js.map} +0 -0
- /package/dist/{chunk-GI4ZBWPQ.js.map → chunk-KY236SP5.js.map} +0 -0
- /package/dist/{chunk-4BCHFSC7.js.map → chunk-LFVZD5EC.js.map} +0 -0
- /package/dist/{chunk-O4M4BDIJ.js.map → chunk-LKFVVN7R.js.map} +0 -0
- /package/dist/{chunk-4RX5O34R.js.map → chunk-MJC7UKH7.js.map} +0 -0
- /package/dist/{chunk-UZZ7SQT3.js.map → chunk-NVVZPBKI.js.map} +0 -0
- /package/dist/{chunk-VBSNUH4J.js.map → chunk-PKUJNICO.js.map} +0 -0
- /package/dist/{chunk-OPBFP4TF.js.map → chunk-QE6YVNP5.js.map} +0 -0
- /package/dist/{chunk-ENBPQEVU.js.map → chunk-QPVNK2VE.js.map} +0 -0
- /package/dist/{chunk-RLJHJQUY.js.map → chunk-QS5Q5RBV.js.map} +0 -0
- /package/dist/{chunk-3EKVN2OP.js.map → chunk-RDLPFM7I.js.map} +0 -0
- /package/dist/{chunk-F4EHXVP7.js.map → chunk-RJQAP333.js.map} +0 -0
- /package/dist/{chunk-5SPCMAUC.js.map → chunk-ROEFLU37.js.map} +0 -0
- /package/dist/{chunk-UZEHHXYC.js.map → chunk-SFHLQPBF.js.map} +0 -0
- /package/dist/{chunk-ZBW7A667.js.map → chunk-SUEOG2S4.js.map} +0 -0
- /package/dist/{chunk-Q7CLGFA7.js.map → chunk-TEMKBSV6.js.map} +0 -0
- /package/dist/{chunk-GMIQV6DD.js.map → chunk-TO36VPZI.js.map} +0 -0
- /package/dist/{chunk-FXHOZGSE.js.map → chunk-V2ZA4YWE.js.map} +0 -0
- /package/dist/{chunk-XH3HGI2N.js.map → chunk-VHKXRYQN.js.map} +0 -0
- /package/dist/{chunk-GAS7KYC7.js.map → chunk-VKWFNPBH.js.map} +0 -0
- /package/dist/{chunk-IL6ODG6M.js.map → chunk-VQWBUPSJ.js.map} +0 -0
- /package/dist/{chunk-5YCNDC3C.js.map → chunk-VQYWKCDR.js.map} +0 -0
- /package/dist/{chunk-54NX5EG4.js.map → chunk-W23JARAQ.js.map} +0 -0
- /package/dist/{chunk-YQNNHLCG.js.map → chunk-WPGR3RW4.js.map} +0 -0
- /package/dist/{chunk-FNHLI2RE.js.map → chunk-WZYHPAG5.js.map} +0 -0
- /package/dist/{chunk-TA4C3XB7.js.map → chunk-XM46Y66S.js.map} +0 -0
- /package/dist/{chunk-PCOVEDPK.js.map → chunk-YRIFXXMI.js.map} +0 -0
- /package/dist/{chunk-TRLOFIQC.js.map → chunk-YTK5MVNF.js.map} +0 -0
- /package/dist/{chunk-Q432REND.js.map → chunk-YTZN2UZO.js.map} +0 -0
- /package/dist/{chunk-6AGWBKQU.js.map → chunk-Z4GUX2M6.js.map} +0 -0
- /package/dist/{chunk-AENM6GKU.js.map → chunk-ZAEPD4C2.js.map} +0 -0
- /package/dist/{chunk-KQW3YGEN.js.map → chunk-ZRMMXWYI.js.map} +0 -0
- /package/dist/{chunk-MCRVQ5YQ.js.map → chunk-ZZCR2QYL.js.map} +0 -0
|
@@ -19,7 +19,12 @@ import { chmodSync, chownSync, lstatSync, mkdirSync, readFileSync, realpathSync,
|
|
|
19
19
|
import path from "node:path";
|
|
20
20
|
|
|
21
21
|
import { expandTildePath } from "../utils/path.js";
|
|
22
|
-
import { applyManagedRegion, fileLines } from "./vault-publish.js";
|
|
22
|
+
import { applyManagedRegion, fileLines, headingSurvivesRoundTrip } from "./vault-publish.js";
|
|
23
|
+
import {
|
|
24
|
+
renderVaultPropertyValue,
|
|
25
|
+
validateVaultProperties,
|
|
26
|
+
type VaultPropertyValue,
|
|
27
|
+
} from "./vault-frontmatter.js";
|
|
23
28
|
import { insertMarkersUnderHeading } from "./vault-insert.js";
|
|
24
29
|
import { validateRegionName } from "./vault-region.js";
|
|
25
30
|
import { assertBeginEndPair } from "./vault-region-pair.js";
|
|
@@ -37,8 +42,8 @@ export interface VaultSectionPublish {
|
|
|
37
42
|
name: string;
|
|
38
43
|
/** Rendered artifact body the region owns. */
|
|
39
44
|
content: string;
|
|
40
|
-
/** Unprefixed stats, e.g. `{ focus_minutes: "220" }`; keys get the configured prefix. */
|
|
41
|
-
properties?: Readonly<Record<string,
|
|
45
|
+
/** Unprefixed stats, e.g. `{ focus_minutes: "220" }`; keys get the configured prefix. Values are plain single-line scalars or lists of them (vault-frontmatter.ts). */
|
|
46
|
+
properties?: Readonly<Record<string, VaultPropertyValue>>;
|
|
42
47
|
/** When present, a provenance footer line is appended inside the region. */
|
|
43
48
|
provenance?: VaultSectionProvenance;
|
|
44
49
|
}
|
|
@@ -97,6 +102,48 @@ export function publishVaultNote(input: PublishVaultNoteInput): VaultPublishStat
|
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
|
|
105
|
+
|
|
106
|
+
// Issue #2917: input boundaries are total and run BEFORE any note byte
|
|
107
|
+
// is read or written, so a rejection can never leave a half-merged
|
|
108
|
+
// note behind.
|
|
109
|
+
|
|
110
|
+
// The heading strategy matches a section by scanning note headings with
|
|
111
|
+
// the shared ATX parser (`applyHeadingRegion`/`insertMarkersUnderHeading`).
|
|
112
|
+
// A name whose rendered heading parses back to something else — a
|
|
113
|
+
// trailing `#` run is stripped as a closing sequence (`## Timeline #`
|
|
114
|
+
// reads as `Timeline`) — can never be matched, so every publish would
|
|
115
|
+
// no-op or mis-scope. Reject it here rather than at match time.
|
|
116
|
+
const headingsToProbe =
|
|
117
|
+
strategy === "heading" ? input.sections.map((section) => section.name) : [];
|
|
118
|
+
if (typeof input.insertUnderHeading === "string" && input.insertUnderHeading.length > 0) {
|
|
119
|
+
headingsToProbe.push(input.insertUnderHeading);
|
|
120
|
+
}
|
|
121
|
+
for (const headingName of headingsToProbe) {
|
|
122
|
+
if (!headingSurvivesRoundTrip(headingName)) {
|
|
123
|
+
throw new RangeError(
|
|
124
|
+
`Section name ${JSON.stringify(headingName)} is not matchable by the heading parser; it must survive a render-and-parse round trip.`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Property values land in note frontmatter or inline fields; validate
|
|
130
|
+
// their shape and bounds (vault-frontmatter.ts) against the final
|
|
131
|
+
// prefixed keys, in every mode, before any file access.
|
|
132
|
+
const propertyEntries: Array<{ key: string; value: VaultPropertyValue }> = [];
|
|
133
|
+
for (const section of input.sections) {
|
|
134
|
+
if (!section.properties) continue;
|
|
135
|
+
for (const key of Object.keys(section.properties)) {
|
|
136
|
+
const value = section.properties[key];
|
|
137
|
+
if (value === undefined) continue;
|
|
138
|
+
propertyEntries.push({ key: `${prefix}${key}`, value });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (propertyEntries.length > 0) {
|
|
142
|
+
const checked = validateVaultProperties(propertyEntries);
|
|
143
|
+
if (!checked.ok) {
|
|
144
|
+
throw new RangeError(`Vault publish properties rejected: ${checked.reason}.`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
100
147
|
const relative = resolveVaultNotePath(input.notePathTemplate, input.date);
|
|
101
148
|
const result = publishRelative(input, relative, { strategy, propertiesMode, prefix });
|
|
102
149
|
return summarizeVaultPublish(result);
|
|
@@ -262,13 +309,13 @@ function refuse(relative: string, outcome: "skipped" | "error", reason: string):
|
|
|
262
309
|
|
|
263
310
|
function decorate(
|
|
264
311
|
section: VaultSectionPublish,
|
|
265
|
-
prefixed: Record<string,
|
|
312
|
+
prefixed: Record<string, VaultPropertyValue> | undefined,
|
|
266
313
|
mode: string,
|
|
267
314
|
): string {
|
|
268
315
|
const parts: string[] = [section.content];
|
|
269
316
|
if (prefixed !== undefined && mode === "dataview-inline") {
|
|
270
317
|
for (const [key, value] of Object.entries(prefixed)) {
|
|
271
|
-
parts.push(`${key}:: ${value}`);
|
|
318
|
+
parts.push(`${key}:: ${renderVaultPropertyValue(value)}`);
|
|
272
319
|
}
|
|
273
320
|
}
|
|
274
321
|
if (section.provenance !== undefined) {
|
|
@@ -388,8 +435,8 @@ function looksLikeRemnicMarkerLine(trimmed: string): boolean {
|
|
|
388
435
|
function frontmatterUpdates(
|
|
389
436
|
sections: readonly VaultSectionPublish[],
|
|
390
437
|
prefix: string,
|
|
391
|
-
): Record<string,
|
|
392
|
-
const updates: Record<string,
|
|
438
|
+
): Record<string, VaultPropertyValue> {
|
|
439
|
+
const updates: Record<string, VaultPropertyValue> = {};
|
|
393
440
|
for (const section of sections) {
|
|
394
441
|
if (!section.properties) continue;
|
|
395
442
|
for (const [key, value] of Object.entries(section.properties)) {
|
|
@@ -406,14 +453,16 @@ function frontmatterUpdates(
|
|
|
406
453
|
*/
|
|
407
454
|
export function mergeFrontmatterKeys(
|
|
408
455
|
noteText: string,
|
|
409
|
-
updates: Readonly<Record<string,
|
|
456
|
+
updates: Readonly<Record<string, VaultPropertyValue>>,
|
|
410
457
|
): { ok: true; text: string } | { ok: false; reason: string } {
|
|
411
458
|
const entries = Object.entries(updates);
|
|
412
459
|
if (entries.length === 0) return { ok: true, text: noteText };
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
460
|
+
// The writer re-validates the same boundary the publisher entry checked
|
|
461
|
+
// (issue #2917): this function is exported, so a direct caller must not
|
|
462
|
+
// be able to smuggle a newline-bearing or unbounded value into a note.
|
|
463
|
+
const checked = validateVaultProperties(entries.map(([key, value]) => ({ key, value })));
|
|
464
|
+
if (!checked.ok) {
|
|
465
|
+
return { ok: false, reason: "invalid_property" };
|
|
417
466
|
}
|
|
418
467
|
|
|
419
468
|
const eol = noteText.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -422,7 +471,12 @@ export function mergeFrontmatterKeys(
|
|
|
422
471
|
const firstLine = firstLineEnd === -1 ? noteText : noteText.slice(0, firstLineEnd);
|
|
423
472
|
|
|
424
473
|
if (!openRe.test(firstLine)) {
|
|
425
|
-
const block = [
|
|
474
|
+
const block = [
|
|
475
|
+
"---",
|
|
476
|
+
...entries.map(([key, value]) => `${key}: ${renderVaultPropertyValue(value)}`),
|
|
477
|
+
"---",
|
|
478
|
+
"",
|
|
479
|
+
].join(eol);
|
|
426
480
|
return { ok: true, text: block + eol + noteText };
|
|
427
481
|
}
|
|
428
482
|
|
|
@@ -451,13 +505,13 @@ export function mergeFrontmatterKeys(
|
|
|
451
505
|
if (rawKey !== rawKey.trimStart()) continue;
|
|
452
506
|
const key = rawKey.trimEnd();
|
|
453
507
|
if (!pending.has(key)) continue;
|
|
454
|
-
lines[i] = `${rawKey}: ${pending.get(key)}`;
|
|
508
|
+
lines[i] = `${rawKey}: ${renderVaultPropertyValue(pending.get(key)!)}`;
|
|
455
509
|
pending.delete(key);
|
|
456
510
|
}
|
|
457
511
|
const insertAt = closeIdx;
|
|
458
512
|
const added: string[] = [];
|
|
459
513
|
for (const [key, value] of pending.entries()) {
|
|
460
|
-
added.push(`${key}: ${value}`);
|
|
514
|
+
added.push(`${key}: ${renderVaultPropertyValue(value)}`);
|
|
461
515
|
}
|
|
462
516
|
lines.splice(insertAt, 0, ...added);
|
|
463
517
|
return { ok: true, text: lines.join(eol) };
|
|
@@ -3,9 +3,14 @@ import test from "node:test";
|
|
|
3
3
|
|
|
4
4
|
import { validateRegionName } from "./vault-region.js";
|
|
5
5
|
|
|
6
|
-
test("validateRegionName
|
|
6
|
+
test("validateRegionName accepts a valid name unchanged", () => {
|
|
7
7
|
assert.deepEqual(validateRegionName("timeline"), { ok: true, name: "timeline" });
|
|
8
|
-
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test("validateRegionName rejects whitespace-padded names instead of trimming them (#2917)", () => {
|
|
11
|
+
assert.deepEqual(validateRegionName(" weekly"), { ok: false, error: "invalid_name" });
|
|
12
|
+
assert.deepEqual(validateRegionName("weekly "), { ok: false, error: "invalid_name" });
|
|
13
|
+
assert.deepEqual(validateRegionName(" weekly "), { ok: false, error: "invalid_name" });
|
|
9
14
|
});
|
|
10
15
|
|
|
11
16
|
test("validateRegionName rejects empty and whitespace-only names", () => {
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* or as name `A` with a `B:start` suffix) and a publisher that resolved
|
|
9
9
|
* that ambiguity differently from the note's own markers would pair a
|
|
10
10
|
* start with a later end and delete the user bytes in between.
|
|
11
|
+
*
|
|
12
|
+
* Whitespace-padded names are rejected, not trimmed (issue #2917): the
|
|
13
|
+
* old silent trim validated one name and wrote another, so markers and
|
|
14
|
+
* heading matches were computed against bytes the caller never saw.
|
|
11
15
|
*/
|
|
12
16
|
|
|
13
17
|
export type ValidateRegionNameResult =
|
|
@@ -21,9 +25,9 @@ export function validateRegionName(name: string): ValidateRegionNameResult {
|
|
|
21
25
|
if (name.includes("\n") || name.includes("\r") || name.includes("-->") || name.includes(":")) {
|
|
22
26
|
return { ok: false, error: "invalid_name" };
|
|
23
27
|
}
|
|
24
|
-
|
|
25
|
-
if (trimmed.length === 0) {
|
|
28
|
+
if (name.trim() !== name || name.trim().length === 0) {
|
|
26
29
|
return { ok: false, error: "invalid_name" };
|
|
27
30
|
}
|
|
28
|
-
return { ok: true, name
|
|
31
|
+
return { ok: true, name };
|
|
29
32
|
}
|
|
33
|
+
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
1
3
|
import { isLoopbackHost } from "./runtime/http-transport.js";
|
|
4
|
+
import { expandTildePath } from "./utils/path.js";
|
|
2
5
|
|
|
3
6
|
export interface BackgroundGenerationConfig {
|
|
4
7
|
/** Full chat-completions URL. Never used as the global OpenAI base URL. */
|
|
@@ -54,14 +57,13 @@ function parseBackgroundGenerationObject(
|
|
|
54
57
|
if (typeof tokenRaw !== "string" || tokenRaw.length === 0) {
|
|
55
58
|
throw new Error(`${keyName} must include a token`);
|
|
56
59
|
}
|
|
57
|
-
const timeoutRaw = record.timeoutSeconds;
|
|
60
|
+
const timeoutRaw = record.timeoutSeconds ?? record.timeout_seconds;
|
|
58
61
|
let timeoutSeconds = 120;
|
|
59
62
|
if (timeoutRaw !== undefined) {
|
|
60
|
-
|
|
61
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
63
|
+
if (typeof timeoutRaw !== "number" || !Number.isFinite(timeoutRaw) || timeoutRaw <= 0) {
|
|
62
64
|
throw new Error(`${keyName} timeoutSeconds must be a finite number > 0`);
|
|
63
65
|
}
|
|
64
|
-
timeoutSeconds =
|
|
66
|
+
timeoutSeconds = timeoutRaw;
|
|
65
67
|
}
|
|
66
68
|
return {
|
|
67
69
|
endpoint: parseBackgroundEndpoint(endpointRaw, `${keyName}.endpoint`),
|
|
@@ -72,8 +74,32 @@ function parseBackgroundGenerationObject(
|
|
|
72
74
|
|
|
73
75
|
export function parseBackgroundGeneration(
|
|
74
76
|
cfg: Record<string, unknown>,
|
|
77
|
+
expandEnv: (value: string) => string,
|
|
75
78
|
): BackgroundGenerationConfig | undefined {
|
|
79
|
+
const pathRaw = cfg.llmBridgeClientConfigPath;
|
|
80
|
+
let fromFile: BackgroundGenerationConfig | undefined;
|
|
81
|
+
if (pathRaw !== undefined && pathRaw !== null && pathRaw !== "") {
|
|
82
|
+
if (typeof pathRaw !== "string") {
|
|
83
|
+
throw new Error("llmBridgeClientConfigPath must be a string");
|
|
84
|
+
}
|
|
85
|
+
const expanded = expandTildePath(expandEnv(pathRaw.trim()));
|
|
86
|
+
let parsed: unknown;
|
|
87
|
+
try {
|
|
88
|
+
parsed = JSON.parse(readFileSync(expanded, "utf8"));
|
|
89
|
+
} catch {
|
|
90
|
+
throw new Error(`llmBridgeClientConfigPath could not be read: ${expanded}`);
|
|
91
|
+
}
|
|
92
|
+
fromFile = parseBackgroundGenerationObject(parsed, "llmBridgeClientConfigPath");
|
|
93
|
+
}
|
|
76
94
|
const explicitRaw = cfg.backgroundGeneration;
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
const fromExplicit =
|
|
96
|
+
explicitRaw === undefined || explicitRaw === null
|
|
97
|
+
? undefined
|
|
98
|
+
: parseBackgroundGenerationObject(explicitRaw, "backgroundGeneration");
|
|
99
|
+
if (!fromFile && !fromExplicit) return undefined;
|
|
100
|
+
return {
|
|
101
|
+
endpoint: fromExplicit?.endpoint ?? fromFile!.endpoint,
|
|
102
|
+
token: fromExplicit?.token ?? fromFile!.token,
|
|
103
|
+
timeoutSeconds: fromExplicit?.timeoutSeconds ?? fromFile!.timeoutSeconds,
|
|
104
|
+
};
|
|
79
105
|
}
|
|
@@ -83,11 +83,13 @@ test("HourlySummarizer uses backgroundGeneration and not openaiBaseUrl", async (
|
|
|
83
83
|
timeoutSeconds: 12,
|
|
84
84
|
},
|
|
85
85
|
});
|
|
86
|
-
|
|
86
|
+
let sentBody: string | undefined;
|
|
87
|
+
globalThis.fetch = (async (url, init) => {
|
|
87
88
|
calls.push(String(url));
|
|
88
89
|
if (String(url) !== "http://127.0.0.1:8765/v1/chat/completions") {
|
|
89
90
|
return new Response("not the bridge", { status: 404 });
|
|
90
91
|
}
|
|
92
|
+
sentBody = String(init?.body);
|
|
91
93
|
return new Response(
|
|
92
94
|
JSON.stringify({
|
|
93
95
|
choices: [{ message: { content: '{"bullets":["bridge-only"]}' } }],
|
|
@@ -114,6 +116,13 @@ test("HourlySummarizer uses backgroundGeneration and not openaiBaseUrl", async (
|
|
|
114
116
|
assert.deepEqual(summary?.bullets, ["bridge-only"]);
|
|
115
117
|
assert.deepEqual(calls, ["http://127.0.0.1:8765/v1/chat/completions"]);
|
|
116
118
|
assert.equal(config.openaiBaseUrl, "http://127.0.0.1:9999/v1");
|
|
119
|
+
// The bridge prompt must spell out the required JSON shape; without it a
|
|
120
|
+
// literal host model returns {"summary": "..."} and the schema rejects it.
|
|
121
|
+
const sent = JSON.parse(String(sentBody)) as {
|
|
122
|
+
messages: Array<{ role: string; content: string }>;
|
|
123
|
+
};
|
|
124
|
+
const system = sent.messages.find((message) => message.role === "system")?.content ?? "";
|
|
125
|
+
assert.match(system, /"bullets"/);
|
|
117
126
|
} finally {
|
|
118
127
|
globalThis.fetch = previousFetch;
|
|
119
128
|
if (previousXdg === undefined) delete process.env.XDG_CONFIG_HOME;
|
|
@@ -23,6 +23,15 @@ export function registerTimelineCommands(cmd: CliCommand, orchestrator: Orchestr
|
|
|
23
23
|
.option("--what <kinds>", "Comma-separated artifacts to publish (default: timeline)")
|
|
24
24
|
.option("--dry-run", "Report per-file outcomes without writing")
|
|
25
25
|
.action((...args: unknown[]) => {
|
|
26
|
+
// Commander passes declared positional args before the options
|
|
27
|
+
// object; `publish` declares none, so a stray positional would
|
|
28
|
+
// displace the options object and silently publish with defaults
|
|
29
|
+
// (issue #2917). Reject any string arg outright.
|
|
30
|
+
if (args.some((arg) => typeof arg === "string")) {
|
|
31
|
+
process.stderr.write("timeline publish takes no positional arguments.\n");
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
26
35
|
const options = (args[0] ?? {}) as Record<string, unknown>;
|
|
27
36
|
const code = runTimelinePublishCli(orchestrator.config, options, {
|
|
28
37
|
stdout: process.stdout,
|
package/src/config.test.ts
CHANGED
|
@@ -2724,21 +2724,88 @@ test("parseConfig coerces string-typed sharedContextAllowBindingAuthority from t
|
|
|
2724
2724
|
);
|
|
2725
2725
|
}
|
|
2726
2726
|
});
|
|
2727
|
+
test("parseConfig coerces string-typed sharedContextEnabled from the CLI", () => {
|
|
2728
|
+
// `--config sharedContextEnabled=true` arrives as a string, so a strict
|
|
2729
|
+
// `=== true` silently left the feature off for anyone who enabled it.
|
|
2730
|
+
// Parity with sharedContextAllowBindingAuthority (issue #2918).
|
|
2731
|
+
// The default recall-pipeline shared-context gate must use the same
|
|
2732
|
+
// coerced boolean — string true with no custom pipeline enables the
|
|
2733
|
+
// section; false/malformed stay off.
|
|
2734
|
+
for (const enabled of ["true", "1", "yes", "on", true]) {
|
|
2735
|
+
const parsed = parseConfig({ sharedContextEnabled: enabled });
|
|
2736
|
+
assert.equal(
|
|
2737
|
+
parsed.sharedContextEnabled,
|
|
2738
|
+
true,
|
|
2739
|
+
`${JSON.stringify(enabled)} must enable shared context`,
|
|
2740
|
+
);
|
|
2741
|
+
assert.equal(
|
|
2742
|
+
parsed.recallPipeline.find((section) => section.id === "shared-context")?.enabled,
|
|
2743
|
+
true,
|
|
2744
|
+
`${JSON.stringify(enabled)} must enable the default shared-context section`,
|
|
2745
|
+
);
|
|
2746
|
+
}
|
|
2747
|
+
for (const disabled of ["false", "0", "no", "off", false, undefined, "", "garbage"]) {
|
|
2748
|
+
const parsed = parseConfig({ sharedContextEnabled: disabled });
|
|
2749
|
+
assert.equal(
|
|
2750
|
+
parsed.sharedContextEnabled,
|
|
2751
|
+
false,
|
|
2752
|
+
`${JSON.stringify(disabled)} must leave shared context off (malformed input never activates)`,
|
|
2753
|
+
);
|
|
2754
|
+
assert.equal(
|
|
2755
|
+
parsed.recallPipeline.find((section) => section.id === "shared-context")?.enabled,
|
|
2756
|
+
false,
|
|
2757
|
+
`${JSON.stringify(disabled)} must leave the default shared-context section off`,
|
|
2758
|
+
);
|
|
2759
|
+
}
|
|
2760
|
+
});
|
|
2761
|
+
|
|
2762
|
+
test("custom recallPipeline keeps operator shared-context enabled (#2918)", () => {
|
|
2763
|
+
const customOff = parseConfig({
|
|
2764
|
+
sharedContextEnabled: "true",
|
|
2765
|
+
recallPipeline: [{ id: "shared-context", enabled: false, maxChars: 1000 }],
|
|
2766
|
+
});
|
|
2767
|
+
assert.equal(customOff.sharedContextEnabled, true);
|
|
2768
|
+
assert.equal(
|
|
2769
|
+
customOff.recallPipeline.find((section) => section.id === "shared-context")?.enabled,
|
|
2770
|
+
false,
|
|
2771
|
+
"custom pipeline must not silently activate shared-context",
|
|
2772
|
+
);
|
|
2773
|
+
|
|
2774
|
+
const customOn = parseConfig({
|
|
2775
|
+
sharedContextEnabled: "false",
|
|
2776
|
+
recallPipeline: [{ id: "shared-context", enabled: true, maxChars: 1000 }],
|
|
2777
|
+
});
|
|
2778
|
+
assert.equal(customOn.sharedContextEnabled, false);
|
|
2779
|
+
assert.equal(
|
|
2780
|
+
customOn.recallPipeline.find((section) => section.id === "shared-context")?.enabled,
|
|
2781
|
+
true,
|
|
2782
|
+
"custom pipeline enabled stays as specified",
|
|
2783
|
+
);
|
|
2784
|
+
});
|
|
2727
2785
|
|
|
2728
|
-
|
|
2786
|
+
|
|
2787
|
+
test("parseConfig consumes llmBridgeClientConfigPath into backgroundGeneration only", () => {
|
|
2729
2788
|
withIsolatedConnectorsDir(false, () => {
|
|
2789
|
+
const dir = mkdtempSync(path.join(tmpdir(), "remnic-llm-bridge-client-"));
|
|
2730
2790
|
const previousKey = process.env.OPENAI_API_KEY;
|
|
2731
2791
|
const previousBase = process.env.OPENAI_BASE_URL;
|
|
2732
2792
|
delete process.env.OPENAI_API_KEY;
|
|
2733
2793
|
delete process.env.OPENAI_BASE_URL;
|
|
2734
2794
|
try {
|
|
2735
|
-
const
|
|
2736
|
-
|
|
2795
|
+
const file = path.join(dir, "client.json");
|
|
2796
|
+
writeFileSync(
|
|
2797
|
+
file,
|
|
2798
|
+
JSON.stringify({
|
|
2737
2799
|
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2800
|
+
health_endpoint: "http://127.0.0.1:8765/healthz",
|
|
2801
|
+
bind: "127.0.0.1",
|
|
2802
|
+
model_policy: "server-owned",
|
|
2803
|
+
max_body_bytes: 524288,
|
|
2804
|
+
timeout_seconds: 120,
|
|
2738
2805
|
token: "bridge-token-fixture",
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
});
|
|
2806
|
+
}),
|
|
2807
|
+
);
|
|
2808
|
+
const parsed = parseConfig({ llmBridgeClientConfigPath: file });
|
|
2742
2809
|
assert.equal(parsed.openaiBaseUrl, undefined);
|
|
2743
2810
|
assert.equal(parsed.openaiApiKey, undefined);
|
|
2744
2811
|
assert.deepEqual(parsed.backgroundGeneration, {
|
|
@@ -2748,11 +2815,7 @@ test("parseConfig consumes backgroundGeneration and leaves openaiBaseUrl untouch
|
|
|
2748
2815
|
});
|
|
2749
2816
|
|
|
2750
2817
|
const explicitOpenAi = parseConfig({
|
|
2751
|
-
|
|
2752
|
-
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2753
|
-
token: "bridge-token-fixture",
|
|
2754
|
-
timeoutSeconds: 120,
|
|
2755
|
-
},
|
|
2818
|
+
llmBridgeClientConfigPath: file,
|
|
2756
2819
|
openaiBaseUrl: "http://127.0.0.1:9999/v1",
|
|
2757
2820
|
openaiApiKey: "keep-me",
|
|
2758
2821
|
});
|
|
@@ -2762,65 +2825,78 @@ test("parseConfig consumes backgroundGeneration and leaves openaiBaseUrl untouch
|
|
|
2762
2825
|
explicitOpenAi.backgroundGeneration?.endpoint,
|
|
2763
2826
|
"http://127.0.0.1:8765/v1/chat/completions",
|
|
2764
2827
|
);
|
|
2828
|
+
|
|
2829
|
+
const explicitBg = parseConfig({
|
|
2830
|
+
backgroundGeneration: {
|
|
2831
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2832
|
+
token: "explicit-token",
|
|
2833
|
+
timeoutSeconds: 30,
|
|
2834
|
+
},
|
|
2835
|
+
});
|
|
2836
|
+
assert.equal(explicitBg.openaiBaseUrl, undefined);
|
|
2837
|
+
assert.deepEqual(explicitBg.backgroundGeneration, {
|
|
2838
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2839
|
+
token: "explicit-token",
|
|
2840
|
+
timeoutSeconds: 30,
|
|
2841
|
+
});
|
|
2765
2842
|
} finally {
|
|
2766
2843
|
if (previousKey === undefined) delete process.env.OPENAI_API_KEY;
|
|
2767
2844
|
else process.env.OPENAI_API_KEY = previousKey;
|
|
2768
2845
|
if (previousBase === undefined) delete process.env.OPENAI_BASE_URL;
|
|
2769
2846
|
else process.env.OPENAI_BASE_URL = previousBase;
|
|
2847
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2770
2848
|
}
|
|
2771
2849
|
});
|
|
2772
2850
|
});
|
|
2773
2851
|
|
|
2774
|
-
test("parseConfig
|
|
2775
|
-
withIsolatedConnectorsDir(false, () => {
|
|
2776
|
-
const parsed = parseConfig({
|
|
2777
|
-
llmBridgeClientConfigPath: "/no/such/remnic-llm-bridge-client.json",
|
|
2778
|
-
});
|
|
2779
|
-
assert.equal(parsed.backgroundGeneration, undefined);
|
|
2780
|
-
});
|
|
2781
|
-
});
|
|
2782
|
-
|
|
2783
|
-
test("parseConfig rejects backgroundGeneration without a token", () => {
|
|
2852
|
+
test("parseConfig rejects an unreadable llmBridgeClientConfigPath", () => {
|
|
2784
2853
|
withIsolatedConnectorsDir(false, () => {
|
|
2785
2854
|
assert.throws(
|
|
2786
|
-
() =>
|
|
2787
|
-
|
|
2788
|
-
backgroundGeneration: {
|
|
2789
|
-
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2790
|
-
},
|
|
2791
|
-
}),
|
|
2792
|
-
/must include a token/,
|
|
2855
|
+
() => parseConfig({ llmBridgeClientConfigPath: "/no/such/remnic-llm-bridge-client.json" }),
|
|
2856
|
+
/llmBridgeClientConfigPath could not be read/,
|
|
2793
2857
|
);
|
|
2794
2858
|
});
|
|
2795
2859
|
});
|
|
2796
2860
|
|
|
2797
|
-
test("parseConfig
|
|
2861
|
+
test("parseConfig rejects a bridge client file without a token", () => {
|
|
2798
2862
|
withIsolatedConnectorsDir(false, () => {
|
|
2799
|
-
const
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2863
|
+
const dir = mkdtempSync(path.join(tmpdir(), "remnic-llm-bridge-client-"));
|
|
2864
|
+
try {
|
|
2865
|
+
const file = path.join(dir, "client.json");
|
|
2866
|
+
writeFileSync(
|
|
2867
|
+
file,
|
|
2868
|
+
JSON.stringify({
|
|
2869
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2870
|
+
}),
|
|
2871
|
+
);
|
|
2872
|
+
assert.throws(
|
|
2873
|
+
() => parseConfig({ llmBridgeClientConfigPath: file }),
|
|
2874
|
+
/must include a token/,
|
|
2875
|
+
);
|
|
2876
|
+
} finally {
|
|
2877
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2878
|
+
}
|
|
2807
2879
|
});
|
|
2808
2880
|
});
|
|
2809
2881
|
|
|
2810
|
-
test("parseConfig keeps env openaiBaseUrl isolated from
|
|
2882
|
+
test("parseConfig keeps env openaiBaseUrl isolated from the Hermes bridge", () => {
|
|
2811
2883
|
withIsolatedConnectorsDir(false, () => {
|
|
2884
|
+
const dir = mkdtempSync(path.join(tmpdir(), "remnic-llm-bridge-env-"));
|
|
2812
2885
|
const previousKey = process.env.OPENAI_API_KEY;
|
|
2813
2886
|
const previousBase = process.env.OPENAI_BASE_URL;
|
|
2814
2887
|
process.env.OPENAI_API_KEY = "env-openai-key";
|
|
2815
2888
|
process.env.OPENAI_BASE_URL = "http://127.0.0.1:9999/v1";
|
|
2816
2889
|
try {
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2890
|
+
const file = path.join(dir, "client.json");
|
|
2891
|
+
writeFileSync(
|
|
2892
|
+
file,
|
|
2893
|
+
JSON.stringify({
|
|
2819
2894
|
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2820
2895
|
token: "bridge-token-fixture",
|
|
2821
|
-
|
|
2822
|
-
},
|
|
2823
|
-
|
|
2896
|
+
timeout_seconds: 45,
|
|
2897
|
+
}),
|
|
2898
|
+
);
|
|
2899
|
+
const parsed = parseConfig({ llmBridgeClientConfigPath: file });
|
|
2824
2900
|
assert.equal(parsed.openaiBaseUrl, "http://127.0.0.1:9999/v1");
|
|
2825
2901
|
assert.equal(parsed.openaiApiKey, "env-openai-key");
|
|
2826
2902
|
assert.deepEqual(parsed.backgroundGeneration, {
|
|
@@ -2833,6 +2909,57 @@ test("parseConfig keeps env openaiBaseUrl isolated from backgroundGeneration", (
|
|
|
2833
2909
|
else process.env.OPENAI_API_KEY = previousKey;
|
|
2834
2910
|
if (previousBase === undefined) delete process.env.OPENAI_BASE_URL;
|
|
2835
2911
|
else process.env.OPENAI_BASE_URL = previousBase;
|
|
2912
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2913
|
+
}
|
|
2914
|
+
});
|
|
2915
|
+
});
|
|
2916
|
+
|
|
2917
|
+
test("parseConfig rejects nonnumeric bridge timeout values", () => {
|
|
2918
|
+
withIsolatedConnectorsDir(false, () => {
|
|
2919
|
+
assert.throws(
|
|
2920
|
+
() =>
|
|
2921
|
+
parseConfig({
|
|
2922
|
+
backgroundGeneration: {
|
|
2923
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2924
|
+
token: "t",
|
|
2925
|
+
timeoutSeconds: true,
|
|
2926
|
+
},
|
|
2927
|
+
}),
|
|
2928
|
+
/timeoutSeconds must be a finite number/,
|
|
2929
|
+
);
|
|
2930
|
+
assert.throws(
|
|
2931
|
+
() =>
|
|
2932
|
+
parseConfig({
|
|
2933
|
+
backgroundGeneration: {
|
|
2934
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2935
|
+
token: "t",
|
|
2936
|
+
timeout_seconds: "45",
|
|
2937
|
+
},
|
|
2938
|
+
}),
|
|
2939
|
+
/timeoutSeconds must be a finite number/,
|
|
2940
|
+
);
|
|
2941
|
+
});
|
|
2942
|
+
});
|
|
2943
|
+
|
|
2944
|
+
test("parseConfig rejects a bridge client file with a nonnumeric timeout", () => {
|
|
2945
|
+
withIsolatedConnectorsDir(false, () => {
|
|
2946
|
+
const dir = mkdtempSync(path.join(tmpdir(), "remnic-llm-bridge-badtimeout-"));
|
|
2947
|
+
try {
|
|
2948
|
+
const file = path.join(dir, "client.json");
|
|
2949
|
+
writeFileSync(
|
|
2950
|
+
file,
|
|
2951
|
+
JSON.stringify({
|
|
2952
|
+
endpoint: "http://127.0.0.1:8765/v1/chat/completions",
|
|
2953
|
+
token: "bridge-token-fixture",
|
|
2954
|
+
timeout_seconds: "45",
|
|
2955
|
+
}),
|
|
2956
|
+
);
|
|
2957
|
+
assert.throws(
|
|
2958
|
+
() => parseConfig({ llmBridgeClientConfigPath: file }),
|
|
2959
|
+
/timeoutSeconds must be a finite number/,
|
|
2960
|
+
);
|
|
2961
|
+
} finally {
|
|
2962
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2836
2963
|
}
|
|
2837
2964
|
});
|
|
2838
2965
|
});
|
package/src/config.ts
CHANGED
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
TriggerMode,
|
|
26
26
|
TrustWeights,
|
|
27
27
|
} from "./types.js";
|
|
28
|
+
import { parseBackgroundGeneration } from "./background-generation-config.js";
|
|
28
29
|
import { parseLocalLlmConfig } from "./local-llm-config.js";
|
|
29
30
|
import { parseConvergeConfig } from "./converge-config.js";
|
|
30
31
|
import { parseExternalWikiRecallGuard } from "./external-wiki-guard.js";
|
|
@@ -519,6 +520,7 @@ function normalizeOpenaiBaseUrl(value: string | undefined, source: "config" | "e
|
|
|
519
520
|
return url;
|
|
520
521
|
}
|
|
521
522
|
|
|
523
|
+
|
|
522
524
|
function normalizeMemoryRelativeDir(raw: unknown, fallback: string): string {
|
|
523
525
|
if (typeof raw !== "string") return fallback;
|
|
524
526
|
const trimmed = raw.trim();
|
|
@@ -1482,6 +1484,7 @@ export function parseConfig(
|
|
|
1482
1484
|
} else if (apiKey !== undefined) {
|
|
1483
1485
|
baseUrl = normalizeOpenaiBaseUrl(readEnvVar("OPENAI_BASE_URL"), "env");
|
|
1484
1486
|
}
|
|
1487
|
+
const backgroundGeneration = parseBackgroundGeneration(cfg, resolveEnvVars);
|
|
1485
1488
|
|
|
1486
1489
|
const sharedCrossSignalSemanticEnabled =
|
|
1487
1490
|
cfg.sharedCrossSignalSemanticEnabled === true || cfg.crossSignalsSemanticEnabled === true;
|
|
@@ -1491,7 +1494,15 @@ export function parseConfig(
|
|
|
1491
1494
|
: typeof cfg.crossSignalsSemanticTimeoutMs === "number"
|
|
1492
1495
|
? Math.max(1, Math.floor(cfg.crossSignalsSemanticTimeoutMs))
|
|
1493
1496
|
: 4000;
|
|
1494
|
-
|
|
1497
|
+
// Coerce once. The default recall-pipeline shared-context gate reads
|
|
1498
|
+
// `cfg.sharedContextEnabled === true`, so it must see this boolean —
|
|
1499
|
+
// not the raw CLI/config string. Custom `recallPipeline` is unchanged.
|
|
1500
|
+
const sharedContextEnabled =
|
|
1501
|
+
coerceBool(cfg.sharedContextEnabled, "sharedContextEnabled") ?? false;
|
|
1502
|
+
const recallPipelineConfig = buildRecallPipelineConfig({
|
|
1503
|
+
...cfg,
|
|
1504
|
+
sharedContextEnabled,
|
|
1505
|
+
});
|
|
1495
1506
|
const maintenanceNamespaceFanoutEnabled = resolveBooleanConfig(
|
|
1496
1507
|
readFlatOrNestedConfig(
|
|
1497
1508
|
cfg,
|
|
@@ -1560,6 +1571,7 @@ export function parseConfig(
|
|
|
1560
1571
|
return {
|
|
1561
1572
|
openaiApiKey: apiKey,
|
|
1562
1573
|
openaiBaseUrl: baseUrl,
|
|
1574
|
+
backgroundGeneration,
|
|
1563
1575
|
model,
|
|
1564
1576
|
reasoningEffort,
|
|
1565
1577
|
triggerMode,
|
|
@@ -3003,10 +3015,9 @@ export function parseConfig(
|
|
|
3003
3015
|
? cfg.routingRulesStateFile.trim()
|
|
3004
3016
|
: "state/routing-rules.json",
|
|
3005
3017
|
|
|
3006
|
-
//
|
|
3007
|
-
sharedContextEnabled
|
|
3008
|
-
//
|
|
3009
|
-
// so a strict `=== true` silently keeps the feature off. Default stays false.
|
|
3018
|
+
// Reuse the hoisted coerce above (default pipeline already saw it).
|
|
3019
|
+
sharedContextEnabled,
|
|
3020
|
+
// Same coercion contract for the binding-authority sibling (#2918 parity).
|
|
3010
3021
|
sharedContextAllowBindingAuthority:
|
|
3011
3022
|
coerceBool(cfg.sharedContextAllowBindingAuthority, "sharedContextAllowBindingAuthority") ?? false,
|
|
3012
3023
|
sharedContextDir:
|
|
@@ -4217,6 +4228,7 @@ function buildDefaultRecallPipeline(cfg: Record<string, unknown>): RecallSection
|
|
|
4217
4228
|
return [
|
|
4218
4229
|
{
|
|
4219
4230
|
id: "shared-context",
|
|
4231
|
+
// Already coerced in parseConfig; do not coerce again.
|
|
4220
4232
|
enabled: cfg.sharedContextEnabled === true,
|
|
4221
4233
|
maxChars:
|
|
4222
4234
|
typeof cfg.sharedContextMaxInjectChars === "number"
|