@remnic/core 10.0.36 → 10.0.38
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 +84 -84
- package/dist/access-authorization-probe.js +85 -85
- package/dist/access-boundary.js +84 -84
- package/dist/access-citation-namespace.js +2 -2
- package/dist/access-cli.js +178 -176
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +84 -84
- package/dist/access-http-briefing.js +85 -85
- package/dist/access-http-query.js +86 -86
- package/dist/access-http.js +108 -108
- package/dist/access-identity-continuity-surface.js +84 -84
- package/dist/access-lcm-surface.js +84 -84
- package/dist/access-mcp.js +97 -97
- package/dist/access-namespace-preflight.js +84 -84
- package/dist/access-observe-write-category.js +13 -13
- package/dist/access-observe-write-surface.js +84 -84
- package/dist/access-offline-manifest.js +12 -12
- package/dist/access-operations-batch.js +88 -88
- package/dist/access-operations.js +95 -95
- package/dist/access-recall-concurrency.js +84 -84
- package/dist/access-recall-diagnostics.js +2 -2
- package/dist/access-recall-response.js +84 -84
- package/dist/access-recall-surface.js +84 -84
- package/dist/access-schema.js +8 -8
- package/dist/access-service.js +84 -84
- package/dist/access-surface-catalog.js +86 -86
- package/dist/active-recall.js +43 -43
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-VPHR3FBI.js → auto-sync-432USQDH.js} +9 -9
- package/dist/briefing.js +32 -32
- package/dist/buffer-eviction.d.ts +16 -0
- package/dist/buffer-eviction.d.ts.map +1 -0
- package/dist/buffer-eviction.js +8 -0
- package/dist/buffer-persistence.d.ts +45 -0
- package/dist/buffer-persistence.d.ts.map +1 -0
- package/dist/buffer-persistence.js +8 -0
- package/dist/buffer.d.ts +5 -2
- package/dist/buffer.d.ts.map +1 -1
- package/dist/buffer.js +13 -11
- package/dist/calibration.js +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +35 -35
- 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-FL6SLVAJ.js → chunk-2AKIVSHP.js} +2 -2
- package/dist/{chunk-ORWDCX5Q.js → chunk-3AODCBKX.js} +11 -11
- package/dist/{chunk-XFDHL252.js → chunk-3K5IEJTK.js} +4 -4
- package/dist/{chunk-6FIFEXFF.js → chunk-3PLAL2KP.js} +21 -7
- package/dist/chunk-3PLAL2KP.js.map +1 -0
- package/dist/{chunk-XVZA6VXC.js → chunk-3SL52JKD.js} +4 -4
- package/dist/{chunk-ZSAQSLKL.js → chunk-3XVBGGF3.js} +2 -2
- package/dist/{chunk-XO4HOBM2.js → chunk-4B37KNMP.js} +2 -2
- package/dist/{chunk-NIANATGL.js → chunk-4IZ6AC2U.js} +2 -2
- package/dist/chunk-4OFXLQJD.js +58 -0
- package/dist/chunk-4OFXLQJD.js.map +1 -0
- package/dist/{chunk-S2PDFSXS.js → chunk-4P4VLPGB.js} +1 -1
- package/dist/{chunk-G5UR4DXQ.js → chunk-53BLBDV6.js} +2 -2
- package/dist/{chunk-PDYP7SUC.js → chunk-5ANUG4JZ.js} +2 -2
- package/dist/{chunk-2ZYIAUYU.js → chunk-5CWH2LKL.js} +4 -4
- package/dist/{chunk-S2S4U4G3.js → chunk-5DCS4C4S.js} +4 -4
- package/dist/{chunk-7WTTE5FW.js → chunk-5K23NQRI.js} +2 -2
- package/dist/{chunk-V3JZZJ2E.js → chunk-5UPOKIFP.js} +12 -12
- package/dist/{chunk-K567EIW3.js → chunk-63YPKHAU.js} +2 -2
- package/dist/{chunk-G3T6YMBO.js → chunk-64S6X4IU.js} +7 -7
- package/dist/{chunk-HJM23E65.js → chunk-6DTIYAAN.js} +2 -2
- package/dist/{chunk-G7XAZU2L.js → chunk-6F5BGIAF.js} +3 -3
- package/dist/{chunk-IHTKBQBS.js → chunk-6JEEY42N.js} +2 -2
- package/dist/{chunk-NHB4RC3G.js → chunk-6QOL4G76.js} +2 -2
- package/dist/{chunk-AD3ZB72W.js → chunk-6SYS5YX3.js} +2 -2
- package/dist/{chunk-DFP37GUN.js → chunk-7HXZOWTR.js} +2 -2
- package/dist/{chunk-DGBWPSM6.js → chunk-7VFNGQ4V.js} +2 -2
- package/dist/{chunk-77ZK533I.js → chunk-7ZRRJ6RG.js} +2 -2
- package/dist/{chunk-GMMZ45C4.js → chunk-AVVCPA7U.js} +6 -8
- package/dist/chunk-AVVCPA7U.js.map +1 -0
- package/dist/{chunk-QISYYK4L.js → chunk-AYBAC2N4.js} +3 -3
- package/dist/{chunk-V44DWTFA.js → chunk-AYXRK264.js} +6 -6
- package/dist/{chunk-LJSBF6PW.js → chunk-C2KOW2UQ.js} +2 -2
- package/dist/{chunk-GY4R4P2A.js → chunk-CUWOSRCS.js} +2 -2
- package/dist/{chunk-VNAIUNXI.js → chunk-CVMAOPAH.js} +10 -10
- package/dist/{chunk-CJKHLACF.js → chunk-DG4H56SK.js} +2 -2
- package/dist/{chunk-BQ6DGL6A.js → chunk-DKHX2FHI.js} +2 -2
- package/dist/{chunk-77IXBNV6.js → chunk-E24RUQEN.js} +2 -2
- package/dist/{chunk-HRT2SJPC.js → chunk-E3NBMTTX.js} +2 -2
- package/dist/{chunk-PTQZPVRQ.js → chunk-E5PVMB3I.js} +2 -2
- package/dist/{chunk-AHS3QEEA.js → chunk-EEOYF3IB.js} +2 -2
- package/dist/{chunk-5XTSIZ3L.js → chunk-EGNONTVT.js} +6 -6
- package/dist/{chunk-PH33R7GN.js → chunk-EHIKY2IA.js} +2 -2
- package/dist/{chunk-4ISHIPOC.js → chunk-FGEY2AGV.js} +2 -2
- package/dist/{chunk-O6YJI5VX.js → chunk-FKTMWDN2.js} +2 -2
- package/dist/{chunk-KQUN4RSX.js → chunk-FQFMLOAC.js} +18 -18
- package/dist/{chunk-5LWODP5R.js → chunk-FRAL3EU4.js} +2 -2
- package/dist/{chunk-AAANTXCQ.js → chunk-FZVZYU5C.js} +2 -2
- package/dist/{chunk-TGAXRT7N.js → chunk-GFYFKXWZ.js} +2 -2
- package/dist/{chunk-ID2PLENW.js → chunk-GGI6FLO6.js} +2 -2
- package/dist/{chunk-GDYLZ6FR.js → chunk-HJ3UTGIW.js} +3 -3
- package/dist/{chunk-X3IFRQKS.js → chunk-I73ZSORJ.js} +4 -4
- package/dist/{chunk-X73SCHKR.js → chunk-I75BWXRZ.js} +2 -2
- package/dist/{chunk-M3GKSCFN.js → chunk-J7G656MY.js} +4 -4
- package/dist/{chunk-EH6KLYIE.js → chunk-JF3MEIHO.js} +4 -4
- package/dist/{chunk-XUB4I2N6.js → chunk-JFI3ATK4.js} +2 -2
- package/dist/{chunk-R4SATHCV.js → chunk-JH2ALMPR.js} +2 -2
- package/dist/{chunk-TKBW4YLS.js → chunk-JH4FCVWJ.js} +2 -2
- package/dist/{chunk-DG5UKN2Y.js → chunk-JIA435P3.js} +2 -2
- package/dist/chunk-KASJJGRG.js +29 -0
- package/dist/chunk-KASJJGRG.js.map +1 -0
- package/dist/{chunk-4Z7O2QVJ.js → chunk-KOAVX2IT.js} +2 -2
- package/dist/{chunk-6NXHX6MI.js → chunk-KOY25HUB.js} +2 -2
- package/dist/{chunk-TRW7N4FS.js → chunk-L2JQSG5M.js} +2 -2
- package/dist/{chunk-QQ4T622E.js → chunk-L7PGPH4E.js} +2 -2
- package/dist/{chunk-TYT4TEQV.js → chunk-LDWE7OZS.js} +6 -2
- package/dist/chunk-LDWE7OZS.js.map +1 -0
- package/dist/{chunk-23VGZ65V.js → chunk-LHBOFROT.js} +2 -2
- package/dist/{chunk-VKB2FGNW.js → chunk-LOMSBYNS.js} +90 -90
- package/dist/{chunk-NDJ42GKB.js → chunk-MCPSMWUC.js} +6 -6
- package/dist/{chunk-ERMT5WQM.js → chunk-MKE5DP3S.js} +2 -2
- package/dist/{chunk-64IO6ZEE.js → chunk-MZWHIAOL.js} +2 -2
- package/dist/{chunk-LDXS746V.js → chunk-N7DVBHU3.js} +3 -3
- package/dist/{chunk-F2JLBXMG.js → chunk-NH6GZEQN.js} +8 -8
- package/dist/{chunk-7FG2JSU6.js → chunk-NMKETOAX.js} +2 -2
- package/dist/{chunk-GAARPWMN.js → chunk-OKKBOTRA.js} +2 -2
- package/dist/{chunk-PCIIKQXW.js → chunk-OLH4XCLU.js} +2 -2
- package/dist/{chunk-XA32GZ6B.js → chunk-OLHN4ZNT.js} +3 -3
- package/dist/{chunk-UR25IQVT.js → chunk-P5CUEB2Q.js} +8 -8
- package/dist/{chunk-LO775P3S.js → chunk-POGPI5GR.js} +2 -2
- package/dist/{chunk-FXO43NBW.js → chunk-PSQ2P2T3.js} +3 -3
- package/dist/{chunk-KRAMCBIW.js → chunk-QKXPOLQD.js} +4 -4
- package/dist/{chunk-65JLKIVA.js → chunk-QO5KDQGG.js} +8 -8
- package/dist/{chunk-A4B7WL5N.js → chunk-QOUKZ2N3.js} +2 -2
- package/dist/{chunk-ZABEDRGQ.js → chunk-RGKXF4W3.js} +2 -2
- package/dist/{chunk-IKCGNTGS.js → chunk-RWRHGE75.js} +2 -2
- package/dist/{chunk-NBH7IRME.js → chunk-SWZOAQUM.js} +54 -54
- package/dist/{chunk-FQ52AJXX.js → chunk-SZPPCEYT.js} +2 -2
- package/dist/{chunk-4YYIZ475.js → chunk-TAEJ2MRR.js} +52 -52
- package/dist/{chunk-3ODEGTVV.js → chunk-TDCR6PQL.js} +2 -2
- package/dist/{chunk-QCP75JGO.js → chunk-TFA6HPOA.js} +5 -5
- package/dist/{chunk-BBDASWNT.js → chunk-TJ5YGCPV.js} +81 -76
- package/dist/chunk-TJ5YGCPV.js.map +1 -0
- package/dist/{chunk-SE3JAD22.js → chunk-TPKB7T6Z.js} +2 -2
- package/dist/{chunk-6VYY2XFK.js → chunk-TVIGN3XZ.js} +19 -19
- package/dist/{chunk-OHMGR6QN.js → chunk-TXP7Q7T5.js} +2 -2
- package/dist/{chunk-ZG3HZZ6K.js → chunk-TYGLV6ZG.js} +5 -1
- package/dist/{chunk-ZG3HZZ6K.js.map → chunk-TYGLV6ZG.js.map} +1 -1
- package/dist/{chunk-AI2VXOSO.js → chunk-TYLNWE4D.js} +2 -2
- package/dist/{chunk-WI6MIJYK.js → chunk-U7HJBODU.js} +5 -5
- package/dist/{chunk-IS4HKNWP.js → chunk-UBN5AOLT.js} +2 -2
- package/dist/{chunk-A6PKEU7T.js → chunk-UFM3PJDT.js} +1 -1
- package/dist/chunk-UFM3PJDT.js.map +1 -0
- package/dist/{chunk-JNELS2TW.js → chunk-UJDTXWMT.js} +2 -2
- package/dist/{chunk-DJMC4W6N.js → chunk-VC3X7XP3.js} +2 -2
- package/dist/{chunk-A2D3WICT.js → chunk-VGFNTY3Y.js} +2 -2
- package/dist/{chunk-X544TW54.js → chunk-VGRM43X6.js} +2 -2
- package/dist/{chunk-CSGFGQBI.js → chunk-VPO53QMG.js} +2 -2
- package/dist/{chunk-BRZRP5WD.js → chunk-VSSQIBVU.js} +2 -2
- package/dist/{chunk-O3VKQMWC.js → chunk-WCBLPKG3.js} +366 -168
- package/dist/chunk-WCBLPKG3.js.map +1 -0
- package/dist/{chunk-GKNX4QO3.js → chunk-WCIDCJOQ.js} +3 -3
- package/dist/{chunk-7VJEZQYF.js → chunk-WEK3OUGO.js} +3 -3
- package/dist/{chunk-IVYAPAHG.js → chunk-WRDFYSUC.js} +2 -2
- package/dist/{chunk-5EILJ6W2.js → chunk-WXPBDEMW.js} +2 -2
- package/dist/{chunk-QZP3RMYP.js → chunk-X247CYL6.js} +4 -4
- package/dist/{chunk-UAYA4NJN.js → chunk-XHVO3CGX.js} +28 -36
- package/dist/chunk-XHVO3CGX.js.map +1 -0
- package/dist/{chunk-YLF42JQ7.js → chunk-XHX67LX6.js} +2 -2
- package/dist/{chunk-C6S2Y7HE.js → chunk-XKDQTDXN.js} +4 -4
- package/dist/{chunk-4AHKNZW7.js → chunk-XLEP7SS3.js} +2 -2
- package/dist/{chunk-B6L7BKA7.js → chunk-XRFLR3XF.js} +4 -4
- package/dist/{chunk-H7QC7WCU.js → chunk-XTBEXZFN.js} +4 -4
- package/dist/{chunk-CIJRM6SQ.js → chunk-Y5ZHZKZD.js} +2 -2
- package/dist/{chunk-H6SKBCNI.js → chunk-YC2C67F7.js} +2 -2
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-YOL56HY5.js → chunk-YQ6SLFNZ.js} +3 -3
- package/dist/{chunk-SIIWHIBK.js → chunk-YYGZ4EIY.js} +2 -2
- package/dist/{chunk-G22A6WJQ.js → chunk-Z2T5BPOZ.js} +2 -2
- package/dist/{chunk-RYUSWAAU.js → chunk-ZAP7BKTZ.js} +6 -6
- package/dist/cli.js +136 -136
- package/dist/coding/export-okf-codegraph.js +33 -33
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +34 -34
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -43
- package/dist/connectors/codex-materialize-runner.js +32 -32
- package/dist/connectors/index.js +32 -32
- package/dist/contradiction/index.js +5 -5
- package/dist/convergence-refresh.js +34 -34
- package/dist/conversation-index/backend.js +2 -2
- package/dist/corpus-watermark.js +34 -34
- package/dist/dashboard-runtime.js +2 -2
- package/dist/deep-recall-http-glue.js +9 -9
- package/dist/deep-recall-policy-llm.js +2 -2
- package/dist/entity-retrieval.js +34 -34
- package/dist/explicit-capture.js +7 -7
- package/dist/external-wiki-access.js +85 -85
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge.d.ts +42 -2
- package/dist/extraction-judge.d.ts.map +1 -1
- package/dist/extraction-judge.js +12 -2
- package/dist/extraction-span-materialize.js +2 -2
- package/dist/extraction.js +47 -47
- package/dist/fallback-llm.d.ts +1 -0
- package/dist/fallback-llm.d.ts.map +1 -1
- package/dist/fallback-llm.js +1 -1
- 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 +33 -33
- package/dist/harmonic-source-lookup.js +2 -2
- package/dist/index.js +236 -234
- package/dist/lcm/index.js +3 -3
- package/dist/location/index.js +35 -35
- package/dist/maintenance/memory-governance.js +32 -32
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +32 -32
- package/dist/maintenance/rebuild-memory-projection-runner.js +34 -34
- package/dist/maintenance/rebuild-memory-projection.js +33 -33
- package/dist/memory-browse-operations.js +85 -85
- package/dist/memory-browse.js +5 -5
- package/dist/memory-subject.js +3 -3
- package/dist/namespaces/migrate.js +33 -33
- package/dist/namespaces/search.js +11 -11
- package/dist/namespaces/storage.js +32 -32
- package/dist/offline-sync-changeset-generations.js +3 -3
- package/dist/offline-sync-embedding-generation.js +2 -2
- package/dist/offline-sync-file-io.js +2 -2
- package/dist/offline-sync-impression-drain.js +3 -3
- package/dist/offline-sync-runtime-state.d.ts.map +1 -1
- package/dist/offline-sync-runtime-state.js +1 -1
- package/dist/offline-sync-snapshot-stream.js +8 -8
- package/dist/offline-sync-upload-staging.js +3 -3
- package/dist/offline-sync.js +8 -8
- package/dist/operator-doctor-corpus.js +35 -35
- package/dist/operator-toolkit.js +54 -54
- package/dist/orchestration/maintenance.js +44 -44
- package/dist/orchestrator.js +183 -181
- package/dist/qmd.js +4 -4
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.js +2 -2
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-navigation-operations.js +85 -85
- package/dist/recall-navigation.js +84 -84
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state-view-admission.js +5 -5
- package/dist/recall-why-service.js +5 -5
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/manifest.js +3 -3
- package/dist/{resolution-V6JBMW7U.js → resolution-4ZEQPXUZ.js} +6 -6
- package/dist/resolution-4ZEQPXUZ.js.map +1 -0
- package/dist/resume-bundles.js +44 -44
- package/dist/retrieval-agents.js +2 -2
- package/dist/salvage-envelope.js +5 -5
- package/dist/search/factory.js +10 -10
- package/dist/search/index.js +14 -14
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/secure-store/index.js +2 -2
- package/dist/semantic-consolidation.js +33 -33
- package/dist/semantic-rule-promotion.js +32 -32
- package/dist/semantic-rule-verifier.js +32 -32
- package/dist/source-agent-qualifier.js +37 -37
- package/dist/standup/build.js +32 -32
- package/dist/storage/buffer-session-files.d.ts +69 -0
- package/dist/storage/buffer-session-files.d.ts.map +1 -0
- package/dist/storage.d.ts +5 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +31 -31
- package/dist/subject-config.js +4 -4
- package/dist/summarizer.js +2 -2
- package/dist/support-passport/index.js +87 -87
- package/dist/transfer/export-okf.js +33 -33
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +32 -32
- package/dist/who-knows-cli.js +33 -33
- package/dist/who-knows.js +32 -32
- package/dist/write-envelope.js +4 -4
- package/package.json +2 -2
- package/src/buffer-eviction.ts +51 -0
- package/src/buffer-incremental-persistence.test.ts +256 -0
- package/src/buffer-persistence.ts +89 -0
- package/src/buffer.ts +32 -61
- package/src/config.test.ts +16 -0
- package/src/config.ts +14 -0
- package/src/extraction-judge-chain.test.ts +298 -2
- package/src/extraction-judge.ts +147 -82
- package/src/fallback-llm.test.ts +94 -0
- package/src/fallback-llm.ts +7 -7
- package/src/offline-sync-runtime-state.ts +24 -2
- package/src/offline-sync.test.ts +9 -0
- package/src/secure-store/secure-fs.ts +11 -0
- package/src/secure-store/secure-store.test.ts +22 -0
- package/src/storage/buffer-session-files.ts +249 -0
- package/src/storage-buffer-sessions.test.ts +369 -0
- package/src/storage.ts +11 -16
- package/src/types.ts +12 -0
- package/dist/chunk-6FIFEXFF.js.map +0 -1
- package/dist/chunk-A6PKEU7T.js.map +0 -1
- package/dist/chunk-BBDASWNT.js.map +0 -1
- package/dist/chunk-GMMZ45C4.js.map +0 -1
- package/dist/chunk-O3VKQMWC.js.map +0 -1
- package/dist/chunk-TYT4TEQV.js.map +0 -1
- package/dist/chunk-UAYA4NJN.js.map +0 -1
- /package/dist/{auto-sync-VPHR3FBI.js.map → auto-sync-432USQDH.js.map} +0 -0
- /package/dist/{graph-edge-decay-IU75NV42.js.map → buffer-eviction.js.map} +0 -0
- /package/dist/{resolution-V6JBMW7U.js.map → buffer-persistence.js.map} +0 -0
- /package/dist/{chunk-FL6SLVAJ.js.map → chunk-2AKIVSHP.js.map} +0 -0
- /package/dist/{chunk-ORWDCX5Q.js.map → chunk-3AODCBKX.js.map} +0 -0
- /package/dist/{chunk-XFDHL252.js.map → chunk-3K5IEJTK.js.map} +0 -0
- /package/dist/{chunk-XVZA6VXC.js.map → chunk-3SL52JKD.js.map} +0 -0
- /package/dist/{chunk-ZSAQSLKL.js.map → chunk-3XVBGGF3.js.map} +0 -0
- /package/dist/{chunk-XO4HOBM2.js.map → chunk-4B37KNMP.js.map} +0 -0
- /package/dist/{chunk-NIANATGL.js.map → chunk-4IZ6AC2U.js.map} +0 -0
- /package/dist/{chunk-S2PDFSXS.js.map → chunk-4P4VLPGB.js.map} +0 -0
- /package/dist/{chunk-G5UR4DXQ.js.map → chunk-53BLBDV6.js.map} +0 -0
- /package/dist/{chunk-PDYP7SUC.js.map → chunk-5ANUG4JZ.js.map} +0 -0
- /package/dist/{chunk-2ZYIAUYU.js.map → chunk-5CWH2LKL.js.map} +0 -0
- /package/dist/{chunk-S2S4U4G3.js.map → chunk-5DCS4C4S.js.map} +0 -0
- /package/dist/{chunk-7WTTE5FW.js.map → chunk-5K23NQRI.js.map} +0 -0
- /package/dist/{chunk-V3JZZJ2E.js.map → chunk-5UPOKIFP.js.map} +0 -0
- /package/dist/{chunk-K567EIW3.js.map → chunk-63YPKHAU.js.map} +0 -0
- /package/dist/{chunk-G3T6YMBO.js.map → chunk-64S6X4IU.js.map} +0 -0
- /package/dist/{chunk-HJM23E65.js.map → chunk-6DTIYAAN.js.map} +0 -0
- /package/dist/{chunk-G7XAZU2L.js.map → chunk-6F5BGIAF.js.map} +0 -0
- /package/dist/{chunk-IHTKBQBS.js.map → chunk-6JEEY42N.js.map} +0 -0
- /package/dist/{chunk-NHB4RC3G.js.map → chunk-6QOL4G76.js.map} +0 -0
- /package/dist/{chunk-AD3ZB72W.js.map → chunk-6SYS5YX3.js.map} +0 -0
- /package/dist/{chunk-DFP37GUN.js.map → chunk-7HXZOWTR.js.map} +0 -0
- /package/dist/{chunk-DGBWPSM6.js.map → chunk-7VFNGQ4V.js.map} +0 -0
- /package/dist/{chunk-77ZK533I.js.map → chunk-7ZRRJ6RG.js.map} +0 -0
- /package/dist/{chunk-QISYYK4L.js.map → chunk-AYBAC2N4.js.map} +0 -0
- /package/dist/{chunk-V44DWTFA.js.map → chunk-AYXRK264.js.map} +0 -0
- /package/dist/{chunk-LJSBF6PW.js.map → chunk-C2KOW2UQ.js.map} +0 -0
- /package/dist/{chunk-GY4R4P2A.js.map → chunk-CUWOSRCS.js.map} +0 -0
- /package/dist/{chunk-VNAIUNXI.js.map → chunk-CVMAOPAH.js.map} +0 -0
- /package/dist/{chunk-CJKHLACF.js.map → chunk-DG4H56SK.js.map} +0 -0
- /package/dist/{chunk-BQ6DGL6A.js.map → chunk-DKHX2FHI.js.map} +0 -0
- /package/dist/{chunk-77IXBNV6.js.map → chunk-E24RUQEN.js.map} +0 -0
- /package/dist/{chunk-HRT2SJPC.js.map → chunk-E3NBMTTX.js.map} +0 -0
- /package/dist/{chunk-PTQZPVRQ.js.map → chunk-E5PVMB3I.js.map} +0 -0
- /package/dist/{chunk-AHS3QEEA.js.map → chunk-EEOYF3IB.js.map} +0 -0
- /package/dist/{chunk-5XTSIZ3L.js.map → chunk-EGNONTVT.js.map} +0 -0
- /package/dist/{chunk-PH33R7GN.js.map → chunk-EHIKY2IA.js.map} +0 -0
- /package/dist/{chunk-4ISHIPOC.js.map → chunk-FGEY2AGV.js.map} +0 -0
- /package/dist/{chunk-O6YJI5VX.js.map → chunk-FKTMWDN2.js.map} +0 -0
- /package/dist/{chunk-KQUN4RSX.js.map → chunk-FQFMLOAC.js.map} +0 -0
- /package/dist/{chunk-5LWODP5R.js.map → chunk-FRAL3EU4.js.map} +0 -0
- /package/dist/{chunk-AAANTXCQ.js.map → chunk-FZVZYU5C.js.map} +0 -0
- /package/dist/{chunk-TGAXRT7N.js.map → chunk-GFYFKXWZ.js.map} +0 -0
- /package/dist/{chunk-ID2PLENW.js.map → chunk-GGI6FLO6.js.map} +0 -0
- /package/dist/{chunk-GDYLZ6FR.js.map → chunk-HJ3UTGIW.js.map} +0 -0
- /package/dist/{chunk-X3IFRQKS.js.map → chunk-I73ZSORJ.js.map} +0 -0
- /package/dist/{chunk-X73SCHKR.js.map → chunk-I75BWXRZ.js.map} +0 -0
- /package/dist/{chunk-M3GKSCFN.js.map → chunk-J7G656MY.js.map} +0 -0
- /package/dist/{chunk-EH6KLYIE.js.map → chunk-JF3MEIHO.js.map} +0 -0
- /package/dist/{chunk-XUB4I2N6.js.map → chunk-JFI3ATK4.js.map} +0 -0
- /package/dist/{chunk-R4SATHCV.js.map → chunk-JH2ALMPR.js.map} +0 -0
- /package/dist/{chunk-TKBW4YLS.js.map → chunk-JH4FCVWJ.js.map} +0 -0
- /package/dist/{chunk-DG5UKN2Y.js.map → chunk-JIA435P3.js.map} +0 -0
- /package/dist/{chunk-4Z7O2QVJ.js.map → chunk-KOAVX2IT.js.map} +0 -0
- /package/dist/{chunk-6NXHX6MI.js.map → chunk-KOY25HUB.js.map} +0 -0
- /package/dist/{chunk-TRW7N4FS.js.map → chunk-L2JQSG5M.js.map} +0 -0
- /package/dist/{chunk-QQ4T622E.js.map → chunk-L7PGPH4E.js.map} +0 -0
- /package/dist/{chunk-23VGZ65V.js.map → chunk-LHBOFROT.js.map} +0 -0
- /package/dist/{chunk-VKB2FGNW.js.map → chunk-LOMSBYNS.js.map} +0 -0
- /package/dist/{chunk-NDJ42GKB.js.map → chunk-MCPSMWUC.js.map} +0 -0
- /package/dist/{chunk-ERMT5WQM.js.map → chunk-MKE5DP3S.js.map} +0 -0
- /package/dist/{chunk-64IO6ZEE.js.map → chunk-MZWHIAOL.js.map} +0 -0
- /package/dist/{chunk-LDXS746V.js.map → chunk-N7DVBHU3.js.map} +0 -0
- /package/dist/{chunk-F2JLBXMG.js.map → chunk-NH6GZEQN.js.map} +0 -0
- /package/dist/{chunk-7FG2JSU6.js.map → chunk-NMKETOAX.js.map} +0 -0
- /package/dist/{chunk-GAARPWMN.js.map → chunk-OKKBOTRA.js.map} +0 -0
- /package/dist/{chunk-PCIIKQXW.js.map → chunk-OLH4XCLU.js.map} +0 -0
- /package/dist/{chunk-XA32GZ6B.js.map → chunk-OLHN4ZNT.js.map} +0 -0
- /package/dist/{chunk-UR25IQVT.js.map → chunk-P5CUEB2Q.js.map} +0 -0
- /package/dist/{chunk-LO775P3S.js.map → chunk-POGPI5GR.js.map} +0 -0
- /package/dist/{chunk-FXO43NBW.js.map → chunk-PSQ2P2T3.js.map} +0 -0
- /package/dist/{chunk-KRAMCBIW.js.map → chunk-QKXPOLQD.js.map} +0 -0
- /package/dist/{chunk-65JLKIVA.js.map → chunk-QO5KDQGG.js.map} +0 -0
- /package/dist/{chunk-A4B7WL5N.js.map → chunk-QOUKZ2N3.js.map} +0 -0
- /package/dist/{chunk-ZABEDRGQ.js.map → chunk-RGKXF4W3.js.map} +0 -0
- /package/dist/{chunk-IKCGNTGS.js.map → chunk-RWRHGE75.js.map} +0 -0
- /package/dist/{chunk-NBH7IRME.js.map → chunk-SWZOAQUM.js.map} +0 -0
- /package/dist/{chunk-FQ52AJXX.js.map → chunk-SZPPCEYT.js.map} +0 -0
- /package/dist/{chunk-4YYIZ475.js.map → chunk-TAEJ2MRR.js.map} +0 -0
- /package/dist/{chunk-3ODEGTVV.js.map → chunk-TDCR6PQL.js.map} +0 -0
- /package/dist/{chunk-QCP75JGO.js.map → chunk-TFA6HPOA.js.map} +0 -0
- /package/dist/{chunk-SE3JAD22.js.map → chunk-TPKB7T6Z.js.map} +0 -0
- /package/dist/{chunk-6VYY2XFK.js.map → chunk-TVIGN3XZ.js.map} +0 -0
- /package/dist/{chunk-OHMGR6QN.js.map → chunk-TXP7Q7T5.js.map} +0 -0
- /package/dist/{chunk-AI2VXOSO.js.map → chunk-TYLNWE4D.js.map} +0 -0
- /package/dist/{chunk-WI6MIJYK.js.map → chunk-U7HJBODU.js.map} +0 -0
- /package/dist/{chunk-IS4HKNWP.js.map → chunk-UBN5AOLT.js.map} +0 -0
- /package/dist/{chunk-JNELS2TW.js.map → chunk-UJDTXWMT.js.map} +0 -0
- /package/dist/{chunk-DJMC4W6N.js.map → chunk-VC3X7XP3.js.map} +0 -0
- /package/dist/{chunk-A2D3WICT.js.map → chunk-VGFNTY3Y.js.map} +0 -0
- /package/dist/{chunk-X544TW54.js.map → chunk-VGRM43X6.js.map} +0 -0
- /package/dist/{chunk-CSGFGQBI.js.map → chunk-VPO53QMG.js.map} +0 -0
- /package/dist/{chunk-BRZRP5WD.js.map → chunk-VSSQIBVU.js.map} +0 -0
- /package/dist/{chunk-GKNX4QO3.js.map → chunk-WCIDCJOQ.js.map} +0 -0
- /package/dist/{chunk-7VJEZQYF.js.map → chunk-WEK3OUGO.js.map} +0 -0
- /package/dist/{chunk-IVYAPAHG.js.map → chunk-WRDFYSUC.js.map} +0 -0
- /package/dist/{chunk-5EILJ6W2.js.map → chunk-WXPBDEMW.js.map} +0 -0
- /package/dist/{chunk-QZP3RMYP.js.map → chunk-X247CYL6.js.map} +0 -0
- /package/dist/{chunk-YLF42JQ7.js.map → chunk-XHX67LX6.js.map} +0 -0
- /package/dist/{chunk-C6S2Y7HE.js.map → chunk-XKDQTDXN.js.map} +0 -0
- /package/dist/{chunk-4AHKNZW7.js.map → chunk-XLEP7SS3.js.map} +0 -0
- /package/dist/{chunk-B6L7BKA7.js.map → chunk-XRFLR3XF.js.map} +0 -0
- /package/dist/{chunk-H7QC7WCU.js.map → chunk-XTBEXZFN.js.map} +0 -0
- /package/dist/{chunk-CIJRM6SQ.js.map → chunk-Y5ZHZKZD.js.map} +0 -0
- /package/dist/{chunk-H6SKBCNI.js.map → chunk-YC2C67F7.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-YOL56HY5.js.map → chunk-YQ6SLFNZ.js.map} +0 -0
- /package/dist/{chunk-SIIWHIBK.js.map → chunk-YYGZ4EIY.js.map} +0 -0
- /package/dist/{chunk-G22A6WJQ.js.map → chunk-Z2T5BPOZ.js.map} +0 -0
- /package/dist/{chunk-RYUSWAAU.js.map → chunk-ZAP7BKTZ.js.map} +0 -0
package/dist/who-knows.js
CHANGED
|
@@ -9,37 +9,37 @@ import {
|
|
|
9
9
|
loadWhoKnowsEntities,
|
|
10
10
|
tokenizeTopic,
|
|
11
11
|
validateWhoKnowsInput
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-DM5QZ3YU.js";
|
|
12
|
+
} from "./chunk-VSSQIBVU.js";
|
|
13
|
+
import "./chunk-WCBLPKG3.js";
|
|
15
14
|
import "./chunk-UHVXE24Y.js";
|
|
15
|
+
import "./chunk-DM5QZ3YU.js";
|
|
16
16
|
import "./chunk-VY6BD5KB.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-JH4FCVWJ.js";
|
|
18
|
+
import "./chunk-LHBOFROT.js";
|
|
19
|
+
import "./chunk-P5CUEB2Q.js";
|
|
20
|
+
import "./chunk-XRFLR3XF.js";
|
|
20
21
|
import "./chunk-7VO6E5UD.js";
|
|
21
22
|
import "./chunk-EXYT52NR.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-CYEPCZN5.js";
|
|
25
|
-
import "./chunk-B6L7BKA7.js";
|
|
26
|
-
import "./chunk-Y5NLBXPV.js";
|
|
23
|
+
import "./chunk-5CWH2LKL.js";
|
|
24
|
+
import "./chunk-XKDQTDXN.js";
|
|
27
25
|
import "./chunk-WNEVEMJ3.js";
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-Y5NLBXPV.js";
|
|
27
|
+
import "./chunk-CYEPCZN5.js";
|
|
28
|
+
import "./chunk-TFA6HPOA.js";
|
|
30
29
|
import "./chunk-F4TWWUMP.js";
|
|
31
30
|
import "./chunk-72A4L5JJ.js";
|
|
31
|
+
import "./chunk-A7Q43EUZ.js";
|
|
32
32
|
import "./chunk-S2V7RUCL.js";
|
|
33
33
|
import "./chunk-PPUNC7UX.js";
|
|
34
34
|
import "./chunk-X3724WL4.js";
|
|
35
|
-
import "./chunk-S2HLHAZ4.js";
|
|
36
35
|
import "./chunk-MRPOZBJC.js";
|
|
36
|
+
import "./chunk-S2HLHAZ4.js";
|
|
37
37
|
import "./chunk-DM2T26WE.js";
|
|
38
38
|
import "./chunk-LDXUBPMO.js";
|
|
39
39
|
import "./chunk-FF6N7BXC.js";
|
|
40
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-WXPBDEMW.js";
|
|
41
41
|
import "./chunk-AAD2ZS6P.js";
|
|
42
|
-
import "./chunk-
|
|
42
|
+
import "./chunk-YQ6SLFNZ.js";
|
|
43
43
|
import "./chunk-ZIKENA2C.js";
|
|
44
44
|
import "./chunk-YXZG5TVN.js";
|
|
45
45
|
import "./chunk-3OUGSOJP.js";
|
|
@@ -55,45 +55,45 @@ import "./chunk-LWRIGKFM.js";
|
|
|
55
55
|
import "./chunk-5WITETWU.js";
|
|
56
56
|
import "./chunk-6CIAGZ6X.js";
|
|
57
57
|
import "./chunk-7CT3AI52.js";
|
|
58
|
-
import "./chunk-
|
|
59
|
-
import "./chunk-
|
|
60
|
-
import "./chunk-L2EXJQJP.js";
|
|
61
|
-
import "./chunk-45GF7Y3V.js";
|
|
62
|
-
import "./chunk-YIJECSIX.js";
|
|
63
|
-
import "./chunk-E2AWJ7KQ.js";
|
|
64
|
-
import "./chunk-UUZ7KZAO.js";
|
|
65
|
-
import "./chunk-V44DWTFA.js";
|
|
58
|
+
import "./chunk-AYXRK264.js";
|
|
59
|
+
import "./chunk-IUM3VSHI.js";
|
|
66
60
|
import "./chunk-G26YNEOC.js";
|
|
67
61
|
import "./chunk-VILPVT4S.js";
|
|
68
62
|
import "./chunk-AF2XMJKD.js";
|
|
69
63
|
import "./chunk-OR42ZI54.js";
|
|
70
|
-
import "./chunk-
|
|
64
|
+
import "./chunk-23G5P7TA.js";
|
|
71
65
|
import "./chunk-C64XATK7.js";
|
|
72
66
|
import "./chunk-42JKGUFJ.js";
|
|
73
|
-
import "./chunk-
|
|
67
|
+
import "./chunk-AVVCPA7U.js";
|
|
68
|
+
import "./chunk-I55KAVET.js";
|
|
69
|
+
import "./chunk-L2EXJQJP.js";
|
|
70
|
+
import "./chunk-45GF7Y3V.js";
|
|
71
|
+
import "./chunk-YIJECSIX.js";
|
|
72
|
+
import "./chunk-E2AWJ7KQ.js";
|
|
73
|
+
import "./chunk-UUZ7KZAO.js";
|
|
74
74
|
import "./chunk-HADD45AR.js";
|
|
75
75
|
import "./chunk-RNFMFC37.js";
|
|
76
76
|
import "./chunk-YCVB7X56.js";
|
|
77
77
|
import "./chunk-PQVCH2AE.js";
|
|
78
78
|
import "./chunk-PJKTFXE2.js";
|
|
79
79
|
import "./chunk-W5BIQOAJ.js";
|
|
80
|
-
import "./chunk-
|
|
80
|
+
import "./chunk-UFM3PJDT.js";
|
|
81
81
|
import "./chunk-YBA52OKG.js";
|
|
82
|
-
import "./chunk-
|
|
82
|
+
import "./chunk-TDCR6PQL.js";
|
|
83
83
|
import "./chunk-BT7NVCML.js";
|
|
84
|
-
import "./chunk-
|
|
84
|
+
import "./chunk-E5PVMB3I.js";
|
|
85
85
|
import "./chunk-BJMBJZ2Y.js";
|
|
86
86
|
import "./chunk-UKJAGEXH.js";
|
|
87
87
|
import "./chunk-FP2373TW.js";
|
|
88
88
|
import "./chunk-L272A5QW.js";
|
|
89
|
-
import "./chunk-
|
|
89
|
+
import "./chunk-UJDTXWMT.js";
|
|
90
90
|
import "./chunk-ZA53AZND.js";
|
|
91
91
|
import "./chunk-7RJUVTVF.js";
|
|
92
92
|
import "./chunk-AL3UYZ5N.js";
|
|
93
93
|
import "./chunk-RL6NEVXT.js";
|
|
94
94
|
import "./chunk-YET735EZ.js";
|
|
95
95
|
import "./chunk-PWPIERBM.js";
|
|
96
|
-
import "./chunk-
|
|
96
|
+
import "./chunk-UBN5AOLT.js";
|
|
97
97
|
import "./chunk-5FVVY2EB.js";
|
|
98
98
|
import "./chunk-BTNNL7ZW.js";
|
|
99
99
|
import "./chunk-JDSVLVCG.js";
|
|
@@ -111,7 +111,7 @@ import "./chunk-3MUKQQ7A.js";
|
|
|
111
111
|
import "./chunk-R2MBW2S4.js";
|
|
112
112
|
import "./chunk-QUIRIG2P.js";
|
|
113
113
|
import "./chunk-LDPPTPO5.js";
|
|
114
|
-
import "./chunk-
|
|
114
|
+
import "./chunk-TYGLV6ZG.js";
|
|
115
115
|
import "./chunk-A6XUJE5D.js";
|
|
116
116
|
import "./chunk-C7HJ3NEI.js";
|
|
117
117
|
import "./chunk-VS2IYZRU.js";
|
package/dist/write-envelope.js
CHANGED
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
isMemoryCategory,
|
|
13
13
|
isSealedMemoryEnvelope,
|
|
14
14
|
sealedWriteToLegacyArgs
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-TDCR6PQL.js";
|
|
16
16
|
import "./chunk-BT7NVCML.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-E5PVMB3I.js";
|
|
18
|
+
import "./chunk-UBN5AOLT.js";
|
|
19
19
|
import "./chunk-5FVVY2EB.js";
|
|
20
20
|
import "./chunk-JDSVLVCG.js";
|
|
21
21
|
import "./chunk-5GKPFL3S.js";
|
|
@@ -24,7 +24,7 @@ import "./chunk-EBRG7ZIK.js";
|
|
|
24
24
|
import "./chunk-P7FMDTKL.js";
|
|
25
25
|
import "./chunk-X4OZMANG.js";
|
|
26
26
|
import "./chunk-R2MBW2S4.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-TYGLV6ZG.js";
|
|
28
28
|
import "./chunk-A6XUJE5D.js";
|
|
29
29
|
import "./chunk-C7HJ3NEI.js";
|
|
30
30
|
import "./chunk-VS2IYZRU.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.38",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3347,7 +3347,7 @@
|
|
|
3347
3347
|
"core"
|
|
3348
3348
|
],
|
|
3349
3349
|
"peerDependencies": {
|
|
3350
|
-
"@remnic/coding-graph": "^10.0.
|
|
3350
|
+
"@remnic/coding-graph": "^10.0.38"
|
|
3351
3351
|
},
|
|
3352
3352
|
"peerDependenciesMeta": {
|
|
3353
3353
|
"@remnic/coding-graph": {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BufferEntryState } from "./types.js";
|
|
2
|
+
|
|
3
|
+
const EMPTY_ENTRY: BufferEntryState = { turns: [], lastExtractionAt: null, extractionCount: 0 };
|
|
4
|
+
|
|
5
|
+
export interface BufferEvictionHooks {
|
|
6
|
+
/** Last activity time (ms) of an entry; older entries are evicted first. */
|
|
7
|
+
activityAt(entry: BufferEntryState): number;
|
|
8
|
+
/** Accepted captures exit via refusal/backpressure, never eviction (#3251). */
|
|
9
|
+
holdsAcceptedCapture(entry: BufferEntryState | undefined): boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Pick the keys to evict so `entries` returns to `maxCount`: the oldest empty
|
|
14
|
+
* sessions first; retained failed extractions (#1908) keep their turns, so if
|
|
15
|
+
* empty entries alone cannot reach the cap the oldest NON-empty sessions go
|
|
16
|
+
* too rather than growing unboundedly. "default", the retained keys and
|
|
17
|
+
* entries holding an accepted capture are never chosen.
|
|
18
|
+
*/
|
|
19
|
+
export function selectEvictedBufferKeys(
|
|
20
|
+
entries: Readonly<Record<string, BufferEntryState>>,
|
|
21
|
+
retainKeys: readonly string[],
|
|
22
|
+
maxCount: number,
|
|
23
|
+
hooks: BufferEvictionHooks,
|
|
24
|
+
): string[] {
|
|
25
|
+
const keys = Object.keys(entries);
|
|
26
|
+
if (keys.length <= maxCount) return [];
|
|
27
|
+
|
|
28
|
+
const insertionOrder = new Map(keys.map((key, index) => [key, index]));
|
|
29
|
+
const byOldestActivity = (left: string, right: string): number => {
|
|
30
|
+
const leftAt = hooks.activityAt(entries[left] ?? EMPTY_ENTRY);
|
|
31
|
+
const rightAt = hooks.activityAt(entries[right] ?? EMPTY_ENTRY);
|
|
32
|
+
if (leftAt !== rightAt) return leftAt - rightAt;
|
|
33
|
+
return (insertionOrder.get(left) ?? 0) - (insertionOrder.get(right) ?? 0);
|
|
34
|
+
};
|
|
35
|
+
const candidates = keys.filter(
|
|
36
|
+
(key) => key !== "default" && !retainKeys.includes(key) && !hooks.holdsAcceptedCapture(entries[key]),
|
|
37
|
+
);
|
|
38
|
+
const emptyRemovable = candidates
|
|
39
|
+
.filter((key) => (entries[key]?.turns.length ?? 0) === 0)
|
|
40
|
+
.sort(byOldestActivity);
|
|
41
|
+
|
|
42
|
+
const removableCount = Math.max(0, keys.length - maxCount);
|
|
43
|
+
const evicted = emptyRemovable.slice(0, removableCount);
|
|
44
|
+
if (evicted.length < removableCount) {
|
|
45
|
+
const nonEmptyRemovable = candidates
|
|
46
|
+
.filter((key) => (entries[key]?.turns.length ?? 0) > 0)
|
|
47
|
+
.sort(byOldestActivity);
|
|
48
|
+
return evicted.concat(nonEmptyRemovable.slice(0, removableCount - evicted.length));
|
|
49
|
+
}
|
|
50
|
+
return evicted;
|
|
51
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session incremental buffer persistence (SmartBuffer layer).
|
|
3
|
+
*
|
|
4
|
+
* Pins the hot-path contract on top of the storage primitives tested in
|
|
5
|
+
* storage-buffer-sessions.test.ts:
|
|
6
|
+
*
|
|
7
|
+
* - a storage that exposes saveBufferSession/deleteBufferSession gets
|
|
8
|
+
* INCREMENTAL saves: only the sessions whose state actually changed are
|
|
9
|
+
* written, only on boundaries that need durability;
|
|
10
|
+
* - sessions whose state did not change are never rewritten;
|
|
11
|
+
* - eviction and resetToEmpty delete the corresponding session files;
|
|
12
|
+
* - a legacy storage (only loadBuffer/saveBuffer) keeps the exact old
|
|
13
|
+
* whole-state behavior — existing deployments and test doubles are
|
|
14
|
+
* unaffected.
|
|
15
|
+
*
|
|
16
|
+
* All saves flow through SmartBuffer's mutation chain, so there is exactly
|
|
17
|
+
* one writer per session file.
|
|
18
|
+
*/
|
|
19
|
+
import test from "node:test";
|
|
20
|
+
import assert from "node:assert/strict";
|
|
21
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
22
|
+
import os from "node:os";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
|
|
25
|
+
import { SmartBuffer } from "./buffer.js";
|
|
26
|
+
import { parseConfig } from "./config.js";
|
|
27
|
+
import { StorageManager } from "./storage.js";
|
|
28
|
+
import type { BufferEntryState, BufferState, BufferTurn } from "./types.js";
|
|
29
|
+
|
|
30
|
+
interface SessionFileRecord {
|
|
31
|
+
entry: BufferEntryState;
|
|
32
|
+
writeCount: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Storage double implementing the incremental per-session surface. Records
|
|
37
|
+
* per-session writes/deletes and whole-state saves separately so tests can
|
|
38
|
+
* assert exactly which files the hot path touched.
|
|
39
|
+
*/
|
|
40
|
+
class IncrementalStorage {
|
|
41
|
+
readonly sessions = new Map<string, SessionFileRecord>();
|
|
42
|
+
readonly deleted: string[] = [];
|
|
43
|
+
wholeStateSaves = 0;
|
|
44
|
+
private initial: BufferState;
|
|
45
|
+
|
|
46
|
+
constructor(initial: BufferState) {
|
|
47
|
+
this.initial = initial;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async loadBuffer(): Promise<BufferState> {
|
|
51
|
+
return structuredClone(this.initial);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async saveBuffer(state: BufferState): Promise<void> {
|
|
55
|
+
this.wholeStateSaves += 1;
|
|
56
|
+
this.initial = structuredClone(state);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async saveBufferSession(key: string, entry: BufferEntryState): Promise<void> {
|
|
60
|
+
const record = this.sessions.get(key) ?? { entry, writeCount: 0 };
|
|
61
|
+
record.entry = structuredClone(entry);
|
|
62
|
+
record.writeCount += 1;
|
|
63
|
+
this.sessions.set(key, record);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async deleteBufferSession(key: string): Promise<void> {
|
|
67
|
+
this.deleted.push(key);
|
|
68
|
+
this.sessions.delete(key);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Storage double implementing ONLY the legacy whole-state surface — every
|
|
74
|
+
* pre-existing test double in the repo looks like this from SmartBuffer's
|
|
75
|
+
* point of view, and must keep working unchanged.
|
|
76
|
+
*/
|
|
77
|
+
class LegacyOnlyStorage {
|
|
78
|
+
wholeStateSaves = 0;
|
|
79
|
+
lastSaved: BufferState | null = null;
|
|
80
|
+
|
|
81
|
+
constructor(private initial: BufferState) {}
|
|
82
|
+
|
|
83
|
+
async loadBuffer(): Promise<BufferState> {
|
|
84
|
+
return structuredClone(this.initial);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async saveBuffer(state: BufferState): Promise<void> {
|
|
88
|
+
this.wholeStateSaves += 1;
|
|
89
|
+
this.lastSaved = structuredClone(state);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function makeTurn(sessionKey: string, content: string): BufferTurn {
|
|
94
|
+
return {
|
|
95
|
+
role: "user",
|
|
96
|
+
content,
|
|
97
|
+
timestamp: "2026-10-29T12:00:00.000Z",
|
|
98
|
+
sessionKey,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function emptyState(): BufferState {
|
|
103
|
+
return { turns: [], lastExtractionAt: null, extractionCount: 0 };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
test("steady-state observe persists only the active session's file", async () => {
|
|
107
|
+
const storage = new IncrementalStorage(emptyState());
|
|
108
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
109
|
+
|
|
110
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
111
|
+
await buffer.flushPendingSave();
|
|
112
|
+
assert.equal(storage.wholeStateSaves, 0, "hot path fell back to whole-state save");
|
|
113
|
+
assert.equal(storage.sessions.get("thread-a")?.writeCount, 1);
|
|
114
|
+
assert.equal(storage.sessions.get("thread-a")?.entry.turns[0]?.content, "alpha");
|
|
115
|
+
|
|
116
|
+
await buffer.addTurn("thread-b", makeTurn("thread-b", "beta"));
|
|
117
|
+
await buffer.flushPendingSave();
|
|
118
|
+
assert.equal(storage.sessions.get("thread-b")?.writeCount, 1);
|
|
119
|
+
// Session A's turn did NOT touch session A's file again.
|
|
120
|
+
assert.equal(storage.sessions.get("thread-a")?.writeCount, 1, "unchanged session file was rewritten");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("a second turn in the same session rewrites only that session's file", async () => {
|
|
124
|
+
const storage = new IncrementalStorage(emptyState());
|
|
125
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
126
|
+
|
|
127
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "one"));
|
|
128
|
+
await buffer.flushPendingSave();
|
|
129
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "two"));
|
|
130
|
+
await buffer.flushPendingSave();
|
|
131
|
+
|
|
132
|
+
const record = storage.sessions.get("thread-a");
|
|
133
|
+
assert.equal(record?.writeCount, 2);
|
|
134
|
+
assert.equal(record?.entry.turns.length, 2);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("extraction-boundary turn persists inline and durably", async () => {
|
|
138
|
+
const storage = new IncrementalStorage(emptyState());
|
|
139
|
+
// bufferMaxTurns: 1 → the very first turn triggers extract_batch.
|
|
140
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 1 }), storage);
|
|
141
|
+
|
|
142
|
+
const outcome = await buffer.addTurnWithOutcome("thread-a", makeTurn("thread-a", "trigger"));
|
|
143
|
+
assert.equal(outcome.decision, "extract_batch");
|
|
144
|
+
// Inline save already ran inside the mutation — no flush needed.
|
|
145
|
+
assert.equal(storage.sessions.get("thread-a")?.writeCount, 1);
|
|
146
|
+
assert.equal(storage.wholeStateSaves, 0, "extraction boundary fell back to whole-state save");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("clearAfterExtraction persists the cleared session state", async () => {
|
|
150
|
+
const storage = new IncrementalStorage(emptyState());
|
|
151
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
152
|
+
|
|
153
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
154
|
+
await buffer.flushPendingSave();
|
|
155
|
+
const before = storage.sessions.get("thread-a")?.writeCount ?? 0;
|
|
156
|
+
|
|
157
|
+
await buffer.clearAfterExtraction("thread-a");
|
|
158
|
+
const record = storage.sessions.get("thread-a");
|
|
159
|
+
assert.equal(record?.writeCount, before + 1, "clearAfterExtraction did not persist the session");
|
|
160
|
+
assert.equal(record?.entry.turns.length, 0);
|
|
161
|
+
assert.equal(record?.entry.extractionCount, 1);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("evicted sessions get their files deleted", async () => {
|
|
165
|
+
const storage = new IncrementalStorage(emptyState());
|
|
166
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
167
|
+
|
|
168
|
+
// normalizeState always materializes a "default" entry, so 198 seeded
|
|
169
|
+
// sessions + default = 199; new-session reaches exactly 200 (the
|
|
170
|
+
// addTurnBounded cap). One more UNBOUNDED addTurn pushes to 201 and
|
|
171
|
+
// pruneEntries evicts the oldest non-default session (s0).
|
|
172
|
+
for (let i = 0; i < 198; i++) {
|
|
173
|
+
const key = `s${i}`;
|
|
174
|
+
await buffer.addTurnBounded(key, makeTurn(key, `content ${i}`));
|
|
175
|
+
}
|
|
176
|
+
await buffer.flushPendingSave();
|
|
177
|
+
|
|
178
|
+
const outcome = await buffer.addTurnBounded("new-session", makeTurn("new-session", "fresh"));
|
|
179
|
+
assert.notEqual(outcome, null, "addTurnBounded refused below capacity");
|
|
180
|
+
await buffer.addTurn("overflow", makeTurn("overflow", "one too many"));
|
|
181
|
+
// The evicted key's file deletion lands on the next persist, like any
|
|
182
|
+
// other buffered state change.
|
|
183
|
+
await buffer.flushPendingSave();
|
|
184
|
+
assert.ok(storage.deleted.includes("s0"), "oldest session was not evicted under capacity pressure");
|
|
185
|
+
assert.ok(
|
|
186
|
+
storage.deleted.length > 0,
|
|
187
|
+
"capacity pressure evicted entries without deleting their session files",
|
|
188
|
+
);
|
|
189
|
+
for (const key of storage.deleted) {
|
|
190
|
+
assert.equal(storage.sessions.has(key), false, `evicted session ${key} still has a file record`);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("resetToEmpty drops every session file on the next persist", async () => {
|
|
195
|
+
const storage = new IncrementalStorage(emptyState());
|
|
196
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
197
|
+
|
|
198
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
199
|
+
await buffer.flushPendingSave();
|
|
200
|
+
buffer.resetToEmpty();
|
|
201
|
+
await buffer.flushPendingSave();
|
|
202
|
+
// resetToEmpty marks every known key for deletion; deleting a key whose
|
|
203
|
+
// file never existed is an ENOENT no-op on real storage (covered in the
|
|
204
|
+
// storage contract tests). The session that HAD a file must be gone.
|
|
205
|
+
assert.ok(storage.deleted.includes("thread-a"));
|
|
206
|
+
assert.equal(storage.sessions.size, 0);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("retained turns survive the per-session persist", async () => {
|
|
210
|
+
const storage = new IncrementalStorage(emptyState());
|
|
211
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
212
|
+
|
|
213
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
214
|
+
await buffer.flushPendingSave();
|
|
215
|
+
await buffer.retainDeferredTurns("thread-a", [makeTurn("thread-a", "alpha")], 5);
|
|
216
|
+
await buffer.flushPendingSave();
|
|
217
|
+
|
|
218
|
+
const record = storage.sessions.get("thread-a");
|
|
219
|
+
assert.equal(record?.entry.retainedTurns?.length, 1, "retained turns were not persisted");
|
|
220
|
+
assert.equal(record?.entry.retainedTurns?.[0]?.content, "alpha");
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test("buffer state survives a restart through per-session files", async () => {
|
|
224
|
+
const root = await mkdtemp(path.join(os.tmpdir(), "remnic-bufio-restart-"));
|
|
225
|
+
try {
|
|
226
|
+
const storage = new StorageManager(root);
|
|
227
|
+
const config = parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 });
|
|
228
|
+
const first = new SmartBuffer(config, storage);
|
|
229
|
+
await first.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
230
|
+
await first.addTurn("thread-b", makeTurn("thread-b", "beta"));
|
|
231
|
+
await first.flushPendingSave();
|
|
232
|
+
|
|
233
|
+
// A fresh process reads the buffer back from the per-session files.
|
|
234
|
+
const second = new SmartBuffer(config, storage);
|
|
235
|
+
await second.load();
|
|
236
|
+
assert.equal(second.getTurns("thread-a").length, 1);
|
|
237
|
+
assert.equal(second.getTurns("thread-a")[0]?.content, "alpha");
|
|
238
|
+
assert.equal(second.getTurns("thread-b")[0]?.content, "beta");
|
|
239
|
+
} finally {
|
|
240
|
+
await rm(root, { recursive: true, force: true });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("legacy-only storage keeps the whole-state saveBuffer behavior", async () => {
|
|
245
|
+
const storage = new LegacyOnlyStorage(emptyState());
|
|
246
|
+
const buffer = new SmartBuffer(parseConfig({ triggerMode: "every_n", bufferMaxTurns: 100 }), storage);
|
|
247
|
+
|
|
248
|
+
await buffer.addTurn("thread-a", makeTurn("thread-a", "alpha"));
|
|
249
|
+
await buffer.flushPendingSave();
|
|
250
|
+
await buffer.addTurn("thread-b", makeTurn("thread-b", "beta"));
|
|
251
|
+
await buffer.flushPendingSave();
|
|
252
|
+
|
|
253
|
+
assert.ok(storage.wholeStateSaves >= 2, "legacy storage did not receive whole-state saves");
|
|
254
|
+
assert.equal(storage.lastSaved?.entries?.["thread-a"]?.turns[0]?.content, "alpha");
|
|
255
|
+
assert.equal(storage.lastSaved?.entries?.["thread-b"]?.turns[0]?.content, "beta");
|
|
256
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { BufferEntryState, BufferState, BufferSurpriseEvent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The buffer persistence surface SmartBuffer depends on.
|
|
5
|
+
*
|
|
6
|
+
* `saveBufferSession` / `deleteBufferSession` are the per-session incremental
|
|
7
|
+
* writes (one file per session); when a storage backend does not provide
|
|
8
|
+
* them, the buffer falls back to the whole-state `saveBuffer`. Both are
|
|
9
|
+
* optional in the type so a storage double only has to implement what it
|
|
10
|
+
* actually supports.
|
|
11
|
+
*/
|
|
12
|
+
export interface BufferStorage {
|
|
13
|
+
loadBuffer(): Promise<BufferState>;
|
|
14
|
+
saveBuffer(state: BufferState): Promise<void>;
|
|
15
|
+
saveBufferSession?(key: string, entry: BufferEntryState): Promise<void>;
|
|
16
|
+
deleteBufferSession?(key: string): Promise<void>;
|
|
17
|
+
/** Optional surprise-telemetry sink; older storage and test doubles omit it. */
|
|
18
|
+
appendBufferSurpriseEvents?(events: BufferSurpriseEvent[]): Promise<number>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Tracks which sessions' persisted files are stale and writes only those.
|
|
23
|
+
*
|
|
24
|
+
* Marks are cleared only after a durable write of that session. All calls
|
|
25
|
+
* happen under SmartBuffer's serialized mutation chain: one writer.
|
|
26
|
+
*/
|
|
27
|
+
export class BufferSessionPersistence {
|
|
28
|
+
private readonly dirty = new Set<string>();
|
|
29
|
+
private readonly deleted = new Set<string>();
|
|
30
|
+
|
|
31
|
+
markDirty(key: string): void {
|
|
32
|
+
this.dirty.add(key);
|
|
33
|
+
this.deleted.delete(key);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
markDeleted(key: string): void {
|
|
37
|
+
this.deleted.add(key);
|
|
38
|
+
this.dirty.delete(key);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Eviction removed `key` from memory: its session file must go, any pending write is moot. */
|
|
42
|
+
markEvicted(keys: readonly string[]): void {
|
|
43
|
+
for (const key of keys) this.markDeleted(key);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
hasPending(): boolean {
|
|
47
|
+
return this.dirty.size > 0 || this.deleted.size > 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Persist buffer state. On session-capable storage this writes ONLY the
|
|
52
|
+
* sessions whose state changed since the last successful persist and
|
|
53
|
+
* deletes files for evicted/reset sessions, so the observe path never
|
|
54
|
+
* re-serializes other sessions' turns. On legacy storage it falls back to
|
|
55
|
+
* the whole-state saveBuffer. Files are deleted before dirty writes: a
|
|
56
|
+
* crash mid-persist can then only resurrect already-evicted data (the same
|
|
57
|
+
* exposure as a whole-file rewrite), never drop sessions the state says
|
|
58
|
+
* exist.
|
|
59
|
+
*/
|
|
60
|
+
async persist(
|
|
61
|
+
storage: BufferStorage,
|
|
62
|
+
state: BufferState,
|
|
63
|
+
peekEntry: (key: string) => BufferEntryState | undefined,
|
|
64
|
+
): Promise<void> {
|
|
65
|
+
const saveSession = storage.saveBufferSession?.bind(storage);
|
|
66
|
+
const deleteSession = storage.deleteBufferSession?.bind(storage);
|
|
67
|
+
if (!saveSession || !deleteSession) {
|
|
68
|
+
await storage.saveBuffer(state);
|
|
69
|
+
this.dirty.clear();
|
|
70
|
+
this.deleted.clear();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
for (const key of [...this.deleted]) {
|
|
74
|
+
await deleteSession(key);
|
|
75
|
+
this.deleted.delete(key);
|
|
76
|
+
}
|
|
77
|
+
for (const key of [...this.dirty]) {
|
|
78
|
+
const entry = peekEntry(key);
|
|
79
|
+
if (!entry) {
|
|
80
|
+
// A dirty key without state must not be written from a fabricated
|
|
81
|
+
// empty entry: treat it as a deletion instead.
|
|
82
|
+
this.markDeleted(key);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
await saveSession(key, entry);
|
|
86
|
+
this.dirty.delete(key);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|