@remnic/core 9.69.73 → 9.69.75
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 +37 -37
- package/dist/access-authorization-probe.js +38 -38
- package/dist/access-boundary.js +37 -37
- package/dist/access-cli.js +110 -108
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +37 -37
- package/dist/access-http-briefing.js +38 -38
- package/dist/access-http-query.js +39 -39
- package/dist/access-http.js +57 -57
- package/dist/access-identity-continuity-surface.js +37 -37
- package/dist/access-lcm-surface.js +37 -37
- package/dist/access-mcp.js +48 -48
- package/dist/access-namespace-preflight.js +37 -37
- package/dist/access-observe-write-category.js +6 -6
- package/dist/access-observe-write-surface.js +37 -37
- package/dist/access-offline-manifest.js +3 -3
- package/dist/access-operations-batch.js +40 -40
- package/dist/access-operations.js +47 -47
- package/dist/access-recall-concurrency.js +37 -37
- package/dist/access-recall-response.js +37 -37
- package/dist/access-recall-surface.js +37 -37
- package/dist/access-schema.js +5 -5
- package/dist/access-service.js +37 -37
- package/dist/access-surface-catalog.js +39 -39
- package/dist/active-recall.js +16 -15
- package/dist/active-recall.js.map +1 -1
- package/dist/briefing.js +8 -8
- package/dist/buffer.js +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +11 -11
- 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-TRLPF7ZP.js → chunk-25LKLNSJ.js} +2 -2
- package/dist/{chunk-GWK7FEUL.js → chunk-2U3R3DDH.js} +6 -6
- package/dist/{chunk-GWQVMKUJ.js → chunk-2UPTRDGM.js} +3 -3
- package/dist/{chunk-MQTCNXTG.js → chunk-4GPI3GVE.js} +7 -7
- package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
- package/dist/{chunk-HRQWSXNB.js → chunk-5HP5F2SQ.js} +3 -3
- package/dist/{chunk-ICMXLHSC.js → chunk-5KNEOYTF.js} +2 -2
- package/dist/{chunk-5I63ZRIH.js → chunk-5LPDXYU3.js} +4 -4
- package/dist/{chunk-JDBZSRUA.js → chunk-62AE2EUZ.js} +2 -2
- package/dist/{chunk-D5F2Z6WO.js → chunk-6BFW7SGF.js} +2 -2
- package/dist/{chunk-HW4DKAAA.js → chunk-6BSPRNFF.js} +2 -2
- package/dist/{chunk-JX2NWPQ4.js → chunk-6JA22L5X.js} +10 -10
- package/dist/{chunk-JUOJGZPV.js → chunk-6OACG7JV.js} +3 -3
- package/dist/{chunk-NZUHZVHF.js → chunk-7COBZFUF.js} +2 -2
- package/dist/{chunk-XY25CPAO.js → chunk-AQJBFLUA.js} +5 -5
- package/dist/{chunk-SUI5JQVE.js → chunk-AWEMJYN2.js} +2 -2
- package/dist/{chunk-VQJ7UAKA.js → chunk-B6PY25JB.js} +1 -1
- package/dist/{chunk-W7PY7IIB.js → chunk-BXCZPPRO.js} +16 -16
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-DQFZOPDL.js → chunk-CGO3A7SR.js} +2 -2
- package/dist/{chunk-SF6RFI5Z.js → chunk-CHDGJJV6.js} +2 -2
- package/dist/{chunk-GUWH5SOO.js → chunk-COHJUEBQ.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/chunk-GBGLS44T.js +20 -0
- package/dist/chunk-GBGLS44T.js.map +1 -0
- package/dist/{chunk-5ID5RTHY.js → chunk-GFD7TWAZ.js} +2 -2
- package/dist/{chunk-G3QJVHFG.js → chunk-GH5YSAAI.js} +15 -12
- package/dist/chunk-GH5YSAAI.js.map +1 -0
- package/dist/{chunk-ZDTG7ALZ.js → chunk-HPK66ZM5.js} +2 -2
- package/dist/{chunk-5TC6MQOW.js → chunk-HS75MCQF.js} +4 -4
- package/dist/{chunk-BSCR5TEN.js → chunk-HZDOLAZV.js} +2 -2
- package/dist/{chunk-UBCVHKZQ.js → chunk-I6Y6QKWF.js} +2 -2
- package/dist/{chunk-YHU5XUF4.js → chunk-IFCKHPY4.js} +2 -2
- package/dist/{chunk-YEHKKZ5T.js → chunk-IGSVMAPQ.js} +2 -2
- package/dist/{chunk-2VV3XLZB.js → chunk-IXLHREAB.js} +4 -4
- package/dist/{chunk-266NJ2YF.js → chunk-JDES3G7T.js} +2 -2
- package/dist/{chunk-VVKLAB3Y.js → chunk-JOMGKV72.js} +2 -2
- package/dist/{chunk-YDMN7TUM.js → chunk-KMHE76A2.js} +2 -2
- package/dist/{chunk-CMAGVPS2.js → chunk-KPSJA45G.js} +2 -2
- package/dist/{chunk-2XGPN5TL.js → chunk-LBL77UXO.js} +7 -7
- package/dist/{chunk-ADWCQWK3.js → chunk-LDOURFFA.js} +2 -2
- package/dist/{chunk-B6RTKSOT.js → chunk-LH6UP5SR.js} +3 -3
- package/dist/chunk-LJLGH2DE.js +65 -0
- package/dist/chunk-LJLGH2DE.js.map +1 -0
- package/dist/{chunk-A7GQBJP5.js → chunk-LVFI5LG7.js} +7 -7
- package/dist/{chunk-6E5GYDIE.js → chunk-MFZACYZ6.js} +2 -2
- package/dist/{chunk-WXPIEWQW.js → chunk-MKNENZCK.js} +3 -3
- package/dist/{chunk-VDKZTNG5.js → chunk-MSRNAAWW.js} +2 -2
- package/dist/{chunk-RG7ZWG3M.js → chunk-NF6LF76X.js} +2 -2
- package/dist/{chunk-7FL25VH3.js → chunk-O4QH33GV.js} +6 -6
- package/dist/{chunk-BIKX37D2.js → chunk-OB2YI57R.js} +35 -35
- package/dist/{chunk-B2FMRNHA.js → chunk-ODP62HIA.js} +2 -2
- package/dist/{chunk-BGBW4H7C.js → chunk-OMYCECTS.js} +2 -2
- package/dist/{chunk-BICNRVEC.js → chunk-QWUJWBZ5.js} +2 -2
- package/dist/{chunk-NEARGPN7.js → chunk-S5FWSNLI.js} +2 -2
- package/dist/{chunk-FN6E373Q.js → chunk-SA2JMMMS.js} +2 -2
- package/dist/{chunk-QVWNNN64.js → chunk-TY5JOP2W.js} +139 -98
- package/dist/chunk-TY5JOP2W.js.map +1 -0
- package/dist/{chunk-WJPRWNZN.js → chunk-UFBHEMNR.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-OVO545UE.js → chunk-VIRTAUJO.js} +2 -2
- package/dist/{chunk-ZHXSOMYH.js → chunk-VVX5PZFS.js} +2 -2
- package/dist/{chunk-AYDU5MJC.js → chunk-VXNWOHOR.js} +2 -2
- package/dist/{chunk-LMMQKZK3.js → chunk-VZBW6CDG.js} +1 -1
- package/dist/{chunk-KNPWG3VI.js → chunk-WDBKDYK2.js} +41 -41
- package/dist/{chunk-ADZLUBNE.js → chunk-WDP7CJZQ.js} +3 -3
- package/dist/{chunk-2ZU6CYTJ.js → chunk-WZKKI6S2.js} +2 -2
- package/dist/{chunk-GRSFFLUY.js → chunk-X2PBZOYZ.js} +2 -2
- package/dist/{chunk-ONEUTVGJ.js → chunk-Y52T5Y6B.js} +2 -2
- package/dist/{chunk-DDNML3YE.js → chunk-YCYFXA6P.js} +2 -2
- package/dist/{chunk-RDWVTUXZ.js → chunk-YMSPN4W4.js} +2 -2
- package/dist/{chunk-AJEUESNJ.js → chunk-YYRMOMX3.js} +2 -2
- package/dist/{chunk-2WMXZYMS.js → chunk-YZENVZWY.js} +2 -2
- package/dist/{chunk-WQZZDN5M.js → chunk-ZHOXXHT5.js} +4 -4
- package/dist/{chunk-GNC5X3J7.js → chunk-ZPED47SP.js} +11 -11
- package/dist/{chunk-RFVF5PLN.js → chunk-ZVTG7JTG.js} +2 -2
- package/dist/cli.js +84 -83
- package/dist/coding/export-okf-codegraph.js +7 -7
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +8 -8
- package/dist/config-search-backend.d.ts +5 -0
- package/dist/config-search-backend.d.ts.map +1 -0
- package/dist/config-search-backend.js +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +16 -15
- package/dist/connectors/codex-materialize-runner.js +8 -8
- package/dist/connectors/index.js +8 -8
- package/dist/convergence-refresh.js +10 -10
- package/dist/corpus-watermark.js +10 -10
- package/dist/deep-recall-http-glue.js +6 -6
- package/dist/deep-recall.js +2 -2
- package/dist/entity-retrieval.js +8 -8
- package/dist/event-order-recall.js +2 -2
- package/dist/external-wiki-access.js +38 -38
- package/dist/extraction.js +10 -10
- package/dist/{graph-edge-decay-ROSUPDX3.js → graph-edge-decay-PVKDKLQK.js} +5 -5
- package/dist/graph-edge-decay-PVKDKLQK.js.map +1 -0
- package/dist/graph-jsonl.js +3 -3
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +4 -4
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/index.js +124 -122
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.js +11 -11
- package/dist/location/index.js +10 -10
- package/dist/maintenance/memory-governance.js +8 -8
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
- package/dist/maintenance/rebuild-memory-projection.js +9 -9
- package/dist/memory-browse-operations.js +38 -38
- package/dist/namespaces/migrate.js +9 -9
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.js +8 -8
- package/dist/offline-sync.js +2 -2
- package/dist/operator-doctor-corpus.js +11 -11
- package/dist/operator-toolkit.js +27 -26
- package/dist/orchestration/extraction-persist-citation.d.ts +4 -0
- package/dist/orchestration/extraction-persist-citation.d.ts.map +1 -0
- package/dist/orchestration/extraction-persist.d.ts +1 -3
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/maintenance.js +16 -16
- package/dist/orchestration/recall-entry.d.ts.map +1 -1
- package/dist/orchestrator.js +110 -108
- package/dist/recall-navigation-operations.js +38 -38
- package/dist/recall-navigation.js +37 -37
- package/dist/resume-bundles.js +17 -16
- package/dist/search/factory.js +3 -3
- package/dist/search/index.js +7 -7
- package/dist/semantic-consolidation.js +9 -9
- package/dist/semantic-rule-promotion.js +8 -8
- package/dist/semantic-rule-verifier.js +8 -8
- package/dist/source-agent-qualifier.js +8 -8
- package/dist/standing-memory-recall.d.ts +22 -0
- package/dist/standing-memory-recall.d.ts.map +1 -0
- package/dist/standing-memory-recall.js +16 -0
- package/dist/standing-memory-recall.js.map +1 -0
- package/dist/standup/build.js +8 -8
- package/dist/storage.js +7 -7
- package/dist/support-passport/index.js +40 -40
- 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 +8 -8
- package/dist/verified-recall.js +8 -8
- package/dist/who-knows-cli.js +9 -9
- package/dist/who-knows.js +8 -8
- package/package.json +2 -2
- package/src/config-search-backend.test.ts +21 -0
- package/src/config-search-backend.ts +17 -0
- package/src/config.ts +2 -3
- package/src/orchestration/extraction-persist-citation.test.ts +9 -0
- package/src/orchestration/extraction-persist-citation.ts +37 -0
- package/src/orchestration/extraction-persist.ts +8 -42
- package/src/orchestration/recall-entry.ts +54 -13
- package/src/standing-memory-block.test.ts +4 -3
- package/src/standing-memory-recall.test.ts +30 -0
- package/src/standing-memory-recall.ts +87 -0
- package/dist/chunk-G3QJVHFG.js.map +0 -1
- package/dist/chunk-QVWNNN64.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-TRLPF7ZP.js.map → chunk-25LKLNSJ.js.map} +0 -0
- /package/dist/{chunk-GWK7FEUL.js.map → chunk-2U3R3DDH.js.map} +0 -0
- /package/dist/{chunk-GWQVMKUJ.js.map → chunk-2UPTRDGM.js.map} +0 -0
- /package/dist/{chunk-MQTCNXTG.js.map → chunk-4GPI3GVE.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
- /package/dist/{chunk-HRQWSXNB.js.map → chunk-5HP5F2SQ.js.map} +0 -0
- /package/dist/{chunk-ICMXLHSC.js.map → chunk-5KNEOYTF.js.map} +0 -0
- /package/dist/{chunk-5I63ZRIH.js.map → chunk-5LPDXYU3.js.map} +0 -0
- /package/dist/{chunk-JDBZSRUA.js.map → chunk-62AE2EUZ.js.map} +0 -0
- /package/dist/{chunk-D5F2Z6WO.js.map → chunk-6BFW7SGF.js.map} +0 -0
- /package/dist/{chunk-HW4DKAAA.js.map → chunk-6BSPRNFF.js.map} +0 -0
- /package/dist/{chunk-JX2NWPQ4.js.map → chunk-6JA22L5X.js.map} +0 -0
- /package/dist/{chunk-JUOJGZPV.js.map → chunk-6OACG7JV.js.map} +0 -0
- /package/dist/{chunk-NZUHZVHF.js.map → chunk-7COBZFUF.js.map} +0 -0
- /package/dist/{chunk-XY25CPAO.js.map → chunk-AQJBFLUA.js.map} +0 -0
- /package/dist/{chunk-SUI5JQVE.js.map → chunk-AWEMJYN2.js.map} +0 -0
- /package/dist/{chunk-VQJ7UAKA.js.map → chunk-B6PY25JB.js.map} +0 -0
- /package/dist/{chunk-W7PY7IIB.js.map → chunk-BXCZPPRO.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-DQFZOPDL.js.map → chunk-CGO3A7SR.js.map} +0 -0
- /package/dist/{chunk-SF6RFI5Z.js.map → chunk-CHDGJJV6.js.map} +0 -0
- /package/dist/{chunk-GUWH5SOO.js.map → chunk-COHJUEBQ.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-5ID5RTHY.js.map → chunk-GFD7TWAZ.js.map} +0 -0
- /package/dist/{chunk-ZDTG7ALZ.js.map → chunk-HPK66ZM5.js.map} +0 -0
- /package/dist/{chunk-5TC6MQOW.js.map → chunk-HS75MCQF.js.map} +0 -0
- /package/dist/{chunk-BSCR5TEN.js.map → chunk-HZDOLAZV.js.map} +0 -0
- /package/dist/{chunk-UBCVHKZQ.js.map → chunk-I6Y6QKWF.js.map} +0 -0
- /package/dist/{chunk-YHU5XUF4.js.map → chunk-IFCKHPY4.js.map} +0 -0
- /package/dist/{chunk-YEHKKZ5T.js.map → chunk-IGSVMAPQ.js.map} +0 -0
- /package/dist/{chunk-2VV3XLZB.js.map → chunk-IXLHREAB.js.map} +0 -0
- /package/dist/{chunk-266NJ2YF.js.map → chunk-JDES3G7T.js.map} +0 -0
- /package/dist/{chunk-VVKLAB3Y.js.map → chunk-JOMGKV72.js.map} +0 -0
- /package/dist/{chunk-YDMN7TUM.js.map → chunk-KMHE76A2.js.map} +0 -0
- /package/dist/{chunk-CMAGVPS2.js.map → chunk-KPSJA45G.js.map} +0 -0
- /package/dist/{chunk-2XGPN5TL.js.map → chunk-LBL77UXO.js.map} +0 -0
- /package/dist/{chunk-ADWCQWK3.js.map → chunk-LDOURFFA.js.map} +0 -0
- /package/dist/{chunk-B6RTKSOT.js.map → chunk-LH6UP5SR.js.map} +0 -0
- /package/dist/{chunk-A7GQBJP5.js.map → chunk-LVFI5LG7.js.map} +0 -0
- /package/dist/{chunk-6E5GYDIE.js.map → chunk-MFZACYZ6.js.map} +0 -0
- /package/dist/{chunk-WXPIEWQW.js.map → chunk-MKNENZCK.js.map} +0 -0
- /package/dist/{chunk-VDKZTNG5.js.map → chunk-MSRNAAWW.js.map} +0 -0
- /package/dist/{chunk-RG7ZWG3M.js.map → chunk-NF6LF76X.js.map} +0 -0
- /package/dist/{chunk-7FL25VH3.js.map → chunk-O4QH33GV.js.map} +0 -0
- /package/dist/{chunk-BIKX37D2.js.map → chunk-OB2YI57R.js.map} +0 -0
- /package/dist/{chunk-B2FMRNHA.js.map → chunk-ODP62HIA.js.map} +0 -0
- /package/dist/{chunk-BGBW4H7C.js.map → chunk-OMYCECTS.js.map} +0 -0
- /package/dist/{chunk-BICNRVEC.js.map → chunk-QWUJWBZ5.js.map} +0 -0
- /package/dist/{chunk-NEARGPN7.js.map → chunk-S5FWSNLI.js.map} +0 -0
- /package/dist/{chunk-FN6E373Q.js.map → chunk-SA2JMMMS.js.map} +0 -0
- /package/dist/{chunk-WJPRWNZN.js.map → chunk-UFBHEMNR.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-OVO545UE.js.map → chunk-VIRTAUJO.js.map} +0 -0
- /package/dist/{chunk-ZHXSOMYH.js.map → chunk-VVX5PZFS.js.map} +0 -0
- /package/dist/{chunk-AYDU5MJC.js.map → chunk-VXNWOHOR.js.map} +0 -0
- /package/dist/{chunk-LMMQKZK3.js.map → chunk-VZBW6CDG.js.map} +0 -0
- /package/dist/{chunk-KNPWG3VI.js.map → chunk-WDBKDYK2.js.map} +0 -0
- /package/dist/{chunk-ADZLUBNE.js.map → chunk-WDP7CJZQ.js.map} +0 -0
- /package/dist/{chunk-2ZU6CYTJ.js.map → chunk-WZKKI6S2.js.map} +0 -0
- /package/dist/{chunk-GRSFFLUY.js.map → chunk-X2PBZOYZ.js.map} +0 -0
- /package/dist/{chunk-ONEUTVGJ.js.map → chunk-Y52T5Y6B.js.map} +0 -0
- /package/dist/{chunk-DDNML3YE.js.map → chunk-YCYFXA6P.js.map} +0 -0
- /package/dist/{chunk-RDWVTUXZ.js.map → chunk-YMSPN4W4.js.map} +0 -0
- /package/dist/{chunk-AJEUESNJ.js.map → chunk-YYRMOMX3.js.map} +0 -0
- /package/dist/{chunk-2WMXZYMS.js.map → chunk-YZENVZWY.js.map} +0 -0
- /package/dist/{chunk-WQZZDN5M.js.map → chunk-ZHOXXHT5.js.map} +0 -0
- /package/dist/{chunk-GNC5X3J7.js.map → chunk-ZPED47SP.js.map} +0 -0
- /package/dist/{chunk-RFVF5PLN.js.map → chunk-ZVTG7JTG.js.map} +0 -0
- /package/dist/{graph-edge-decay-ROSUPDX3.js.map → config-search-backend.js.map} +0 -0
package/src/config.ts
CHANGED
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
TrustWeights,
|
|
27
27
|
} from "./types.js";
|
|
28
28
|
import { parseBackgroundGeneration } from "./background-generation-config.js";
|
|
29
|
+
import { parseSearchBackend } from "./config-search-backend.js";
|
|
29
30
|
import { parseLocalLlmConfig } from "./local-llm-config.js";
|
|
30
31
|
import { parseConvergeConfig } from "./converge-config.js";
|
|
31
32
|
import { parseExternalWikiRecallGuard } from "./external-wiki-guard.js";
|
|
@@ -3173,9 +3174,7 @@ export function parseConfig(
|
|
|
3173
3174
|
: 500,
|
|
3174
3175
|
|
|
3175
3176
|
// Search backend abstraction
|
|
3176
|
-
searchBackend: (
|
|
3177
|
-
? (cfg.searchBackend as "qmd" | "remote" | "noop" | "lancedb" | "meilisearch" | "orama")
|
|
3178
|
-
: "qmd",
|
|
3177
|
+
searchBackend: parseSearchBackend(cfg.searchBackend),
|
|
3179
3178
|
remoteSearchBaseUrl: typeof cfg.remoteSearchBaseUrl === "string" ? cfg.remoteSearchBaseUrl : undefined,
|
|
3180
3179
|
remoteSearchApiKey: typeof cfg.remoteSearchApiKey === "string" ? cfg.remoteSearchApiKey : undefined,
|
|
3181
3180
|
remoteSearchTimeoutMs: typeof cfg.remoteSearchTimeoutMs === "number" ? cfg.remoteSearchTimeoutMs : 30_000,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import { applyInlineCitation, normalizeStoredHashSource } from "./extraction-persist-citation.js";
|
|
5
|
+
|
|
6
|
+
test("#3091 citation helpers no-op when inline attribution is off", () => {
|
|
7
|
+
assert.equal(applyInlineCitation("hello", false, "[{ts}]", {}), "hello");
|
|
8
|
+
assert.equal(normalizeStoredHashSource("hello", false, "[{ts}]"), "hello");
|
|
9
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ContentHashIndex } from "../index.js";
|
|
2
|
+
import { sanitizeMemoryContent } from "../sanitize.js";
|
|
3
|
+
import {
|
|
4
|
+
attachCitation,
|
|
5
|
+
type CitationContext,
|
|
6
|
+
hasCitationForTemplate,
|
|
7
|
+
stripCitationForTemplate,
|
|
8
|
+
} from "../source-attribution.js";
|
|
9
|
+
|
|
10
|
+
export function normalizeStoredHashSource(
|
|
11
|
+
raw: string,
|
|
12
|
+
citationEnabled: boolean,
|
|
13
|
+
citationTemplate: string,
|
|
14
|
+
): string {
|
|
15
|
+
return ContentHashIndex.normalizeContent(
|
|
16
|
+
sanitizeMemoryContent(
|
|
17
|
+
citationEnabled && hasCitationForTemplate(raw, citationTemplate)
|
|
18
|
+
? stripCitationForTemplate(raw, citationTemplate)
|
|
19
|
+
: raw,
|
|
20
|
+
).text,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function applyInlineCitation(
|
|
25
|
+
content: string,
|
|
26
|
+
citationEnabled: boolean,
|
|
27
|
+
citationTemplate: string,
|
|
28
|
+
citationContextBase: Omit<CitationContext, "ts">,
|
|
29
|
+
): string {
|
|
30
|
+
if (!citationEnabled) return content;
|
|
31
|
+
if (typeof content !== "string" || content.length === 0) return content;
|
|
32
|
+
const citationContext: CitationContext = {
|
|
33
|
+
...citationContextBase,
|
|
34
|
+
ts: new Date().toISOString(),
|
|
35
|
+
};
|
|
36
|
+
return attachCitation(content, citationContext, citationTemplate);
|
|
37
|
+
}
|
|
@@ -125,6 +125,10 @@ import { applySemanticMergeAtPersist, runMergedTargetPostEffects, writeMergedVer
|
|
|
125
125
|
import { buildMergedTargetPromotionPayload } from "./semantic-merge-promotion-payload.js";
|
|
126
126
|
import { persistMergedTargetThreadEpisode } from "./semantic-merge-commit-effects.js";
|
|
127
127
|
import { ExtractionAnchorSnapshot } from "./extraction-anchor-snapshot.js";
|
|
128
|
+
import {
|
|
129
|
+
applyInlineCitation as applyInlineCitationToContent,
|
|
130
|
+
normalizeStoredHashSource as normalizeStoredHashSourceContent,
|
|
131
|
+
} from "./extraction-persist-citation.js";
|
|
128
132
|
|
|
129
133
|
export class ExtractionPersistCoordinator {
|
|
130
134
|
constructor(
|
|
@@ -145,26 +149,12 @@ export class ExtractionPersistCoordinator {
|
|
|
145
149
|
sourceContext?: ExtractionSourceContext,
|
|
146
150
|
baseNamespace?: string,
|
|
147
151
|
scopeProfileWritePlan?: ResolvedScopeProfilePlan | null,
|
|
148
|
-
/** Verbatim source turn text the facts were extracted from (faithfulness gate #1576). */
|
|
149
152
|
sourceText?: string,
|
|
150
153
|
graphCaps: GraphConstructionCapabilitySet = resolveGraphConstructionCapabilities(this.deps.config),
|
|
151
154
|
lifecycleCaps: MemoryLifecycleCapabilitySet = resolveMemoryLifecycleCapabilities(this.deps.config),
|
|
152
155
|
): Promise<{ persistedIds: string[]; memoryPathById: Map<string, string> }> {
|
|
153
|
-
// Inline source attribution (issue #369). When enabled, every extracted
|
|
154
|
-
// fact is rewritten to carry a compact provenance tag inside its body so
|
|
155
|
-
// the citation survives hostile memory text, copy/paste, and LLM quoting.
|
|
156
|
-
// The helper is a no-op when the feature flag is off, so legacy pipelines
|
|
157
|
-
// see zero behavioral change.
|
|
158
156
|
const citationEnabled = resolvePipelineProcessingCapabilities(this.deps.config).inlineSourceAttribution === true;
|
|
159
157
|
const citationTemplate = this.deps.config.inlineSourceAttributionFormat;
|
|
160
|
-
// #1909: the main-path fact writes defer their per-fact fact-hash-index flush
|
|
161
|
-
// to the orchestrator's end-of-persist reconciling batch save ONLY when fact
|
|
162
|
-
// deduplication is enabled (with it off, contentHashIndexForStorage() returns
|
|
163
|
-
// null and the batch save is a no-op, so the write must save immediately).
|
|
164
|
-
// Round 11: there is NO fact-hashes.ready marker anymore — the fact-hash
|
|
165
|
-
// index is ALWAYS rebuilt from the corpus on restart (see
|
|
166
|
-
// ensureFactHashIndexAuthoritative), so a deferred write, crash, or
|
|
167
|
-
// multi-process interleave is safe by construction with no marker to guard.
|
|
168
158
|
const factDedupEnabled = resolveRecallAuxiliaryCapabilities(this.deps.config).factDeduplication;
|
|
169
159
|
const harmonicConstructionEnabled = resolveCapabilities(this.deps.config).harmonicRetrieval;
|
|
170
160
|
const harmonicAnchorsEnabled =
|
|
@@ -182,40 +172,16 @@ export class ExtractionPersistCoordinator {
|
|
|
182
172
|
let harmonicSourceOrder = 0;
|
|
183
173
|
const promotedCopyProbe = createBatchPromotedCopyProbe(this.deps.config, this.deps.getStorageRouter, scopeProfileWritePlan); // #2330 finding F: one promoted-copy scan per namespace per batch
|
|
184
174
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const normalizeStoredHashSource = (raw: string): string =>
|
|
188
|
-
ContentHashIndex.normalizeContent(
|
|
189
|
-
sanitizeMemoryContent(
|
|
190
|
-
citationEnabled && hasCitationForTemplate(raw, citationTemplate)
|
|
191
|
-
? stripCitationForTemplate(raw, citationTemplate)
|
|
192
|
-
: raw,
|
|
193
|
-
).text,
|
|
194
|
-
);
|
|
195
|
-
// The stable fields (agent, session) are computed once; `ts` is intentionally
|
|
196
|
-
// omitted here and added fresh per invocation so each fact in a large batch
|
|
197
|
-
// gets its own insertion timestamp rather than sharing a single batch-start time.
|
|
175
|
+
const normalizeStoredHashSource = (raw: string): string =>
|
|
176
|
+
normalizeStoredHashSourceContent(raw, citationEnabled, citationTemplate);
|
|
198
177
|
const citationContextBase: Omit<CitationContext, "ts"> = citationEnabled
|
|
199
178
|
? {
|
|
200
179
|
agent: sourceContext?.principal,
|
|
201
180
|
session: sourceContext?.sessionKey,
|
|
202
181
|
}
|
|
203
182
|
: {};
|
|
204
|
-
const applyInlineCitation = (content: string): string =>
|
|
205
|
-
|
|
206
|
-
if (typeof content !== "string" || content.length === 0) return content;
|
|
207
|
-
// Build a fresh CitationContext per call so `ts` reflects the actual
|
|
208
|
-
// insertion time of each individual fact rather than the batch-start time.
|
|
209
|
-
const citationContext: CitationContext = {
|
|
210
|
-
...citationContextBase,
|
|
211
|
-
ts: new Date().toISOString(),
|
|
212
|
-
};
|
|
213
|
-
// `attachCitation` already calls `hasCitationForTemplate` internally and
|
|
214
|
-
// is a no-op when the content already carries a citation (default or
|
|
215
|
-
// custom template). The outer check was redundant and has been removed
|
|
216
|
-
// to avoid a maintenance hazard where the two guard paths could diverge.
|
|
217
|
-
return attachCitation(content, citationContext, citationTemplate);
|
|
218
|
-
};
|
|
183
|
+
const applyInlineCitation = (content: string): string =>
|
|
184
|
+
applyInlineCitationToContent(content, citationEnabled, citationTemplate, citationContextBase);
|
|
219
185
|
const persistedIds: string[] = [];
|
|
220
186
|
const memoryPathById = new Map<string, string>();
|
|
221
187
|
const anchorSnapshots = new ExtractionAnchorSnapshot({
|
|
@@ -23,7 +23,12 @@ import type { IdentityInjectionMode, PluginConfig, QmdSearchResult } from "../ty
|
|
|
23
23
|
import { stateViewPacketActive } from "../recall-state-view-anchors.js";
|
|
24
24
|
import { resultStateViewKey, stateViewPacketKeys } from "../recall-state-view.js";
|
|
25
25
|
import { applyRecallStateViews } from "../recall-state-view-wire.js";
|
|
26
|
-
import { composeRecallContext } from "../recall-context-composition.js";
|
|
26
|
+
import { composeRecallContext, type RecallContextComposition } from "../recall-context-composition.js";
|
|
27
|
+
import {
|
|
28
|
+
memoriesToStandingEntries,
|
|
29
|
+
prefixStandingMemoryBlock,
|
|
30
|
+
renderStandingMemoryBlock,
|
|
31
|
+
} from "../standing-memory-recall.js";
|
|
27
32
|
import {
|
|
28
33
|
notifyContextComposition,
|
|
29
34
|
recallFailureComposition,
|
|
@@ -151,16 +156,53 @@ export class RecallEntryCoordinator {
|
|
|
151
156
|
return lockedMsg;
|
|
152
157
|
}
|
|
153
158
|
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
let standingText = "";
|
|
160
|
+
const standingBudget =
|
|
161
|
+
typeof options.budgetCharsOverride === "number" &&
|
|
162
|
+
Number.isInteger(options.budgetCharsOverride) &&
|
|
163
|
+
options.budgetCharsOverride >= 0
|
|
164
|
+
? options.budgetCharsOverride
|
|
165
|
+
: this.deps.config.recallBudgetChars;
|
|
166
|
+
if (this.deps.config.recallStandingBlock && !namespacesEnabled && standingBudget !== 0 && !options.asOf) {
|
|
167
|
+
try {
|
|
168
|
+
const memories = await this.deps.storage.readAllMemories({
|
|
169
|
+
abortSignal: abortController.signal,
|
|
170
|
+
});
|
|
171
|
+
standingText = renderStandingMemoryBlock(
|
|
172
|
+
this.deps.config,
|
|
173
|
+
memoriesToStandingEntries(memories, { requestingConnector: options.sourceConnector }),
|
|
174
|
+
);
|
|
175
|
+
} catch (err) {
|
|
176
|
+
log.warn(`standing memory block skipped: ${err}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const innerObserver = options.onContextComposition;
|
|
180
|
+
const innerBudget =
|
|
181
|
+
standingText.length > 0 && standingBudget && standingBudget > 0
|
|
182
|
+
? Math.max(0, standingBudget - standingText.length - 2)
|
|
183
|
+
: options.budgetCharsOverride;
|
|
184
|
+
const recallOptions = {
|
|
185
|
+
...options,
|
|
186
|
+
abortSignal: abortController.signal,
|
|
187
|
+
budgetCharsOverride: innerBudget,
|
|
188
|
+
onContextComposition:
|
|
189
|
+
standingText.length > 0
|
|
190
|
+
? (composition: RecallContextComposition) =>
|
|
191
|
+
innerObserver?.({
|
|
192
|
+
...composition,
|
|
193
|
+
context: prefixStandingMemoryBlock(
|
|
194
|
+
composition.context ?? "",
|
|
195
|
+
standingText,
|
|
196
|
+
standingBudget,
|
|
197
|
+
),
|
|
198
|
+
})
|
|
199
|
+
: innerObserver,
|
|
200
|
+
};
|
|
156
201
|
try {
|
|
157
|
-
const recallPromise = this.deps.recallInternal(prompt, sessionKey,
|
|
158
|
-
...options,
|
|
159
|
-
abortSignal: abortController.signal,
|
|
160
|
-
}, caps, graphCaps);
|
|
202
|
+
const recallPromise = this.deps.recallInternal(prompt, sessionKey, recallOptions, caps, graphCaps);
|
|
161
203
|
const RECALL_TIMEOUT_MS = this.deps.config.recallOuterTimeoutMs ?? 75_000;
|
|
162
204
|
if (RECALL_TIMEOUT_MS <= 0) {
|
|
163
|
-
return await recallPromise;
|
|
205
|
+
return prefixStandingMemoryBlock(await recallPromise, standingText, standingBudget);
|
|
164
206
|
}
|
|
165
207
|
|
|
166
208
|
let timeoutHandle: NodeJS.Timeout | null = null;
|
|
@@ -196,18 +238,17 @@ export class RecallEntryCoordinator {
|
|
|
196
238
|
}
|
|
197
239
|
}
|
|
198
240
|
|
|
199
|
-
return recallResult;
|
|
241
|
+
return prefixStandingMemoryBlock(recallResult, standingText, standingBudget);
|
|
200
242
|
} catch (err) {
|
|
201
243
|
this.deps.logRecallFailure(err);
|
|
202
|
-
// endTrace() is safe here: if no trace is active (disabled or already
|
|
203
|
-
// closed by recallInternal's try/finally), it returns null immediately.
|
|
204
244
|
this.deps.profiler.endTrace();
|
|
205
|
-
// Caller-cancelled recalls stay quiet: the failure was the caller's
|
|
206
|
-
// abort, not a recall degradation (issue #2972 contract).
|
|
207
245
|
const missing = options.abortSignal?.aborted
|
|
208
246
|
? null
|
|
209
247
|
: recallFailureComposition(err);
|
|
210
248
|
if (!missing) return "";
|
|
249
|
+
if (standingText.length > 0) {
|
|
250
|
+
missing.context = prefixStandingMemoryBlock(missing.context ?? "", standingText, standingBudget);
|
|
251
|
+
}
|
|
211
252
|
notifyContextComposition(options.onContextComposition, missing, (observerErr) => {
|
|
212
253
|
log.warn("recall: context composition observer failed open", observerErr);
|
|
213
254
|
});
|
|
@@ -230,6 +230,7 @@ async function writeFact(memoryDir: string): Promise<void> {
|
|
|
230
230
|
`created: ${now}`,
|
|
231
231
|
`updated: ${now}`,
|
|
232
232
|
"source: extraction",
|
|
233
|
+
"origin: user",
|
|
233
234
|
"confidence: 0.8",
|
|
234
235
|
"confidenceTier: high",
|
|
235
236
|
"tags: []",
|
|
@@ -242,7 +243,7 @@ async function writeFact(memoryDir: string): Promise<void> {
|
|
|
242
243
|
await writeFile(path.join(factsDir, "standing-fact.md"), `${fact.join("\n")}\n`, "utf-8");
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
test("
|
|
246
|
+
test("recall injects the standing memory block when the flag is on", async () => {
|
|
246
247
|
const off = await makeOrchestrator();
|
|
247
248
|
const on = await makeOrchestrator({ recallStandingBlock: true });
|
|
248
249
|
try {
|
|
@@ -250,8 +251,8 @@ test("zero-diff: recall output is byte-identical with the flag off vs on (pre-wi
|
|
|
250
251
|
await writeFact(on.memoryDir);
|
|
251
252
|
const outOff = await off.orchestrator.recall("how do deploys go out", "sess-standing-off");
|
|
252
253
|
const outOn = await on.orchestrator.recall("how do deploys go out", "sess-standing-on");
|
|
253
|
-
assert.
|
|
254
|
-
assert.ok(
|
|
254
|
+
assert.ok(!outOff.includes("## Standing Memory (Remnic)"), "flag off keeps recall unchanged");
|
|
255
|
+
assert.ok(outOn.includes("## Standing Memory (Remnic)"), "flag on injects the standing block");
|
|
255
256
|
assert.ok(outOn.includes("blue pipeline"), "sanity: the fact is recalled");
|
|
256
257
|
} finally {
|
|
257
258
|
await off.orchestrator.destroy();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import { parseConfig } from "./config.js";
|
|
5
|
+
import {
|
|
6
|
+
memoriesToStandingEntries,
|
|
7
|
+
prefixStandingMemoryBlock,
|
|
8
|
+
renderStandingMemoryBlock,
|
|
9
|
+
} from "./standing-memory-recall.js";
|
|
10
|
+
|
|
11
|
+
test("#3089 standing block is omitted when recallStandingBlock is off", () => {
|
|
12
|
+
const off = parseConfig({});
|
|
13
|
+
const on = parseConfig({ recallStandingBlock: true });
|
|
14
|
+
const entries = memoriesToStandingEntries([
|
|
15
|
+
{
|
|
16
|
+
id: "fact-1",
|
|
17
|
+
content: "The blue pipeline is the only deploy path.",
|
|
18
|
+
frontmatter: { id: "fact-1", pinned: true, origin: "user" },
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
const recall = "per-turn recall";
|
|
22
|
+
assert.equal(renderStandingMemoryBlock(off, entries), "");
|
|
23
|
+
assert.equal(prefixStandingMemoryBlock(recall, renderStandingMemoryBlock(off, entries)), recall);
|
|
24
|
+
const standing = renderStandingMemoryBlock(on, entries);
|
|
25
|
+
assert.ok(standing.includes("## Standing Memory (Remnic)"));
|
|
26
|
+
assert.ok(standing.includes("blue pipeline"));
|
|
27
|
+
const prefixed = prefixStandingMemoryBlock(recall, standing);
|
|
28
|
+
assert.ok(prefixed.startsWith(standing));
|
|
29
|
+
assert.ok(prefixed.includes("per-turn recall"));
|
|
30
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_UNTRUSTED_ORIGINS,
|
|
3
|
+
isUntrustedOrigin,
|
|
4
|
+
parseOriginClass,
|
|
5
|
+
} from "./security/origin-authority.js";
|
|
6
|
+
import type { PluginConfig } from "./types.js";
|
|
7
|
+
import {
|
|
8
|
+
buildStandingMemoryBlock,
|
|
9
|
+
lintStandingBlockVolatility,
|
|
10
|
+
type StandingMemoryEntry,
|
|
11
|
+
} from "./standing-memory-block.js";
|
|
12
|
+
|
|
13
|
+
export interface StandingMemorySource {
|
|
14
|
+
id?: string;
|
|
15
|
+
path?: string;
|
|
16
|
+
content: string;
|
|
17
|
+
frontmatter: {
|
|
18
|
+
id?: unknown;
|
|
19
|
+
pinned?: unknown;
|
|
20
|
+
updated?: unknown;
|
|
21
|
+
origin?: unknown;
|
|
22
|
+
status?: unknown;
|
|
23
|
+
toolScoped?: unknown;
|
|
24
|
+
sourceConnector?: unknown;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function memoriesToStandingEntries(
|
|
29
|
+
memories: readonly StandingMemorySource[],
|
|
30
|
+
opts: { requestingConnector?: string } = {},
|
|
31
|
+
): StandingMemoryEntry[] {
|
|
32
|
+
const entries: StandingMemoryEntry[] = [];
|
|
33
|
+
for (const memory of memories) {
|
|
34
|
+
const id = String(memory.frontmatter.id ?? memory.id ?? memory.path ?? "");
|
|
35
|
+
if (!id) continue;
|
|
36
|
+
if (isUntrustedOrigin(parseOriginClass(memory.frontmatter.origin), DEFAULT_UNTRUSTED_ORIGINS)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (typeof memory.frontmatter.status === "string" && memory.frontmatter.status !== "active") {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const requestingConnector = opts.requestingConnector?.trim();
|
|
43
|
+
const memoryConnector =
|
|
44
|
+
typeof memory.frontmatter.sourceConnector === "string" ? memory.frontmatter.sourceConnector.trim() : "";
|
|
45
|
+
if (memory.frontmatter.toolScoped === true && memoryConnector && requestingConnector && memoryConnector !== requestingConnector) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const description =
|
|
49
|
+
memory.content
|
|
50
|
+
.split("\n")
|
|
51
|
+
.map((line) => line.trim())
|
|
52
|
+
.find((line) => line.length > 0 && !line.startsWith("#") && !line.startsWith("---")) ?? "";
|
|
53
|
+
if (description.length < 8) continue;
|
|
54
|
+
if (lintStandingBlockVolatility(description).length > 0) continue;
|
|
55
|
+
const pinned = memory.frontmatter.pinned === true;
|
|
56
|
+
const lastChangedAt =
|
|
57
|
+
typeof memory.frontmatter.updated === "string" ? memory.frontmatter.updated : undefined;
|
|
58
|
+
entries.push({ id, description: description.slice(0, 200), pinned, lastChangedAt });
|
|
59
|
+
}
|
|
60
|
+
return entries;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function renderStandingMemoryBlock(config: PluginConfig, entries: StandingMemoryEntry[]): string {
|
|
64
|
+
if (!config.recallStandingBlock || entries.length === 0) return "";
|
|
65
|
+
try {
|
|
66
|
+
return buildStandingMemoryBlock({
|
|
67
|
+
entries,
|
|
68
|
+
nowMs: Date.now(),
|
|
69
|
+
maxChars: config.standingBlockMaxChars,
|
|
70
|
+
freshDays: config.standingBlockFreshDays,
|
|
71
|
+
}).text;
|
|
72
|
+
} catch {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function prefixStandingMemoryBlock(
|
|
78
|
+
recallResult: string,
|
|
79
|
+
standingText: string,
|
|
80
|
+
budgetChars?: number,
|
|
81
|
+
): string {
|
|
82
|
+
if (standingText.length === 0) return recallResult;
|
|
83
|
+
if (budgetChars === 0) return recallResult;
|
|
84
|
+
const combined = `${standingText}\n\n${recallResult}`;
|
|
85
|
+
if (!budgetChars || combined.length <= budgetChars) return combined;
|
|
86
|
+
return combined.slice(0, budgetChars);
|
|
87
|
+
}
|