@remnic/core 10.0.59 → 10.0.61
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.js +53 -50
- package/dist/access-authorization-probe.js +54 -51
- package/dist/access-boundary.js +53 -50
- package/dist/access-cli.js +143 -140
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +53 -50
- package/dist/access-http-briefing.js +54 -51
- package/dist/access-http-query.js +55 -52
- package/dist/access-http.js +76 -73
- package/dist/access-identity-continuity-surface.js +53 -50
- package/dist/access-lcm-surface.js +53 -50
- package/dist/access-mcp.js +64 -61
- package/dist/access-namespace-preflight.js +53 -50
- package/dist/access-observe-write-category.js +10 -10
- package/dist/access-observe-write-surface.js +53 -50
- package/dist/access-offline-manifest.js +7 -7
- package/dist/access-operations-batch.js +56 -53
- package/dist/access-operations.js +63 -60
- package/dist/access-recall-concurrency.js +53 -50
- package/dist/access-recall-response.js +53 -50
- package/dist/access-recall-surface.js +53 -50
- package/dist/access-schema.js +9 -9
- package/dist/access-service.js +53 -50
- package/dist/access-surface-catalog.js +55 -52
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +24 -20
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/briefing.js +16 -12
- package/dist/buffer-persistence.d.ts +14 -3
- package/dist/buffer-persistence.d.ts.map +1 -1
- package/dist/buffer-persistence.js +1 -1
- package/dist/buffer-turn-helpers.d.ts +7 -0
- package/dist/buffer-turn-helpers.d.ts.map +1 -1
- package/dist/buffer-turn-helpers.js +5 -3
- package/dist/buffer.d.ts +2 -0
- package/dist/buffer.d.ts.map +1 -1
- package/dist/buffer.js +7 -7
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +19 -15
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-ZAZZOQAQ.js → chunk-23OEPU3K.js} +2 -2
- package/dist/{chunk-XDKEHZUC.js → chunk-264B57GV.js} +2 -2
- package/dist/{chunk-5U2BBF7E.js → chunk-46U6L5DM.js} +20 -10
- package/dist/chunk-46U6L5DM.js.map +1 -0
- package/dist/chunk-4LZ7SVKM.js +211 -0
- package/dist/chunk-4LZ7SVKM.js.map +1 -0
- package/dist/{chunk-NRGQ5HJO.js → chunk-4P4VLPGB.js} +1 -1
- package/dist/{chunk-GIRWNTMV.js → chunk-4PG5R6BJ.js} +2 -2
- package/dist/{chunk-52II7PB6.js → chunk-645WOU5I.js} +4 -4
- package/dist/{chunk-RG3I2663.js → chunk-64JLBFCQ.js} +2 -2
- package/dist/{chunk-G3T6YMBO.js → chunk-64S6X4IU.js} +7 -7
- package/dist/{chunk-WASVDS6G.js → chunk-6HTEPYOI.js} +4 -4
- package/dist/{chunk-6AEKSOWV.js → chunk-6I6DFULH.js} +8 -8
- package/dist/{chunk-DJR37Q37.js → chunk-6T4CMKNP.js} +2 -2
- package/dist/{chunk-RHJ5VGB3.js → chunk-73A2DDDR.js} +2 -2
- package/dist/{chunk-4B73TQQV.js → chunk-7AKPLEJV.js} +2 -2
- package/dist/{chunk-UHH67NLU.js → chunk-7OKYO2UC.js} +2 -2
- package/dist/{chunk-KAL5SXPP.js → chunk-7ULSP7AU.js} +6 -6
- package/dist/{chunk-USNU3BEQ.js → chunk-A4FZLM6Q.js} +2 -2
- package/dist/{chunk-VV73XT3A.js → chunk-BJLCV2P3.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-BUKK5SWA.js} +2 -2
- package/dist/{chunk-DJFULNXK.js → chunk-C2AYUXEF.js} +2 -2
- package/dist/{chunk-QY24FSXT.js → chunk-D3BYJSHX.js} +51 -51
- package/dist/{chunk-JZRQY7ZQ.js → chunk-D4WR56FR.js} +2 -2
- package/dist/{chunk-3E3Z6UA3.js → chunk-DMYNM3WG.js} +124 -97
- package/dist/chunk-DMYNM3WG.js.map +1 -0
- package/dist/{chunk-FB4JQEFS.js → chunk-DP22K7IC.js} +2 -2
- package/dist/{chunk-EJFOGYF3.js → chunk-DTQJ7BRN.js} +3 -3
- package/dist/{chunk-MLUPSZFK.js → chunk-DZL5PBEJ.js} +2 -2
- package/dist/{chunk-JD5F5MYN.js → chunk-EGCC5OJE.js} +3 -3
- package/dist/{chunk-IQSRVR6Z.js → chunk-EJ4RS7I7.js} +2 -2
- package/dist/{chunk-WBN66HPI.js → chunk-ELHJK7LM.js} +6 -6
- package/dist/{chunk-EH46DHBU.js → chunk-ENAPZQA6.js} +2 -2
- package/dist/{chunk-LLG5VNK7.js → chunk-F2UAAI6B.js} +2 -2
- package/dist/{chunk-YZNTAOPZ.js → chunk-FKNNWH7P.js} +2 -2
- package/dist/{chunk-AAANTXCQ.js → chunk-FZVZYU5C.js} +2 -2
- package/dist/{chunk-ON77FQXH.js → chunk-G6GMZJQ4.js} +2 -2
- package/dist/{chunk-OL7A7NKH.js → chunk-GNP4BV4Z.js} +2 -2
- package/dist/{chunk-GDYLZ6FR.js → chunk-HJ3UTGIW.js} +3 -3
- package/dist/{chunk-CCL2OXFO.js → chunk-HSHLDSPX.js} +3 -3
- package/dist/{chunk-R4BR62UO.js → chunk-HWMGQDZI.js} +2 -2
- package/dist/{chunk-BPIAXMGC.js → chunk-IIUEHIQ2.js} +2 -2
- package/dist/{chunk-RTJJPW3C.js → chunk-ILMB3X4X.js} +5 -5
- package/dist/{chunk-RFT4OPYI.js → chunk-IPN67KVR.js} +2 -2
- package/dist/chunk-JCL7RO2G.js +674 -0
- package/dist/chunk-JCL7RO2G.js.map +1 -0
- package/dist/{chunk-IEW6NDHX.js → chunk-JGSWWD33.js} +9 -9
- package/dist/{chunk-A3UFV4K3.js → chunk-JIYJIH5N.js} +2 -2
- package/dist/{chunk-4G2A7MH3.js → chunk-JKUVPVKR.js} +3 -3
- package/dist/{chunk-YJHOVA42.js → chunk-JL5FHZ7O.js} +30 -6
- package/dist/chunk-JL5FHZ7O.js.map +1 -0
- package/dist/{chunk-VCLNU6MY.js → chunk-L2HSSVVD.js} +2 -2
- package/dist/{chunk-U2A56LLF.js → chunk-L334PSLW.js} +8 -8
- package/dist/{chunk-HQUYENKK.js → chunk-LIUI46BX.js} +3 -3
- package/dist/{chunk-ERMT5WQM.js → chunk-MKE5DP3S.js} +2 -2
- package/dist/{chunk-4OFXLQJD.js → chunk-MPDLLLOG.js} +8 -3
- package/dist/chunk-MPDLLLOG.js.map +1 -0
- package/dist/{chunk-6BO27AWQ.js → chunk-MPJ7VHHA.js} +2 -2
- package/dist/{chunk-WXBVGKS6.js → chunk-N7RAABFM.js} +182 -421
- package/dist/chunk-N7RAABFM.js.map +1 -0
- package/dist/{chunk-KMJDH4KX.js → chunk-NSUGAIIB.js} +16 -16
- package/dist/{chunk-7NT3FKAF.js → chunk-NXHBQC2O.js} +2 -2
- package/dist/{chunk-JEX2JL3U.js → chunk-OH55F76C.js} +2 -2
- package/dist/{chunk-37VTMUAL.js → chunk-OUJ4DVR5.js} +2 -2
- package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
- package/dist/{chunk-2IVK5IDY.js → chunk-P5F7ISLV.js} +2 -2
- package/dist/{chunk-PM4PKC3Y.js → chunk-PNVQNAJM.js} +3 -3
- package/dist/{chunk-FXWX7VD3.js → chunk-PRYDNBCO.js} +12 -12
- package/dist/{chunk-YDDLSGYE.js → chunk-PUTH5REB.js} +2 -2
- package/dist/{chunk-GFAEKSFR.js → chunk-QBK3IM6W.js} +5 -5
- package/dist/{chunk-KRAMCBIW.js → chunk-QKXPOLQD.js} +4 -4
- package/dist/{chunk-YDT3OEYF.js → chunk-R4ZHF4K2.js} +2 -2
- package/dist/{chunk-ISNPYOXR.js → chunk-RBUR6USI.js} +5 -5
- package/dist/{chunk-WZYAXOGO.js → chunk-RZSHIJYY.js} +2 -2
- package/dist/{chunk-TYSD7UQO.js → chunk-SVTIWBSA.js} +2 -2
- package/dist/{chunk-AMKIIRLL.js → chunk-TBFAQHQZ.js} +2 -2
- package/dist/{chunk-ZE5N4JSY.js → chunk-TKCJI7WA.js} +2 -2
- package/dist/{chunk-RYB553SS.js → chunk-TLOAAOT3.js} +2 -2
- package/dist/{chunk-RKRX4C4H.js → chunk-TPKB7T6Z.js} +2 -2
- package/dist/{chunk-JZCBMKR5.js → chunk-TUCEP2LS.js} +5 -5
- package/dist/{chunk-KZMRMKC7.js → chunk-U7MIMS2Y.js} +11 -1
- package/dist/chunk-U7MIMS2Y.js.map +1 -0
- package/dist/{chunk-OMWQO7H6.js → chunk-UEDC2VGP.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/{chunk-JY2BGCYN.js → chunk-VCYH2XUY.js} +2 -2
- package/dist/{chunk-NGH74LDV.js → chunk-WD2QH3JM.js} +9 -9
- package/dist/{chunk-G6A3SGCE.js → chunk-WVEEVYMH.js} +8 -25
- package/dist/chunk-WVEEVYMH.js.map +1 -0
- package/dist/{chunk-UGTYADB4.js → chunk-WWSJQ7MP.js} +3 -3
- package/dist/{chunk-UQBOPCDK.js → chunk-X4PAATLA.js} +2 -2
- package/dist/{chunk-KBOQQEVC.js → chunk-XAFSZ4DP.js} +2 -2
- package/dist/{chunk-2S6JADBB.js → chunk-XICJL56Z.js} +2 -2
- package/dist/{chunk-Y5KESB7T.js → chunk-XJDSZFBZ.js} +45 -45
- package/dist/{chunk-24SIB3EW.js → chunk-XWE3EOWX.js} +2 -2
- package/dist/{chunk-Y77FXULH.js → chunk-XWXBXBOX.js} +2 -2
- package/dist/{chunk-VKQI47DJ.js → chunk-Y7427SL7.js} +4 -4
- package/dist/{chunk-TEH5MDX5.js → chunk-YH7HJNWV.js} +22 -22
- package/dist/chunk-YHTG64XV.js +117 -0
- package/dist/chunk-YHTG64XV.js.map +1 -0
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-2M36PR7R.js → chunk-Z2T5BPOZ.js} +2 -2
- package/dist/cli.js +100 -97
- package/dist/coding/export-okf-codegraph.js +15 -11
- package/dist/coding/export-okf-codegraph.js.map +1 -1
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +17 -13
- package/dist/config.js +24 -20
- package/dist/connectors/codex-materialize-runner.js +16 -12
- package/dist/connectors/index.js +16 -12
- package/dist/convergence-refresh.js +18 -14
- package/dist/corpus-scan-worker-host.d.ts +109 -0
- package/dist/corpus-scan-worker-host.d.ts.map +1 -0
- package/dist/corpus-scan-worker-host.js +15 -0
- package/dist/corpus-scan-worker.entry.d.ts +21 -0
- package/dist/corpus-scan-worker.entry.d.ts.map +1 -0
- package/dist/corpus-scan-worker.entry.js +60 -0
- package/dist/corpus-scan-worker.entry.js.map +1 -0
- package/dist/corpus-scan-worker.entry.mjs +176 -0
- package/dist/corpus-scan.d.ts +71 -0
- package/dist/corpus-scan.d.ts.map +1 -0
- package/dist/corpus-scan.js +16 -0
- package/dist/corpus-watermark.d.ts.map +1 -1
- package/dist/corpus-watermark.js +18 -14
- package/dist/dashboard-runtime.js +2 -2
- package/dist/deep-recall-http-glue.js +10 -10
- package/dist/embedding-fallback.js +2 -2
- package/dist/{entity-canonical-id-migration-F3JVG6K6.js → entity-canonical-id-migration-CUDCKWPF.js} +4 -2
- package/dist/entity-canonical-id-migration-CUDCKWPF.js.map +1 -0
- package/dist/entity-retrieval.js +18 -14
- package/dist/event-order-recall.js +3 -3
- package/dist/external-wiki-access.js +54 -51
- package/dist/extraction.js +21 -17
- package/dist/{graph-edge-decay-IU75NV42.js → graph-edge-decay-2BZTY2IM.js} +5 -5
- package/dist/graph-edge-decay-2BZTY2IM.js.map +1 -0
- package/dist/graph-jsonl.js +3 -3
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +2 -2
- package/dist/harmonic-retrieval.js +16 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -169
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.js +5 -5
- package/dist/location/index.js +18 -14
- package/dist/maintenance/memory-governance.js +16 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -12
- package/dist/maintenance/rebuild-memory-projection-runner.js +18 -14
- package/dist/maintenance/rebuild-memory-projection.js +17 -13
- package/dist/memory-browse-operations.js +54 -51
- package/dist/memory-browse.js +5 -5
- package/dist/namespaces/migrate.js +17 -13
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.js +16 -12
- package/dist/offline-sync-changeset-generations.js +4 -4
- package/dist/offline-sync-embedding-generation.js +3 -3
- package/dist/offline-sync-snapshot-stream.js +7 -7
- package/dist/offline-sync.js +6 -6
- package/dist/operator-doctor-corpus.js +19 -15
- package/dist/operator-toolkit.js +35 -31
- package/dist/orchestration/buffer-drain-gate.d.ts +21 -0
- package/dist/orchestration/buffer-drain-gate.d.ts.map +1 -0
- package/dist/orchestration/buffer-drain-runner.d.ts +79 -0
- package/dist/orchestration/buffer-drain-runner.d.ts.map +1 -0
- package/dist/orchestration/buffer-drain-runner.js +780 -0
- package/dist/orchestration/buffer-drain-runner.js.map +1 -0
- package/dist/orchestration/buffer-swap.d.ts +12 -0
- package/dist/orchestration/buffer-swap.d.ts.map +1 -0
- package/dist/orchestration/maintenance.js +26 -22
- package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
- package/dist/orchestrator.d.ts +4 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +143 -140
- package/dist/qmd.js +4 -4
- package/dist/recall-navigation-operations.js +54 -51
- package/dist/recall-navigation.js +53 -50
- package/dist/recall-state-view-admission.js +5 -5
- package/dist/recall-why-service.js +5 -5
- package/dist/resume-bundles.js +25 -21
- package/dist/search/factory.js +6 -6
- package/dist/search/index.js +12 -12
- package/dist/semantic-consolidation.js +17 -13
- package/dist/semantic-rule-promotion.js +16 -12
- package/dist/semantic-rule-verifier.js +16 -12
- package/dist/source-agent-qualifier.js +19 -15
- package/dist/standup/build.js +16 -12
- package/dist/storage/buffer-drain-claims.d.ts +159 -0
- package/dist/storage/buffer-drain-claims.d.ts.map +1 -0
- package/dist/storage/buffer-drain-claims.js +18 -0
- package/dist/storage/buffer-drain-claims.js.map +1 -0
- package/dist/storage/buffer-session-files.d.ts +14 -2
- package/dist/storage/buffer-session-files.d.ts.map +1 -1
- package/dist/storage/buffer-session-files.js +22 -0
- package/dist/storage/buffer-session-files.js.map +1 -0
- package/dist/storage/entity-canonical-id-migration.d.ts.map +1 -1
- package/dist/storage/memory-read-store.d.ts +5 -9
- package/dist/storage/memory-read-store.d.ts.map +1 -1
- package/dist/storage.d.ts +6 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +17 -13
- package/dist/support-passport/index.js +56 -53
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-okf.js +16 -12
- package/dist/verified-recall.js +16 -12
- package/dist/who-knows-cli.js +17 -13
- package/dist/who-knows.js +16 -12
- package/package.json +32 -2
- package/scripts/build-with-heap.mjs +8 -0
- package/src/buffer-drain-handover.test.ts +307 -0
- package/src/buffer-persistence.ts +27 -5
- package/src/buffer-turn-helpers.ts +16 -0
- package/src/buffer.ts +32 -2
- package/src/corpus-scan-worker-host.ts +314 -0
- package/src/corpus-scan-worker.entry.mjs +176 -0
- package/src/corpus-scan-worker.entry.ts +95 -0
- package/src/corpus-scan.ts +215 -0
- package/src/corpus-watermark.ts +28 -12
- package/src/index.ts +1 -1
- package/src/orchestration/buffer-drain-gate.test.ts +40 -0
- package/src/orchestration/buffer-drain-gate.ts +38 -0
- package/src/orchestration/buffer-drain-runner.ts +312 -0
- package/src/orchestration/buffer-swap.ts +27 -0
- package/src/orchestration/turn-ingestion.ts +2 -0
- package/src/orchestrator.ts +9 -6
- package/src/storage/buffer-drain-claims.test.ts +448 -0
- package/src/storage/buffer-drain-claims.ts +593 -0
- package/src/storage/buffer-session-files.ts +50 -3
- package/src/storage/entity-canonical-id-migration.ts +4 -26
- package/src/storage/memory-read-store.ts +17 -99
- package/src/storage.ts +8 -11
- package/src/testing/subjects/extraction-lifecycle.test.ts +34 -0
- package/dist/chunk-3E3Z6UA3.js.map +0 -1
- package/dist/chunk-4OFXLQJD.js.map +0 -1
- package/dist/chunk-5U2BBF7E.js.map +0 -1
- package/dist/chunk-G6A3SGCE.js.map +0 -1
- package/dist/chunk-KZMRMKC7.js.map +0 -1
- package/dist/chunk-WXBVGKS6.js.map +0 -1
- package/dist/chunk-YJHOVA42.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{chunk-ZAZZOQAQ.js.map → chunk-23OEPU3K.js.map} +0 -0
- /package/dist/{chunk-XDKEHZUC.js.map → chunk-264B57GV.js.map} +0 -0
- /package/dist/{chunk-NRGQ5HJO.js.map → chunk-4P4VLPGB.js.map} +0 -0
- /package/dist/{chunk-GIRWNTMV.js.map → chunk-4PG5R6BJ.js.map} +0 -0
- /package/dist/{chunk-52II7PB6.js.map → chunk-645WOU5I.js.map} +0 -0
- /package/dist/{chunk-RG3I2663.js.map → chunk-64JLBFCQ.js.map} +0 -0
- /package/dist/{chunk-G3T6YMBO.js.map → chunk-64S6X4IU.js.map} +0 -0
- /package/dist/{chunk-WASVDS6G.js.map → chunk-6HTEPYOI.js.map} +0 -0
- /package/dist/{chunk-6AEKSOWV.js.map → chunk-6I6DFULH.js.map} +0 -0
- /package/dist/{chunk-DJR37Q37.js.map → chunk-6T4CMKNP.js.map} +0 -0
- /package/dist/{chunk-RHJ5VGB3.js.map → chunk-73A2DDDR.js.map} +0 -0
- /package/dist/{chunk-4B73TQQV.js.map → chunk-7AKPLEJV.js.map} +0 -0
- /package/dist/{chunk-UHH67NLU.js.map → chunk-7OKYO2UC.js.map} +0 -0
- /package/dist/{chunk-KAL5SXPP.js.map → chunk-7ULSP7AU.js.map} +0 -0
- /package/dist/{chunk-USNU3BEQ.js.map → chunk-A4FZLM6Q.js.map} +0 -0
- /package/dist/{chunk-VV73XT3A.js.map → chunk-BJLCV2P3.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-BUKK5SWA.js.map} +0 -0
- /package/dist/{chunk-DJFULNXK.js.map → chunk-C2AYUXEF.js.map} +0 -0
- /package/dist/{chunk-QY24FSXT.js.map → chunk-D3BYJSHX.js.map} +0 -0
- /package/dist/{chunk-JZRQY7ZQ.js.map → chunk-D4WR56FR.js.map} +0 -0
- /package/dist/{chunk-FB4JQEFS.js.map → chunk-DP22K7IC.js.map} +0 -0
- /package/dist/{chunk-EJFOGYF3.js.map → chunk-DTQJ7BRN.js.map} +0 -0
- /package/dist/{chunk-MLUPSZFK.js.map → chunk-DZL5PBEJ.js.map} +0 -0
- /package/dist/{chunk-JD5F5MYN.js.map → chunk-EGCC5OJE.js.map} +0 -0
- /package/dist/{chunk-IQSRVR6Z.js.map → chunk-EJ4RS7I7.js.map} +0 -0
- /package/dist/{chunk-WBN66HPI.js.map → chunk-ELHJK7LM.js.map} +0 -0
- /package/dist/{chunk-EH46DHBU.js.map → chunk-ENAPZQA6.js.map} +0 -0
- /package/dist/{chunk-LLG5VNK7.js.map → chunk-F2UAAI6B.js.map} +0 -0
- /package/dist/{chunk-YZNTAOPZ.js.map → chunk-FKNNWH7P.js.map} +0 -0
- /package/dist/{chunk-AAANTXCQ.js.map → chunk-FZVZYU5C.js.map} +0 -0
- /package/dist/{chunk-ON77FQXH.js.map → chunk-G6GMZJQ4.js.map} +0 -0
- /package/dist/{chunk-OL7A7NKH.js.map → chunk-GNP4BV4Z.js.map} +0 -0
- /package/dist/{chunk-GDYLZ6FR.js.map → chunk-HJ3UTGIW.js.map} +0 -0
- /package/dist/{chunk-CCL2OXFO.js.map → chunk-HSHLDSPX.js.map} +0 -0
- /package/dist/{chunk-R4BR62UO.js.map → chunk-HWMGQDZI.js.map} +0 -0
- /package/dist/{chunk-BPIAXMGC.js.map → chunk-IIUEHIQ2.js.map} +0 -0
- /package/dist/{chunk-RTJJPW3C.js.map → chunk-ILMB3X4X.js.map} +0 -0
- /package/dist/{chunk-RFT4OPYI.js.map → chunk-IPN67KVR.js.map} +0 -0
- /package/dist/{chunk-IEW6NDHX.js.map → chunk-JGSWWD33.js.map} +0 -0
- /package/dist/{chunk-A3UFV4K3.js.map → chunk-JIYJIH5N.js.map} +0 -0
- /package/dist/{chunk-4G2A7MH3.js.map → chunk-JKUVPVKR.js.map} +0 -0
- /package/dist/{chunk-VCLNU6MY.js.map → chunk-L2HSSVVD.js.map} +0 -0
- /package/dist/{chunk-U2A56LLF.js.map → chunk-L334PSLW.js.map} +0 -0
- /package/dist/{chunk-HQUYENKK.js.map → chunk-LIUI46BX.js.map} +0 -0
- /package/dist/{chunk-ERMT5WQM.js.map → chunk-MKE5DP3S.js.map} +0 -0
- /package/dist/{chunk-6BO27AWQ.js.map → chunk-MPJ7VHHA.js.map} +0 -0
- /package/dist/{chunk-KMJDH4KX.js.map → chunk-NSUGAIIB.js.map} +0 -0
- /package/dist/{chunk-7NT3FKAF.js.map → chunk-NXHBQC2O.js.map} +0 -0
- /package/dist/{chunk-JEX2JL3U.js.map → chunk-OH55F76C.js.map} +0 -0
- /package/dist/{chunk-37VTMUAL.js.map → chunk-OUJ4DVR5.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-2IVK5IDY.js.map → chunk-P5F7ISLV.js.map} +0 -0
- /package/dist/{chunk-PM4PKC3Y.js.map → chunk-PNVQNAJM.js.map} +0 -0
- /package/dist/{chunk-FXWX7VD3.js.map → chunk-PRYDNBCO.js.map} +0 -0
- /package/dist/{chunk-YDDLSGYE.js.map → chunk-PUTH5REB.js.map} +0 -0
- /package/dist/{chunk-GFAEKSFR.js.map → chunk-QBK3IM6W.js.map} +0 -0
- /package/dist/{chunk-KRAMCBIW.js.map → chunk-QKXPOLQD.js.map} +0 -0
- /package/dist/{chunk-YDT3OEYF.js.map → chunk-R4ZHF4K2.js.map} +0 -0
- /package/dist/{chunk-ISNPYOXR.js.map → chunk-RBUR6USI.js.map} +0 -0
- /package/dist/{chunk-WZYAXOGO.js.map → chunk-RZSHIJYY.js.map} +0 -0
- /package/dist/{chunk-TYSD7UQO.js.map → chunk-SVTIWBSA.js.map} +0 -0
- /package/dist/{chunk-AMKIIRLL.js.map → chunk-TBFAQHQZ.js.map} +0 -0
- /package/dist/{chunk-ZE5N4JSY.js.map → chunk-TKCJI7WA.js.map} +0 -0
- /package/dist/{chunk-RYB553SS.js.map → chunk-TLOAAOT3.js.map} +0 -0
- /package/dist/{chunk-RKRX4C4H.js.map → chunk-TPKB7T6Z.js.map} +0 -0
- /package/dist/{chunk-JZCBMKR5.js.map → chunk-TUCEP2LS.js.map} +0 -0
- /package/dist/{chunk-OMWQO7H6.js.map → chunk-UEDC2VGP.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-JY2BGCYN.js.map → chunk-VCYH2XUY.js.map} +0 -0
- /package/dist/{chunk-NGH74LDV.js.map → chunk-WD2QH3JM.js.map} +0 -0
- /package/dist/{chunk-UGTYADB4.js.map → chunk-WWSJQ7MP.js.map} +0 -0
- /package/dist/{chunk-UQBOPCDK.js.map → chunk-X4PAATLA.js.map} +0 -0
- /package/dist/{chunk-KBOQQEVC.js.map → chunk-XAFSZ4DP.js.map} +0 -0
- /package/dist/{chunk-2S6JADBB.js.map → chunk-XICJL56Z.js.map} +0 -0
- /package/dist/{chunk-Y5KESB7T.js.map → chunk-XJDSZFBZ.js.map} +0 -0
- /package/dist/{chunk-24SIB3EW.js.map → chunk-XWE3EOWX.js.map} +0 -0
- /package/dist/{chunk-Y77FXULH.js.map → chunk-XWXBXBOX.js.map} +0 -0
- /package/dist/{chunk-VKQI47DJ.js.map → chunk-Y7427SL7.js.map} +0 -0
- /package/dist/{chunk-TEH5MDX5.js.map → chunk-YH7HJNWV.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-2M36PR7R.js.map → chunk-Z2T5BPOZ.js.map} +0 -0
- /package/dist/{entity-canonical-id-migration-F3JVG6K6.js.map → corpus-scan-worker-host.js.map} +0 -0
- /package/dist/{graph-edge-decay-IU75NV42.js.map → corpus-scan.js.map} +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Out-of-process extraction-buffer drain (`remnic buffer drain`).
|
|
3
|
+
*
|
|
4
|
+
* The runner owns ONE claimed session at a time and drives it through the
|
|
5
|
+
* SAME extraction pipeline the daemon uses — the same chunking
|
|
6
|
+
* (`chunkExtractionWindow` + the model's input budget), the same retry /
|
|
7
|
+
* provider-circuit semantics, the same dropped-chunk side-file recovery. It
|
|
8
|
+
* adds no extraction logic of its own.
|
|
9
|
+
*
|
|
10
|
+
* The difference is ownership: the claimed session's turns live in a drain
|
|
11
|
+
* claim (a durable file), not in a live buffer. So the runner wires a
|
|
12
|
+
* claim-backed `SmartBuffer` into the extraction queue instead of the live
|
|
13
|
+
* one. Every chunk that extracts successfully is removed from the claim
|
|
14
|
+
* immediately, which makes the drain resumable: a kill at any instant
|
|
15
|
+
* leaves the un-extracted turns in the claim, and the next run continues
|
|
16
|
+
* from there.
|
|
17
|
+
*
|
|
18
|
+
* Concurrency lives in the CLI (worker processes, one session each at a
|
|
19
|
+
* time): the in-process extraction queue is serial by design, so a single
|
|
20
|
+
* runner never runs two sessions' extractions at once.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { BufferStorage } from "../buffer-persistence.js";
|
|
24
|
+
import { BufferDrainClaims, type DrainLease } from "../storage/buffer-drain-claims.js";
|
|
25
|
+
import type { BufferEntryState, BufferState } from "../types.js";
|
|
26
|
+
import { hostname } from "node:os";
|
|
27
|
+
import { describeError } from "../buffer-turn-helpers.js";
|
|
28
|
+
import { log } from "../logger.js";
|
|
29
|
+
import { selfDeps } from "./self-deps.js";
|
|
30
|
+
import { TurnIngestionCoordinator, type TurnIngestionDeps } from "./turn-ingestion.js";
|
|
31
|
+
import type { ExtractionRunResult } from "./extraction-run.js";
|
|
32
|
+
import type { Orchestrator } from "../orchestrator.js";
|
|
33
|
+
|
|
34
|
+
export type DrainSessionStatus = "drained" | "deferred" | "failed" | "skipped";
|
|
35
|
+
|
|
36
|
+
export interface DrainSessionOutcome {
|
|
37
|
+
key: string;
|
|
38
|
+
status: DrainSessionStatus;
|
|
39
|
+
/** Turns the claim held when the drain started. */
|
|
40
|
+
turnsAtStart: number;
|
|
41
|
+
/** Turns still in the claim when the drain stopped. */
|
|
42
|
+
turnsRemaining: number;
|
|
43
|
+
/** Facts the extraction persisted during this run. */
|
|
44
|
+
persistedCount: number;
|
|
45
|
+
/** Durable outputs (memories + entities) the extraction wrote. */
|
|
46
|
+
durableOutputCount: number;
|
|
47
|
+
/** Why the session was skipped or deferred (machine-readable). */
|
|
48
|
+
reason?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface BufferDrainRunnerOptions {
|
|
52
|
+
/** Identity of this drainer; owns the lease it takes. */
|
|
53
|
+
ownerId: string;
|
|
54
|
+
/** Lease lifetime in ms. The heartbeat keeps it alive while draining. */
|
|
55
|
+
leaseMs?: number;
|
|
56
|
+
/** Cancels the run at the next chunk boundary. */
|
|
57
|
+
signal?: AbortSignal;
|
|
58
|
+
/** Progress callback (per session, and per claim transition). */
|
|
59
|
+
onEvent?: (event: DrainRunnerEvent) => void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** A failed drain run: the reason a chunk or the session could not finish. */
|
|
63
|
+
export type DrainExtractionError = Error;
|
|
64
|
+
|
|
65
|
+
export type DrainRunnerEvent =
|
|
66
|
+
| { type: "session_started"; key: string; turns: number }
|
|
67
|
+
| { type: "session_finished"; key: string; outcome: DrainSessionOutcome };
|
|
68
|
+
|
|
69
|
+
const DEFAULT_LEASE_MS = 120_000;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A `BufferStorage` view of one drain claim: the claim file IS the buffer.
|
|
73
|
+
* Writes are the drain's progress (what is left to extract), so every
|
|
74
|
+
* successfully extracted chunk is durably removed before the next one runs.
|
|
75
|
+
*/
|
|
76
|
+
class ClaimBufferStorage implements BufferStorage {
|
|
77
|
+
constructor(
|
|
78
|
+
private readonly claims: BufferDrainClaims,
|
|
79
|
+
private readonly key: string,
|
|
80
|
+
private readonly ownerId: string,
|
|
81
|
+
private readonly entry: BufferEntryState,
|
|
82
|
+
) {}
|
|
83
|
+
|
|
84
|
+
async loadBuffer(): Promise<BufferState> {
|
|
85
|
+
const entries: NonNullable<BufferState["entries"]> = Object.create(null);
|
|
86
|
+
entries[this.key] = {
|
|
87
|
+
turns: this.entry.turns,
|
|
88
|
+
retainedTurns: this.entry.retainedTurns,
|
|
89
|
+
lastExtractionAt: this.entry.lastExtractionAt,
|
|
90
|
+
extractionCount: this.entry.extractionCount,
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
turns: this.entry.turns,
|
|
94
|
+
lastExtractionAt: this.entry.lastExtractionAt,
|
|
95
|
+
extractionCount: this.entry.extractionCount,
|
|
96
|
+
entries,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async saveBuffer(state: BufferState): Promise<void> {
|
|
101
|
+
// Whole-state fallback (the claim covers one session): persist the entry.
|
|
102
|
+
const entry = state.entries?.[this.key];
|
|
103
|
+
await this.claims.writeEntry(this.key, this.ownerId, entry ?? { turns: [], lastExtractionAt: null, extractionCount: 0 }, this.entry);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async saveBufferSession(key: string, entry: BufferEntryState): Promise<void> {
|
|
107
|
+
await this.claims.writeEntry(key, this.ownerId, entry, key === this.key ? this.entry : undefined);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async deleteBufferSession(): Promise<void> {
|
|
111
|
+
// The claim is removed by the ack path, never by a buffer eviction: the
|
|
112
|
+
// drain decides when the session is finished.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export class BufferDrainRunner {
|
|
117
|
+
constructor(private readonly orchestrator: Orchestrator) {}
|
|
118
|
+
|
|
119
|
+
/** The claim store of this orchestrator's memory root. */
|
|
120
|
+
get claims(): BufferDrainClaims {
|
|
121
|
+
return this.orchestrator.storage.bufferDrainClaims();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Drain one claimed session. The caller owns the lease (it may have taken
|
|
126
|
+
* it already); this method verifies ownership before touching content.
|
|
127
|
+
*/
|
|
128
|
+
async drainSession(key: string, options: BufferDrainRunnerOptions): Promise<DrainSessionOutcome> {
|
|
129
|
+
const claims = this.claims;
|
|
130
|
+
const leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;
|
|
131
|
+
const lease: DrainLease = {
|
|
132
|
+
ownerId: options.ownerId,
|
|
133
|
+
pid: process.pid,
|
|
134
|
+
host: hostname(),
|
|
135
|
+
acquiredAt: new Date().toISOString(),
|
|
136
|
+
heartbeatAt: new Date().toISOString(),
|
|
137
|
+
leaseMs,
|
|
138
|
+
};
|
|
139
|
+
const claim = await claims.load(key);
|
|
140
|
+
if (!claim) {
|
|
141
|
+
return { key, status: "skipped", turnsAtStart: 0, turnsRemaining: 0, persistedCount: 0, durableOutputCount: 0, reason: "not_claimed" };
|
|
142
|
+
}
|
|
143
|
+
const turnsAtStart = claim.entry.turns.length + (claim.entry.retainedTurns?.length ?? 0);
|
|
144
|
+
options.onEvent?.({ type: "session_started", key, turns: turnsAtStart });
|
|
145
|
+
|
|
146
|
+
// Take the lease unless this drainer already holds it.
|
|
147
|
+
const held = await claims.adopt(key, lease);
|
|
148
|
+
if (held === "busy") {
|
|
149
|
+
const outcome: DrainSessionOutcome = {
|
|
150
|
+
key,
|
|
151
|
+
status: "skipped",
|
|
152
|
+
turnsAtStart,
|
|
153
|
+
turnsRemaining: turnsAtStart,
|
|
154
|
+
persistedCount: 0,
|
|
155
|
+
durableOutputCount: 0,
|
|
156
|
+
reason: "claimed_by_another_drain",
|
|
157
|
+
};
|
|
158
|
+
options.onEvent?.({ type: "session_finished", key, outcome });
|
|
159
|
+
return outcome;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// The claim is the buffer for this run: every successful chunk is
|
|
163
|
+
// removed from it, so a kill leaves exactly the un-extracted turns.
|
|
164
|
+
// The swap covers the whole extraction (its clear path reads the live
|
|
165
|
+
// buffer), so progress lands in the claim, not in a session file.
|
|
166
|
+
const claimStorage = new ClaimBufferStorage(claims, key, options.ownerId, claim.entry);
|
|
167
|
+
const coordinator = new TurnIngestionCoordinator(selfDeps<TurnIngestionDeps>(this.orchestrator));
|
|
168
|
+
|
|
169
|
+
// The claim's turns (retained first, like the live buffer's order).
|
|
170
|
+
const turns = [...(claim.entry.retainedTurns ?? []), ...claim.entry.turns];
|
|
171
|
+
if (turns.length === 0) {
|
|
172
|
+
await claims.ack(key, options.ownerId);
|
|
173
|
+
const outcome: DrainSessionOutcome = {
|
|
174
|
+
key,
|
|
175
|
+
status: "drained",
|
|
176
|
+
turnsAtStart,
|
|
177
|
+
turnsRemaining: 0,
|
|
178
|
+
persistedCount: 0,
|
|
179
|
+
durableOutputCount: 0,
|
|
180
|
+
};
|
|
181
|
+
options.onEvent?.({ type: "session_finished", key, outcome });
|
|
182
|
+
return outcome;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Keep the lease alive while a long extraction runs; a lost lease means
|
|
186
|
+
// another drainer took the claim, so this run must stop instead of
|
|
187
|
+
// writing progress into a claim it no longer owns.
|
|
188
|
+
const abort = new AbortController();
|
|
189
|
+
const signal = options.signal ? AbortSignal.any([options.signal, abort.signal]) : abort.signal;
|
|
190
|
+
const heartbeat = setInterval(() => {
|
|
191
|
+
void claims
|
|
192
|
+
.heartbeat(key, options.ownerId, leaseMs)
|
|
193
|
+
.then((state) => {
|
|
194
|
+
if (state === "lost") abort.abort(new Error(`buffer drain: lease lost for session ${key}`));
|
|
195
|
+
})
|
|
196
|
+
.catch((err: Error) => {
|
|
197
|
+
// A heartbeat that cannot be renewed is a lease that cannot be
|
|
198
|
+
// held: another drainer may adopt the claim, so stop this run
|
|
199
|
+
// cleanly at the next chunk boundary (the next run resumes it).
|
|
200
|
+
abort.abort(new Error(`buffer drain: lease heartbeat failed for session ${key}: ${describeError(err)}`));
|
|
201
|
+
});
|
|
202
|
+
}, Math.max(1_000, Math.floor(leaseMs / 3)));
|
|
203
|
+
heartbeat.unref?.();
|
|
204
|
+
|
|
205
|
+
const settledResult = await this.orchestrator.withBufferStorage(claimStorage, async () => {
|
|
206
|
+
const swapTurns = this.orchestrator.buffer.getTurns(key);
|
|
207
|
+
const { promise, resolve } = Promise.withResolvers<{ error?: unknown; result?: ExtractionRunResult }>();
|
|
208
|
+
let settled = false;
|
|
209
|
+
void coordinator
|
|
210
|
+
.queueBufferedExtraction(swapTurns, "trigger_mode", {
|
|
211
|
+
bufferKey: key,
|
|
212
|
+
clearBufferAfterExtraction: true,
|
|
213
|
+
// The drain owns this session's content: the daemon's own dedupe
|
|
214
|
+
// gate must not skip it, and the thresholds do not apply to a
|
|
215
|
+
// backlog.
|
|
216
|
+
skipDedupeCheck: true,
|
|
217
|
+
skipCharThreshold: true,
|
|
218
|
+
skipUserTurnThreshold: true,
|
|
219
|
+
abortSignal: signal,
|
|
220
|
+
onTaskSettled: (error, result) => {
|
|
221
|
+
if (settled) return;
|
|
222
|
+
settled = true;
|
|
223
|
+
resolve({ error, result });
|
|
224
|
+
},
|
|
225
|
+
})
|
|
226
|
+
.catch((error: DrainExtractionError) => {
|
|
227
|
+
if (settled) return;
|
|
228
|
+
settled = true;
|
|
229
|
+
resolve({ error });
|
|
230
|
+
});
|
|
231
|
+
return await promise;
|
|
232
|
+
});
|
|
233
|
+
clearInterval(heartbeat);
|
|
234
|
+
const remaining = await claims.load(key);
|
|
235
|
+
const turnsRemaining = remaining
|
|
236
|
+
? remaining.entry.turns.length + (remaining.entry.retainedTurns?.length ?? 0)
|
|
237
|
+
: 0;
|
|
238
|
+
const result = settledResult.result;
|
|
239
|
+
const persistedCount = result?.persistedCount ?? 0;
|
|
240
|
+
const durableOutputCount = result?.durableOutputCount ?? 0;
|
|
241
|
+
|
|
242
|
+
let status: DrainSessionStatus;
|
|
243
|
+
let reason: string | undefined;
|
|
244
|
+
if (turnsRemaining === 0) {
|
|
245
|
+
// Everything extracted (or dropped with a recovery side-file): the
|
|
246
|
+
// claim is finished and the session file is gone for good.
|
|
247
|
+
await claims.ack(key, options.ownerId);
|
|
248
|
+
status = "drained";
|
|
249
|
+
} else if (settledResult.error) {
|
|
250
|
+
// A failed run keeps the remaining turns for the next attempt.
|
|
251
|
+
await claims.releaseLease(key, options.ownerId);
|
|
252
|
+
status = "failed";
|
|
253
|
+
reason = describeError(settledResult.error);
|
|
254
|
+
} else {
|
|
255
|
+
// Deferred: provider breaker / backoff / a chunk still pending. The
|
|
256
|
+
// content stays claimed and the next run resumes it.
|
|
257
|
+
await claims.releaseLease(key, options.ownerId);
|
|
258
|
+
status = "deferred";
|
|
259
|
+
reason = result?.reason ?? "deferred";
|
|
260
|
+
}
|
|
261
|
+
log.info(
|
|
262
|
+
`buffer drain: session ${key} ${status} (${turnsRemaining} turn(s) remaining)`,
|
|
263
|
+
);
|
|
264
|
+
const outcome: DrainSessionOutcome = {
|
|
265
|
+
key,
|
|
266
|
+
status,
|
|
267
|
+
turnsAtStart,
|
|
268
|
+
turnsRemaining,
|
|
269
|
+
persistedCount,
|
|
270
|
+
durableOutputCount,
|
|
271
|
+
};
|
|
272
|
+
if (reason !== undefined) outcome.reason = reason;
|
|
273
|
+
options.onEvent?.({ type: "session_finished", key, outcome });
|
|
274
|
+
return outcome;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Claim a session file for the drain. Returns false when it is not claimable. */
|
|
278
|
+
async claim(key: string, ownerId: string, leaseMs = DEFAULT_LEASE_MS): Promise<boolean> {
|
|
279
|
+
const lease: DrainLease = {
|
|
280
|
+
ownerId,
|
|
281
|
+
pid: process.pid,
|
|
282
|
+
host: hostname(),
|
|
283
|
+
acquiredAt: new Date().toISOString(),
|
|
284
|
+
heartbeatAt: new Date().toISOString(),
|
|
285
|
+
leaseMs,
|
|
286
|
+
};
|
|
287
|
+
return (await this.claims.claimFromSessionFile(key, lease)) === "claimed";
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Sessions with buffered turns, claimed or not (CLI scan). */
|
|
291
|
+
async scan(): Promise<{ key: string; turns: number; claimed: boolean }[]> {
|
|
292
|
+
const sessions = await this.orchestrator.storage.loadBuffer();
|
|
293
|
+
const entries = sessions.entries ?? {};
|
|
294
|
+
const out: { key: string; turns: number; claimed: boolean }[] = [];
|
|
295
|
+
const seen = new Set<string>();
|
|
296
|
+
for (const [key, entry] of Object.entries(entries)) {
|
|
297
|
+
seen.add(key);
|
|
298
|
+
const claim = this.claims.isClaimed(key) ? await this.claims.load(key) : null;
|
|
299
|
+
const turns = claim
|
|
300
|
+
? claim.entry.turns.length + (claim.entry.retainedTurns?.length ?? 0)
|
|
301
|
+
: entry.turns.length + (entry.retainedTurns?.length ?? 0);
|
|
302
|
+
out.push({ key, turns, claimed: claim !== null });
|
|
303
|
+
}
|
|
304
|
+
// Claims the buffer state no longer lists (drained by an earlier run
|
|
305
|
+
// whose claim file outlived its session file).
|
|
306
|
+
for (const listed of await this.claims.list()) {
|
|
307
|
+
if (seen.has(listed.key)) continue;
|
|
308
|
+
out.push({ key: listed.key, turns: listed.turnCount, claimed: true });
|
|
309
|
+
}
|
|
310
|
+
return out;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoped buffer swap for the out-of-process buffer drain.
|
|
3
|
+
*
|
|
4
|
+
* The drain claims a session's turns into a durable claim file and drives
|
|
5
|
+
* the extraction against THAT buffer: a successfully extracted chunk leaves
|
|
6
|
+
* the claim (so the drain is resumable) instead of the live session file.
|
|
7
|
+
* The live buffer is restored when the task settles.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { SmartBuffer } from "../buffer.js";
|
|
11
|
+
import type { BufferStorage } from "../buffer-persistence.js";
|
|
12
|
+
import type { Orchestrator } from "../orchestrator.js";
|
|
13
|
+
|
|
14
|
+
export async function withBufferStorage<T>(
|
|
15
|
+
orchestrator: Orchestrator,
|
|
16
|
+
storage: BufferStorage,
|
|
17
|
+
task: () => Promise<T>,
|
|
18
|
+
): Promise<T> {
|
|
19
|
+
const live = orchestrator.buffer;
|
|
20
|
+
orchestrator.buffer = new SmartBuffer(orchestrator.config, storage);
|
|
21
|
+
try {
|
|
22
|
+
await orchestrator.buffer.load();
|
|
23
|
+
return await task();
|
|
24
|
+
} finally {
|
|
25
|
+
orchestrator.buffer = live;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -43,6 +43,7 @@ import type { BufferTurn, PluginConfig, SourceConnectorProvenance } from "../typ
|
|
|
43
43
|
|
|
44
44
|
import { groupTurnsByExtractionScope, bufferTurnsEqual } from "../buffer-turn-helpers.js";
|
|
45
45
|
import { ExtractionDrain } from "./extraction-drain.js";
|
|
46
|
+
import { skipClaimedSession } from "./buffer-drain-gate.js";
|
|
46
47
|
import { resolveScopeProfilePlan, type ResolvedScopeProfilePlan, hasExplicitNamespacePolicy } from "../namespaces/scope-profiles.js";
|
|
47
48
|
import { resolveCodingNamespaceOverlay, combineNamespaces } from "../coding/coding-namespace.js";
|
|
48
49
|
import { canWriteNamespace, defaultNamespaceForPrincipal } from "../namespaces/principal.js";
|
|
@@ -854,6 +855,7 @@ export class TurnIngestionCoordinator {
|
|
|
854
855
|
} = {},
|
|
855
856
|
): Promise<void> {
|
|
856
857
|
const bufferKey = options.bufferKey ?? turnsToExtract[0]?.sessionKey ?? "default";
|
|
858
|
+
if (skipClaimedSession(this.deps.buffer, bufferKey, (result) => options.onTaskSettled?.(undefined, result))) return;
|
|
857
859
|
if (
|
|
858
860
|
!options.skipDedupeCheck &&
|
|
859
861
|
!this.deps.shouldQueueExtraction(turnsToExtract, { bufferKey })
|
package/src/orchestrator.ts
CHANGED
|
@@ -21,6 +21,8 @@ import { formatDaySummaryMemories } from "./day-summary.js";
|
|
|
21
21
|
import { resolveHomeDir } from "./runtime/env.js";
|
|
22
22
|
import { migrateFromEngram } from "./migrate/from-engram.js";
|
|
23
23
|
import { SmartBuffer } from "./buffer.js";
|
|
24
|
+
import { withBufferStorage } from "./orchestration/buffer-swap.js";
|
|
25
|
+
import type { BufferStorage } from "./buffer-persistence.js";
|
|
24
26
|
import { chunkContent, type ChunkingConfig } from "./chunking.js";
|
|
25
27
|
import { semanticChunkContent, type SemanticChunkResult } from "./semantic-chunking.js";
|
|
26
28
|
import { ExtractionEngine } from "./extraction.js";
|
|
@@ -593,7 +595,7 @@ export class Orchestrator {
|
|
|
593
595
|
private readonly conversationIndexBackend?: ConversationIndexBackend;
|
|
594
596
|
readonly sharedContext?: SharedContextManager;
|
|
595
597
|
readonly compounding?: CompoundingEngine;
|
|
596
|
-
|
|
598
|
+
buffer: SmartBuffer;
|
|
597
599
|
readonly transcript: TranscriptManager;
|
|
598
600
|
readonly sessionObserver: SessionObserverState;
|
|
599
601
|
readonly summarizer: HourlySummarizer;
|
|
@@ -2348,11 +2350,7 @@ export class Orchestrator {
|
|
|
2348
2350
|
// behavior while still placing every X-ray writer in the same ordering
|
|
2349
2351
|
// domain. In particular, a pre-aborted legacy recall continues to
|
|
2350
2352
|
// resolve with an empty string rather than rejecting.
|
|
2351
|
-
const { result } = await this.runRecallWithXrayCapture(
|
|
2352
|
-
prompt,
|
|
2353
|
-
sessionKey,
|
|
2354
|
-
options,
|
|
2355
|
-
);
|
|
2353
|
+
const { result } = await this.runRecallWithXrayCapture(prompt, sessionKey, options);
|
|
2356
2354
|
return result;
|
|
2357
2355
|
}
|
|
2358
2356
|
return this.invokeRecall(prompt, sessionKey, options);
|
|
@@ -2967,6 +2965,11 @@ export class Orchestrator {
|
|
|
2967
2965
|
);
|
|
2968
2966
|
}
|
|
2969
2967
|
|
|
2968
|
+
/** Run `task` with the buffer backed by `storage` (the drain claims). */
|
|
2969
|
+
async withBufferStorage<T>(storage: BufferStorage, task: () => Promise<T>): Promise<T> {
|
|
2970
|
+
return withBufferStorage(this, storage, task);
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2970
2973
|
async flushSession(
|
|
2971
2974
|
sessionKey: string,
|
|
2972
2975
|
options: SessionFlushOptions,
|