@remnic/core 1.0.1 → 1.0.3
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/LICENSE +21 -0
- package/README.md +48 -0
- package/dist/access-cli.d.ts +13 -3
- package/dist/access-cli.js +90 -75
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +10 -3
- package/dist/access-http.js +25 -18
- package/dist/access-mcp.d.ts +30 -3
- package/dist/access-mcp.js +16 -1
- package/dist/access-schema.d.ts +46 -46
- package/dist/access-schema.js +1 -1
- package/dist/access-service.d.ts +65 -4
- package/dist/access-service.js +21 -15
- package/dist/active-memory-bridge.d.ts +66 -0
- package/dist/active-memory-bridge.js +11 -0
- package/dist/active-recall.d.ts +96 -0
- package/dist/active-recall.js +308 -0
- package/dist/active-recall.js.map +1 -0
- package/dist/behavior-learner.js +1 -1
- package/dist/bootstrap.d.ts +6 -3
- package/dist/bootstrap.js +2 -2
- package/dist/boxes.js +2 -2
- package/dist/briefing.d.ts +169 -0
- package/dist/briefing.js +52 -0
- package/dist/briefing.js.map +1 -0
- package/dist/buffer.d.ts +19 -5
- package/dist/buffer.js +2 -2
- package/dist/calibration.js +6 -6
- package/dist/causal-behavior.js +5 -5
- package/dist/causal-chain.js +3 -3
- package/dist/causal-consolidation.d.ts +22 -2
- package/dist/causal-consolidation.js +36 -9
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +6 -6
- package/dist/causal-trajectory-graph.js +1 -1
- package/dist/causal-trajectory.d.ts +14 -1
- package/dist/causal-trajectory.js +5 -1
- package/dist/{chunk-KWBU5S5U.js → chunk-2ODBA7MQ.js} +9 -3
- package/dist/chunk-2ODBA7MQ.js.map +1 -0
- package/dist/{chunk-6UJQNRIO.js → chunk-2VFW5K5U.js} +93 -36
- package/dist/chunk-2VFW5K5U.js.map +1 -0
- package/dist/chunk-3PG3H5TD.js +7 -0
- package/dist/chunk-3PG3H5TD.js.map +1 -0
- package/dist/{chunk-NTTLPF7F.js → chunk-3QFQGRHO.js} +5 -5
- package/dist/chunk-4DJQYKMN.js +187 -0
- package/dist/chunk-4DJQYKMN.js.map +1 -0
- package/dist/chunk-4KAN3GZ3.js +225 -0
- package/dist/chunk-4KAN3GZ3.js.map +1 -0
- package/dist/{chunk-ORZMT74A.js → chunk-4NRAJUDS.js} +11 -1
- package/dist/chunk-4NRAJUDS.js.map +1 -0
- package/dist/{chunk-B7LOFDVE.js → chunk-4WMCPJWX.js} +8 -3
- package/dist/chunk-4WMCPJWX.js.map +1 -0
- package/dist/{chunk-G3AG3KZN.js → chunk-5IZL4DCV.js} +2 -2
- package/dist/{chunk-BRK4ODMI.js → chunk-5NPGSAVB.js} +2 -2
- package/dist/chunk-6MKAMLQL.js +16 -0
- package/dist/chunk-6MKAMLQL.js.map +1 -0
- package/dist/{chunk-ESSMF2FR.js → chunk-6PFRXT4K.js} +15 -6
- package/dist/chunk-6PFRXT4K.js.map +1 -0
- package/dist/chunk-6ZH4TU6I.js +245 -0
- package/dist/chunk-6ZH4TU6I.js.map +1 -0
- package/dist/{chunk-V4YC4LUK.js → chunk-74JR4N5J.js} +175 -63
- package/dist/chunk-74JR4N5J.js.map +1 -0
- package/dist/{chunk-L5RPWGFK.js → chunk-7DHTMOND.js} +2 -2
- package/dist/{chunk-TVVVQQAK.js → chunk-7PA4OZEU.js} +53 -11
- package/dist/chunk-7PA4OZEU.js.map +1 -0
- package/dist/{chunk-Q6FETXJA.js → chunk-7SEAZFFB.js} +2 -2
- package/dist/chunk-ALXMCZEU.js +332 -0
- package/dist/chunk-ALXMCZEU.js.map +1 -0
- package/dist/{chunk-QANCTXQF.js → chunk-AYPYCLR7.js} +3 -3
- package/dist/{chunk-WWIQTB2Y.js → chunk-BKQJBXXX.js} +9 -2
- package/dist/chunk-BKQJBXXX.js.map +1 -0
- package/dist/{chunk-LP47L3ZX.js → chunk-BTY5RRRF.js} +7 -7
- package/dist/{chunk-SCHEKPYH.js → chunk-C2EFFULQ.js} +1 -1
- package/dist/{chunk-GJR6D6KC.js → chunk-D654IBA6.js} +2 -2
- package/dist/{chunk-UV2FO7J4.js → chunk-E6K4NIEU.js} +2 -2
- package/dist/{chunk-T4WRIV2C.js → chunk-EABGC2TL.js} +2 -2
- package/dist/chunk-ECKDIK5F.js +813 -0
- package/dist/chunk-ECKDIK5F.js.map +1 -0
- package/dist/chunk-EJI5XIBB.js +232 -0
- package/dist/chunk-EJI5XIBB.js.map +1 -0
- package/dist/{chunk-ONRU4L2N.js → chunk-FEMOX5AD.js} +2 -2
- package/dist/{chunk-IFFFR3MR.js → chunk-FSFEQI74.js} +3 -3
- package/dist/chunk-G4SK7DSQ.js +121 -0
- package/dist/chunk-G4SK7DSQ.js.map +1 -0
- package/dist/{chunk-UIYZ5T3I.js → chunk-GJQPH5G3.js} +8 -8
- package/dist/{chunk-2PO5ZRKV.js → chunk-GZCUW5IC.js} +16 -3
- package/dist/chunk-GZCUW5IC.js.map +1 -0
- package/dist/{chunk-IZME7KW2.js → chunk-HITJFT7E.js} +24 -10
- package/dist/{chunk-IZME7KW2.js.map → chunk-HITJFT7E.js.map} +1 -1
- package/dist/chunk-IQT3XTKW.js +121 -0
- package/dist/chunk-IQT3XTKW.js.map +1 -0
- package/dist/{chunk-BDFZXRSO.js → chunk-J4IYOZZ5.js} +15 -2
- package/dist/chunk-J4IYOZZ5.js.map +1 -0
- package/dist/{chunk-ZKYI7UVO.js → chunk-JR4ZC3G4.js} +2 -2
- package/dist/{chunk-UCYSTFZR.js → chunk-JRNQ3RNA.js} +2 -2
- package/dist/{chunk-UYSKNO6E.js → chunk-JROGC36Y.js} +15 -4
- package/dist/chunk-JROGC36Y.js.map +1 -0
- package/dist/{chunk-GPGBSNKM.js → chunk-K4FLSOR5.js} +2 -2
- package/dist/{chunk-M5ZBBBJI.js → chunk-KEG4GNGI.js} +2 -2
- package/dist/chunk-KVE7R4CG.js +320 -0
- package/dist/chunk-KVE7R4CG.js.map +1 -0
- package/dist/{chunk-L7WO3MZ4.js → chunk-KWP7T3DP.js} +2 -2
- package/dist/chunk-LAYN4LDC.js +267 -0
- package/dist/chunk-LAYN4LDC.js.map +1 -0
- package/dist/{chunk-PGK3VUHN.js → chunk-MTLYEMJB.js} +3 -2
- package/dist/chunk-MTLYEMJB.js.map +1 -0
- package/dist/{chunk-J47FNDR7.js → chunk-MYQWXITD.js} +7 -7
- package/dist/{chunk-YNI4S5WT.js → chunk-N53K2EXC.js} +2 -2
- package/dist/{chunk-763GUIOU.js → chunk-NBNN5GOB.js} +2 -2
- package/dist/{chunk-CXWFUJR2.js → chunk-NSB3WSYS.js} +125 -6
- package/dist/chunk-NSB3WSYS.js.map +1 -0
- package/dist/{chunk-KL4CP4SB.js → chunk-O5ETUNBT.js} +17 -5
- package/dist/chunk-O5ETUNBT.js.map +1 -0
- package/dist/{chunk-OOSWAUYB.js → chunk-ODWDQNRE.js} +2 -2
- package/dist/{chunk-ISY75RLM.js → chunk-OJFGVJS6.js} +288 -7
- package/dist/chunk-OJFGVJS6.js.map +1 -0
- package/dist/{chunk-HLBYLYRD.js → chunk-PAORGQRI.js} +70 -13
- package/dist/chunk-PAORGQRI.js.map +1 -0
- package/dist/{chunk-ZJLY4QSU.js → chunk-PMB3WGDL.js} +69 -6
- package/dist/chunk-PMB3WGDL.js.map +1 -0
- package/dist/{chunk-J3BT33K7.js → chunk-POBPGDWI.js} +5 -5
- package/dist/{chunk-QWUUMMIK.js → chunk-POMSFKTB.js} +1351 -76
- package/dist/chunk-POMSFKTB.js.map +1 -0
- package/dist/{chunk-OTAVQCSF.js → chunk-PYXS46O7.js} +2 -2
- package/dist/chunk-QDW3E4RD.js +108 -0
- package/dist/chunk-QDW3E4RD.js.map +1 -0
- package/dist/{chunk-YNCQ7E4M.js → chunk-QDYXG4CS.js} +4 -3
- package/dist/chunk-QDYXG4CS.js.map +1 -0
- package/dist/{chunk-XUHI52HK.js → chunk-QKAH5B6E.js} +4 -4
- package/dist/{chunk-HLXVTBF3.js → chunk-QNJMBKFK.js} +3 -2
- package/dist/chunk-QNJMBKFK.js.map +1 -0
- package/dist/chunk-RCICHSHL.js +789 -0
- package/dist/chunk-RCICHSHL.js.map +1 -0
- package/dist/{chunk-HG2NKWR2.js → chunk-S4LX5EBI.js} +2 -2
- package/dist/{chunk-4A24LIM2.js → chunk-S75M5ZRK.js} +2 -2
- package/dist/{chunk-QCCCQT3O.js → chunk-TBBDFYXW.js} +2 -2
- package/dist/chunk-TBBDFYXW.js.map +1 -0
- package/dist/{chunk-U4PV25RD.js → chunk-U2IQTSBY.js} +1 -1
- package/dist/chunk-U2IQTSBY.js.map +1 -0
- package/dist/chunk-U66YHYC7.js +31 -0
- package/dist/chunk-U66YHYC7.js.map +1 -0
- package/dist/{chunk-MWGVGUIS.js → chunk-UEYA6UC7.js} +36 -4
- package/dist/chunk-UEYA6UC7.js.map +1 -0
- package/dist/{chunk-MDDAA2AO.js → chunk-UPMD5XND.js} +2 -2
- package/dist/{chunk-M5KEYE5E.js → chunk-URB2WSKZ.js} +2 -2
- package/dist/chunk-UVJFDP7P.js +202 -0
- package/dist/chunk-UVJFDP7P.js.map +1 -0
- package/dist/{chunk-QY2BHY5O.js → chunk-V7XCAHIB.js} +265 -25
- package/dist/chunk-V7XCAHIB.js.map +1 -0
- package/dist/chunk-W6SL7OFG.js +180 -0
- package/dist/chunk-W6SL7OFG.js.map +1 -0
- package/dist/{chunk-QDOSNLB4.js → chunk-X4WESCKA.js} +17 -15
- package/dist/chunk-X4WESCKA.js.map +1 -0
- package/dist/{chunk-OTFNI3OO.js → chunk-XMGSSBFX.js} +1738 -383
- package/dist/chunk-XMGSSBFX.js.map +1 -0
- package/dist/chunk-YDBIWGNI.js +298 -0
- package/dist/chunk-YDBIWGNI.js.map +1 -0
- package/dist/chunk-YFYL2SIJ.js +7857 -0
- package/dist/chunk-YFYL2SIJ.js.map +1 -0
- package/dist/chunking.js +1 -1
- package/dist/citations.d.ts +67 -0
- package/dist/citations.js +13 -0
- package/dist/citations.js.map +1 -0
- package/dist/cli-DwIBnp2g.d.ts +1240 -0
- package/dist/cli.d.ts +31 -1147
- package/dist/cli.js +149 -7092
- package/dist/cli.js.map +1 -1
- package/dist/codex-materialize-CQlLTzke.d.ts +139 -0
- package/dist/codex-thread-key.d.ts +3 -0
- package/dist/codex-thread-key.js +7 -0
- package/dist/codex-thread-key.js.map +1 -0
- package/dist/config.js +3 -2
- package/dist/connectors/codex/instructions.md +160 -0
- package/dist/connectors/codex/resources/namespace-cheatsheet.md +48 -0
- package/dist/day-summary.d.ts +7 -2
- package/dist/day-summary.js +5 -2
- package/dist/embedding-fallback.d.ts +96 -2
- package/dist/embedding-fallback.js +6 -4
- package/dist/{engine-2A6J4XEX.js → engine-X7X3AAG3.js} +10 -7
- package/dist/engine-X7X3AAG3.js.map +1 -0
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +10 -7
- package/dist/entity-schema.d.ts +11 -0
- package/dist/entity-schema.js +19 -0
- package/dist/entity-schema.js.map +1 -0
- package/dist/explicit-capture.d.ts +6 -3
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-judge.d.ts +66 -0
- package/dist/extraction-judge.js +18 -0
- package/dist/extraction-judge.js.map +1 -0
- package/dist/extraction.d.ts +1 -0
- package/dist/extraction.js +12 -10
- package/dist/fallback-llm.js +4 -4
- package/dist/graph.js +1 -1
- package/dist/importance.d.ts +11 -1
- package/dist/importance.js +3 -1
- package/dist/index.d.ts +1140 -8
- package/dist/index.js +3350 -333
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +2 -1
- package/dist/intent.js +3 -1
- package/dist/lifecycle.js +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +1 -1
- package/dist/memory-cache.d.ts +2 -2
- package/dist/memory-cache.js +1 -1
- package/dist/{memory-projection-store-NxMkbocT.d.ts → memory-projection-store-DeSXPh1j.d.ts} +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/model-registry.js +2 -2
- package/dist/models-json.js +2 -2
- package/dist/native-knowledge.js +2 -2
- package/dist/negative.js +2 -2
- package/dist/operator-toolkit.js +20 -16
- package/dist/{orchestrator-CIvLFHx3.d.ts → orchestrator-B9kwlCep.d.ts} +254 -9
- package/dist/orchestrator.d.ts +6 -3
- package/dist/orchestrator.js +70 -58
- package/dist/page-versioning.d.ts +77 -0
- package/dist/page-versioning.js +15 -0
- package/dist/page-versioning.js.map +1 -0
- package/dist/plugin-id.d.ts +37 -0
- package/dist/plugin-id.js +11 -0
- package/dist/plugin-id.js.map +1 -0
- package/dist/policy-runtime.js +2 -2
- package/dist/profiling.js +2 -2
- package/dist/qmd.d.ts +5 -2
- package/dist/qmd.js +3 -3
- package/dist/recall-audit.d.ts +20 -0
- package/dist/recall-audit.js +50 -0
- package/dist/recall-audit.js.map +1 -0
- package/dist/recall-mmr.d.ts +152 -0
- package/dist/recall-mmr.js +17 -0
- package/dist/recall-mmr.js.map +1 -0
- package/dist/recall-qos.js +2 -2
- package/dist/recall-state.js +2 -2
- package/dist/relevance.js +2 -2
- package/dist/resolve-provider-secret.js +2 -2
- package/dist/resume-bundles.js +5 -4
- package/dist/retrieval-agents.js +2 -2
- package/dist/retrieval.js +2 -2
- package/dist/schemas.d.ts +422 -64
- package/dist/schemas.js +3 -1
- package/dist/sdk-compat.d.ts +2 -0
- package/dist/sdk-compat.js +6 -3
- package/dist/sdk-compat.js.map +1 -1
- package/dist/semantic-chunking.d.ts +87 -0
- package/dist/semantic-chunking.js +20 -0
- package/dist/semantic-chunking.js.map +1 -0
- package/dist/semantic-consolidation-DrvSYRdB.d.ts +119 -0
- package/dist/semantic-consolidation.d.ts +4 -42
- package/dist/semantic-consolidation.js +23 -2
- package/dist/semantic-rule-promotion.js +9 -6
- package/dist/semantic-rule-verifier.js +10 -7
- package/dist/session-observer-state.js +2 -2
- package/dist/session-toggles.d.ts +22 -0
- package/dist/session-toggles.js +116 -0
- package/dist/session-toggles.js.map +1 -0
- package/dist/skills-registry.d.ts +47 -0
- package/dist/skills-registry.js +48 -0
- package/dist/skills-registry.js.map +1 -0
- package/dist/source-attribution.d.ts +169 -0
- package/dist/source-attribution.js +27 -0
- package/dist/source-attribution.js.map +1 -0
- package/dist/storage.d.ts +171 -10
- package/dist/storage.js +16 -5
- package/dist/summarizer.js +7 -7
- package/dist/temporal-supersession.d.ts +127 -0
- package/dist/temporal-supersession.js +20 -0
- package/dist/temporal-supersession.js.map +1 -0
- package/dist/threading.js +2 -2
- package/dist/tier-migration.d.ts +2 -1
- package/dist/tier-routing.js +2 -2
- package/dist/tokens.d.ts +21 -1
- package/dist/tokens.js +5 -1
- package/dist/transcript.js +2 -2
- package/dist/types.d.ts +497 -3
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +2 -2
- package/dist/utility-runtime.js +3 -3
- package/dist/verified-recall.js +11 -8
- package/dist/whitespace.d.ts +4 -0
- package/dist/whitespace.js +9 -0
- package/dist/whitespace.js.map +1 -0
- package/package.json +14 -8
- package/dist/chunk-2CJCWDMR.js +0 -87
- package/dist/chunk-2CJCWDMR.js.map +0 -1
- package/dist/chunk-2PO5ZRKV.js.map +0 -1
- package/dist/chunk-6UJQNRIO.js.map +0 -1
- package/dist/chunk-B7LOFDVE.js.map +0 -1
- package/dist/chunk-BDFZXRSO.js.map +0 -1
- package/dist/chunk-CXWFUJR2.js.map +0 -1
- package/dist/chunk-DORBM6OB.js +0 -81
- package/dist/chunk-DORBM6OB.js.map +0 -1
- package/dist/chunk-ESSMF2FR.js.map +0 -1
- package/dist/chunk-HLBYLYRD.js.map +0 -1
- package/dist/chunk-HLXVTBF3.js.map +0 -1
- package/dist/chunk-ISY75RLM.js.map +0 -1
- package/dist/chunk-KL4CP4SB.js.map +0 -1
- package/dist/chunk-KWBU5S5U.js.map +0 -1
- package/dist/chunk-MWGVGUIS.js.map +0 -1
- package/dist/chunk-ORZMT74A.js.map +0 -1
- package/dist/chunk-OTFNI3OO.js.map +0 -1
- package/dist/chunk-PGK3VUHN.js.map +0 -1
- package/dist/chunk-QCCCQT3O.js.map +0 -1
- package/dist/chunk-QDOSNLB4.js.map +0 -1
- package/dist/chunk-QPKFPHOO.js +0 -178
- package/dist/chunk-QPKFPHOO.js.map +0 -1
- package/dist/chunk-QWUUMMIK.js.map +0 -1
- package/dist/chunk-QY2BHY5O.js.map +0 -1
- package/dist/chunk-TVVVQQAK.js.map +0 -1
- package/dist/chunk-U4PV25RD.js.map +0 -1
- package/dist/chunk-UYSKNO6E.js.map +0 -1
- package/dist/chunk-V4YC4LUK.js.map +0 -1
- package/dist/chunk-WWIQTB2Y.js.map +0 -1
- package/dist/chunk-YNCQ7E4M.js.map +0 -1
- package/dist/chunk-ZJLY4QSU.js.map +0 -1
- /package/dist/{engine-2A6J4XEX.js.map → active-memory-bridge.js.map} +0 -0
- /package/dist/{chunk-NTTLPF7F.js.map → chunk-3QFQGRHO.js.map} +0 -0
- /package/dist/{chunk-G3AG3KZN.js.map → chunk-5IZL4DCV.js.map} +0 -0
- /package/dist/{chunk-BRK4ODMI.js.map → chunk-5NPGSAVB.js.map} +0 -0
- /package/dist/{chunk-L5RPWGFK.js.map → chunk-7DHTMOND.js.map} +0 -0
- /package/dist/{chunk-Q6FETXJA.js.map → chunk-7SEAZFFB.js.map} +0 -0
- /package/dist/{chunk-QANCTXQF.js.map → chunk-AYPYCLR7.js.map} +0 -0
- /package/dist/{chunk-LP47L3ZX.js.map → chunk-BTY5RRRF.js.map} +0 -0
- /package/dist/{chunk-SCHEKPYH.js.map → chunk-C2EFFULQ.js.map} +0 -0
- /package/dist/{chunk-GJR6D6KC.js.map → chunk-D654IBA6.js.map} +0 -0
- /package/dist/{chunk-UV2FO7J4.js.map → chunk-E6K4NIEU.js.map} +0 -0
- /package/dist/{chunk-T4WRIV2C.js.map → chunk-EABGC2TL.js.map} +0 -0
- /package/dist/{chunk-ONRU4L2N.js.map → chunk-FEMOX5AD.js.map} +0 -0
- /package/dist/{chunk-IFFFR3MR.js.map → chunk-FSFEQI74.js.map} +0 -0
- /package/dist/{chunk-UIYZ5T3I.js.map → chunk-GJQPH5G3.js.map} +0 -0
- /package/dist/{chunk-ZKYI7UVO.js.map → chunk-JR4ZC3G4.js.map} +0 -0
- /package/dist/{chunk-UCYSTFZR.js.map → chunk-JRNQ3RNA.js.map} +0 -0
- /package/dist/{chunk-GPGBSNKM.js.map → chunk-K4FLSOR5.js.map} +0 -0
- /package/dist/{chunk-M5ZBBBJI.js.map → chunk-KEG4GNGI.js.map} +0 -0
- /package/dist/{chunk-L7WO3MZ4.js.map → chunk-KWP7T3DP.js.map} +0 -0
- /package/dist/{chunk-J47FNDR7.js.map → chunk-MYQWXITD.js.map} +0 -0
- /package/dist/{chunk-YNI4S5WT.js.map → chunk-N53K2EXC.js.map} +0 -0
- /package/dist/{chunk-763GUIOU.js.map → chunk-NBNN5GOB.js.map} +0 -0
- /package/dist/{chunk-OOSWAUYB.js.map → chunk-ODWDQNRE.js.map} +0 -0
- /package/dist/{chunk-J3BT33K7.js.map → chunk-POBPGDWI.js.map} +0 -0
- /package/dist/{chunk-OTAVQCSF.js.map → chunk-PYXS46O7.js.map} +0 -0
- /package/dist/{chunk-XUHI52HK.js.map → chunk-QKAH5B6E.js.map} +0 -0
- /package/dist/{chunk-HG2NKWR2.js.map → chunk-S4LX5EBI.js.map} +0 -0
- /package/dist/{chunk-4A24LIM2.js.map → chunk-S75M5ZRK.js.map} +0 -0
- /package/dist/{chunk-MDDAA2AO.js.map → chunk-UPMD5XND.js.map} +0 -0
- /package/dist/{chunk-M5KEYE5E.js.map → chunk-URB2WSKZ.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/access-schema.ts"],"sourcesContent":["// Request/response schema validation for the Remnic HTTP API.\n// Uses zod for runtime validation — returns structured 400 errors with\n// field-level detail so consumers get clear feedback on malformed requests.\n\nimport { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Error formatting\n// ---------------------------------------------------------------------------\n\nexport interface SchemaValidationError {\n error: string;\n code: \"validation_error\";\n details: Array<{ field: string; message: string }>;\n}\n\nexport function formatZodError(error: z.ZodError): SchemaValidationError {\n return {\n error: \"request validation failed\",\n code: \"validation_error\",\n details: error.issues.map((issue) => ({\n field: issue.path.join(\".\") || \"(root)\",\n message: issue.message,\n })),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Shared fields\n// ---------------------------------------------------------------------------\n\nconst namespaceSchema = z.string().trim().max(256).optional();\nconst sessionKeySchema = z.string().trim().min(1).max(512).optional();\nconst idempotencyKeySchema = z.string().trim().min(1).max(256).optional();\nconst dryRunSchema = z.boolean().optional();\nconst schemaVersionSchema = z.number().int().optional();\n\n// ---------------------------------------------------------------------------\n// Recall\n// ---------------------------------------------------------------------------\n\nexport const recallRequestSchema = z.object({\n query: z.string().min(1, \"query is required\"),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n topK: z.number().int().min(0).max(200).optional(),\n mode: z.enum([\"auto\", \"no_recall\", \"minimal\", \"full\", \"graph_mode\"]).optional(),\n includeDebug: z.boolean().optional(),\n});\n\nexport const recallExplainRequestSchema = z.object({\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Observe\n// ---------------------------------------------------------------------------\n\nconst messageSchema = z.object({\n role: z.enum([\"user\", \"assistant\"]),\n content: z.string().min(1, \"message content must be non-empty\"),\n});\n\nexport const observeRequestSchema = z.object({\n sessionKey: z.string().trim().min(1, \"sessionKey is required\").max(512),\n messages: z.array(messageSchema).min(1, \"messages must be a non-empty array\"),\n namespace: namespaceSchema,\n skipExtraction: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Memory store / suggestion submit\n// ---------------------------------------------------------------------------\n\nconst writeContentSchema = z.string().min(1, \"content is required\").max(50000);\nconst categorySchema = z\n .enum([\n \"fact\", \"preference\", \"correction\", \"entity\", \"decision\",\n \"relationship\", \"principle\", \"commitment\", \"moment\", \"skill\", \"rule\",\n ])\n .optional();\nconst confidenceSchema = z.number().min(0).max(1).optional();\nconst tagsSchema = z.array(z.string().max(256)).max(50).optional();\nconst entityRefSchema = z.string().trim().max(512).optional();\nconst ttlSchema = z.string().trim().max(128).optional();\nconst sourceReasonSchema = z.string().trim().max(2000).optional();\n\nexport const memoryStoreRequestSchema = z.object({\n schemaVersion: schemaVersionSchema,\n idempotencyKey: idempotencyKeySchema,\n dryRun: dryRunSchema,\n sessionKey: sessionKeySchema,\n content: writeContentSchema,\n category: categorySchema,\n confidence: confidenceSchema,\n namespace: namespaceSchema,\n tags: tagsSchema,\n entityRef: entityRefSchema,\n ttl: ttlSchema,\n sourceReason: sourceReasonSchema,\n});\n\nexport const suggestionSubmitRequestSchema = memoryStoreRequestSchema;\n\n// ---------------------------------------------------------------------------\n// Review disposition\n// ---------------------------------------------------------------------------\n\nexport const reviewDispositionRequestSchema = z.object({\n memoryId: z.string().trim().min(1, \"memoryId is required\"),\n status: z.enum([\n \"active\", \"pending_review\", \"quarantined\", \"rejected\", \"superseded\", \"archived\",\n ]),\n reasonCode: z.string().trim().min(1, \"reasonCode is required\"),\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Trust-zone promote\n// ---------------------------------------------------------------------------\n\nexport const trustZonePromoteRequestSchema = z.object({\n recordId: z.string().trim().min(1, \"recordId is required\"),\n targetZone: z.enum([\"working\", \"trusted\"], {\n errorMap: () => ({ message: \"targetZone must be 'working' or 'trusted'\" }),\n }),\n promotionReason: z.string().trim().min(1, \"promotionReason is required\"),\n recordedAt: z.string().trim().optional(),\n summary: z.string().trim().max(5000).optional(),\n dryRun: dryRunSchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Trust-zone demo-seed\n// ---------------------------------------------------------------------------\n\nexport const trustZoneDemoSeedRequestSchema = z.object({\n scenario: z.string().trim().max(256).optional(),\n recordedAt: z.string().trim().optional(),\n dryRun: dryRunSchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// LCM search\n// ---------------------------------------------------------------------------\n\nexport const lcmSearchRequestSchema = z.object({\n query: z.string().min(1, \"query is required\"),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n limit: z.number().int().min(1).max(100).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Day summary\n// ---------------------------------------------------------------------------\n\nexport const daySummaryRequestSchema = z.object({\n memories: z.string().max(100000).optional(),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type RecallRequest = z.infer<typeof recallRequestSchema>;\nexport type RecallExplainRequest = z.infer<typeof recallExplainRequestSchema>;\nexport type ObserveRequest = z.infer<typeof observeRequestSchema>;\nexport type MemoryStoreRequest = z.infer<typeof memoryStoreRequestSchema>;\nexport type SuggestionSubmitRequest = z.infer<typeof suggestionSubmitRequestSchema>;\nexport type ReviewDispositionRequest = z.infer<typeof reviewDispositionRequestSchema>;\nexport type TrustZonePromoteRequest = z.infer<typeof trustZonePromoteRequestSchema>;\nexport type TrustZoneDemoSeedRequest = z.infer<typeof trustZoneDemoSeedRequestSchema>;\nexport type LcmSearchRequest = z.infer<typeof lcmSearchRequestSchema>;\nexport type DaySummaryRequest = z.infer<typeof daySummaryRequestSchema>;\n\n// ---------------------------------------------------------------------------\n// Validation helper\n// ---------------------------------------------------------------------------\n\nexport type SchemaName =\n | \"recall\"\n | \"recallExplain\"\n | \"observe\"\n | \"memoryStore\"\n | \"suggestionSubmit\"\n | \"reviewDisposition\"\n | \"trustZonePromote\"\n | \"trustZoneDemoSeed\"\n | \"lcmSearch\"\n | \"daySummary\";\n\nexport type SchemaTypeFor<N extends SchemaName> =\n N extends \"recall\" ? RecallRequest\n : N extends \"recallExplain\" ? RecallExplainRequest\n : N extends \"observe\" ? ObserveRequest\n : N extends \"memoryStore\" ? MemoryStoreRequest\n : N extends \"suggestionSubmit\" ? SuggestionSubmitRequest\n : N extends \"reviewDisposition\" ? ReviewDispositionRequest\n : N extends \"trustZonePromote\" ? TrustZonePromoteRequest\n : N extends \"trustZoneDemoSeed\" ? TrustZoneDemoSeedRequest\n : N extends \"lcmSearch\" ? LcmSearchRequest\n : N extends \"daySummary\" ? DaySummaryRequest\n : never;\n\nconst schemas: Record<SchemaName, z.ZodTypeAny> = {\n recall: recallRequestSchema,\n recallExplain: recallExplainRequestSchema,\n observe: observeRequestSchema,\n memoryStore: memoryStoreRequestSchema,\n suggestionSubmit: suggestionSubmitRequestSchema,\n reviewDisposition: reviewDispositionRequestSchema,\n trustZonePromote: trustZonePromoteRequestSchema,\n trustZoneDemoSeed: trustZoneDemoSeedRequestSchema,\n lcmSearch: lcmSearchRequestSchema,\n daySummary: daySummaryRequestSchema,\n};\n\n/**\n * Validate a request body against the named schema.\n * Returns `{ success: true, data }` on pass or\n * `{ success: false, error }` on failure with field-level detail.\n */\nexport function validateRequest<T = unknown>(\n schemaName: SchemaName,\n body: unknown,\n): { success: true; data: T } | { success: false; error: SchemaValidationError } {\n const schema = schemas[schemaName];\n if (!schema) {\n return {\n success: false,\n error: {\n error: `unknown schema: ${schemaName}`,\n code: \"validation_error\",\n details: [],\n },\n };\n }\n const result = schema.safeParse(body);\n if (result.success) {\n return { success: true, data: result.data as T };\n }\n return { success: false, error: formatZodError(result.error) };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lifecycle.ts"],"sourcesContent":["import type {\n LifecycleState,\n MemoryCategory,\n MemoryFile,\n MemoryFrontmatter,\n VerificationState,\n} from \"./types.js\";\n\nexport interface LifecyclePolicy {\n promoteHeatThreshold: number;\n staleDecayThreshold: number;\n archiveDecayThreshold: number;\n protectedCategories: MemoryCategory[];\n}\n\nexport interface LifecycleSignals {\n /**\n * Optional relevance feedback in [-1, 1]. Negative values increase decay.\n * Positive values raise heat.\n */\n feedbackScore?: number;\n /**\n * Optional bounded prior derived from memory-action outcomes in [-1, 1].\n * This is intentionally low-impact to avoid circular amplification.\n */\n actionPriorScore?: number;\n /**\n * Optional causal impact score from CMC chain analysis in [0, 0.3].\n * Computed as 0.1 * incomingEdges + 0.15 * outgoingEdges, clamped.\n * Weight in heat/decay is intentionally low (0.05) to avoid circular amplification.\n */\n causalImpactScore?: number;\n}\n\nexport interface LifecycleDecision {\n currentState: LifecycleState;\n nextState: LifecycleState;\n heatScore: number;\n decayScore: number;\n changed: boolean;\n reason: string;\n}\n\nexport interface LifecycleValueInputs {\n confidence: number;\n access: number;\n recency: number;\n importance: number;\n feedback: number;\n disputedPenalty: number;\n}\n\nconst DEFAULT_POLICY: LifecyclePolicy = {\n promoteHeatThreshold: 0.55,\n staleDecayThreshold: 0.65,\n archiveDecayThreshold: 0.85,\n protectedCategories: [\"decision\", \"principle\", \"commitment\", \"preference\"],\n};\n\nexport function clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n if (value < 0) return 0;\n if (value > 1) return 1;\n return value;\n}\n\nexport function clampLifecycleThreshold(value: number): number {\n return clamp01(value);\n}\n\nfunction parseIsoMs(value?: string): number | null {\n if (!value) return null;\n const ms = Date.parse(value);\n return Number.isFinite(ms) ? ms : null;\n}\n\nexport function daysSince(value: string | undefined, nowMs: number): number {\n const ts = parseIsoMs(value);\n if (ts === null) return 365;\n return Math.max(0, (nowMs - ts) / 86_400_000);\n}\n\nfunction confidenceTierWeight(frontmatter: MemoryFrontmatter): number {\n switch (frontmatter.confidenceTier) {\n case \"explicit\":\n return 1;\n case \"implied\":\n return 0.8;\n case \"inferred\":\n return 0.6;\n case \"speculative\":\n return 0.35;\n default:\n return clamp01(frontmatter.confidence ?? 0.5);\n }\n}\n\nfunction accessWeight(accessCount: number | undefined): number {\n const raw = accessCount ?? 0;\n if (raw <= 0) return 0;\n return clamp01(Math.log1p(raw) / Math.log1p(20));\n}\n\nfunction recencyWeight(frontmatter: MemoryFrontmatter, nowMs: number): number {\n const lastTouch = frontmatter.lastAccessed ?? frontmatter.updated ?? frontmatter.created;\n const ageDays = daysSince(lastTouch, nowMs);\n return clamp01(1 - ageDays / 90);\n}\n\nfunction feedbackWeight(signals?: LifecycleSignals): number {\n const raw = (signals?.feedbackScore ?? 0) + (signals?.actionPriorScore ?? 0);\n return clamp01((raw + 1) / 2);\n}\n\nfunction boundedFeedbackScore(signals?: LifecycleSignals): number {\n const raw = (signals?.feedbackScore ?? 0) + (signals?.actionPriorScore ?? 0);\n if (!Number.isFinite(raw)) return 0;\n if (raw < -1) return -1;\n if (raw > 1) return 1;\n return raw;\n}\n\nfunction isProtectedMemory(\n frontmatter: MemoryFrontmatter,\n policy: LifecyclePolicy,\n): boolean {\n return frontmatter.policyClass === \"protected\" || policy.protectedCategories.includes(frontmatter.category);\n}\n\nexport function resolveLifecycleState(frontmatter: MemoryFrontmatter): LifecycleState {\n if (frontmatter.status === \"archived\") return \"archived\";\n return frontmatter.lifecycleState ?? \"candidate\";\n}\n\nexport function computeHeat(\n memory: Pick<MemoryFile, \"frontmatter\">,\n now: Date,\n signals?: LifecycleSignals,\n): number {\n const frontmatter = memory.frontmatter;\n if (frontmatter.status === \"archived\") return 0;\n\n const inputs = computeLifecycleValueInputs(memory, now, signals);\n const causalBoost = clamp01(signals?.causalImpactScore ?? 0) * 0.05;\n const score = (inputs.confidence * 0.25)\n + (inputs.access * 0.3)\n + (inputs.recency * 0.2)\n + (inputs.importance * 0.15)\n + (inputs.feedback * 0.1)\n + causalBoost\n - inputs.disputedPenalty;\n return clamp01(score);\n}\n\nexport function computeLifecycleValueInputs(\n memory: Pick<MemoryFile, \"frontmatter\">,\n now: Date,\n signals?: LifecycleSignals,\n): LifecycleValueInputs {\n const frontmatter = memory.frontmatter;\n const nowMs = now.getTime();\n return {\n confidence: confidenceTierWeight(frontmatter),\n access: accessWeight(frontmatter.accessCount),\n recency: recencyWeight(frontmatter, nowMs),\n importance: clamp01(frontmatter.importance?.score ?? 0.5),\n feedback: feedbackWeight(signals),\n disputedPenalty: frontmatter.verificationState === \"disputed\" ? 0.2 : 0,\n };\n}\n\nexport function computeDecay(\n memory: Pick<MemoryFile, \"frontmatter\">,\n now: Date,\n signals?: LifecycleSignals,\n): number {\n const frontmatter = memory.frontmatter;\n if (frontmatter.status === \"archived\") return 1;\n\n const nowMs = now.getTime();\n const ageDays = daysSince(frontmatter.updated ?? frontmatter.created, nowMs);\n const staleAccessDays = daysSince(frontmatter.lastAccessed, nowMs);\n const ageRisk = clamp01(ageDays / 180);\n const staleAccessRisk = clamp01(staleAccessDays / 120);\n const confidenceRisk = 1 - confidenceTierWeight(frontmatter);\n const feedbackRisk = clamp01((boundedFeedbackScore(signals) * -1 + 1) / 2);\n const heat = computeHeat(memory, now, signals);\n\n const score = (ageRisk * 0.3)\n + (staleAccessRisk * 0.25)\n + (confidenceRisk * 0.2)\n + (feedbackRisk * 0.1)\n + ((1 - heat) * 0.15);\n\n return clamp01(score);\n}\n\nfunction toTerminalDisputedState(\n currentState: LifecycleState,\n): LifecycleState {\n if (currentState === \"archived\") return \"archived\";\n return \"stale\";\n}\n\nfunction isActiveEligible(verificationState?: VerificationState): boolean {\n return verificationState === \"user_confirmed\" || verificationState === \"system_inferred\";\n}\n\nexport function decideLifecycleTransition(\n memory: Pick<MemoryFile, \"frontmatter\">,\n policy: Partial<LifecyclePolicy>,\n now: Date,\n signals?: LifecycleSignals,\n): LifecycleDecision {\n const mergedPolicy: LifecyclePolicy = { ...DEFAULT_POLICY, ...policy };\n const frontmatter = memory.frontmatter;\n const currentState = resolveLifecycleState(frontmatter);\n const heatScore = computeHeat(memory, now, signals);\n const decayScore = computeDecay(memory, now, signals);\n const protectedMemory = isProtectedMemory(frontmatter, mergedPolicy);\n\n if (currentState === \"archived\") {\n return {\n currentState,\n nextState: \"archived\",\n heatScore,\n decayScore,\n changed: false,\n reason: \"archived_is_terminal\",\n };\n }\n\n if (frontmatter.verificationState === \"disputed\") {\n const nextState = toTerminalDisputedState(currentState);\n return {\n currentState,\n nextState,\n heatScore,\n decayScore,\n changed: nextState !== currentState,\n reason: \"disputed_memories_do_not_promote_to_active\",\n };\n }\n\n if (decayScore >= mergedPolicy.archiveDecayThreshold && !protectedMemory) {\n return {\n currentState,\n nextState: \"archived\",\n heatScore,\n decayScore,\n changed: true,\n reason: \"decay_exceeded_archive_threshold\",\n };\n }\n\n if (decayScore >= mergedPolicy.staleDecayThreshold) {\n return {\n currentState,\n nextState: \"stale\",\n heatScore,\n decayScore,\n changed: currentState !== \"stale\",\n reason: \"decay_exceeded_stale_threshold\",\n };\n }\n\n if (heatScore >= mergedPolicy.promoteHeatThreshold) {\n const nextState = isActiveEligible(frontmatter.verificationState)\n ? \"active\"\n : \"validated\";\n return {\n currentState,\n nextState,\n heatScore,\n decayScore,\n changed: currentState !== nextState,\n reason: \"heat_exceeded_promote_threshold\",\n };\n }\n\n return {\n currentState,\n nextState: currentState,\n heatScore,\n decayScore,\n changed: false,\n reason: \"no_transition\",\n };\n}\n"],"mappings":";AAoDA,IAAM,iBAAkC;AAAA,EACtC,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,qBAAqB,CAAC,YAAY,aAAa,cAAc,YAAY;AAC3E;AAEO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO;AACT;AAEO,SAAS,wBAAwB,OAAuB;AAC7D,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,WAAW,OAA+B;AACjD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,SAAS,EAAE,IAAI,KAAK;AACpC;AAEO,SAAS,UAAU,OAA2B,OAAuB;AAC1E,QAAM,KAAK,WAAW,KAAK;AAC3B,MAAI,OAAO,KAAM,QAAO;AACxB,SAAO,KAAK,IAAI,IAAI,QAAQ,MAAM,KAAU;AAC9C;AAEA,SAAS,qBAAqB,aAAwC;AACpE,UAAQ,YAAY,gBAAgB;AAAA,IAClC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,QAAQ,YAAY,cAAc,GAAG;AAAA,EAChD;AACF;AAEA,SAAS,aAAa,aAAyC;AAC7D,QAAM,MAAM,eAAe;AAC3B,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,QAAQ,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC;AACjD;AAEA,SAAS,cAAc,aAAgC,OAAuB;AAC5E,QAAM,YAAY,YAAY,gBAAgB,YAAY,WAAW,YAAY;AACjF,QAAM,UAAU,UAAU,WAAW,KAAK;AAC1C,SAAO,QAAQ,IAAI,UAAU,EAAE;AACjC;AAEA,SAAS,eAAe,SAAoC;AAC1D,QAAM,OAAO,SAAS,iBAAiB,MAAM,SAAS,oBAAoB;AAC1E,SAAO,SAAS,MAAM,KAAK,CAAC;AAC9B;AAEA,SAAS,qBAAqB,SAAoC;AAChE,QAAM,OAAO,SAAS,iBAAiB,MAAM,SAAS,oBAAoB;AAC1E,MAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,MAAI,MAAM,GAAI,QAAO;AACrB,MAAI,MAAM,EAAG,QAAO;AACpB,SAAO;AACT;AAEA,SAAS,kBACP,aACA,QACS;AACT,SAAO,YAAY,gBAAgB,eAAe,OAAO,oBAAoB,SAAS,YAAY,QAAQ;AAC5G;AAEO,SAAS,sBAAsB,aAAgD;AACpF,MAAI,YAAY,WAAW,WAAY,QAAO;AAC9C,SAAO,YAAY,kBAAkB;AACvC;AAEO,SAAS,YACd,QACA,KACA,SACQ;AACR,QAAM,cAAc,OAAO;AAC3B,MAAI,YAAY,WAAW,WAAY,QAAO;AAE9C,QAAM,SAAS,4BAA4B,QAAQ,KAAK,OAAO;AAC/D,QAAM,cAAc,QAAQ,SAAS,qBAAqB,CAAC,IAAI;AAC/D,QAAM,QAAS,OAAO,aAAa,OAC9B,OAAO,SAAS,MAChB,OAAO,UAAU,MACjB,OAAO,aAAa,OACpB,OAAO,WAAW,MACnB,cACA,OAAO;AACX,SAAO,QAAQ,KAAK;AACtB;AAEO,SAAS,4BACd,QACA,KACA,SACsB;AACtB,QAAM,cAAc,OAAO;AAC3B,QAAM,QAAQ,IAAI,QAAQ;AAC1B,SAAO;AAAA,IACL,YAAY,qBAAqB,WAAW;AAAA,IAC5C,QAAQ,aAAa,YAAY,WAAW;AAAA,IAC5C,SAAS,cAAc,aAAa,KAAK;AAAA,IACzC,YAAY,QAAQ,YAAY,YAAY,SAAS,GAAG;AAAA,IACxD,UAAU,eAAe,OAAO;AAAA,IAChC,iBAAiB,YAAY,sBAAsB,aAAa,MAAM;AAAA,EACxE;AACF;AAEO,SAAS,aACd,QACA,KACA,SACQ;AACR,QAAM,cAAc,OAAO;AAC3B,MAAI,YAAY,WAAW,WAAY,QAAO;AAE9C,QAAM,QAAQ,IAAI,QAAQ;AAC1B,QAAM,UAAU,UAAU,YAAY,WAAW,YAAY,SAAS,KAAK;AAC3E,QAAM,kBAAkB,UAAU,YAAY,cAAc,KAAK;AACjE,QAAM,UAAU,QAAQ,UAAU,GAAG;AACrC,QAAM,kBAAkB,QAAQ,kBAAkB,GAAG;AACrD,QAAM,iBAAiB,IAAI,qBAAqB,WAAW;AAC3D,QAAM,eAAe,SAAS,qBAAqB,OAAO,IAAI,KAAK,KAAK,CAAC;AACzE,QAAM,OAAO,YAAY,QAAQ,KAAK,OAAO;AAE7C,QAAM,QAAS,UAAU,MACpB,kBAAkB,OAClB,iBAAiB,MACjB,eAAe,OACd,IAAI,QAAQ;AAElB,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,wBACP,cACgB;AAChB,MAAI,iBAAiB,WAAY,QAAO;AACxC,SAAO;AACT;AAEA,SAAS,iBAAiB,mBAAgD;AACxE,SAAO,sBAAsB,oBAAoB,sBAAsB;AACzE;AAEO,SAAS,0BACd,QACA,QACA,KACA,SACmB;AACnB,QAAM,eAAgC,EAAE,GAAG,gBAAgB,GAAG,OAAO;AACrE,QAAM,cAAc,OAAO;AAC3B,QAAM,eAAe,sBAAsB,WAAW;AACtD,QAAM,YAAY,YAAY,QAAQ,KAAK,OAAO;AAClD,QAAM,aAAa,aAAa,QAAQ,KAAK,OAAO;AACpD,QAAM,kBAAkB,kBAAkB,aAAa,YAAY;AAEnE,MAAI,iBAAiB,YAAY;AAC/B,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,YAAY,sBAAsB,YAAY;AAChD,UAAM,YAAY,wBAAwB,YAAY;AACtD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,cAAc;AAAA,MACvB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,cAAc,aAAa,yBAAyB,CAAC,iBAAiB;AACxE,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,cAAc,aAAa,qBAAqB;AAClD,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,SAAS,iBAAiB;AAAA,MAC1B,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,aAAa,aAAa,sBAAsB;AAClD,UAAM,YAAY,iBAAiB,YAAY,iBAAiB,IAC5D,WACA;AACJ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,iBAAiB;AAAA,MAC1B,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/operator-toolkit.ts","../src/namespaces/migrate.ts"],"sourcesContent":["import path from \"node:path\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, readFile, readdir, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { lintWorkspaceFiles } from \"./hygiene.js\";\nimport { parseConfig } from \"./config.js\";\nimport { readEnvVar, resolveHomeDir } from \"./runtime/env.js\";\nimport {\n resolveCuratedIncludeFilesStatePath,\n resolveNativeKnowledgeStatePath,\n resolveOpenClawWorkspaceStatePath,\n} from \"./native-knowledge.js\";\nimport { StorageManager } from \"./storage.js\";\nimport { listNamespaces } from \"./namespaces/migrate.js\";\nimport {\n createEvalBaselineSnapshot,\n getEvalHarnessStatus,\n runEvalBaselineDeltaReport,\n runEvalBenchmarkCiGate,\n validateEvalBenchmarkPack,\n type EvalBaselineDeltaReport,\n type EvalCiGateReport,\n type EvalHarnessStatus,\n} from \"./evals.js\";\nimport { analyzeGraphHealth, type GraphHealthReport } from \"./graph.js\";\nimport {\n analyzeSessionIntegrity,\n applySessionRepair,\n planSessionRepair,\n type SessionIntegrityReport,\n type SessionRepairApplyResult,\n type SessionRepairPlan,\n} from \"./session-integrity.js\";\nimport {\n listMemoryGovernanceRuns,\n readMemoryGovernanceRunArtifact,\n} from \"./maintenance/memory-governance.js\";\nimport type { FileHygieneConfig, MemoryFile, PluginConfig } from \"./types.js\";\n\ninterface QmdRuntimeLike {\n probe(): Promise<boolean>;\n isAvailable(): boolean;\n ensureCollection(memoryDir: string): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\">;\n debugStatus(): string;\n}\n\ninterface ConversationIndexLike {\n getConversationIndexHealth(): Promise<{\n enabled: boolean;\n backend: \"qmd\" | \"faiss\";\n status: \"ok\" | \"degraded\" | \"disabled\";\n chunkDocCount: number;\n lastUpdateAt: string | null;\n qmdAvailable?: boolean;\n faiss?: {\n ok: boolean;\n status: \"ok\" | \"degraded\" | \"error\";\n indexPath: string;\n message?: string;\n manifest?: {\n version: number;\n modelId: string;\n normalizedModelId: string;\n dimension: number;\n chunkCount: number;\n updatedAt: string;\n lastSuccessfulRebuildAt: string;\n };\n };\n }>;\n rebuildConversationIndex(\n sessionKey?: string,\n hours?: number,\n opts?: { embed?: boolean },\n ): Promise<{\n chunks: number;\n skipped: boolean;\n reason?: string;\n embedded?: boolean;\n rebuilt?: boolean;\n }>;\n}\n\nexport interface OperatorToolkitOrchestrator extends ConversationIndexLike {\n config: PluginConfig;\n qmd: QmdRuntimeLike;\n}\n\nexport interface OperatorConfigLoadResult {\n found: boolean;\n path: string;\n parsed: boolean;\n memoryDir?: string;\n workspaceDir?: string;\n error?: string;\n}\n\nexport interface OperatorSetupReport {\n schemaVersion: 1;\n generatedAt: string;\n config: OperatorConfigLoadResult;\n memoryDir: string;\n workspaceDir: string;\n directories: Array<{ path: string; exists: boolean; writable: boolean }>;\n qmd: {\n enabled: boolean;\n available: boolean;\n collectionState: \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n debugStatus: string;\n };\n nativeKnowledge: {\n enabled: boolean;\n includeFiles: string[];\n curatedIncludeSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n openclawWorkspaceAdapterEnabled: boolean;\n obsidianVaultAdapterEnabled: boolean;\n obsidianSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n };\n explicitCapture: {\n captureMode: string;\n enabled: boolean;\n memoryDocPath: string;\n memoryDocExists: boolean;\n memoryDocInstalled: boolean;\n memoryDocUpdated: boolean;\n memoryDocRemoved: boolean;\n preview: string | null;\n };\n nextSteps: string[];\n verificationCommands: string[];\n}\n\nexport interface OperatorDoctorCheck {\n key: string;\n status: \"ok\" | \"warn\" | \"error\";\n summary: string;\n remediation?: string;\n details?: unknown;\n}\n\nexport interface OperatorConfigReviewFinding {\n key: string;\n status: \"recommend\" | \"problem\";\n setting: string;\n currentValue: string;\n defaultValue: string;\n recommendedValue: string;\n summary: string;\n rationale: string;\n}\n\nexport interface OperatorConfigReviewReport {\n schemaVersion: 1;\n generatedAt: string;\n ok: boolean;\n config: OperatorConfigLoadResult;\n profile: {\n memoryOsPreset?: string;\n searchBackend: string;\n qmdEnabled: boolean;\n qmdDaemonEnabled: boolean;\n nativeKnowledgeEnabled: boolean;\n fileHygieneEnabled: boolean;\n conversationIndexEnabled: boolean;\n };\n summary: {\n recommend: number;\n problem: number;\n };\n findings: OperatorConfigReviewFinding[];\n}\n\nexport interface OperatorDoctorReport {\n schemaVersion: 1;\n generatedAt: string;\n ok: boolean;\n summary: {\n ok: number;\n warn: number;\n error: number;\n };\n config: OperatorConfigLoadResult;\n checks: OperatorDoctorCheck[];\n}\n\nexport interface OperatorInventoryNamespaceSummary {\n namespace: string;\n memoryCount: number;\n entityCount: number;\n}\n\nexport interface OperatorInventoryReport {\n schemaVersion: 1;\n generatedAt: string;\n memoryDir: string;\n totals: {\n memories: number;\n entities: number;\n namespaces: number;\n reviewQueue: number;\n storageBytes: number;\n };\n categories: Record<string, number>;\n statuses: Record<string, number>;\n namespaces: OperatorInventoryNamespaceSummary[];\n ageBands: Record<string, number>;\n profile: {\n exists: boolean;\n chars: number;\n lines: number;\n };\n storageFootprint: {\n bytes: number;\n byTopLevel: Record<string, number>;\n };\n archivePressure: {\n archived: number;\n pendingReview: number;\n quarantined: number;\n rejected: number;\n };\n conversationIndex: {\n enabled: boolean;\n backend: \"qmd\" | \"faiss\";\n status: \"ok\" | \"degraded\" | \"disabled\";\n chunkDocCount: number;\n lastUpdateAt: string | null;\n };\n nativeKnowledge: {\n enabled: boolean;\n curatedIncludeSync: {\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n obsidianSync: {\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n };\n}\n\nexport interface BenchmarkRecallReport {\n schemaVersion: 1;\n generatedAt: string;\n mode: \"status\" | \"validate\" | \"baseline-report\" | \"ci-gate\" | \"snapshot\";\n status: EvalHarnessStatus;\n validate?: Awaited<ReturnType<typeof validateEvalBenchmarkPack>>;\n baselineReport?: EvalBaselineDeltaReport;\n ciGate?: EvalCiGateReport;\n snapshot?: {\n targetPath: string;\n snapshotId: string;\n };\n}\n\nexport interface OperatorRepairReport {\n schemaVersion: 1;\n generatedAt: string;\n dryRun: boolean;\n sessionCheck: SessionIntegrityReport;\n sessionRepairPlan: SessionRepairPlan;\n sessionRepairApply: SessionRepairApplyResult;\n graphHealth: GraphHealthReport;\n}\n\nexport interface OperatorSetupOptions {\n orchestrator: OperatorToolkitOrchestrator;\n installCaptureInstructions?: boolean;\n captureInstructionsMode?: \"preview\" | \"install\" | \"remove\";\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorDoctorOptions {\n orchestrator: OperatorToolkitOrchestrator;\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorConfigReviewOptions {\n orchestrator: OperatorToolkitOrchestrator;\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorInventoryOptions {\n orchestrator: OperatorToolkitOrchestrator;\n now?: Date;\n}\n\nexport interface BenchmarkRecallOptions {\n config: Pick<\n PluginConfig,\n | \"memoryDir\"\n | \"evalStoreDir\"\n | \"evalHarnessEnabled\"\n | \"evalShadowModeEnabled\"\n | \"benchmarkBaselineSnapshotsEnabled\"\n | \"benchmarkDeltaReporterEnabled\"\n | \"memoryRedTeamBenchEnabled\"\n >;\n validatePath?: string;\n baseEvalStoreDir?: string;\n candidateEvalStoreDir?: string;\n snapshotId?: string;\n createSnapshot?: boolean;\n snapshotNotes?: string;\n gitRef?: string;\n createdAt?: string;\n now?: Date;\n}\n\nexport interface OperatorRepairOptions {\n config: Pick<\n PluginConfig,\n \"memoryDir\" | \"entityGraphEnabled\" | \"timeGraphEnabled\" | \"causalGraphEnabled\"\n >;\n apply?: boolean;\n dryRun?: boolean;\n allowSessionFileRepair?: boolean;\n sessionFilesDir?: string;\n now?: Date;\n}\n\nfunction resolveConfigPath(explicitPath?: string): string {\n if (explicitPath && explicitPath.trim().length > 0) return explicitPath.trim();\n const configured =\n readEnvVar(\"OPENCLAW_ENGRAM_CONFIG_PATH\") ||\n readEnvVar(\"OPENCLAW_CONFIG_PATH\");\n if (configured && configured.trim().length > 0) return configured.trim();\n return path.join(resolveHomeDir(), \".openclaw\", \"openclaw.json\");\n}\n\nasync function loadCliPluginConfig(configPath?: string): Promise<OperatorConfigLoadResult> {\n const resolvedPath = resolveConfigPath(configPath);\n try {\n const raw = JSON.parse(await readFile(resolvedPath, \"utf-8\")) as Record<string, unknown>;\n const pluginEntry = raw?.plugins && typeof raw.plugins === \"object\"\n ? (raw.plugins as Record<string, unknown>).entries\n : undefined;\n const config =\n pluginEntry && typeof pluginEntry === \"object\"\n ? (pluginEntry as Record<string, unknown>)[\"openclaw-engram\"]\n : undefined;\n const parsedConfig = parseConfig(\n config && typeof config === \"object\"\n ? ((config as Record<string, unknown>).config ?? {})\n : {},\n );\n return {\n found: true,\n path: resolvedPath,\n parsed: true,\n memoryDir: parsedConfig.memoryDir,\n workspaceDir: parsedConfig.workspaceDir,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n found: !/ENOENT/i.test(message),\n path: resolvedPath,\n parsed: false,\n error: message,\n };\n }\n}\n\nasync function isWritable(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatConfigValue(value: unknown): string {\n if (value === undefined || value === null) return \"(unset)\";\n if (typeof value === \"string\") return value.length > 0 ? value : \"(unset)\";\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n return JSON.stringify(value);\n}\n\nasync function gatherDirectoryStatus(\n paths: string[],\n): Promise<Array<{ path: string; exists: boolean; writable: boolean }>> {\n return Promise.all(paths.map(async (targetPath) => {\n try {\n await access(targetPath, fsConstants.F_OK);\n return {\n path: targetPath,\n exists: true,\n writable: await isWritable(targetPath),\n };\n } catch {\n return {\n path: targetPath,\n exists: false,\n writable: false,\n };\n }\n }));\n}\n\nfunction getSetupPaths(config: PluginConfig): string[] {\n return [\n config.memoryDir,\n config.workspaceDir,\n path.join(config.memoryDir, \"facts\"),\n path.join(config.memoryDir, \"entities\"),\n path.join(config.memoryDir, \"state\"),\n path.join(config.memoryDir, \"questions\"),\n path.join(config.memoryDir, \"artifacts\"),\n path.join(config.memoryDir, \"config\"),\n ];\n}\n\nasync function readJsonIfExists(filePath: string): Promise<unknown | null> {\n try {\n return JSON.parse(await readFile(filePath, \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n}\n\nasync function summarizeNativeKnowledgeStatus(config: PluginConfig): Promise<{\n enabled: boolean;\n includeFiles: string[];\n curatedIncludeSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n openclawWorkspaceAdapterEnabled: boolean;\n obsidianVaultAdapterEnabled: boolean;\n obsidianSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n}> {\n const nativeKnowledge = config.nativeKnowledge;\n const nativeKnowledgeStateDir = nativeKnowledge?.stateDir ?? \"state/native-knowledge\";\n const curatedStatePath = nativeKnowledge\n ? resolveCuratedIncludeFilesStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"curated-include-sync.json\");\n const obsidianStatePath = nativeKnowledge\n ? resolveNativeKnowledgeStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"obsidian-sync.json\");\n const openclawStatePath = nativeKnowledge\n ? resolveOpenClawWorkspaceStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"openclaw-workspace-sync.json\");\n const [curatedRaw, obsidianRaw, openclawRaw] = await Promise.all([\n readJsonIfExists(curatedStatePath),\n readJsonIfExists(obsidianStatePath),\n readJsonIfExists(openclawStatePath),\n ]);\n\n const curatedFiles = curatedRaw && typeof curatedRaw === \"object\" && curatedRaw !== null\n && \"files\" in curatedRaw && typeof (curatedRaw as { files?: unknown }).files === \"object\"\n && (curatedRaw as { files?: unknown }).files !== null\n ? (curatedRaw as {\n updatedAt?: unknown;\n files: Record<string, { deleted?: boolean; chunks?: unknown[] }>;\n })\n : null;\n\n let curatedActiveChunkCount = 0;\n let curatedDeletedFileCount = 0;\n for (const file of Object.values(curatedFiles?.files ?? {})) {\n if (file.deleted) {\n curatedDeletedFileCount += 1;\n continue;\n }\n curatedActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;\n }\n\n const obsidianVaults = obsidianRaw && typeof obsidianRaw === \"object\" && obsidianRaw !== null\n && \"vaults\" in obsidianRaw && typeof (obsidianRaw as { vaults?: unknown }).vaults === \"object\"\n && (obsidianRaw as { vaults?: unknown }).vaults !== null\n ? (obsidianRaw as {\n updatedAt?: unknown;\n vaults: Record<string, { notes?: Record<string, { deleted?: boolean; chunks?: unknown[] }> }>;\n })\n : null;\n\n let obsidianActiveChunkCount = 0;\n let obsidianDeletedNoteCount = 0;\n for (const vault of Object.values(obsidianVaults?.vaults ?? {})) {\n for (const note of Object.values(vault.notes ?? {})) {\n if (note.deleted) {\n obsidianDeletedNoteCount += 1;\n continue;\n }\n obsidianActiveChunkCount += Array.isArray(note.chunks) ? note.chunks.length : 0;\n }\n }\n\n const openclawFiles = openclawRaw && typeof openclawRaw === \"object\" && openclawRaw !== null\n && \"files\" in openclawRaw && typeof (openclawRaw as { files?: unknown }).files === \"object\"\n && (openclawRaw as { files?: unknown }).files !== null\n ? (openclawRaw as {\n updatedAt?: unknown;\n files: Record<string, { deleted?: boolean; chunks?: unknown[] }>;\n })\n : null;\n\n let openclawActiveChunkCount = 0;\n let openclawDeletedFileCount = 0;\n for (const file of Object.values(openclawFiles?.files ?? {})) {\n if (file.deleted) {\n openclawDeletedFileCount += 1;\n continue;\n }\n openclawActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;\n }\n\n return {\n enabled: nativeKnowledge?.enabled === true,\n includeFiles: nativeKnowledge?.includeFiles ?? [],\n curatedIncludeSync: {\n statePath: curatedStatePath,\n exists: curatedFiles !== null,\n updatedAt: typeof curatedFiles?.updatedAt === \"string\" ? curatedFiles.updatedAt : null,\n fileCount: Object.keys(curatedFiles?.files ?? {}).length,\n activeChunkCount: curatedActiveChunkCount,\n deletedFileCount: curatedDeletedFileCount,\n },\n openclawWorkspaceAdapterEnabled: nativeKnowledge?.openclawWorkspace?.enabled === true,\n obsidianVaultAdapterEnabled: (nativeKnowledge?.obsidianVaults?.length ?? 0) > 0,\n obsidianSync: {\n statePath: obsidianStatePath,\n exists: obsidianVaults !== null,\n updatedAt: typeof obsidianVaults?.updatedAt === \"string\" ? obsidianVaults.updatedAt : null,\n vaultCount: Object.keys(obsidianVaults?.vaults ?? {}).length,\n activeChunkCount: obsidianActiveChunkCount,\n deletedNoteCount: obsidianDeletedNoteCount,\n },\n openclawWorkspaceSync: {\n statePath: openclawStatePath,\n exists: openclawFiles !== null,\n updatedAt: typeof openclawFiles?.updatedAt === \"string\" ? openclawFiles.updatedAt : null,\n fileCount: Object.keys(openclawFiles?.files ?? {}).length,\n activeChunkCount: openclawActiveChunkCount,\n deletedFileCount: openclawDeletedFileCount,\n },\n };\n}\n\nconst CAPTURE_INSTRUCTIONS_START = \"<!-- BEGIN ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->\";\nconst CAPTURE_INSTRUCTIONS_END = \"<!-- END ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->\";\n\nfunction buildCaptureInstructions(): string {\n return [\n CAPTURE_INSTRUCTIONS_START,\n \"# Memory\",\n \"\",\n \"Use this file for explicit memory capture notes when Engram runs in explicit or hybrid mode.\",\n \"\",\n \"## Suggested format\",\n \"\",\n \"- Write durable facts, decisions, commitments, or corrections.\",\n \"- Keep entries concise and specific.\",\n \"- Avoid secrets, tokens, and private credentials.\",\n \"\",\n \"## Example\",\n \"\",\n \"- Decision: recall benchmark packs live under `state/evals/benchmarks/`.\",\n \"- Commitment: rerun `openclaw engram doctor --json` after changing retrieval settings.\",\n \"\",\n CAPTURE_INSTRUCTIONS_END,\n ].join(\"\\n\");\n}\n\nfunction upsertManagedCaptureInstructions(existing: string | null, snippet: string): { content: string; updated: boolean; installed: boolean } {\n if (!existing || existing.trim().length === 0) {\n return { content: `${snippet}\\n`, updated: false, installed: true };\n }\n if (existing.includes(CAPTURE_INSTRUCTIONS_START) && existing.includes(CAPTURE_INSTRUCTIONS_END)) {\n const next = existing.replace(\n new RegExp(`${CAPTURE_INSTRUCTIONS_START}[\\\\s\\\\S]*?${CAPTURE_INSTRUCTIONS_END}`),\n snippet,\n );\n return { content: next.endsWith(\"\\n\") ? next : `${next}\\n`, updated: next !== existing, installed: false };\n }\n const trimmed = existing.trimEnd();\n return {\n content: `${trimmed}\\n\\n${snippet}\\n`,\n updated: false,\n installed: true,\n };\n}\n\nfunction removeManagedCaptureInstructions(existing: string): { content: string; removed: boolean } {\n if (!existing.includes(CAPTURE_INSTRUCTIONS_START) || !existing.includes(CAPTURE_INSTRUCTIONS_END)) {\n return { content: existing, removed: false };\n }\n const stripped = existing\n .replace(new RegExp(`\\\\n*${CAPTURE_INSTRUCTIONS_START}[\\\\s\\\\S]*?${CAPTURE_INSTRUCTIONS_END}\\\\n*`), \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n return {\n content: stripped.length > 0 ? `${stripped}\\n` : \"\",\n removed: true,\n };\n}\n\nexport async function runOperatorSetup(options: OperatorSetupOptions): Promise<OperatorSetupReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n const storage = new StorageManager(options.orchestrator.config.memoryDir);\n await storage.ensureDirectories();\n await mkdir(options.orchestrator.config.workspaceDir, { recursive: true });\n\n const qmdAvailable = await options.orchestrator.qmd.probe();\n const collectionState = options.orchestrator.config.qmdEnabled\n ? await options.orchestrator.qmd.ensureCollection(options.orchestrator.config.memoryDir)\n : \"skipped\";\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(options.orchestrator.config);\n\n const memoryDocPath = path.join(options.orchestrator.config.workspaceDir, \"MEMORY.md\");\n const captureInstructionsMode =\n options.captureInstructionsMode\n ?? (options.installCaptureInstructions ? \"install\" : undefined);\n let memoryDocExists = false;\n try {\n await access(memoryDocPath, fsConstants.F_OK);\n memoryDocExists = true;\n } catch {\n memoryDocExists = false;\n }\n let memoryDocInstalled = false;\n let memoryDocUpdated = false;\n let memoryDocRemoved = false;\n const explicitCaptureEnabled = options.orchestrator.config.captureMode === \"explicit\"\n || options.orchestrator.config.captureMode === \"hybrid\";\n const captureInstructionsPreview = captureInstructionsMode ? buildCaptureInstructions() : null;\n if (captureInstructionsMode) {\n if (captureInstructionsMode === \"preview\") {\n // no-op, preview only\n } else if (captureInstructionsMode === \"install\") {\n const existing = memoryDocExists ? await readFile(memoryDocPath, \"utf-8\") : null;\n const next = upsertManagedCaptureInstructions(existing, captureInstructionsPreview ?? \"\");\n if (!existing || next.content !== existing) {\n await writeFile(memoryDocPath, next.content, \"utf-8\");\n }\n memoryDocExists = true;\n memoryDocInstalled = next.installed;\n memoryDocUpdated = next.updated;\n } else if (captureInstructionsMode === \"remove\" && memoryDocExists) {\n const existing = await readFile(memoryDocPath, \"utf-8\");\n const next = removeManagedCaptureInstructions(existing);\n if (next.removed) {\n if (next.content.length === 0) {\n await unlink(memoryDocPath);\n memoryDocExists = false;\n } else {\n await writeFile(memoryDocPath, next.content, \"utf-8\");\n memoryDocExists = true;\n }\n memoryDocRemoved = true;\n }\n }\n }\n\n const directories = await gatherDirectoryStatus(getSetupPaths(options.orchestrator.config));\n const nextSteps = [\n `Run \\`openclaw engram doctor${options.installCaptureInstructions ? \"\" : \" --json\"}\\` to verify runtime health.`,\n \"Run `openclaw engram inventory --json` to capture a baseline footprint.\",\n \"If QMD is enabled and the collection is missing, add the collection to `~/.config/qmd/index.yml` and run `qmd update && qmd embed`.\",\n ];\n if (explicitCaptureEnabled && !memoryDocExists) {\n nextSteps.push(\"Run `openclaw engram setup --preview-capture-instructions` to review the managed explicit-capture snippet, then `--install-capture-instructions` to write it.\");\n }\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n config: configStatus,\n memoryDir: options.orchestrator.config.memoryDir,\n workspaceDir: options.orchestrator.config.workspaceDir,\n directories,\n qmd: {\n enabled: options.orchestrator.config.qmdEnabled,\n available: qmdAvailable,\n collectionState,\n debugStatus: options.orchestrator.qmd.debugStatus(),\n },\n nativeKnowledge: nativeKnowledgeStatus,\n explicitCapture: {\n captureMode: options.orchestrator.config.captureMode,\n enabled: explicitCaptureEnabled,\n memoryDocPath,\n memoryDocExists,\n memoryDocInstalled,\n memoryDocUpdated,\n memoryDocRemoved,\n preview: captureInstructionsMode === \"preview\" ? captureInstructionsPreview : null,\n },\n nextSteps,\n verificationCommands: [\n \"openclaw engram doctor --json\",\n \"openclaw engram inventory --json\",\n \"openclaw engram benchmark recall --json\",\n ],\n };\n}\n\nfunction summarizeHygieneWarnings(\n warnings: Awaited<ReturnType<typeof lintWorkspaceFiles>>,\n hygiene: FileHygieneConfig | undefined,\n): OperatorDoctorCheck {\n if (!hygiene?.enabled || hygiene.lintEnabled !== true) {\n return {\n key: \"file_hygiene\",\n status: \"warn\",\n summary: \"File hygiene linting is disabled; bootstrap file truncation warnings are not active.\",\n remediation: \"Enable `fileHygiene.enabled` and `fileHygiene.lintEnabled` if large workspace bootstrap files are common.\",\n details: {\n enabled: hygiene?.enabled === true,\n lintEnabled: hygiene?.lintEnabled === true,\n },\n };\n }\n if (warnings.length > 0) {\n return {\n key: \"file_hygiene\",\n status: \"warn\",\n summary: `${warnings.length} bootstrap file(s) are near or above the configured budget.`,\n remediation: \"Archive/split the listed files or adjust `fileHygiene` budgets.\",\n details: { warnings },\n };\n }\n return {\n key: \"file_hygiene\",\n status: \"ok\",\n summary: \"Bootstrap file hygiene is within budget.\",\n details: {\n enabled: true,\n lintPaths: hygiene.lintPaths,\n budgetBytes: hygiene.lintBudgetBytes,\n },\n };\n}\n\nfunction buildConfigReviewFinding(input: {\n key: string;\n status: \"recommend\" | \"problem\";\n setting: string;\n currentValue: unknown;\n defaultValue: unknown;\n recommendedValue: unknown;\n summary: string;\n rationale: string;\n}): OperatorConfigReviewFinding {\n return {\n key: input.key,\n status: input.status,\n setting: input.setting,\n currentValue: formatConfigValue(input.currentValue),\n defaultValue: formatConfigValue(input.defaultValue),\n recommendedValue: formatConfigValue(input.recommendedValue),\n summary: input.summary,\n rationale: input.rationale,\n };\n}\n\nexport async function runOperatorConfigReview(\n options: OperatorConfigReviewOptions,\n): Promise<OperatorConfigReviewReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n return buildOperatorConfigReviewReport({\n now,\n configStatus,\n config: options.orchestrator.config,\n });\n}\n\nasync function buildOperatorConfigReviewReport(input: {\n now: Date;\n configStatus: OperatorConfigLoadResult;\n config: PluginConfig;\n}): Promise<OperatorConfigReviewReport> {\n const { now, configStatus, config } = input;\n const findings: OperatorConfigReviewFinding[] = [];\n const searchBackend = config.searchBackend ?? \"qmd\";\n const workspaceBootstrapFiles = [\n path.join(config.workspaceDir, \"IDENTITY.md\"),\n path.join(config.workspaceDir, \"MEMORY.md\"),\n path.join(config.workspaceDir, \"USER.md\"),\n ];\n const workspaceBootstrapExists = (await Promise.all(workspaceBootstrapFiles.map(pathExists))).some(Boolean);\n\n if (\n config.memoryOsPreset !== \"conservative\" &&\n config.memoryOsPreset !== \"balanced\" &&\n config.memoryOsPreset !== \"research-max\" &&\n config.memoryOsPreset !== \"local-llm-heavy\" &&\n config.queryAwareIndexingEnabled === false &&\n config.verbatimArtifactsEnabled === false &&\n config.rerankEnabled === false\n ) {\n findings.push(buildConfigReviewFinding({\n key: \"balanced_preset\",\n status: \"recommend\",\n setting: \"memoryOsPreset\",\n currentValue: config.memoryOsPreset,\n defaultValue: \"(unset)\",\n recommendedValue: \"balanced\",\n summary: \"Adopt the balanced preset as the baseline configuration profile.\",\n rationale:\n \"The balanced preset enables the recommended indexing, reranking, and artifact defaults without turning on the higher-churn graph and learning loops.\",\n }));\n }\n\n if (config.qmdEnabled && config.qmdDaemonEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_daemon\",\n status: \"recommend\",\n setting: \"qmdDaemonEnabled\",\n currentValue: config.qmdDaemonEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"Enable the QMD daemon path when QMD powers recall.\",\n rationale:\n \"The daemon path reduces recall/search contention by preferring the MCP transport instead of repeated subprocess calls when QMD is available.\",\n }));\n }\n\n if (workspaceBootstrapExists && config.nativeKnowledge?.enabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"native_knowledge_enabled\",\n status: \"recommend\",\n setting: \"nativeKnowledge.enabled\",\n currentValue: config.nativeKnowledge?.enabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Enable native knowledge recall for workspace bootstrap documents.\",\n rationale:\n \"When files like IDENTITY.md or MEMORY.md already exist, native knowledge recall can chunk and inject them directly instead of relying only on extracted memories.\",\n }));\n }\n\n if (workspaceBootstrapExists && config.fileHygiene?.enabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"file_hygiene_enabled\",\n status: \"recommend\",\n setting: \"fileHygiene.enabled\",\n currentValue: config.fileHygiene?.enabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Enable file hygiene to avoid silent workspace-file truncation.\",\n rationale:\n \"OpenClaw bootstrap files can grow quietly; file hygiene warns before oversized files are truncated during prompt bootstrap.\",\n }));\n }\n\n if (searchBackend === \"qmd\" && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_search_backend_disabled\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"QMD search is selected but QMD is disabled.\",\n rationale:\n \"When searchBackend resolves to qmd while qmdEnabled is false, Engram falls back to the noop backend and disables the primary search path.\",\n }));\n }\n\n if (config.qmdColdTierEnabled === true && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_cold_tier_requires_qmd\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"Cold-tier QMD recall is enabled while QMD itself is disabled.\",\n rationale:\n \"The cold tier depends on the same QMD runtime as the hot tier, so turning QMD off leaves the extra tiering path unusable.\",\n }));\n }\n\n if (config.qmdTierMigrationEnabled && config.qmdColdTierEnabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_tier_migration_requires_cold_tier\",\n status: \"problem\",\n setting: \"qmdColdTierEnabled\",\n currentValue: config.qmdColdTierEnabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Hot/cold tier migration is enabled without the cold tier itself.\",\n rationale:\n \"Tier migration depends on the cold-tier collection and recall path, so enabling migration while the cold tier is off leaves the feature in a contradictory state.\",\n }));\n }\n\n if (config.conversationIndexEnabled && config.conversationIndexBackend === \"qmd\" && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"conversation_index_qmd_requires_qmd\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"The conversation index is configured for QMD while QMD is disabled.\",\n rationale:\n \"A QMD-backed conversation index cannot rebuild or serve queries when the underlying QMD runtime is disabled.\",\n }));\n }\n\n const summary = findings.reduce(\n (acc, finding) => {\n acc[finding.status] += 1;\n return acc;\n },\n { recommend: 0, problem: 0 },\n );\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n ok: configStatus.parsed && summary.problem === 0,\n config: configStatus,\n profile: {\n memoryOsPreset: config.memoryOsPreset,\n searchBackend,\n qmdEnabled: config.qmdEnabled,\n qmdDaemonEnabled: config.qmdDaemonEnabled,\n nativeKnowledgeEnabled: config.nativeKnowledge?.enabled === true,\n fileHygieneEnabled: config.fileHygiene?.enabled === true,\n conversationIndexEnabled: config.conversationIndexEnabled,\n },\n summary,\n findings,\n };\n}\n\nexport async function runOperatorDoctor(options: OperatorDoctorOptions): Promise<OperatorDoctorReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n const checks: OperatorDoctorCheck[] = [];\n const config = options.orchestrator.config;\n const configReview = await buildOperatorConfigReviewReport({\n now,\n configStatus,\n config,\n });\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);\n const setupPaths = await gatherDirectoryStatus(getSetupPaths(config));\n const missingPaths = setupPaths.filter((entry) => !entry.exists).map((entry) => entry.path);\n\n checks.push({\n key: \"config\",\n status: configStatus.parsed\n ? \"ok\"\n : options.configPath\n ? \"error\"\n : \"warn\",\n summary: configStatus.parsed ? \"OpenClaw config loaded and Engram config parsed successfully.\" : \"Config file could not be parsed.\",\n remediation: configStatus.parsed ? undefined : \"Fix the config file or set OPENCLAW_ENGRAM_CONFIG_PATH/OPENCLAW_CONFIG_PATH.\",\n details: configStatus,\n });\n\n checks.push({\n key: \"memory_dir\",\n status: missingPaths.length === 0 ? \"ok\" : \"warn\",\n summary: missingPaths.length === 0\n ? \"Expected Engram directories exist.\"\n : `${missingPaths.length} expected directory path(s) are missing.`,\n remediation: missingPaths.length === 0 ? undefined : \"Run `openclaw engram setup` to create missing directories.\",\n details: { directories: setupPaths },\n });\n\n checks.push({\n key: \"config_review\",\n status: configReview.summary.problem > 0 ? \"error\" : configReview.summary.recommend > 0 ? \"warn\" : \"ok\",\n summary: configReview.summary.problem > 0\n ? `${configReview.summary.problem} configuration problem(s) detected.`\n : configReview.summary.recommend > 0\n ? `No configuration problems detected; ${configReview.summary.recommend} optional recommendation(s) are available.`\n : \"No configuration problems detected.\",\n remediation: configReview.summary.problem > 0 || configReview.summary.recommend > 0\n ? \"Run `openclaw engram config-review` to inspect and fix the flagged configuration combinations.\"\n : undefined,\n details: configReview,\n });\n\n const qmdAvailable = await options.orchestrator.qmd.probe();\n const collectionState = config.qmdEnabled\n ? await options.orchestrator.qmd.ensureCollection(config.memoryDir)\n : \"skipped\";\n checks.push({\n key: \"qmd\",\n status: !config.qmdEnabled\n ? \"warn\"\n : !qmdAvailable\n ? \"error\"\n : collectionState === \"present\"\n ? \"ok\"\n : collectionState === \"missing\"\n ? \"error\"\n : \"warn\",\n summary: !config.qmdEnabled\n ? \"QMD is disabled in config.\"\n : qmdAvailable\n ? `QMD is reachable (${collectionState}).`\n : \"QMD is not currently reachable.\",\n remediation: !config.qmdEnabled\n ? \"Enable `qmdEnabled` if you expect hybrid search.\"\n : !qmdAvailable\n ? \"Ensure the `qmd` binary is installed and on PATH, or set `qmdPath`.\"\n : collectionState === \"missing\"\n ? \"Add the configured collection to `~/.config/qmd/index.yml`.\"\n : collectionState === \"present\"\n ? undefined\n : \"Re-run `openclaw engram setup` after restoring QMD access.\",\n details: {\n available: qmdAvailable,\n collectionState,\n debugStatus: options.orchestrator.qmd.debugStatus(),\n },\n });\n\n const conversationIndex = await options.orchestrator.getConversationIndexHealth();\n checks.push({\n key: \"conversation_index\",\n status: conversationIndex.status === \"ok\"\n ? \"ok\"\n : conversationIndex.enabled\n ? \"error\"\n : \"warn\",\n summary: conversationIndex.enabled\n ? `Conversation index backend is ${conversationIndex.status}.`\n : \"Conversation index is disabled.\",\n remediation: conversationIndex.enabled && conversationIndex.status !== \"ok\"\n ? \"Run `openclaw engram rebuild-index` to refresh the conversation index artifacts.\"\n : undefined,\n details: conversationIndex,\n });\n\n const meta = await new StorageManager(config.memoryDir).loadMeta();\n checks.push({\n key: \"maintenance\",\n status: meta.lastExtractionAt || meta.lastConsolidationAt ? \"ok\" : \"warn\",\n summary: meta.lastExtractionAt || meta.lastConsolidationAt\n ? \"Extraction/consolidation metadata is present.\"\n : \"No extraction or consolidation metadata found yet.\",\n remediation: meta.lastExtractionAt || meta.lastConsolidationAt\n ? undefined\n : \"Run a normal agent turn or `openclaw engram consolidate` after seeding memory.\",\n details: meta,\n });\n\n const syncedChunkCount =\n nativeKnowledgeStatus.curatedIncludeSync.activeChunkCount +\n nativeKnowledgeStatus.obsidianSync.activeChunkCount +\n nativeKnowledgeStatus.openclawWorkspaceSync.activeChunkCount;\n const hasSyncState =\n nativeKnowledgeStatus.curatedIncludeSync.exists ||\n nativeKnowledgeStatus.obsidianSync.exists ||\n nativeKnowledgeStatus.openclawWorkspaceSync.exists;\n checks.push({\n key: \"native_knowledge\",\n status: !nativeKnowledgeStatus.enabled\n ? \"warn\"\n : hasSyncState\n ? \"ok\"\n : \"warn\",\n summary: !nativeKnowledgeStatus.enabled\n ? \"Native knowledge sync is disabled.\"\n : hasSyncState\n ? `Native knowledge sync state is present (${syncedChunkCount} active chunks).`\n : \"Native knowledge sync is enabled but no sync state has been written yet.\",\n remediation: !nativeKnowledgeStatus.enabled\n ? \"Enable `nativeKnowledge.enabled` if curated workspace recall should participate in retrieval.\"\n : hasSyncState\n ? undefined\n : \"Run a recall, sync, or setup flow that touches native knowledge sources, then rerun `openclaw engram doctor --json`.\",\n details: nativeKnowledgeStatus,\n });\n\n const agentAccessEnabled = config.agentAccessHttp?.enabled === true;\n checks.push({\n key: \"access_http_auth\",\n status: !agentAccessEnabled\n ? \"warn\"\n : config.agentAccessHttp?.authToken\n ? \"ok\"\n : \"error\",\n summary: !agentAccessEnabled\n ? \"Agent access HTTP bridge is disabled.\"\n : config.agentAccessHttp?.authToken\n ? \"Agent access HTTP bridge has an auth token configured.\"\n : \"Agent access HTTP bridge is enabled without an auth token.\",\n remediation: !agentAccessEnabled\n ? \"Ignore unless you plan to enable the HTTP bridge.\"\n : config.agentAccessHttp?.authToken\n ? undefined\n : \"Set `agentAccessHttp.authToken` before exposing the bridge.\",\n });\n\n const warnings = config.fileHygiene?.lintEnabled\n ? await lintWorkspaceFiles({\n workspaceDir: config.workspaceDir,\n paths: config.fileHygiene.lintPaths,\n budgetBytes: config.fileHygiene.lintBudgetBytes,\n warnRatio: config.fileHygiene.lintWarnRatio,\n })\n : [];\n checks.push(summarizeHygieneWarnings(warnings, config.fileHygiene));\n\n const summary = checks.reduce(\n (acc, check) => {\n acc[check.status] += 1;\n return acc;\n },\n { ok: 0, warn: 0, error: 0 },\n );\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n ok: summary.error === 0,\n summary,\n config: configStatus,\n checks,\n };\n}\n\nfunction getMemoryAgeBand(memory: MemoryFile, now: Date): string {\n const created = Date.parse(memory.frontmatter.created ?? \"\");\n if (!Number.isFinite(created)) return \"unknown\";\n const ageDays = Math.max(0, Math.floor((now.getTime() - created) / 86_400_000));\n if (ageDays < 7) return \"0_6d\";\n if (ageDays < 30) return \"7_29d\";\n if (ageDays < 90) return \"30_89d\";\n return \"90d_plus\";\n}\n\nasync function dirSize(targetPath: string): Promise<number> {\n try {\n const info = await stat(targetPath);\n if (info.isFile()) return info.size;\n if (!info.isDirectory()) return 0;\n } catch {\n return 0;\n }\n\n let total = 0;\n let entries;\n try {\n entries = await readdir(targetPath, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const entry of entries) {\n total += await dirSize(path.join(targetPath, entry.name));\n }\n return total;\n}\n\nasync function summarizeStorageFootprint(memoryDir: string): Promise<{ bytes: number; byTopLevel: Record<string, number> }> {\n const topLevel = [\n \"facts\",\n \"entities\",\n \"questions\",\n \"corrections\",\n \"artifacts\",\n \"state\",\n \"identity\",\n \"namespaces\",\n \"summaries\",\n \"profile.md\",\n ];\n const byTopLevel: Record<string, number> = {};\n let bytes = 0;\n for (const name of topLevel) {\n const size = await dirSize(path.join(memoryDir, name));\n if (size > 0) {\n byTopLevel[name] = size;\n bytes += size;\n }\n }\n return { bytes, byTopLevel };\n}\n\nexport async function runOperatorInventory(options: OperatorInventoryOptions): Promise<OperatorInventoryReport> {\n const now = options.now ?? new Date();\n const config = options.orchestrator.config;\n const namespaceEntries = await listNamespaces({ config });\n const uniqueRootEntries = new Map<string, { namespace: string; rootDir: string }>();\n for (const entry of namespaceEntries) {\n if (!uniqueRootEntries.has(entry.rootDir)) {\n uniqueRootEntries.set(entry.rootDir, { namespace: entry.namespace, rootDir: entry.rootDir });\n }\n }\n const categories: Record<string, number> = {};\n const statuses: Record<string, number> = {};\n const ageBands: Record<string, number> = {\n \"0_6d\": 0,\n \"7_29d\": 0,\n \"30_89d\": 0,\n \"90d_plus\": 0,\n unknown: 0,\n };\n const namespaces: OperatorInventoryNamespaceSummary[] = [];\n let totalMemories = 0;\n let totalEntities = 0;\n let archived = 0;\n let pendingReview = 0;\n let quarantined = 0;\n let rejected = 0;\n\n for (const entry of uniqueRootEntries.values()) {\n const storage = new StorageManager(entry.rootDir);\n const memories = await storage.readAllMemories();\n const entities = await storage.readAllEntityFiles();\n namespaces.push({\n namespace: entry.namespace,\n memoryCount: memories.length,\n entityCount: entities.length,\n });\n totalMemories += memories.length;\n totalEntities += entities.length;\n for (const memory of memories) {\n const category = memory.frontmatter.category;\n categories[category] = (categories[category] ?? 0) + 1;\n const status = memory.frontmatter.status ?? \"active\";\n statuses[status] = (statuses[status] ?? 0) + 1;\n ageBands[getMemoryAgeBand(memory, now)] += 1;\n if (status === \"archived\") archived += 1;\n if (status === \"pending_review\") pendingReview += 1;\n if (status === \"quarantined\") quarantined += 1;\n if (status === \"rejected\") rejected += 1;\n }\n }\n\n const defaultStorage = new StorageManager(config.memoryDir);\n const profile = await defaultStorage.readProfile();\n const footprint = await summarizeStorageFootprint(config.memoryDir);\n const reviewRunId = (await listMemoryGovernanceRuns(config.memoryDir))[0];\n let reviewQueue = 0;\n if (reviewRunId) {\n try {\n reviewQueue = (await readMemoryGovernanceRunArtifact(config.memoryDir, reviewRunId)).reviewQueue.length;\n } catch {\n reviewQueue = 0;\n }\n }\n const conversationIndex = await options.orchestrator.getConversationIndexHealth();\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n memoryDir: config.memoryDir,\n totals: {\n memories: totalMemories,\n entities: totalEntities,\n namespaces: namespaceEntries.length,\n reviewQueue,\n storageBytes: footprint.bytes,\n },\n categories,\n statuses,\n namespaces,\n ageBands,\n profile: {\n exists: profile.length > 0,\n chars: profile.length,\n lines: profile.length > 0 ? profile.split(\"\\n\").length : 0,\n },\n storageFootprint: footprint,\n archivePressure: {\n archived,\n pendingReview,\n quarantined,\n rejected,\n },\n conversationIndex: {\n enabled: conversationIndex.enabled,\n backend: conversationIndex.backend,\n status: conversationIndex.status,\n chunkDocCount: conversationIndex.chunkDocCount,\n lastUpdateAt: conversationIndex.lastUpdateAt,\n },\n nativeKnowledge: {\n enabled: nativeKnowledgeStatus.enabled,\n curatedIncludeSync: nativeKnowledgeStatus.curatedIncludeSync,\n obsidianSync: nativeKnowledgeStatus.obsidianSync,\n openclawWorkspaceSync: nativeKnowledgeStatus.openclawWorkspaceSync,\n },\n };\n}\n\nexport async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promise<BenchmarkRecallReport> {\n const now = options.now ?? new Date();\n const status = await getEvalHarnessStatus({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n enabled: options.config.evalHarnessEnabled,\n shadowModeEnabled: options.config.evalShadowModeEnabled,\n baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,\n memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,\n });\n\n if (options.createSnapshot && options.snapshotId) {\n const snapshot = await createEvalBaselineSnapshot({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,\n snapshotId: options.snapshotId,\n notes: options.snapshotNotes,\n gitRef: options.gitRef,\n createdAt: options.createdAt,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"snapshot\",\n status,\n snapshot: {\n targetPath: snapshot.targetPath,\n snapshotId: snapshot.snapshot.snapshotId,\n },\n };\n }\n\n if (options.baseEvalStoreDir && options.candidateEvalStoreDir) {\n const ciGate = await runEvalBenchmarkCiGate({\n baseEvalStoreDir: options.baseEvalStoreDir,\n candidateEvalStoreDir: options.candidateEvalStoreDir,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"ci-gate\",\n status,\n ciGate,\n };\n }\n\n if (options.snapshotId) {\n const baselineReport = await runEvalBaselineDeltaReport({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n benchmarkDeltaReporterEnabled: options.config.benchmarkDeltaReporterEnabled,\n snapshotId: options.snapshotId,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"baseline-report\",\n status,\n baselineReport,\n };\n }\n\n if (options.validatePath) {\n const validate = await validateEvalBenchmarkPack(options.validatePath, {\n memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"validate\",\n status,\n validate,\n };\n }\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"status\",\n status,\n };\n}\n\nexport async function runOperatorRepair(options: OperatorRepairOptions): Promise<OperatorRepairReport> {\n const now = options.now ?? new Date();\n const dryRun = options.dryRun === true || options.apply !== true;\n const sessionCheck = await analyzeSessionIntegrity({ memoryDir: options.config.memoryDir });\n const sessionRepairPlan = planSessionRepair({\n report: sessionCheck,\n dryRun,\n allowSessionFileRepair: options.allowSessionFileRepair,\n sessionFilesDir: options.sessionFilesDir,\n });\n const sessionRepairApply = await applySessionRepair({\n plan: sessionRepairPlan,\n });\n const graphHealth = await analyzeGraphHealth(options.config.memoryDir, {\n entityGraphEnabled: options.config.entityGraphEnabled,\n timeGraphEnabled: options.config.timeGraphEnabled,\n causalGraphEnabled: options.config.causalGraphEnabled,\n includeRepairGuidance: true,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n dryRun,\n sessionCheck,\n sessionRepairPlan,\n sessionRepairApply,\n graphHealth,\n };\n}\n","import path from \"node:path\";\nimport { access, mkdir, readdir, rename } from \"node:fs/promises\";\nimport type { PluginConfig } from \"../types.js\";\nimport { NamespaceStorageRouter } from \"./storage.js\";\nimport { namespaceCollectionName } from \"./search.js\";\nimport { isSafeRouteNamespace } from \"../routing/engine.js\";\n\nconst LEGACY_NAMESPACE_CHILDREN = [\n \"facts\",\n \"corrections\",\n \"entities\",\n \"questions\",\n \"artifacts\",\n \"identity\",\n \"state\",\n \"config\",\n \"summaries\",\n \"profile.md\",\n] as const;\n\nexport interface NamespaceInventoryEntry {\n namespace: string;\n rootDir: string;\n exists: boolean;\n usesLegacyRoot: boolean;\n hasMemoryData: boolean;\n collection: string;\n}\n\nexport interface NamespaceVerifyReport {\n ok: boolean;\n problems: string[];\n namespaces: NamespaceInventoryEntry[];\n}\n\nexport interface NamespaceMigrationMove {\n from: string;\n to: string;\n}\n\nexport interface NamespaceMigrationReport {\n dryRun: boolean;\n fromRoot: string;\n targetRoot: string;\n moved: NamespaceMigrationMove[];\n collection: string;\n}\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function hasAnyLegacyData(rootDir: string): Promise<boolean> {\n for (const child of LEGACY_NAMESPACE_CHILDREN) {\n if (await exists(path.join(rootDir, child))) return true;\n }\n return false;\n}\n\nasync function discoverConfiguredNamespaces(\n config: PluginConfig,\n): Promise<string[]> {\n const discovered = new Set<string>([\n config.defaultNamespace,\n config.sharedNamespace,\n ...config.namespacePolicies.map((policy) => policy.name),\n ]);\n\n const namespacesDir = path.join(config.memoryDir, \"namespaces\");\n try {\n const entries = await readdir(namespacesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && isSafeRouteNamespace(entry.name)) {\n discovered.add(entry.name);\n }\n }\n } catch {\n // No namespace directory yet.\n }\n\n return [...discovered];\n}\n\nexport async function listNamespaces(options: {\n config: PluginConfig;\n storageRouter?: NamespaceStorageRouter;\n}): Promise<NamespaceInventoryEntry[]> {\n const storageRouter = options.storageRouter ?? new NamespaceStorageRouter(options.config);\n const namespaces = await discoverConfiguredNamespaces(options.config);\n const items = await Promise.all(\n namespaces.map(async (namespace) => {\n const storage = await storageRouter.storageFor(namespace);\n const usesLegacyRoot =\n namespace === options.config.defaultNamespace &&\n storage.dir === options.config.memoryDir;\n return {\n namespace,\n rootDir: storage.dir,\n exists: await exists(storage.dir),\n usesLegacyRoot,\n hasMemoryData: await hasAnyLegacyData(storage.dir),\n collection: namespaceCollectionName(options.config.qmdCollection, namespace, {\n defaultNamespace: options.config.defaultNamespace,\n useLegacyDefaultCollection: usesLegacyRoot,\n }),\n } satisfies NamespaceInventoryEntry;\n }),\n );\n\n return items.sort((a, b) => a.namespace.localeCompare(b.namespace));\n}\n\nexport async function verifyNamespaces(options: {\n config: PluginConfig;\n storageRouter?: NamespaceStorageRouter;\n}): Promise<NamespaceVerifyReport> {\n const namespaces = await listNamespaces(options);\n const problems: string[] = [];\n\n for (const entry of namespaces) {\n if (entry.exists && !entry.hasMemoryData) {\n problems.push(`${entry.namespace}: root exists but contains no Engram data`);\n }\n }\n\n return {\n ok: problems.length === 0,\n problems,\n namespaces,\n };\n}\n\nexport async function runNamespaceMigration(options: {\n config: PluginConfig;\n to: string;\n dryRun?: boolean;\n}): Promise<NamespaceMigrationReport> {\n if (!options.config.namespacesEnabled) {\n throw new Error(\"Namespaces are disabled.\");\n }\n\n const targetNamespace = options.to.trim();\n if (!isSafeRouteNamespace(targetNamespace)) {\n throw new Error(`Invalid namespace: ${options.to}`);\n }\n\n const targetRoot = path.join(options.config.memoryDir, \"namespaces\", targetNamespace);\n const moved: NamespaceMigrationMove[] = [];\n\n for (const child of LEGACY_NAMESPACE_CHILDREN) {\n const from = path.join(options.config.memoryDir, child);\n if (!(await exists(from))) continue;\n const to = path.join(targetRoot, child);\n if (await exists(to)) {\n throw new Error(`Target already contains ${child}: ${to}`);\n }\n moved.push({ from, to });\n }\n\n if (!options.dryRun && moved.length > 0) {\n await mkdir(targetRoot, { recursive: true });\n for (const move of moved) {\n await rename(move.from, move.to);\n }\n }\n\n return {\n dryRun: options.dryRun === true,\n fromRoot: options.config.memoryDir,\n targetRoot,\n moved,\n collection: namespaceCollectionName(options.config.qmdCollection, targetNamespace, {\n defaultNamespace: options.config.defaultNamespace,\n useLegacyDefaultCollection: false,\n }),\n };\n}\n"],"mappings":"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","names":["path","access","mkdir","readdir","path","access","mkdir","readdir"]}
|
package/dist/chunk-QPKFPHOO.js
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
log
|
|
3
|
-
} from "./chunk-KWBU5S5U.js";
|
|
4
|
-
|
|
5
|
-
// src/embedding-fallback.ts
|
|
6
|
-
import path from "path";
|
|
7
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
8
|
-
var DEFAULT_OPENAI_MODEL = "text-embedding-3-small";
|
|
9
|
-
var EmbeddingFallback = class {
|
|
10
|
-
constructor(config) {
|
|
11
|
-
this.config = config;
|
|
12
|
-
this.indexPath = path.join(config.memoryDir, "state", "embeddings.json");
|
|
13
|
-
}
|
|
14
|
-
config;
|
|
15
|
-
indexPath;
|
|
16
|
-
loaded = null;
|
|
17
|
-
async isAvailable() {
|
|
18
|
-
return await this.resolveProvider() !== null;
|
|
19
|
-
}
|
|
20
|
-
async search(query, limit) {
|
|
21
|
-
const provider = await this.resolveProvider();
|
|
22
|
-
if (!provider) return [];
|
|
23
|
-
const index = await this.loadIndex(provider);
|
|
24
|
-
const ids = Object.keys(index.entries);
|
|
25
|
-
if (ids.length === 0) return [];
|
|
26
|
-
const queryVector = await this.embed(query, provider);
|
|
27
|
-
if (!queryVector) return [];
|
|
28
|
-
const scored = ids.map((id) => {
|
|
29
|
-
const entry = index.entries[id];
|
|
30
|
-
return {
|
|
31
|
-
id,
|
|
32
|
-
path: entry.path,
|
|
33
|
-
score: cosineSimilarity(queryVector, entry.vector)
|
|
34
|
-
};
|
|
35
|
-
}).filter((r) => Number.isFinite(r.score)).sort((a, b) => b.score - a.score).slice(0, Math.max(1, limit));
|
|
36
|
-
return scored;
|
|
37
|
-
}
|
|
38
|
-
async indexFile(memoryId, content, filePath) {
|
|
39
|
-
const provider = await this.resolveProvider();
|
|
40
|
-
if (!provider) return;
|
|
41
|
-
const vector = await this.embed(content, provider);
|
|
42
|
-
if (!vector) return;
|
|
43
|
-
const index = await this.loadIndex(provider);
|
|
44
|
-
const relPath = toMemoryRelativePath(this.config.memoryDir, filePath);
|
|
45
|
-
index.entries[memoryId] = {
|
|
46
|
-
vector,
|
|
47
|
-
path: relPath
|
|
48
|
-
};
|
|
49
|
-
await this.saveIndex(index);
|
|
50
|
-
}
|
|
51
|
-
async removeFromIndex(memoryId) {
|
|
52
|
-
const provider = await this.resolveProvider();
|
|
53
|
-
if (!provider) return;
|
|
54
|
-
const index = await this.loadIndex(provider);
|
|
55
|
-
if (!index.entries[memoryId]) return;
|
|
56
|
-
delete index.entries[memoryId];
|
|
57
|
-
await this.saveIndex(index);
|
|
58
|
-
}
|
|
59
|
-
async resolveProvider() {
|
|
60
|
-
if (!this.config.embeddingFallbackEnabled) return null;
|
|
61
|
-
const preferred = this.config.embeddingFallbackProvider;
|
|
62
|
-
const providers = preferred === "auto" ? ["openai", "local"] : [preferred];
|
|
63
|
-
for (const p of providers) {
|
|
64
|
-
if (p === "openai" && this.config.openaiApiKey) {
|
|
65
|
-
const baseUrl = this.config.openaiBaseUrl ?? "https://api.openai.com/v1";
|
|
66
|
-
return {
|
|
67
|
-
type: "openai",
|
|
68
|
-
model: DEFAULT_OPENAI_MODEL,
|
|
69
|
-
endpoint: `${baseUrl.replace(/\/$/, "")}/embeddings`,
|
|
70
|
-
headers: {
|
|
71
|
-
"Content-Type": "application/json",
|
|
72
|
-
Authorization: `Bearer ${this.config.openaiApiKey}`
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
if (p === "local" && this.config.localLlmEnabled && this.config.localLlmUrl) {
|
|
77
|
-
const base = this.config.localLlmUrl.replace(/\/$/, "");
|
|
78
|
-
const endpoint = /\/v1$/i.test(base) ? `${base}/embeddings` : `${base}/v1/embeddings`;
|
|
79
|
-
const headers = {
|
|
80
|
-
"Content-Type": "application/json",
|
|
81
|
-
...this.config.localLlmHeaders ?? {}
|
|
82
|
-
};
|
|
83
|
-
if (this.config.localLlmApiKey && this.config.localLlmAuthHeader !== false) {
|
|
84
|
-
headers.Authorization = `Bearer ${this.config.localLlmApiKey}`;
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
type: "local",
|
|
88
|
-
model: this.config.localLlmModel || DEFAULT_OPENAI_MODEL,
|
|
89
|
-
endpoint,
|
|
90
|
-
headers
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
async embed(input, provider) {
|
|
97
|
-
try {
|
|
98
|
-
const res = await fetch(provider.endpoint, {
|
|
99
|
-
method: "POST",
|
|
100
|
-
headers: provider.headers,
|
|
101
|
-
body: JSON.stringify({
|
|
102
|
-
model: provider.model,
|
|
103
|
-
input: input.slice(0, 8e3),
|
|
104
|
-
encoding_format: "float"
|
|
105
|
-
})
|
|
106
|
-
});
|
|
107
|
-
if (!res.ok) {
|
|
108
|
-
log.debug(`embedding fallback request failed: ${provider.type} ${res.status}`);
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const payload = await res.json();
|
|
112
|
-
const vector = payload?.data?.[0]?.embedding;
|
|
113
|
-
if (!Array.isArray(vector)) return null;
|
|
114
|
-
return vector.map((n) => Number(n)).filter((n) => Number.isFinite(n));
|
|
115
|
-
} catch (err) {
|
|
116
|
-
log.debug(`embedding fallback error: ${err}`);
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
async loadIndex(provider) {
|
|
121
|
-
if (this.loaded && this.loaded.provider === provider.type && this.loaded.model === provider.model) {
|
|
122
|
-
return this.loaded;
|
|
123
|
-
}
|
|
124
|
-
try {
|
|
125
|
-
const raw = await readFile(this.indexPath, "utf-8");
|
|
126
|
-
const parsed = JSON.parse(raw);
|
|
127
|
-
if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === "object") {
|
|
128
|
-
this.loaded = {
|
|
129
|
-
version: 1,
|
|
130
|
-
provider: provider.type,
|
|
131
|
-
model: provider.model,
|
|
132
|
-
entries: parsed.entries
|
|
133
|
-
};
|
|
134
|
-
return this.loaded;
|
|
135
|
-
}
|
|
136
|
-
} catch {
|
|
137
|
-
}
|
|
138
|
-
this.loaded = {
|
|
139
|
-
version: 1,
|
|
140
|
-
provider: provider.type,
|
|
141
|
-
model: provider.model,
|
|
142
|
-
entries: {}
|
|
143
|
-
};
|
|
144
|
-
return this.loaded;
|
|
145
|
-
}
|
|
146
|
-
async saveIndex(index) {
|
|
147
|
-
await mkdir(path.dirname(this.indexPath), { recursive: true });
|
|
148
|
-
await writeFile(this.indexPath, JSON.stringify(index), "utf-8");
|
|
149
|
-
this.loaded = index;
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
function toMemoryRelativePath(memoryDir, filePath) {
|
|
153
|
-
if (!path.isAbsolute(filePath)) return filePath;
|
|
154
|
-
const rel = path.relative(memoryDir, filePath);
|
|
155
|
-
return rel.startsWith("..") ? filePath : rel;
|
|
156
|
-
}
|
|
157
|
-
function cosineSimilarity(a, b) {
|
|
158
|
-
const n = Math.min(a.length, b.length);
|
|
159
|
-
if (n === 0) return 0;
|
|
160
|
-
let dot = 0;
|
|
161
|
-
let normA = 0;
|
|
162
|
-
let normB = 0;
|
|
163
|
-
for (let i = 0; i < n; i++) {
|
|
164
|
-
const av = a[i] ?? 0;
|
|
165
|
-
const bv = b[i] ?? 0;
|
|
166
|
-
dot += av * bv;
|
|
167
|
-
normA += av * av;
|
|
168
|
-
normB += bv * bv;
|
|
169
|
-
}
|
|
170
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
171
|
-
if (denom === 0) return 0;
|
|
172
|
-
return dot / denom;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export {
|
|
176
|
-
EmbeddingFallback
|
|
177
|
-
};
|
|
178
|
-
//# sourceMappingURL=chunk-QPKFPHOO.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/embedding-fallback.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { log } from \"./logger.js\";\nimport type { PluginConfig } from \"./types.js\";\n\ntype EmbeddingProviderType = \"openai\" | \"local\";\n\ntype ProviderConfig = {\n type: EmbeddingProviderType;\n model: string;\n endpoint: string;\n headers: Record<string, string>;\n};\n\ntype EmbeddingIndexEntry = {\n vector: number[];\n path: string;\n};\n\ntype EmbeddingIndexFile = {\n version: 1;\n provider: EmbeddingProviderType;\n model: string;\n entries: Record<string, EmbeddingIndexEntry>;\n};\n\nconst DEFAULT_OPENAI_MODEL = \"text-embedding-3-small\";\n\nexport class EmbeddingFallback {\n private readonly indexPath: string;\n private loaded: EmbeddingIndexFile | null = null;\n\n constructor(private readonly config: PluginConfig) {\n this.indexPath = path.join(config.memoryDir, \"state\", \"embeddings.json\");\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.resolveProvider()) !== null;\n }\n\n async search(\n query: string,\n limit: number,\n ): Promise<Array<{ id: string; score: number; path: string }>> {\n const provider = await this.resolveProvider();\n if (!provider) return [];\n\n const index = await this.loadIndex(provider);\n const ids = Object.keys(index.entries);\n if (ids.length === 0) return [];\n\n const queryVector = await this.embed(query, provider);\n if (!queryVector) return [];\n\n const scored = ids\n .map((id) => {\n const entry = index.entries[id];\n return {\n id,\n path: entry.path,\n score: cosineSimilarity(queryVector, entry.vector),\n };\n })\n .filter((r) => Number.isFinite(r.score))\n .sort((a, b) => b.score - a.score)\n .slice(0, Math.max(1, limit));\n\n return scored;\n }\n\n async indexFile(memoryId: string, content: string, filePath: string): Promise<void> {\n const provider = await this.resolveProvider();\n if (!provider) return;\n const vector = await this.embed(content, provider);\n if (!vector) return;\n\n const index = await this.loadIndex(provider);\n const relPath = toMemoryRelativePath(this.config.memoryDir, filePath);\n index.entries[memoryId] = {\n vector,\n path: relPath,\n };\n await this.saveIndex(index);\n }\n\n async removeFromIndex(memoryId: string): Promise<void> {\n const provider = await this.resolveProvider();\n if (!provider) return;\n\n const index = await this.loadIndex(provider);\n if (!index.entries[memoryId]) return;\n delete index.entries[memoryId];\n await this.saveIndex(index);\n }\n\n private async resolveProvider(): Promise<ProviderConfig | null> {\n if (!this.config.embeddingFallbackEnabled) return null;\n\n const preferred = this.config.embeddingFallbackProvider;\n const providers = preferred === \"auto\" ? [\"openai\", \"local\"] : [preferred];\n\n for (const p of providers) {\n if (p === \"openai\" && this.config.openaiApiKey) {\n const baseUrl = this.config.openaiBaseUrl ?? \"https://api.openai.com/v1\";\n return {\n type: \"openai\",\n model: DEFAULT_OPENAI_MODEL,\n endpoint: `${baseUrl.replace(/\\/$/, \"\")}/embeddings`,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.config.openaiApiKey}`,\n },\n };\n }\n\n if (p === \"local\" && this.config.localLlmEnabled && this.config.localLlmUrl) {\n const base = this.config.localLlmUrl.replace(/\\/$/, \"\");\n const endpoint = /\\/v1$/i.test(base) ? `${base}/embeddings` : `${base}/v1/embeddings`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(this.config.localLlmHeaders ?? {}),\n };\n if (this.config.localLlmApiKey && this.config.localLlmAuthHeader !== false) {\n headers.Authorization = `Bearer ${this.config.localLlmApiKey}`;\n }\n return {\n type: \"local\",\n model: this.config.localLlmModel || DEFAULT_OPENAI_MODEL,\n endpoint,\n headers,\n };\n }\n }\n\n return null;\n }\n\n private async embed(input: string, provider: ProviderConfig): Promise<number[] | null> {\n try {\n const res = await fetch(provider.endpoint, {\n method: \"POST\",\n headers: provider.headers,\n body: JSON.stringify({\n model: provider.model,\n input: input.slice(0, 8000),\n encoding_format: \"float\",\n }),\n });\n if (!res.ok) {\n log.debug(`embedding fallback request failed: ${provider.type} ${res.status}`);\n return null;\n }\n const payload = (await res.json()) as any;\n const vector = payload?.data?.[0]?.embedding;\n if (!Array.isArray(vector)) return null;\n return vector.map((n: unknown) => Number(n)).filter((n: number) => Number.isFinite(n));\n } catch (err) {\n log.debug(`embedding fallback error: ${err}`);\n return null;\n }\n }\n\n private async loadIndex(provider: ProviderConfig): Promise<EmbeddingIndexFile> {\n if (this.loaded && this.loaded.provider === provider.type && this.loaded.model === provider.model) {\n return this.loaded;\n }\n\n try {\n const raw = await readFile(this.indexPath, \"utf-8\");\n const parsed = JSON.parse(raw) as EmbeddingIndexFile;\n if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === \"object\") {\n this.loaded = {\n version: 1,\n provider: provider.type,\n model: provider.model,\n entries: parsed.entries,\n };\n return this.loaded;\n }\n } catch {\n // ignore and create a new index\n }\n\n this.loaded = {\n version: 1,\n provider: provider.type,\n model: provider.model,\n entries: {},\n };\n return this.loaded;\n }\n\n private async saveIndex(index: EmbeddingIndexFile): Promise<void> {\n await mkdir(path.dirname(this.indexPath), { recursive: true });\n await writeFile(this.indexPath, JSON.stringify(index), \"utf-8\");\n this.loaded = index;\n }\n}\n\nfunction toMemoryRelativePath(memoryDir: string, filePath: string): string {\n if (!path.isAbsolute(filePath)) return filePath;\n const rel = path.relative(memoryDir, filePath);\n return rel.startsWith(\"..\") ? filePath : rel;\n}\n\nfunction cosineSimilarity(a: number[], b: number[]): number {\n const n = Math.min(a.length, b.length);\n if (n === 0) return 0;\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < n; i++) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n dot += av * bv;\n normA += av * av;\n normB += bv * bv;\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n if (denom === 0) return 0;\n return dot / denom;\n}\n\n"],"mappings":"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","names":[]}
|