@remnic/core 9.3.613 → 9.3.615
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-cli.js +59 -58
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +4 -2
- package/dist/access-http.js +23 -23
- package/dist/access-mcp.d.ts +9 -2
- package/dist/access-mcp.js +20 -20
- package/dist/access-schema.d.ts +26 -14
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-D2J9dh_9.d.ts → access-service-CBNEKjzN.d.ts} +71 -6
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +17 -17
- package/dist/active-recall.js +20 -3
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.js +2 -3
- package/dist/behavior-learner.js.map +1 -1
- package/dist/bootstrap.d.ts +1 -1
- package/dist/briefing.js +3 -3
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -1
- package/dist/calibration.d.ts +5 -2
- package/dist/calibration.js +7 -5
- package/dist/calibration.js.map +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/causal-consolidation.d.ts +8 -2
- package/dist/causal-consolidation.js +13 -11
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-3BP57I6J.js → chunk-2F6NP3NT.js} +2 -1
- package/dist/{chunk-3BP57I6J.js.map → chunk-2F6NP3NT.js.map} +1 -1
- package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
- package/dist/{chunk-HSVJGWYS.js → chunk-2ROPI5OE.js} +2 -2
- package/dist/{chunk-C4SQJZAF.js → chunk-2SGJY2UY.js} +6 -3
- package/dist/chunk-2SGJY2UY.js.map +1 -0
- package/dist/{chunk-ZDTVJXIP.js → chunk-3MAONBX3.js} +13 -5
- package/dist/chunk-3MAONBX3.js.map +1 -0
- package/dist/{chunk-G3Z3QEF5.js → chunk-3PY7VHV7.js} +2 -2
- package/dist/chunk-3PY7VHV7.js.map +1 -0
- package/dist/{chunk-CF3ZF2YU.js → chunk-3QSU4NFF.js} +3 -3
- package/dist/{chunk-AJA46VX5.js → chunk-3T74IZB3.js} +11 -2
- package/dist/chunk-3T74IZB3.js.map +1 -0
- package/dist/{chunk-KVEVLBKC.js → chunk-4HFJQCJZ.js} +13 -8
- package/dist/chunk-4HFJQCJZ.js.map +1 -0
- package/dist/{chunk-KGK2QKWL.js → chunk-4R4KTDIE.js} +1 -1
- package/dist/chunk-4R4KTDIE.js.map +1 -0
- package/dist/{chunk-OI27U2HT.js → chunk-5BTCT236.js} +2 -2
- package/dist/{chunk-TH67Q46T.js → chunk-5OHHEORR.js} +64 -21
- package/dist/chunk-5OHHEORR.js.map +1 -0
- package/dist/{chunk-CO7ZO4TU.js → chunk-5VDJMYTF.js} +2 -2
- package/dist/{chunk-BFBF3XEF.js → chunk-6BDVBBBY.js} +33 -25
- package/dist/{chunk-BFBF3XEF.js.map → chunk-6BDVBBBY.js.map} +1 -1
- package/dist/{chunk-EAZGEEG2.js → chunk-6L46YAEZ.js} +45 -9
- package/dist/chunk-6L46YAEZ.js.map +1 -0
- package/dist/{chunk-YFS5OEKO.js → chunk-7MLB4NCL.js} +2 -2
- package/dist/{chunk-LZ3VEOU5.js → chunk-AL4RAJL5.js} +22 -5
- package/dist/chunk-AL4RAJL5.js.map +1 -0
- package/dist/{chunk-557IAFPD.js → chunk-APRRL26Q.js} +2 -2
- package/dist/{chunk-QDDHYAKV.js → chunk-AZDOWD2L.js} +2 -2
- package/dist/{chunk-MLT75J5S.js → chunk-B6SU7YSE.js} +3 -3
- package/dist/{chunk-FXKPZ3H6.js → chunk-BPSGLMQ4.js} +2 -2
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-NOMEVTUD.js → chunk-C6C7XVKG.js} +5 -4
- package/dist/chunk-C6C7XVKG.js.map +1 -0
- package/dist/{chunk-XKIQZXUB.js → chunk-CI7RKSRE.js} +7 -1
- package/dist/chunk-CI7RKSRE.js.map +1 -0
- package/dist/{chunk-IK34DVAC.js → chunk-CIOMS6DI.js} +2 -2
- package/dist/{chunk-2I5JGH3M.js → chunk-CYEPCZN5.js} +2 -2
- package/dist/{chunk-2I5JGH3M.js.map → chunk-CYEPCZN5.js.map} +1 -1
- package/dist/{chunk-JHMFYY7L.js → chunk-DCGT4FPP.js} +13 -5
- package/dist/chunk-DCGT4FPP.js.map +1 -0
- package/dist/{chunk-7DZRO2DC.js → chunk-DEPRLVLK.js} +2 -2
- package/dist/{chunk-CSKLPDN6.js → chunk-DEVUWMME.js} +52 -19
- package/dist/chunk-DEVUWMME.js.map +1 -0
- package/dist/{chunk-DHGSZ3UD.js → chunk-DGNQRNLL.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-HJNQQICM.js → chunk-EXUAP5LH.js} +108 -51
- package/dist/chunk-EXUAP5LH.js.map +1 -0
- package/dist/chunk-FAV25DUZ.js +12 -0
- package/dist/chunk-FAV25DUZ.js.map +1 -0
- package/dist/{chunk-ETUPBUHB.js → chunk-GDASG7NC.js} +2 -2
- package/dist/{chunk-L227SKTB.js → chunk-GDB4J2H3.js} +17 -1
- package/dist/chunk-GDB4J2H3.js.map +1 -0
- package/dist/{chunk-IP73YCZP.js → chunk-GLPBYIXN.js} +4 -2
- package/dist/chunk-GLPBYIXN.js.map +1 -0
- package/dist/{chunk-4HP7HIE3.js → chunk-HP5FMB6L.js} +2 -2
- package/dist/{chunk-EVZFIAPG.js → chunk-IBTZEBUD.js} +23 -10
- package/dist/chunk-IBTZEBUD.js.map +1 -0
- package/dist/{chunk-DOX2CG6Y.js → chunk-IEUU7O4F.js} +2 -2
- package/dist/{chunk-EUML3N6B.js → chunk-IMA6GU4Y.js} +3 -3
- package/dist/chunk-IMA6GU4Y.js.map +1 -0
- package/dist/{chunk-JNANKJLN.js → chunk-JOASJWQR.js} +2 -2
- package/dist/chunk-JOASJWQR.js.map +1 -0
- package/dist/{chunk-WSGF57U2.js → chunk-JQDZQ4TB.js} +2 -2
- package/dist/{chunk-HINSGUA7.js → chunk-KBL3JJR6.js} +9 -13
- package/dist/chunk-KBL3JJR6.js.map +1 -0
- package/dist/{chunk-IOTENEVL.js → chunk-KGLPJROV.js} +57 -50
- package/dist/chunk-KGLPJROV.js.map +1 -0
- package/dist/{chunk-W7L6HXUC.js → chunk-LXOM6IQU.js} +2 -2
- package/dist/{chunk-G6R5UD3Q.js → chunk-MGN7VHWQ.js} +42 -1
- package/dist/{chunk-G6R5UD3Q.js.map → chunk-MGN7VHWQ.js.map} +1 -1
- package/dist/{chunk-DLJ4IR6M.js → chunk-MHQC2WU2.js} +2 -2
- package/dist/chunk-MHQC2WU2.js.map +1 -0
- package/dist/{chunk-5RPTH6AU.js → chunk-NM5NQYJE.js} +20 -19
- package/dist/chunk-NM5NQYJE.js.map +1 -0
- package/dist/{chunk-6JGNHWCI.js → chunk-OBIRVF36.js} +3 -3
- package/dist/{chunk-CHCA44C3.js → chunk-ODPLEWB6.js} +3 -3
- package/dist/chunk-ODPLEWB6.js.map +1 -0
- package/dist/{chunk-HENLZHIT.js → chunk-OIF36KGD.js} +7 -4
- package/dist/chunk-OIF36KGD.js.map +1 -0
- package/dist/{chunk-GUPISBV2.js → chunk-PP2JH3GP.js} +2 -2
- package/dist/{chunk-OXJBNGBK.js → chunk-PSUB67YB.js} +2 -2
- package/dist/{chunk-UWY7GIVS.js → chunk-PYIFUBRK.js} +45 -13
- package/dist/chunk-PYIFUBRK.js.map +1 -0
- package/dist/{chunk-KIB7SDIJ.js → chunk-Q6YIJGXJ.js} +2 -2
- package/dist/{chunk-ZT3EGNLR.js → chunk-QPD426WT.js} +2 -2
- package/dist/{chunk-RLV3PQGH.js → chunk-QVO4YOB7.js} +6 -6
- package/dist/{chunk-GMAG2HS4.js → chunk-RG3LBSGH.js} +46 -9
- package/dist/chunk-RG3LBSGH.js.map +1 -0
- package/dist/{chunk-XSWKORGM.js → chunk-S53OYO3F.js} +3 -1
- package/dist/chunk-S53OYO3F.js.map +1 -0
- package/dist/{chunk-YCN4BVDK.js → chunk-SCPFRKIT.js} +4 -2
- package/dist/chunk-SCPFRKIT.js.map +1 -0
- package/dist/{chunk-NZPF2SYV.js → chunk-T7N6KQGS.js} +138 -5
- package/dist/chunk-T7N6KQGS.js.map +1 -0
- package/dist/{chunk-VJXSUAO7.js → chunk-TNOWU6RP.js} +13 -10
- package/dist/chunk-TNOWU6RP.js.map +1 -0
- package/dist/{chunk-PCI747N2.js → chunk-TZVQQTG4.js} +48 -19
- package/dist/chunk-TZVQQTG4.js.map +1 -0
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-IK7DCC5H.js → chunk-VMGLYN42.js} +2 -2
- package/dist/{chunk-KM2A35EO.js → chunk-WB3LYXC5.js} +11 -7
- package/dist/chunk-WB3LYXC5.js.map +1 -0
- package/dist/{chunk-PPPZY2EU.js → chunk-WD2W4234.js} +9 -3
- package/dist/chunk-WD2W4234.js.map +1 -0
- package/dist/{chunk-NSKYFGDL.js → chunk-X4QQB7O6.js} +2 -2
- package/dist/{chunk-HPWVAEET.js → chunk-X6IRLNOO.js} +3 -7
- package/dist/chunk-X6IRLNOO.js.map +1 -0
- package/dist/{chunk-46GJIW5M.js → chunk-XAZOWLW4.js} +5 -5
- package/dist/{chunk-46GJIW5M.js.map → chunk-XAZOWLW4.js.map} +1 -1
- package/dist/{chunk-XPSVGJYA.js → chunk-YRMKDTKF.js} +12 -9
- package/dist/chunk-YRMKDTKF.js.map +1 -0
- package/dist/{chunk-6ZZP4EJF.js → chunk-ZJR7VG5L.js} +3 -3
- package/dist/{chunk-6ZZP4EJF.js.map → chunk-ZJR7VG5L.js.map} +1 -1
- package/dist/{chunk-2QANQKSQ.js → chunk-ZK32E74R.js} +156 -45
- package/dist/chunk-ZK32E74R.js.map +1 -0
- package/dist/{cli-OrfKXNU4.d.ts → cli-Cw729yLf.d.ts} +6 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +61 -60
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.js +39 -11
- package/dist/compounding/preference-consolidator.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/consolidation-provenance-check.js +1 -1
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/indexer.js +1 -1
- package/dist/cross-namespace-budget.js +1 -1
- package/dist/enrichment/index.js +1 -1
- package/dist/entity-retrieval.js +3 -3
- package/dist/evals.js +1 -1
- package/dist/explicit-capture.d.ts +11 -1
- package/dist/explicit-capture.js +1 -1
- package/dist/extraction-judge.js +8 -1
- package/dist/extraction.js +2 -2
- package/dist/fallback-llm.d.ts +23 -6
- package/dist/fallback-llm.js +5 -3
- package/dist/{first-start-migration-GYJWIH36.js → first-start-migration-FF7YFGRP.js} +6 -6
- package/dist/index.d.ts +3 -3
- package/dist/index.js +95 -94
- package/dist/index.js.map +1 -1
- package/dist/lcm/archive.js +2 -2
- package/dist/lcm/engine.js +5 -5
- package/dist/lcm/index.js +7 -7
- package/dist/lcm/summarizer.js +3 -3
- package/dist/maintenance/memory-governance-cron.d.ts +6 -4
- package/dist/maintenance/memory-governance-cron.js +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/mcp-memory-inspector-app.js +1 -1
- package/dist/migrate/from-engram.js +1 -1
- package/dist/namespaces/migrate.js +16 -15
- package/dist/namespaces/search.js +12 -11
- package/dist/namespaces/storage.js +3 -3
- package/dist/network/webdav.d.ts +2 -0
- package/dist/network/webdav.js +1 -1
- package/dist/objective-state-writers.js +2 -2
- package/dist/operator-toolkit.d.ts +3 -1
- package/dist/operator-toolkit.js +21 -20
- package/dist/{orchestrator-DTRQG75J.d.ts → orchestrator-CqWOjfgl.d.ts} +46 -3
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +48 -45
- package/dist/patterns-cli.js +1 -1
- package/dist/qmd-recall-cache.d.ts +2 -0
- package/dist/qmd-recall-cache.js +1 -1
- package/dist/qmd.d.ts +37 -2
- package/dist/qmd.js +4 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +57 -0
- package/dist/recall-planner-llm.js +167 -0
- package/dist/recall-planner-llm.js.map +1 -0
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.js +2 -2
- package/dist/routing/store.js +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/search/factory.js +11 -10
- package/dist/search/index.js +11 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +3 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +3 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/noop-backend.js +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +3 -2
- package/dist/search/port.d.ts +6 -1
- package/dist/search/port.js +7 -0
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/search/remote-backend.js +1 -1
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/session-observer-state.js +1 -1
- package/dist/storage.js +2 -2
- package/dist/summarizer.js +2 -2
- package/dist/temporal-index.js +1 -1
- package/dist/{tier-stats-SKML2OSF.js → tier-stats-3LYQ3VV5.js} +3 -3
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-sqlite.js +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/types.d.ts +32 -0
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +1 -1
- package/dist/utility-runtime.js +2 -2
- package/dist/verified-recall.js +3 -3
- package/dist/work/board.js +2 -2
- package/dist/work/storage.d.ts +2 -0
- package/dist/work/storage.js +1 -1
- package/package.json +1 -1
- package/src/access-http.ts +24 -10
- package/src/access-mcp.test.ts +160 -0
- package/src/access-mcp.ts +72 -7
- package/src/access-schema.ts +11 -0
- package/src/access-service-coding-write.test.ts +478 -0
- package/src/access-service.ts +237 -32
- package/src/active-recall.test.ts +40 -0
- package/src/active-recall.ts +19 -2
- package/src/behavior-learner.ts +5 -3
- package/src/buffer-session.test.ts +58 -0
- package/src/buffer-surprise-trigger.test.ts +4 -18
- package/src/buffer.ts +39 -11
- package/src/calibration.ts +10 -4
- package/src/causal-consolidation.test.ts +47 -2
- package/src/causal-consolidation.ts +13 -9
- package/src/cli.ts +19 -4
- package/src/compounding/engine.ts +2 -0
- package/src/compounding/preference-consolidator.test.ts +292 -0
- package/src/compounding/preference-consolidator.ts +55 -19
- package/src/config.test.ts +213 -0
- package/src/config.ts +175 -4
- package/src/connectors/codex-materialize-runner.ts +7 -4
- package/src/consolidation-provenance-check.ts +24 -5
- package/src/conversation-index/indexer.test.ts +22 -0
- package/src/conversation-index/indexer.ts +7 -3
- package/src/cross-namespace-budget.test.ts +44 -21
- package/src/cross-namespace-budget.ts +2 -2
- package/src/enrichment/pipeline.ts +11 -16
- package/src/evals.ts +1 -1
- package/src/explicit-capture.ts +19 -2
- package/src/extraction-judge-chain.test.ts +55 -0
- package/src/extraction-judge.ts +7 -9
- package/src/extraction.ts +16 -5
- package/src/fallback-llm.test.ts +600 -1
- package/src/fallback-llm.ts +91 -22
- package/src/maintenance/memory-governance-cron.ts +39 -29
- package/src/mcp-memory-inspector-app.ts +54 -12
- package/src/message-parts/index.ts +6 -0
- package/src/message-parts/message-parts.test.ts +30 -0
- package/src/migrate/from-engram.ts +19 -5
- package/src/namespaces/search.test.ts +15 -2
- package/src/namespaces/search.ts +1 -1
- package/src/network/webdav.ts +61 -21
- package/src/operator-toolkit.ts +6 -2
- package/src/orchestrator.ts +173 -20
- package/src/qmd-client.test.ts +85 -0
- package/src/qmd-recall-cache.test.ts +16 -0
- package/src/qmd-recall-cache.ts +7 -0
- package/src/qmd.test.ts +54 -0
- package/src/qmd.ts +119 -19
- package/src/recall-planner-llm.test.ts +224 -0
- package/src/recall-planner-llm.ts +289 -0
- package/src/routing/store.ts +4 -8
- package/src/search/factory.ts +3 -0
- package/src/search/lancedb-backend.ts +15 -3
- package/src/search/meilisearch-backend.ts +70 -7
- package/src/search/noop-backend.ts +5 -1
- package/src/search/orama-backend.ts +15 -3
- package/src/search/port.ts +15 -0
- package/src/search/remote-backend.ts +5 -1
- package/src/session-observer-state.ts +1 -1
- package/src/summarizer.ts +3 -3
- package/src/temporal-index.test.ts +18 -0
- package/src/temporal-index.ts +45 -0
- package/src/training-export/cli-date-validation.test.ts +36 -0
- package/src/training-export/date-parse.ts +21 -2
- package/src/transfer/export-sqlite.ts +3 -0
- package/src/types.ts +35 -0
- package/src/utility-learner.ts +1 -0
- package/src/work/storage.ts +23 -0
- package/dist/chunk-2QANQKSQ.js.map +0 -1
- package/dist/chunk-5RPTH6AU.js.map +0 -1
- package/dist/chunk-AJA46VX5.js.map +0 -1
- package/dist/chunk-C4SQJZAF.js.map +0 -1
- package/dist/chunk-CHCA44C3.js.map +0 -1
- package/dist/chunk-CSKLPDN6.js.map +0 -1
- package/dist/chunk-DLJ4IR6M.js.map +0 -1
- package/dist/chunk-EAZGEEG2.js.map +0 -1
- package/dist/chunk-EUML3N6B.js.map +0 -1
- package/dist/chunk-EVZFIAPG.js.map +0 -1
- package/dist/chunk-G3Z3QEF5.js.map +0 -1
- package/dist/chunk-GMAG2HS4.js.map +0 -1
- package/dist/chunk-HENLZHIT.js.map +0 -1
- package/dist/chunk-HINSGUA7.js.map +0 -1
- package/dist/chunk-HJNQQICM.js.map +0 -1
- package/dist/chunk-HPWVAEET.js.map +0 -1
- package/dist/chunk-IOTENEVL.js.map +0 -1
- package/dist/chunk-IP73YCZP.js.map +0 -1
- package/dist/chunk-JHMFYY7L.js.map +0 -1
- package/dist/chunk-JNANKJLN.js.map +0 -1
- package/dist/chunk-KGK2QKWL.js.map +0 -1
- package/dist/chunk-KM2A35EO.js.map +0 -1
- package/dist/chunk-KVEVLBKC.js.map +0 -1
- package/dist/chunk-L227SKTB.js.map +0 -1
- package/dist/chunk-LZ3VEOU5.js.map +0 -1
- package/dist/chunk-NOMEVTUD.js.map +0 -1
- package/dist/chunk-NZPF2SYV.js.map +0 -1
- package/dist/chunk-PCI747N2.js.map +0 -1
- package/dist/chunk-PPPZY2EU.js.map +0 -1
- package/dist/chunk-TH67Q46T.js.map +0 -1
- package/dist/chunk-UWY7GIVS.js.map +0 -1
- package/dist/chunk-VJXSUAO7.js.map +0 -1
- package/dist/chunk-XKIQZXUB.js.map +0 -1
- package/dist/chunk-XPSVGJYA.js.map +0 -1
- package/dist/chunk-XSWKORGM.js.map +0 -1
- package/dist/chunk-YCN4BVDK.js.map +0 -1
- package/dist/chunk-ZDTVJXIP.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-HSVJGWYS.js.map → chunk-2ROPI5OE.js.map} +0 -0
- /package/dist/{chunk-CF3ZF2YU.js.map → chunk-3QSU4NFF.js.map} +0 -0
- /package/dist/{chunk-OI27U2HT.js.map → chunk-5BTCT236.js.map} +0 -0
- /package/dist/{chunk-CO7ZO4TU.js.map → chunk-5VDJMYTF.js.map} +0 -0
- /package/dist/{chunk-YFS5OEKO.js.map → chunk-7MLB4NCL.js.map} +0 -0
- /package/dist/{chunk-557IAFPD.js.map → chunk-APRRL26Q.js.map} +0 -0
- /package/dist/{chunk-QDDHYAKV.js.map → chunk-AZDOWD2L.js.map} +0 -0
- /package/dist/{chunk-MLT75J5S.js.map → chunk-B6SU7YSE.js.map} +0 -0
- /package/dist/{chunk-FXKPZ3H6.js.map → chunk-BPSGLMQ4.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-IK34DVAC.js.map → chunk-CIOMS6DI.js.map} +0 -0
- /package/dist/{chunk-7DZRO2DC.js.map → chunk-DEPRLVLK.js.map} +0 -0
- /package/dist/{chunk-DHGSZ3UD.js.map → chunk-DGNQRNLL.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-ETUPBUHB.js.map → chunk-GDASG7NC.js.map} +0 -0
- /package/dist/{chunk-4HP7HIE3.js.map → chunk-HP5FMB6L.js.map} +0 -0
- /package/dist/{chunk-DOX2CG6Y.js.map → chunk-IEUU7O4F.js.map} +0 -0
- /package/dist/{chunk-WSGF57U2.js.map → chunk-JQDZQ4TB.js.map} +0 -0
- /package/dist/{chunk-W7L6HXUC.js.map → chunk-LXOM6IQU.js.map} +0 -0
- /package/dist/{chunk-6JGNHWCI.js.map → chunk-OBIRVF36.js.map} +0 -0
- /package/dist/{chunk-GUPISBV2.js.map → chunk-PP2JH3GP.js.map} +0 -0
- /package/dist/{chunk-OXJBNGBK.js.map → chunk-PSUB67YB.js.map} +0 -0
- /package/dist/{chunk-KIB7SDIJ.js.map → chunk-Q6YIJGXJ.js.map} +0 -0
- /package/dist/{chunk-ZT3EGNLR.js.map → chunk-QPD426WT.js.map} +0 -0
- /package/dist/{chunk-RLV3PQGH.js.map → chunk-QVO4YOB7.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-IK7DCC5H.js.map → chunk-VMGLYN42.js.map} +0 -0
- /package/dist/{chunk-NSKYFGDL.js.map → chunk-X4QQB7O6.js.map} +0 -0
- /package/dist/{first-start-migration-GYJWIH36.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
- /package/dist/{tier-stats-SKML2OSF.js.map → tier-stats-3LYQ3VV5.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utility-learner.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { clamp01 } from \"./lifecycle.js\";\nimport {\n readUtilityTelemetryEvents,\n resolveUtilityTelemetryDir,\n type UtilityTelemetryDecision,\n type UtilityTelemetryEvent,\n type UtilityTelemetryOutcome,\n type UtilityTelemetryTarget,\n} from \"./utility-telemetry.js\";\n\nexport interface UtilityLearningWeight {\n target: UtilityTelemetryTarget;\n decision: UtilityTelemetryDecision;\n eventCount: number;\n learnedWeight: number;\n averageUtilityScore: number;\n confidence: number;\n outcomeCounts: Partial<Record<UtilityTelemetryOutcome, number>>;\n updatedAt: string;\n}\n\nexport interface UtilityLearningSnapshot {\n version: 1;\n updatedAt: string;\n windowDays: number;\n minEventCount: number;\n maxWeightMagnitude: number;\n weights: UtilityLearningWeight[];\n}\n\nexport interface UtilityLearningStatus {\n enabled: boolean;\n promotionByOutcomeEnabled: boolean;\n rootDir: string;\n statePath: string;\n snapshot: UtilityLearningSnapshot | null;\n weights: {\n total: number;\n positive: number;\n negative: number;\n zero: number;\n latestUpdatedAt?: string;\n };\n}\n\nexport interface UtilityLearningResult {\n applied: boolean;\n reason: \"disabled\" | \"insufficient_events\" | \"learned\";\n statePath: string;\n snapshot: UtilityLearningSnapshot | null;\n}\n\nconst UTILITY_LEARNING_SNAPSHOT_VERSION = 1;\nconst UTILITY_LEARNING_STATE_FILE = \"learning-state.json\";\n\nfunction clampWeight(value: number, maxWeightMagnitude: number): number {\n const limit = Number.isFinite(maxWeightMagnitude) && maxWeightMagnitude > 0\n ? maxWeightMagnitude\n : 0;\n return Math.max(-limit, Math.min(limit, value));\n}\n\nfunction coerceLearningWindowDays(value: number): number {\n if (!Number.isFinite(value)) return 14;\n return Math.max(1, Math.floor(value));\n}\n\nfunction coerceMinEventCount(value: number): number {\n if (!Number.isFinite(value)) return 3;\n return Math.max(1, Math.floor(value));\n}\n\nfunction coerceMaxWeightMagnitude(value: number): number {\n if (!Number.isFinite(value)) return 0.35;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction roundWeight(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n\nfunction outcomeCountsFor(events: UtilityTelemetryEvent[]): Partial<Record<UtilityTelemetryOutcome, number>> {\n const counts: Partial<Record<UtilityTelemetryOutcome, number>> = {};\n for (const event of events) {\n counts[event.outcome] = (counts[event.outcome] ?? 0) + 1;\n }\n return counts;\n}\n\nfunction selectRecentEvents(events: UtilityTelemetryEvent[], now: Date, windowDays: number): UtilityTelemetryEvent[] {\n if (!Number.isFinite(windowDays) || windowDays <= 0) return [...events];\n const minTimestamp = now.getTime() - windowDays * 86_400_000;\n return events.filter((event) => {\n const ts = Date.parse(event.recordedAt);\n return Number.isFinite(ts) && ts >= minTimestamp;\n });\n}\n\nfunction confidenceFromEvents(eventCount: number, averageUtilityScore: number): number {\n if (eventCount <= 0) return 0;\n return roundWeight(clamp01(Math.abs(averageUtilityScore) * Math.min(1, eventCount / 10)));\n}\n\nfunction validateUtilityLearningSnapshot(raw: unknown): UtilityLearningSnapshot {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(\"utility learning snapshot must be an object\");\n }\n const record = raw as Record<string, unknown>;\n if (record.version !== UTILITY_LEARNING_SNAPSHOT_VERSION) {\n throw new Error(\"utility learning snapshot version must be 1\");\n }\n if (typeof record.updatedAt !== \"string\" || record.updatedAt.length === 0) {\n throw new Error(\"utility learning snapshot updatedAt must be a string\");\n }\n if (typeof record.windowDays !== \"number\" || !Number.isFinite(record.windowDays) || record.windowDays < 0) {\n throw new Error(\"utility learning snapshot windowDays must be a non-negative number\");\n }\n if (typeof record.minEventCount !== \"number\" || !Number.isFinite(record.minEventCount) || record.minEventCount < 1) {\n throw new Error(\"utility learning snapshot minEventCount must be >= 1\");\n }\n if (\n typeof record.maxWeightMagnitude !== \"number\" ||\n !Number.isFinite(record.maxWeightMagnitude) ||\n record.maxWeightMagnitude < 0\n ) {\n throw new Error(\"utility learning snapshot maxWeightMagnitude must be >= 0\");\n }\n if (!Array.isArray(record.weights)) {\n throw new Error(\"utility learning snapshot weights must be an array\");\n }\n\n const weights = record.weights.map((entry) => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(\"utility learning weight must be an object\");\n }\n const weight = entry as Record<string, unknown>;\n const target = weight.target;\n const decision = weight.decision;\n if (target !== \"promotion\" && target !== \"ranking\") {\n throw new Error(\"utility learning weight target must be promotion|ranking\");\n }\n if (![\"promote\", \"demote\", \"hold\", \"boost\", \"suppress\"].includes(String(decision))) {\n throw new Error(\"utility learning weight decision is invalid\");\n }\n if (typeof weight.eventCount !== \"number\" || !Number.isFinite(weight.eventCount) || weight.eventCount < 0) {\n throw new Error(\"utility learning weight eventCount must be >= 0\");\n }\n if (typeof weight.learnedWeight !== \"number\" || !Number.isFinite(weight.learnedWeight)) {\n throw new Error(\"utility learning weight learnedWeight must be finite\");\n }\n if (typeof weight.averageUtilityScore !== \"number\" || !Number.isFinite(weight.averageUtilityScore)) {\n throw new Error(\"utility learning weight averageUtilityScore must be finite\");\n }\n if (typeof weight.confidence !== \"number\" || !Number.isFinite(weight.confidence)) {\n throw new Error(\"utility learning weight confidence must be finite\");\n }\n if (typeof weight.updatedAt !== \"string\" || weight.updatedAt.length === 0) {\n throw new Error(\"utility learning weight updatedAt must be a string\");\n }\n const outcomeCounts = (weight.outcomeCounts ?? {}) as Partial<Record<UtilityTelemetryOutcome, number>>;\n return {\n target,\n decision: decision as UtilityTelemetryDecision,\n eventCount: weight.eventCount,\n learnedWeight: roundWeight(weight.learnedWeight),\n averageUtilityScore: roundWeight(weight.averageUtilityScore),\n confidence: roundWeight(clamp01(weight.confidence)),\n outcomeCounts,\n updatedAt: weight.updatedAt,\n } satisfies UtilityLearningWeight;\n });\n\n return {\n version: 1,\n updatedAt: record.updatedAt,\n windowDays: record.windowDays,\n minEventCount: record.minEventCount,\n maxWeightMagnitude: record.maxWeightMagnitude,\n weights,\n };\n}\n\nexport function resolveUtilityLearningStatePath(memoryDir: string, utilityTelemetryDir?: string): string {\n return path.join(resolveUtilityTelemetryDir(memoryDir, utilityTelemetryDir), UTILITY_LEARNING_STATE_FILE);\n}\n\nexport async function readUtilityLearningSnapshot(\n memoryDir: string,\n utilityTelemetryDir?: string,\n): Promise<UtilityLearningSnapshot | null> {\n const statePath = resolveUtilityLearningStatePath(memoryDir, utilityTelemetryDir);\n try {\n const raw = JSON.parse(await readFile(statePath, \"utf8\")) as unknown;\n return validateUtilityLearningSnapshot(raw);\n } catch {\n return null;\n }\n}\n\nasync function writeUtilityLearningSnapshot(\n statePath: string,\n snapshot: UtilityLearningSnapshot,\n): Promise<void> {\n const tempPath = `${statePath}.tmp`;\n await mkdir(path.dirname(statePath), { recursive: true });\n await writeFile(tempPath, `${JSON.stringify(snapshot, null, 2)}\\n`, \"utf8\");\n await rename(tempPath, statePath);\n}\n\nexport async function learnUtilityPromotionWeights(options: {\n memoryDir: string;\n utilityTelemetryDir?: string;\n enabled: boolean;\n now?: Date;\n learningWindowDays: number;\n minEventCount: number;\n maxWeightMagnitude: number;\n}): Promise<UtilityLearningResult> {\n const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);\n if (!options.enabled) {\n return {\n applied: false,\n reason: \"disabled\",\n statePath,\n snapshot: null,\n };\n }\n\n const now = options.now ?? new Date();\n const updatedAt = now.toISOString();\n const windowDays = coerceLearningWindowDays(options.learningWindowDays);\n const minEventCount = coerceMinEventCount(options.minEventCount);\n const maxWeightMagnitude = coerceMaxWeightMagnitude(options.maxWeightMagnitude);\n const recentEvents = selectRecentEvents(\n (\n await readUtilityTelemetryEvents({\n memoryDir: options.memoryDir,\n utilityTelemetryDir: options.utilityTelemetryDir,\n })\n ).events,\n now,\n windowDays,\n );\n\n const grouped = new Map<string, UtilityTelemetryEvent[]>();\n for (const event of recentEvents) {\n const key = `${event.target}:${event.decision}`;\n const existing = grouped.get(key);\n if (existing) {\n existing.push(event);\n } else {\n grouped.set(key, [event]);\n }\n }\n\n const weights: UtilityLearningWeight[] = [];\n for (const events of grouped.values()) {\n if (events.length < minEventCount) continue;\n const target = events[0].target;\n const decision = events[0].decision;\n const averageUtilityScore = events.reduce((sum, event) => sum + event.utilityScore, 0) / events.length;\n const confidence = confidenceFromEvents(events.length, averageUtilityScore);\n const learnedWeight = roundWeight(\n clampWeight(averageUtilityScore * confidence, maxWeightMagnitude),\n );\n weights.push({\n target,\n decision,\n eventCount: events.length,\n learnedWeight,\n averageUtilityScore: roundWeight(averageUtilityScore),\n confidence,\n outcomeCounts: outcomeCountsFor(events),\n updatedAt,\n });\n }\n\n weights.sort((left, right) => {\n const targetCompare = left.target.localeCompare(right.target);\n if (targetCompare !== 0) return targetCompare;\n return left.decision.localeCompare(right.decision);\n });\n\n const snapshot: UtilityLearningSnapshot = {\n version: 1,\n updatedAt,\n windowDays,\n minEventCount,\n maxWeightMagnitude,\n weights,\n };\n\n if (weights.length === 0) {\n return {\n applied: false,\n reason: \"insufficient_events\",\n statePath,\n snapshot,\n };\n }\n\n await writeUtilityLearningSnapshot(statePath, snapshot);\n return {\n applied: true,\n reason: \"learned\",\n statePath,\n snapshot,\n };\n}\n\nexport async function getUtilityLearningStatus(options: {\n memoryDir: string;\n utilityTelemetryDir?: string;\n enabled: boolean;\n promotionByOutcomeEnabled?: boolean;\n}): Promise<UtilityLearningStatus> {\n const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);\n const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);\n if (!options.enabled) {\n return {\n enabled: false,\n promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,\n rootDir,\n statePath,\n snapshot: null,\n weights: {\n total: 0,\n positive: 0,\n negative: 0,\n zero: 0,\n },\n };\n }\n\n const snapshot = await readUtilityLearningSnapshot(options.memoryDir, options.utilityTelemetryDir);\n const weights = snapshot?.weights ?? [];\n return {\n enabled: true,\n promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,\n rootDir,\n statePath,\n snapshot,\n weights: {\n total: weights.length,\n positive: weights.filter((entry) => entry.learnedWeight > 0).length,\n negative: weights.filter((entry) => entry.learnedWeight < 0).length,\n zero: weights.filter((entry) => entry.learnedWeight === 0).length,\n latestUpdatedAt: snapshot?.updatedAt,\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/utility-learner.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { clamp01 } from \"./lifecycle.js\";\nimport {\n readUtilityTelemetryEvents,\n resolveUtilityTelemetryDir,\n type UtilityTelemetryDecision,\n type UtilityTelemetryEvent,\n type UtilityTelemetryOutcome,\n type UtilityTelemetryTarget,\n} from \"./utility-telemetry.js\";\n\nexport interface UtilityLearningWeight {\n target: UtilityTelemetryTarget;\n decision: UtilityTelemetryDecision;\n eventCount: number;\n learnedWeight: number;\n averageUtilityScore: number;\n confidence: number;\n outcomeCounts: Partial<Record<UtilityTelemetryOutcome, number>>;\n updatedAt: string;\n}\n\nexport interface UtilityLearningSnapshot {\n version: 1;\n updatedAt: string;\n windowDays: number;\n minEventCount: number;\n maxWeightMagnitude: number;\n weights: UtilityLearningWeight[];\n}\n\nexport interface UtilityLearningStatus {\n enabled: boolean;\n promotionByOutcomeEnabled: boolean;\n rootDir: string;\n statePath: string;\n snapshot: UtilityLearningSnapshot | null;\n weights: {\n total: number;\n positive: number;\n negative: number;\n zero: number;\n latestUpdatedAt?: string;\n };\n}\n\nexport interface UtilityLearningResult {\n applied: boolean;\n reason: \"disabled\" | \"insufficient_events\" | \"learned\";\n statePath: string;\n snapshot: UtilityLearningSnapshot | null;\n}\n\nconst UTILITY_LEARNING_SNAPSHOT_VERSION = 1;\nconst UTILITY_LEARNING_STATE_FILE = \"learning-state.json\";\n\nfunction clampWeight(value: number, maxWeightMagnitude: number): number {\n const limit = Number.isFinite(maxWeightMagnitude) && maxWeightMagnitude > 0\n ? maxWeightMagnitude\n : 0;\n return Math.max(-limit, Math.min(limit, value));\n}\n\nfunction coerceLearningWindowDays(value: number): number {\n if (!Number.isFinite(value)) return 14;\n return Math.max(1, Math.floor(value));\n}\n\nfunction coerceMinEventCount(value: number): number {\n if (!Number.isFinite(value)) return 3;\n return Math.max(1, Math.floor(value));\n}\n\nfunction coerceMaxWeightMagnitude(value: number): number {\n if (!Number.isFinite(value)) return 0.35;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction roundWeight(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n\nfunction outcomeCountsFor(events: UtilityTelemetryEvent[]): Partial<Record<UtilityTelemetryOutcome, number>> {\n const counts: Partial<Record<UtilityTelemetryOutcome, number>> = {};\n for (const event of events) {\n counts[event.outcome] = (counts[event.outcome] ?? 0) + 1;\n }\n return counts;\n}\n\nfunction selectRecentEvents(events: UtilityTelemetryEvent[], now: Date, windowDays: number): UtilityTelemetryEvent[] {\n if (!Number.isFinite(windowDays) || windowDays <= 0) return [...events];\n const minTimestamp = now.getTime() - windowDays * 86_400_000;\n return events.filter((event) => {\n const ts = Date.parse(event.recordedAt);\n return Number.isFinite(ts) && ts >= minTimestamp;\n });\n}\n\nfunction confidenceFromEvents(eventCount: number, averageUtilityScore: number): number {\n if (eventCount <= 0) return 0;\n return roundWeight(clamp01(Math.abs(averageUtilityScore) * Math.min(1, eventCount / 10)));\n}\n\nfunction validateUtilityLearningSnapshot(raw: unknown): UtilityLearningSnapshot {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(\"utility learning snapshot must be an object\");\n }\n const record = raw as Record<string, unknown>;\n if (record.version !== UTILITY_LEARNING_SNAPSHOT_VERSION) {\n throw new Error(\"utility learning snapshot version must be 1\");\n }\n if (typeof record.updatedAt !== \"string\" || record.updatedAt.length === 0) {\n throw new Error(\"utility learning snapshot updatedAt must be a string\");\n }\n if (typeof record.windowDays !== \"number\" || !Number.isFinite(record.windowDays) || record.windowDays < 0) {\n throw new Error(\"utility learning snapshot windowDays must be a non-negative number\");\n }\n if (typeof record.minEventCount !== \"number\" || !Number.isFinite(record.minEventCount) || record.minEventCount < 1) {\n throw new Error(\"utility learning snapshot minEventCount must be >= 1\");\n }\n if (\n typeof record.maxWeightMagnitude !== \"number\" ||\n !Number.isFinite(record.maxWeightMagnitude) ||\n record.maxWeightMagnitude < 0\n ) {\n throw new Error(\"utility learning snapshot maxWeightMagnitude must be >= 0\");\n }\n if (!Array.isArray(record.weights)) {\n throw new Error(\"utility learning snapshot weights must be an array\");\n }\n\n const weights = record.weights.map((entry) => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(\"utility learning weight must be an object\");\n }\n const weight = entry as Record<string, unknown>;\n const target = weight.target;\n const decision = weight.decision;\n if (target !== \"promotion\" && target !== \"ranking\") {\n throw new Error(\"utility learning weight target must be promotion|ranking\");\n }\n if (![\"promote\", \"demote\", \"hold\", \"boost\", \"suppress\"].includes(String(decision))) {\n throw new Error(\"utility learning weight decision is invalid\");\n }\n if (typeof weight.eventCount !== \"number\" || !Number.isFinite(weight.eventCount) || weight.eventCount < 0) {\n throw new Error(\"utility learning weight eventCount must be >= 0\");\n }\n if (typeof weight.learnedWeight !== \"number\" || !Number.isFinite(weight.learnedWeight)) {\n throw new Error(\"utility learning weight learnedWeight must be finite\");\n }\n if (typeof weight.averageUtilityScore !== \"number\" || !Number.isFinite(weight.averageUtilityScore)) {\n throw new Error(\"utility learning weight averageUtilityScore must be finite\");\n }\n if (typeof weight.confidence !== \"number\" || !Number.isFinite(weight.confidence)) {\n throw new Error(\"utility learning weight confidence must be finite\");\n }\n if (typeof weight.updatedAt !== \"string\" || weight.updatedAt.length === 0) {\n throw new Error(\"utility learning weight updatedAt must be a string\");\n }\n const outcomeCounts = (weight.outcomeCounts ?? {}) as Partial<Record<UtilityTelemetryOutcome, number>>;\n return {\n target,\n decision: decision as UtilityTelemetryDecision,\n eventCount: weight.eventCount,\n learnedWeight: roundWeight(weight.learnedWeight),\n averageUtilityScore: roundWeight(weight.averageUtilityScore),\n confidence: roundWeight(clamp01(weight.confidence)),\n outcomeCounts,\n updatedAt: weight.updatedAt,\n } satisfies UtilityLearningWeight;\n });\n\n return {\n version: 1,\n updatedAt: record.updatedAt,\n windowDays: record.windowDays,\n minEventCount: record.minEventCount,\n maxWeightMagnitude: record.maxWeightMagnitude,\n weights,\n };\n}\n\nexport function resolveUtilityLearningStatePath(memoryDir: string, utilityTelemetryDir?: string): string {\n return path.join(resolveUtilityTelemetryDir(memoryDir, utilityTelemetryDir), UTILITY_LEARNING_STATE_FILE);\n}\n\nexport async function readUtilityLearningSnapshot(\n memoryDir: string,\n utilityTelemetryDir?: string,\n): Promise<UtilityLearningSnapshot | null> {\n const statePath = resolveUtilityLearningStatePath(memoryDir, utilityTelemetryDir);\n try {\n const raw = JSON.parse(await readFile(statePath, \"utf8\")) as unknown;\n return validateUtilityLearningSnapshot(raw);\n } catch {\n return null;\n }\n}\n\nasync function writeUtilityLearningSnapshot(\n statePath: string,\n snapshot: UtilityLearningSnapshot,\n): Promise<void> {\n const tempPath = `${statePath}.tmp`;\n await mkdir(path.dirname(statePath), { recursive: true });\n await writeFile(tempPath, `${JSON.stringify(snapshot, null, 2)}\\n`, \"utf8\");\n await rename(tempPath, statePath);\n}\n\nexport async function learnUtilityPromotionWeights(options: {\n memoryDir: string;\n utilityTelemetryDir?: string;\n enabled: boolean;\n now?: Date;\n learningWindowDays: number;\n minEventCount: number;\n maxWeightMagnitude: number;\n}): Promise<UtilityLearningResult> {\n const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);\n if (!options.enabled) {\n return {\n applied: false,\n reason: \"disabled\",\n statePath,\n snapshot: null,\n };\n }\n\n const now = options.now ?? new Date();\n const updatedAt = now.toISOString();\n const windowDays = coerceLearningWindowDays(options.learningWindowDays);\n const minEventCount = coerceMinEventCount(options.minEventCount);\n const maxWeightMagnitude = coerceMaxWeightMagnitude(options.maxWeightMagnitude);\n const recentEvents = selectRecentEvents(\n (\n await readUtilityTelemetryEvents({\n memoryDir: options.memoryDir,\n utilityTelemetryDir: options.utilityTelemetryDir,\n })\n ).events,\n now,\n windowDays,\n );\n\n const grouped = new Map<string, UtilityTelemetryEvent[]>();\n for (const event of recentEvents) {\n const key = `${event.target}:${event.decision}`;\n const existing = grouped.get(key);\n if (existing) {\n existing.push(event);\n } else {\n grouped.set(key, [event]);\n }\n }\n\n const weights: UtilityLearningWeight[] = [];\n for (const events of grouped.values()) {\n if (events.length < minEventCount) continue;\n const target = events[0].target;\n const decision = events[0].decision;\n const averageUtilityScore = events.reduce((sum, event) => sum + event.utilityScore, 0) / events.length;\n const confidence = confidenceFromEvents(events.length, averageUtilityScore);\n const learnedWeight = roundWeight(\n clampWeight(averageUtilityScore * confidence, maxWeightMagnitude),\n );\n weights.push({\n target,\n decision,\n eventCount: events.length,\n learnedWeight,\n averageUtilityScore: roundWeight(averageUtilityScore),\n confidence,\n outcomeCounts: outcomeCountsFor(events),\n updatedAt,\n });\n }\n\n weights.sort((left, right) => {\n const targetCompare = left.target.localeCompare(right.target);\n if (targetCompare !== 0) return targetCompare;\n return left.decision.localeCompare(right.decision);\n });\n\n const snapshot: UtilityLearningSnapshot = {\n version: 1,\n updatedAt,\n windowDays,\n minEventCount,\n maxWeightMagnitude,\n weights,\n };\n\n if (weights.length === 0) {\n await writeUtilityLearningSnapshot(statePath, snapshot);\n return {\n applied: false,\n reason: \"insufficient_events\",\n statePath,\n snapshot,\n };\n }\n\n await writeUtilityLearningSnapshot(statePath, snapshot);\n return {\n applied: true,\n reason: \"learned\",\n statePath,\n snapshot,\n };\n}\n\nexport async function getUtilityLearningStatus(options: {\n memoryDir: string;\n utilityTelemetryDir?: string;\n enabled: boolean;\n promotionByOutcomeEnabled?: boolean;\n}): Promise<UtilityLearningStatus> {\n const rootDir = resolveUtilityTelemetryDir(options.memoryDir, options.utilityTelemetryDir);\n const statePath = resolveUtilityLearningStatePath(options.memoryDir, options.utilityTelemetryDir);\n if (!options.enabled) {\n return {\n enabled: false,\n promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,\n rootDir,\n statePath,\n snapshot: null,\n weights: {\n total: 0,\n positive: 0,\n negative: 0,\n zero: 0,\n },\n };\n }\n\n const snapshot = await readUtilityLearningSnapshot(options.memoryDir, options.utilityTelemetryDir);\n const weights = snapshot?.weights ?? [];\n return {\n enabled: true,\n promotionByOutcomeEnabled: options.promotionByOutcomeEnabled === true,\n rootDir,\n statePath,\n snapshot,\n weights: {\n total: weights.length,\n positive: weights.filter((entry) => entry.learnedWeight > 0).length,\n negative: weights.filter((entry) => entry.learnedWeight < 0).length,\n zero: weights.filter((entry) => entry.learnedWeight === 0).length,\n latestUpdatedAt: snapshot?.updatedAt,\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CodexAdapter
|
|
3
|
+
} from "./chunk-RSUYKGGZ.js";
|
|
1
4
|
import {
|
|
2
5
|
HermesAdapter
|
|
3
6
|
} from "./chunk-42NQ7AVG.js";
|
|
@@ -7,9 +10,6 @@ import {
|
|
|
7
10
|
import {
|
|
8
11
|
ClaudeCodeAdapter
|
|
9
12
|
} from "./chunk-J64TK33U.js";
|
|
10
|
-
import {
|
|
11
|
-
CodexAdapter
|
|
12
|
-
} from "./chunk-RSUYKGGZ.js";
|
|
13
13
|
|
|
14
14
|
// src/adapters/registry.ts
|
|
15
15
|
var AdapterRegistry = class {
|
|
@@ -53,4 +53,4 @@ var AdapterRegistry = class {
|
|
|
53
53
|
export {
|
|
54
54
|
AdapterRegistry
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-2QSZNTDO.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isTemporalQuery,
|
|
3
3
|
recencyWindowBoundsFromPrompt
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MGN7VHWQ.js";
|
|
5
5
|
import {
|
|
6
6
|
isAbortError
|
|
7
7
|
} from "./chunk-PVGDJXVK.js";
|
|
@@ -406,4 +406,4 @@ export {
|
|
|
406
406
|
augmentWithDirectAndTemporal,
|
|
407
407
|
parallelRetrieval
|
|
408
408
|
};
|
|
409
|
-
//# sourceMappingURL=chunk-
|
|
409
|
+
//# sourceMappingURL=chunk-2ROPI5OE.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gatewayTaskChainOptions
|
|
3
|
+
} from "./chunk-DEVUWMME.js";
|
|
1
4
|
import {
|
|
2
5
|
extractJsonCandidates
|
|
3
6
|
} from "./chunk-UZB5KHKX.js";
|
|
@@ -348,7 +351,7 @@ async function callJudgeLlm(userPrompt, config, localLlm, fallbackLlm) {
|
|
|
348
351
|
];
|
|
349
352
|
const modelOverride = config.extractionJudgeModel || void 0;
|
|
350
353
|
const skipLocal = config.modelSource === "gateway";
|
|
351
|
-
const
|
|
354
|
+
const gatewayChain = gatewayTaskChainOptions(config);
|
|
352
355
|
if (localLlm && !skipLocal) {
|
|
353
356
|
try {
|
|
354
357
|
const result = await localLlm.chatCompletion(messages, {
|
|
@@ -377,7 +380,7 @@ async function callJudgeLlm(userPrompt, config, localLlm, fallbackLlm) {
|
|
|
377
380
|
maxTokens: 2048,
|
|
378
381
|
timeoutMs: 1500,
|
|
379
382
|
...modelOverride ? { model: modelOverride } : {},
|
|
380
|
-
...
|
|
383
|
+
...gatewayChain
|
|
381
384
|
}
|
|
382
385
|
);
|
|
383
386
|
if (result?.content) {
|
|
@@ -483,4 +486,4 @@ export {
|
|
|
483
486
|
createVerdictCache,
|
|
484
487
|
createDeferCountMap
|
|
485
488
|
};
|
|
486
|
-
//# sourceMappingURL=chunk-
|
|
489
|
+
//# sourceMappingURL=chunk-2SGJY2UY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/extraction-judge.ts"],"sourcesContent":["/**\n * Extraction Judge — LLM-as-judge fact-worthiness gate (issue #376).\n *\n * Evaluates extracted facts against a durability rubric before they are\n * persisted. Facts that are unlikely to be useful 30+ days from now or\n * across sessions are rejected (or shadow-logged depending on config).\n *\n * Design constraints:\n * - Corrections and principles are auto-approved (safety bypass).\n * - Critical-importance facts are auto-approved.\n * - Batches respect extractionJudgeBatchSize.\n * - Content-hash caching avoids redundant LLM calls.\n * - Performance budget: <= 1.5s per batch.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { log } from \"./logger.js\";\nimport type { PluginConfig, ImportanceLevel } from \"./types.js\";\nimport type { LocalLlmClient } from \"./local-llm.js\";\nimport { type FallbackLlmClient, gatewayTaskChainOptions } from \"./fallback-llm.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport { normalizeProcedureSteps } from \"./procedural/procedure-types.js\";\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\nexport interface JudgeCandidate {\n text: string;\n category: string;\n confidence: number;\n tags?: string[];\n /** Local importance level, set by caller before judging. */\n importanceLevel?: ImportanceLevel;\n}\n\n/**\n * Verdict kinds (issue #562, PR 1).\n *\n * - `\"accept\"`: fact is durable, persist it.\n * - `\"reject\"`: fact is not durable, drop it.\n * - `\"defer\"`: fact is ambiguous; push it back into the buffer for another\n * pass with fresh context. Inspired by MemReader (arxiv 2604.07877).\n *\n * PR 1 only introduces the type. No emit path produces `\"defer\"` yet — the\n * defer-capable prompt, buffer re-routing, telemetry, and GRPO data\n * collection are landing in PRs 2, 3, and 4 respectively.\n */\nexport type JudgeVerdictKind = \"accept\" | \"reject\" | \"defer\";\n\n/**\n * Judge verdict shape.\n *\n * Back-compat note: `kind` is optional. Verdicts serialized before PR 1\n * (both in-memory cache entries and any persisted caches) only carry\n * `{ durable, reason }`. Downstream consumers must either read `durable`\n * directly, or use {@link getVerdictKind} / {@link isDurableVerdict} which\n * gracefully fall back to the boolean when `kind` is missing, and ignore\n * unknown future `kind` values rather than crashing.\n */\nexport interface JudgeVerdict {\n /**\n * True iff the fact should be persisted. For `\"defer\"` verdicts this is\n * `false` — a deferred fact is not (yet) persisted, so callers that only\n * look at `durable` will treat defer as \"skip this turn\", which matches\n * the pre-PR-1 fail-closed behavior for non-accepted verdicts.\n */\n durable: boolean;\n reason: string;\n /**\n * Optional explicit verdict kind. Added in PR 1 of issue #562. Legacy\n * verdicts (including cache entries produced before this field existed)\n * do not set `kind`; use {@link getVerdictKind} to read this safely.\n */\n kind?: JudgeVerdictKind;\n}\n\n/**\n * Resolve a verdict's effective kind.\n *\n * - If `kind` is explicitly set to one of the known values, return it.\n * - If `kind` is absent, infer from `durable` (back-compat with pre-PR-1\n * cache entries and emit paths that have not been updated yet).\n * - If `kind` is set to an unrecognised value (forward-compat, e.g. a\n * future cache entry loaded by an older build), fall back to `durable`\n * so we never crash on unknown strings.\n */\nexport function getVerdictKind(verdict: JudgeVerdict): JudgeVerdictKind {\n const raw = verdict.kind;\n if (raw === \"accept\" || raw === \"reject\" || raw === \"defer\") {\n return raw;\n }\n return verdict.durable ? \"accept\" : \"reject\";\n}\n\n/**\n * Type guard: returns `true` only for verdicts that should be persisted.\n * Treats both `\"reject\"` and `\"defer\"` as \"not durable\" — defer means the\n * caller should re-evaluate later, not write now.\n */\nexport function isDurableVerdict(verdict: JudgeVerdict): boolean {\n return getVerdictKind(verdict) === \"accept\";\n}\n\n/**\n * Validate a cache entry loaded from persistence / another process.\n *\n * Strict: accepts legacy `{ durable, reason }` entries and new entries\n * whose `kind` is one of the three known `JudgeVerdictKind` values.\n * Rejects structurally wrong types and unknown `kind` strings so the\n * type-guard narrowing is sound — callers that receive\n * `value is JudgeVerdict` can safely treat `kind` as the declared\n * union.\n *\n * Forward-compat is handled by {@link normalizeCachedVerdict}, which\n * drops unknown `kind` strings before validation so a newer build's\n * cache entry still loads instead of being rejected.\n */\nexport function isValidCachedVerdict(value: unknown): value is JudgeVerdict {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n if (typeof v.durable !== \"boolean\") return false;\n if (typeof v.reason !== \"string\") return false;\n if (v.kind !== undefined) {\n if (v.kind !== \"accept\" && v.kind !== \"reject\" && v.kind !== \"defer\") {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Forward-compatible cache-entry loader.\n *\n * Drops unknown `kind` strings to `undefined` (so `getVerdictKind` can\n * fall back to `durable`), then validates structurally. Non-string\n * `kind` values are still treated as structural violations and rejected.\n * Returns the sanitised verdict, or `null` when the entry is structurally\n * unusable.\n */\nexport function normalizeCachedVerdict(value: unknown): JudgeVerdict | null {\n if (typeof value !== \"object\" || value === null) return null;\n const v = value as Record<string, unknown>;\n if (typeof v.durable !== \"boolean\") return null;\n if (typeof v.reason !== \"string\") return null;\n let kind: JudgeVerdictKind | undefined;\n if (v.kind !== undefined) {\n if (typeof v.kind !== \"string\") return null;\n if (v.kind === \"accept\" || v.kind === \"reject\" || v.kind === \"defer\") {\n kind = v.kind;\n }\n // Unknown string `kind`: dropped to undefined for forward-compat.\n }\n const out: JudgeVerdict = { durable: v.durable, reason: v.reason };\n if (kind !== undefined) out.kind = kind;\n return out;\n}\n\nexport interface JudgeBatchResult {\n verdicts: Map<number, JudgeVerdict>;\n /** Number of verdicts served from cache. */\n cached: number;\n /** Number of verdicts produced by an LLM call. */\n judged: number;\n /** Total wall-clock time in milliseconds. */\n elapsed: number;\n /**\n * Number of verdicts in this batch that resolved to `\"defer\"` (issue #562,\n * PR 2). Callers can use this to decide whether to retain buffer turns for\n * the next extraction pass.\n */\n deferred: number;\n /**\n * Number of defers that were forcibly converted to `\"reject\"` because the\n * same candidate text had already been deferred at least\n * `extractionJudgeMaxDeferrals` times. Rolled out of `deferred` — a\n * candidate counted here is *not* also in `deferred`.\n */\n deferredCappedToReject: number;\n}\n\n/**\n * Per-verdict observation emitted by `judgeFactDurability` when an\n * `onVerdict` callback is supplied (issue #562, PR 3). Used to wire the\n * observation ledger / telemetry stream without coupling the judge module\n * directly to filesystem I/O. One event is emitted for every resolved\n * verdict, including auto-approved and cache-hit paths.\n */\nexport interface JudgeVerdictObservation {\n verdict: JudgeVerdict;\n /** The original `JudgeCandidate` passed in (same reference). */\n candidate: JudgeCandidate;\n /** SHA-256 of `text\\0category`, same key the cache/deferCounter use. */\n contentHash: string;\n /** Verdict resolution path. Useful for debugging + dashboards. */\n source: \"auto-approve\" | \"cache\" | \"llm\" | \"llm-cap-rejected\" | \"fail-open\";\n /**\n * How many times this candidate had already been deferred before this\n * verdict resolved. 0 when the candidate had never been deferred.\n */\n priorDeferrals: number;\n /**\n * Milliseconds from batch start to now. Shared across verdicts emitted in\n * the same batch.\n */\n elapsedMs: number;\n}\n\n// ---------------------------------------------------------------------------\n// Prompt (embedded; mirrors prompts/extraction_judge.prompt.md)\n// ---------------------------------------------------------------------------\n\nconst JUDGE_SYSTEM_PROMPT = `You are a memory curator evaluating whether extracted facts are **durable** — worth storing for long-term recall across sessions.\n\nA fact is **durable** if it will still be useful 30+ days from now and is relevant across multiple sessions, not just the current task.\n\nReturn one of three verdicts per candidate:\n\nACCEPT — the fact is durable, persist it:\n- Personal preferences, identities, or relationships\n- Decisions with rationale that affect future work\n- Corrections to previously held beliefs\n- Principles, rules, or constraints the user wants respected\n- Stable facts about projects, tools, or workflows\n- Commitments, deadlines, or obligations\n\nREJECT — the fact is not durable, drop it:\n- Transient task details (\"currently debugging line 42\")\n- Ephemeral state (\"the build is running now\")\n- Routine operations (\"ran npm install\")\n- Conversational filler or acknowledgements\n- Information that will be stale within hours\n- Step-by-step instructions for a one-time task\n\nDEFER — the fact MIGHT be durable but needs more context to decide. The candidate will be re-evaluated on a later extraction pass with fresh context; if it cannot be resolved within a small number of re-evaluations it will be rejected.\n- Ambiguous referents (\"he said they'd follow up on it\")\n- Partial or in-progress statements that might become durable once completed\n- Future-tense commitments whose subject or timeline is unclear\n- Facts whose durability hinges on context not present in the candidate text\n\nDo NOT use defer as a soft reject. Reject facts you are confident are transient. Only defer when another turn of context would genuinely change the verdict.\n\nReturn a JSON array of objects with these fields:\n- index: number (the candidate index)\n- kind: string — one of \"accept\", \"reject\", \"defer\"\n- reason: string (brief explanation, under 80 characters)\n\nYou may also include durable (boolean) for backwards compatibility: true for accept, false for reject or defer. If kind is omitted, durable determines the verdict.\n\nRules:\n1. Return exactly one verdict per input candidate, matched by index.\n2. When in doubt between accept and reject, lean toward accept — false negatives (losing a useful fact) are worse than false positives (keeping a marginal one).\n3. Use defer only when another turn of context would genuinely change the verdict.\n4. Output valid JSON only. No markdown fences, no commentary.\n\nExample output:\n[{\"index\": 0, \"kind\": \"accept\", \"durable\": true, \"reason\": \"Stable personal preference\"}, {\"index\": 1, \"kind\": \"reject\", \"durable\": false, \"reason\": \"Ephemeral build status\"}, {\"index\": 2, \"kind\": \"defer\", \"durable\": false, \"reason\": \"Ambiguous pronoun\"}]`;\n\n// ---------------------------------------------------------------------------\n// Content-hash cache (in-memory, per-process fallback)\n// ---------------------------------------------------------------------------\n\n/** Maximum entries before evicting the oldest half. */\nconst VERDICT_CACHE_MAX_SIZE = 10_000;\n\n/** Module-level fallback cache, used when callers do not pass their own. */\nconst defaultVerdictCache = new Map<string, JudgeVerdict>();\n\n/**\n * Per-content-hash deferral counter (issue #562, PR 2).\n *\n * When the judge emits a `\"defer\"` verdict for a candidate whose content\n * has already been deferred `extractionJudgeMaxDeferrals` times, the verdict\n * is forcibly converted to `\"reject\"` so a pathological LLM response cannot\n * produce an infinite defer loop.\n *\n * Module-level with a size cap so stale test state cannot leak between runs\n * in the unlikely case a caller does not clear it between processes.\n */\nconst defaultDeferCounts = new Map<string, number>();\nconst DEFER_COUNT_MAX_SIZE = 20_000;\n\nfunction cacheKey(text: string, category: string): string {\n return createHash(\"sha256\").update(`${text}\\0${category}`).digest(\"hex\");\n}\n\n/**\n * Resolve the effective defer cap from config, defaulting to 2 when the\n * config value is missing or non-positive. Matches the PR 2 spec.\n */\nfunction resolveDeferCap(config: PluginConfig): number {\n const raw = (config as { extractionJudgeMaxDeferrals?: number })\n .extractionJudgeMaxDeferrals;\n if (typeof raw === \"number\" && Number.isFinite(raw) && raw >= 1) {\n return Math.floor(raw);\n }\n return 2;\n}\n\n/**\n * Enforce the max-size invariant on a verdict cache. When the cache exceeds\n * VERDICT_CACHE_MAX_SIZE, the oldest half of entries are deleted (Map\n * iteration order is insertion order).\n */\nfunction enforceMaxCacheSize(cache: Map<string, JudgeVerdict>): void {\n if (cache.size <= VERDICT_CACHE_MAX_SIZE) return;\n const deleteCount = Math.floor(cache.size / 2);\n let deleted = 0;\n for (const key of cache.keys()) {\n if (deleted >= deleteCount) break;\n cache.delete(key);\n deleted++;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Categories that bypass the judge (safety / correctness)\n// ---------------------------------------------------------------------------\n\nconst AUTO_APPROVE_CATEGORIES = new Set([\"correction\", \"principle\"]);\n\n/** Explicit trigger phrasing — procedures must match to persist (issue #519). */\nconst PROCEDURE_TRIGGER_RE =\n /(when you|whenever|before you|before running|always\\s|first\\b.*\\bthen|to deploy|to ship|run these steps|follow these steps|how (i|we)\\s|recipe for|workflow|each time you)/i;\n\n/**\n * Deterministic gate for extracted `procedure` memories: ≥2 steps with non-empty\n * intents and explicit trigger wording in title and/or steps.\n */\nexport function validateProcedureExtraction(input: {\n content: string;\n procedureSteps?: unknown;\n}): JudgeVerdict {\n const steps = normalizeProcedureSteps(input.procedureSteps);\n if (steps.length < 2) {\n return { durable: false, reason: \"Procedure requires at least two steps with intents\" };\n }\n const combined = [input.content, ...steps.map((s) => s.intent)].join(\" \").toLowerCase();\n if (!PROCEDURE_TRIGGER_RE.test(combined)) {\n return { durable: false, reason: \"Procedure missing explicit trigger phrasing\" };\n }\n return { durable: true, reason: \"Procedure structure validated\" };\n}\n\n// ---------------------------------------------------------------------------\n// Core judge function\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate a batch of candidate facts for durability.\n *\n * Auto-approves corrections, principles, and critical-importance facts.\n * Remaining candidates are batched (up to extractionJudgeBatchSize),\n * checked against an in-memory content-hash cache, and sent to the LLM\n * for verdict.\n */\nexport async function judgeFactDurability(\n candidates: JudgeCandidate[],\n config: PluginConfig,\n localLlm: LocalLlmClient | null,\n fallbackLlm: FallbackLlmClient | null,\n cache?: Map<string, JudgeVerdict>,\n deferCounts?: Map<string, number>,\n onVerdict?: (observation: JudgeVerdictObservation) => void,\n): Promise<JudgeBatchResult> {\n const startMs = Date.now();\n const verdicts = new Map<number, JudgeVerdict>();\n let cached = 0;\n let judged = 0;\n let deferred = 0;\n let deferredCappedToReject = 0;\n\n // Use caller-provided cache for per-orchestrator scoping, or fall back\n // to the module-level default cache.\n const verdictCache = cache ?? defaultVerdictCache;\n const deferCountMap = deferCounts ?? defaultDeferCounts;\n const deferCap = resolveDeferCap(config);\n\n // Lazy emit (Codex P2): when `onVerdict` is undefined (default path —\n // telemetry off), payload construction is skipped entirely. Callers\n // pass a factory instead of a pre-built observation so the `sha256`\n // `contentHash` and surrounding object allocation only run when a\n // subscriber is present. For large batches with telemetry off this\n // removes per-verdict overhead that would otherwise fire on every\n // auto-approved / cache / fail-open path.\n const emit = (build: () => JudgeVerdictObservation): void => {\n if (!onVerdict) return;\n let observation: JudgeVerdictObservation;\n try {\n observation = build();\n } catch (err) {\n log.debug(\n `extraction-judge: onVerdict builder threw (non-fatal): ${err instanceof Error ? err.message : String(err)}`,\n );\n return;\n }\n try {\n onVerdict(observation);\n } catch (err) {\n // Fail-open: telemetry errors must never block extraction.\n log.debug(\n `extraction-judge: onVerdict callback threw (non-fatal): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n };\n\n if (candidates.length === 0) {\n return {\n verdicts,\n cached,\n judged,\n elapsed: 0,\n deferred,\n deferredCappedToReject,\n };\n }\n\n // Indices that need LLM judgment\n const pendingIndices: number[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const c = candidates[i];\n\n // Auto-approve safety categories\n if (AUTO_APPROVE_CATEGORIES.has(c.category)) {\n const v: JudgeVerdict = {\n durable: true,\n reason: `Auto-approved: ${c.category} category bypasses judge`,\n };\n verdicts.set(i, v);\n emit(() => ({\n verdict: v,\n candidate: c,\n contentHash: cacheKey(c.text, c.category),\n source: \"auto-approve\",\n priorDeferrals: 0,\n elapsedMs: Date.now() - startMs,\n }));\n continue;\n }\n\n // Auto-approve critical importance\n if (c.importanceLevel === \"critical\") {\n const v: JudgeVerdict = {\n durable: true,\n reason: \"Auto-approved: critical importance\",\n };\n verdicts.set(i, v);\n emit(() => ({\n verdict: v,\n candidate: c,\n contentHash: cacheKey(c.text, c.category),\n source: \"auto-approve\",\n priorDeferrals: 0,\n elapsedMs: Date.now() - startMs,\n }));\n continue;\n }\n\n // Check cache\n const key = cacheKey(c.text, c.category);\n const cachedVerdict = verdictCache.get(key);\n if (cachedVerdict) {\n verdicts.set(i, cachedVerdict);\n cached++;\n emit(() => ({\n verdict: cachedVerdict,\n candidate: c,\n contentHash: key,\n source: \"cache\",\n priorDeferrals: deferCountMap.get(key) ?? 0,\n elapsedMs: Date.now() - startMs,\n }));\n continue;\n }\n\n pendingIndices.push(i);\n }\n\n // If all resolved without LLM, return early\n if (pendingIndices.length === 0) {\n return {\n verdicts,\n cached,\n judged,\n elapsed: Date.now() - startMs,\n deferred,\n deferredCappedToReject,\n };\n }\n\n // Batch the pending candidates up to batchSize\n const batchSize = config.extractionJudgeBatchSize;\n for (let batchStart = 0; batchStart < pendingIndices.length; batchStart += batchSize) {\n const batchIndices = pendingIndices.slice(batchStart, batchStart + batchSize);\n const batchPayload = batchIndices.map((idx) => ({\n index: idx,\n text: candidates[idx].text,\n category: candidates[idx].category,\n confidence: candidates[idx].confidence,\n }));\n\n const userPrompt = JSON.stringify(batchPayload);\n\n try {\n const llmResponse = await callJudgeLlm(\n userPrompt,\n config,\n localLlm,\n fallbackLlm,\n );\n\n if (llmResponse) {\n const parsed = parseJudgeResponse(llmResponse, batchIndices);\n // Per-batch defer-increment dedupe (codex P2): a single extraction\n // pass must not advance the cap more than once for identical\n // candidate content, even if the same text appears multiple times\n // in the same LLM response. Duplicate hits share the first\n // increment's `priorDeferrals` snapshot.\n const deferredThisBatch = new Set<string>();\n for (const [idx, rawVerdict] of parsed.entries()) {\n const c = candidates[idx];\n const key = cacheKey(c.text, c.category);\n let verdict = rawVerdict;\n let source: JudgeVerdictObservation[\"source\"] = \"llm\";\n const priorDefers = deferCountMap.get(key) ?? 0;\n\n // Defer cap (issue #562, PR 2). A candidate that has already been\n // deferred `deferCap` times is forcibly rejected so a pathological\n // LLM response cannot produce an infinite defer loop.\n if (getVerdictKind(verdict) === \"defer\") {\n if (priorDefers >= deferCap) {\n verdict = {\n durable: false,\n reason: `Defer cap reached (${deferCap} prior defers); rejecting`,\n kind: \"reject\",\n };\n source = \"llm-cap-rejected\";\n // Only clear + count the cap conversion once per batch for\n // this key — duplicates in the same response all resolve to\n // reject but should not inflate the cap-rejection counter.\n if (!deferredThisBatch.has(key)) {\n deferCountMap.delete(key);\n deferredCappedToReject++;\n deferredThisBatch.add(key);\n }\n } else if (!deferredThisBatch.has(key)) {\n deferCountMap.set(key, priorDefers + 1);\n deferred++;\n deferredThisBatch.add(key);\n // Bound the per-process defer-counter map.\n if (deferCountMap.size > DEFER_COUNT_MAX_SIZE) {\n const drop = Math.floor(deferCountMap.size / 2);\n let dropped = 0;\n for (const k of deferCountMap.keys()) {\n if (dropped >= drop) break;\n deferCountMap.delete(k);\n dropped++;\n }\n }\n }\n // else: duplicate defer for a key already counted this batch —\n // no additional counter increment, verdict still marked defer.\n } else {\n // On accept/reject, clear any outstanding defer counter so a\n // future reappearance of the same text starts fresh.\n deferCountMap.delete(key);\n }\n\n verdicts.set(idx, verdict);\n judged++;\n // Cache non-defer verdicts. Defer is intentionally NOT cached:\n // caching it would short-circuit the re-evaluation pass that is\n // the entire point of the defer verdict.\n if (getVerdictKind(verdict) !== \"defer\") {\n verdictCache.set(key, verdict);\n }\n emit(() => ({\n verdict,\n candidate: c,\n contentHash: key,\n source,\n priorDeferrals: priorDefers,\n elapsedMs: Date.now() - startMs,\n }));\n }\n // Evict oldest entries if cache exceeds max size\n enforceMaxCacheSize(verdictCache);\n }\n } catch (err) {\n // Fail-open: if the LLM call fails, approve all candidates in this batch\n log.warn(\n `extraction-judge: LLM call failed, approving batch (fail-open): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n // Fill in any missing verdicts from this batch (fail-open: approve).\n // Clear defer counts so a transient outage doesn't leave stale state\n // that causes later defers to hit the cap early.\n for (const idx of batchIndices) {\n if (!verdicts.has(idx)) {\n const c = candidates[idx];\n const hash = cacheKey(c.text, c.category);\n // Capture the prior deferral count BEFORE clearing so the\n // telemetry event reflects the true state rather than always 0.\n const priorDefers = deferCountMap.get(hash) ?? 0;\n deferCountMap.delete(hash);\n const v: JudgeVerdict = {\n durable: true,\n reason: \"Approved by default (judge unavailable or parse error)\",\n };\n verdicts.set(idx, v);\n emit(() => {\n return {\n verdict: v,\n candidate: c,\n contentHash: hash,\n source: \"fail-open\",\n priorDeferrals: priorDefers,\n elapsedMs: Date.now() - startMs,\n };\n });\n }\n }\n }\n\n return {\n verdicts,\n cached,\n judged,\n elapsed: Date.now() - startMs,\n deferred,\n deferredCappedToReject,\n };\n}\n\n// ---------------------------------------------------------------------------\n// LLM call helpers\n// ---------------------------------------------------------------------------\n\nasync function callJudgeLlm(\n userPrompt: string,\n config: PluginConfig,\n localLlm: LocalLlmClient | null,\n fallbackLlm: FallbackLlmClient | null,\n): Promise<string | null> {\n const messages: Array<{ role: \"system\" | \"user\"; content: string }> = [\n { role: \"system\", content: JUDGE_SYSTEM_PROMPT },\n { role: \"user\", content: userPrompt },\n ];\n\n const modelOverride = config.extractionJudgeModel || undefined;\n\n // When modelSource is \"gateway\", skip localLlm and go directly to fallback\n // (the gateway-routed backend). This respects the operator's explicit\n // routing preference.\n const skipLocal = config.modelSource === \"gateway\";\n\n // Route judge-gated extractions through the SAME shared resolution as every\n // other background task (taskModelChain > gatewayAgentId in gateway mode), so\n // the judge never silently falls back to the persona/default chain when a\n // task chain is configured (gotcha #22, #39). Issue #1365 / PR #1425.\n const gatewayChain = gatewayTaskChainOptions(config);\n\n // Try local LLM first (unless modelSource says gateway)\n if (localLlm && !skipLocal) {\n try {\n const result = await (localLlm as any).chatCompletion(messages, {\n temperature: 0.1,\n maxTokens: 2048,\n responseFormat: { type: \"json_object\" },\n timeoutMs: 1500,\n operation: \"extraction-judge\",\n ...(modelOverride ? { model: modelOverride } : {}),\n });\n if (result?.content) {\n return result.content;\n }\n } catch (err) {\n log.debug(\n `extraction-judge: local LLM failed, trying fallback: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Try fallback LLM\n if (fallbackLlm) {\n try {\n const result = await fallbackLlm.chatCompletion(\n messages as Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n {\n temperature: 0.1,\n maxTokens: 2048,\n timeoutMs: 1500,\n ...(modelOverride ? { model: modelOverride } : {}),\n ...gatewayChain,\n },\n );\n if (result?.content) {\n return result.content;\n }\n } catch (err) {\n log.debug(\n `extraction-judge: fallback LLM failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Response parsing\n// ---------------------------------------------------------------------------\n\nfunction parseJudgeResponse(\n raw: string,\n expectedIndices: number[],\n): Map<number, JudgeVerdict> {\n const result = new Map<number, JudgeVerdict>();\n const expectedSet = new Set(expectedIndices);\n\n try {\n // Try direct parse first, then fall back to JSON extraction\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n const candidates = extractJsonCandidates(raw);\n if (candidates.length > 0) {\n parsed = JSON.parse(candidates[0]);\n }\n }\n\n if (!Array.isArray(parsed)) {\n // Might be wrapped in an object with a key\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const values = Object.values(parsed as Record<string, unknown>);\n for (const v of values) {\n if (Array.isArray(v)) {\n parsed = v;\n break;\n }\n }\n }\n if (!Array.isArray(parsed)) {\n log.debug(\"extraction-judge: response is not an array, cannot parse\");\n return result;\n }\n }\n\n for (const item of parsed) {\n if (\n typeof item !== \"object\" ||\n item === null ||\n typeof (item as any).index !== \"number\"\n ) {\n continue;\n }\n const idx = (item as any).index as number;\n if (!expectedSet.has(idx)) continue;\n\n // Parse kind first — it's the primary signal in PR 2 and above.\n // Fall back to durable for pre-PR-2 model responses that only return\n // the boolean.\n let kind: JudgeVerdictKind | undefined;\n const rawKind = (item as any).kind;\n const rawAction = (item as any).action;\n if (rawKind === \"accept\" || rawKind === \"reject\" || rawKind === \"defer\") {\n kind = rawKind;\n } else if (\n rawAction === \"accept\" ||\n rawAction === \"reject\" ||\n rawAction === \"defer\"\n ) {\n // Tolerate `action` as an alias — MemReader uses that word in the\n // paper and models may echo it.\n kind = rawAction;\n }\n\n const hasDurable = typeof (item as any).durable === \"boolean\";\n const durableFromModel = hasDurable\n ? ((item as any).durable as boolean)\n : undefined;\n\n // Resolve the durable flag from kind when present; otherwise trust\n // the model's boolean; otherwise fail-open to durable=true.\n let durable: boolean;\n if (kind === \"accept\") {\n durable = true;\n } else if (kind === \"reject\" || kind === \"defer\") {\n durable = false;\n } else if (durableFromModel !== undefined) {\n durable = durableFromModel;\n } else {\n durable = true; // fail-open\n }\n\n const reason =\n typeof (item as any).reason === \"string\"\n ? ((item as any).reason as string).slice(0, 120)\n : \"No reason provided\";\n\n const verdict: JudgeVerdict = { durable, reason };\n if (kind !== undefined) verdict.kind = kind;\n result.set(idx, verdict);\n }\n } catch (err) {\n log.debug(\n `extraction-judge: failed to parse response: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Cache management (exposed for testing)\n// ---------------------------------------------------------------------------\n\n/** Clear the in-memory default verdict cache. Primarily for tests. */\nexport function clearVerdictCache(): void {\n defaultVerdictCache.clear();\n defaultDeferCounts.clear();\n}\n\n/** Return the current default verdict cache size. Primarily for tests. */\nexport function verdictCacheSize(): number {\n return defaultVerdictCache.size;\n}\n\n/** Create a new per-instance verdict cache. Orchestrators should hold one. */\nexport function createVerdictCache(): Map<string, JudgeVerdict> {\n return new Map();\n}\n\n/**\n * Create a new per-instance defer-counter map. Orchestrators should hold one\n * alongside their verdict cache so defer counts survive across extraction\n * passes within a single orchestrator but do not leak across orchestrators.\n */\nexport function createDeferCountMap(): Map<string, number> {\n return new Map();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scanMemoryDir
|
|
3
|
+
} from "./chunk-Q4CAQGKQ.js";
|
|
1
4
|
import {
|
|
2
5
|
isSearchAborted,
|
|
3
6
|
throwIfSearchAborted
|
|
4
7
|
} from "./chunk-CINZGPSJ.js";
|
|
5
8
|
import {
|
|
6
|
-
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
resolveEnsureCollectionArgs
|
|
10
|
+
} from "./chunk-FAV25DUZ.js";
|
|
8
11
|
import {
|
|
9
12
|
log
|
|
10
13
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -236,9 +239,14 @@ var LanceDbBackend = class {
|
|
|
236
239
|
log.debug(`LanceDbBackend embed failed: ${err}`);
|
|
237
240
|
}
|
|
238
241
|
}
|
|
239
|
-
async ensureCollection(_memoryDir,
|
|
242
|
+
async ensureCollection(_memoryDir, collectionOrExecution, execution) {
|
|
243
|
+
const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(
|
|
244
|
+
collectionOrExecution,
|
|
245
|
+
execution
|
|
246
|
+
);
|
|
247
|
+
if (isSearchAborted(effectiveExecution)) return "skipped";
|
|
240
248
|
try {
|
|
241
|
-
await this.
|
|
249
|
+
await this.ensureTableForCollection(collection ?? this.collection);
|
|
242
250
|
return "present";
|
|
243
251
|
} catch {
|
|
244
252
|
return "missing";
|
|
@@ -483,4 +491,4 @@ function isMissingVectorProviderColumnError(err) {
|
|
|
483
491
|
export {
|
|
484
492
|
LanceDbBackend
|
|
485
493
|
};
|
|
486
|
-
//# sourceMappingURL=chunk-
|
|
494
|
+
//# sourceMappingURL=chunk-3MAONBX3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/search/lancedb-backend.ts"],"sourcesContent":["import { log } from \"../logger.js\";\nimport {\n resolveEnsureCollectionArgs,\n type SearchBackend,\n type SearchExecutionOptions,\n type SearchQueryOptions,\n type SearchResult,\n} from \"./port.js\";\nimport type { EmbedHelper, EmbedProviderIdentity, EmbedWithProviderResult } from \"./embed-helper.js\";\nimport { scanMemoryDir } from \"./document-scanner.js\";\nimport { isSearchAborted, throwIfSearchAborted } from \"./abort.js\";\n\nexport interface LanceDbBackendOptions {\n dbPath: string;\n collection: string;\n embedHelper: EmbedHelper;\n memoryDir: string;\n embeddingDimension: number;\n}\n\n/**\n * LanceDB search backend — embedded hybrid FTS+vector with RRF reranking.\n *\n * Uses @lancedb/lancedb for native Arrow-backed storage.\n * One table per collection. Supports full-text, vector, and hybrid search.\n */\nexport class LanceDbBackend implements SearchBackend {\n private readonly dbPath: string;\n private readonly collection: string;\n private readonly embedHelper: EmbedHelper;\n private readonly memoryDir: string;\n private readonly embeddingDimension: number;\n private available = false;\n private db: any = null;\n private lanceModule: any = null;\n private readonly vectorProviderCompatibility = new WeakMap<\n object,\n { providerIdentity: EmbedProviderIdentity; compatible: boolean }\n >();\n\n constructor(opts: LanceDbBackendOptions) {\n this.dbPath = opts.dbPath;\n this.collection = opts.collection;\n this.embedHelper = opts.embedHelper;\n this.memoryDir = opts.memoryDir;\n this.embeddingDimension = opts.embeddingDimension;\n }\n\n async probe(): Promise<boolean> {\n try {\n await this.ensureDb();\n this.available = true;\n return true;\n } catch (err) {\n log.debug(`LanceDbBackend probe failed: ${err}`);\n this.available = false;\n return false;\n }\n }\n\n isAvailable(): boolean {\n return this.available;\n }\n\n debugStatus(): string {\n return `backend=lancedb available=${this.available} dbPath=${this.dbPath}`;\n }\n\n async search(\n query: string,\n _collection?: string,\n maxResults?: number,\n _options?: SearchQueryOptions,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n return this.hybridSearch(query, _collection, maxResults, execution);\n }\n\n async searchGlobal(query: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n const limit = maxResults ?? 10;\n if (!this.available) return [];\n\n try {\n throwIfSearchAborted(execution, \"LanceDbBackend global search aborted\");\n const db = await this.ensureDb();\n const tableNames = await db.tableNames();\n const allResults: SearchResult[] = [];\n\n for (const name of tableNames) {\n throwIfSearchAborted(execution, \"LanceDbBackend global search aborted\");\n try {\n const table = await db.openTable(name);\n const results = await this.searchTable(table, query, \"hybrid\", limit, execution);\n allResults.push(...results);\n } catch {\n // Skip tables that fail\n }\n }\n\n allResults.sort((a, b) => b.score - a.score);\n return allResults.slice(0, limit);\n } catch (err) {\n log.debug(`LanceDbBackend searchGlobal failed: ${err}`);\n return [];\n }\n }\n\n async bm25Search(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"fts\", maxResults ?? 10, execution);\n }\n\n async vectorSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"vector\", maxResults ?? 10, execution);\n }\n\n async hybridSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const table = await this.ensureTableForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!table) return [];\n return this.searchTable(table, query, \"hybrid\", maxResults ?? 10, execution);\n }\n\n async update(execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollection(this.collection, execution);\n }\n\n async updateCollection(collection: string, execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollectionFromDir(collection, this.memoryDir, execution);\n }\n\n async updateCollectionFromDir(collection: string, memoryDir: string, execution?: SearchExecutionOptions): Promise<void> {\n if (isSearchAborted(execution)) return;\n let table = await this.ensureTableForCollection(collection);\n if (isSearchAborted(execution)) return;\n if (!table) return;\n\n const docs = await scanMemoryDir(memoryDir);\n if (isSearchAborted(execution)) return;\n if (docs.length === 0) {\n // Clear stale data when no docs remain\n try {\n const db = await this.ensureDb();\n await db.dropTable(collection).catch(() => {});\n if (collection === this.collection) this.table = null;\n } catch {\n // Best-effort cleanup\n }\n return;\n }\n\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n const existingVectors = new Map<string, {\n vector: number[];\n providerIdentity?: string;\n }>();\n const vectorProviderColumnState = await this.tableVectorProviderColumnState(table);\n if (vectorProviderColumnState === \"missing\") {\n table = await this.recreateTableForCollection(collection);\n if (isSearchAborted(execution)) return;\n if (!table) return;\n } else if (vectorProviderColumnState === \"present\") {\n try {\n const existingRows = await table.query().select([\"docid\", \"vector\", \"vectorProvider\"]).toArray();\n for (const row of existingRows ?? []) {\n if (isSearchAborted(execution)) return;\n const docid = row.docid;\n if (typeof docid !== \"string\") continue;\n const vector = row.vector;\n if (!vector || typeof vector !== \"object\") continue;\n existingVectors.set(docid, {\n vector: Array.from(vector as ArrayLike<number>),\n providerIdentity: typeof row.vectorProvider === \"string\" ? row.vectorProvider : undefined,\n });\n }\n } catch {\n log.debug(\"LanceDbBackend skipped refresh after vector preservation failed\");\n return;\n }\n } else {\n log.debug(\"LanceDbBackend skipped vector preservation after vectorProvider probe failed\");\n return;\n }\n\n const rows = docs.map((d) => {\n const existing = existingVectors.get(d.docid);\n const canPreserveVector =\n existing &&\n this.isCompatibleStoredVector(existing.vector) &&\n (!embeddingProviderIdentity ||\n existing.providerIdentity === embeddingProviderIdentity);\n return {\n docid: d.docid,\n path: d.path,\n content: d.content,\n snippet: d.snippet,\n vector: canPreserveVector\n ? existing.vector\n : new Array(this.embeddingDimension).fill(0),\n vectorProvider: canPreserveVector\n ? existing.providerIdentity ?? \"\"\n : \"\",\n };\n });\n\n try {\n if (isSearchAborted(execution)) return;\n await table.add(rows, { mode: \"overwrite\" });\n this.rememberVectorProviderCompatibility(\n table,\n embeddingProviderIdentity,\n rows.length > 0 && rows.every((row) => row.vectorProvider === embeddingProviderIdentity),\n );\n if (isSearchAborted(execution)) return;\n // Create FTS index on content column\n try {\n await table.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail on some platforms — degrade gracefully\n }\n if (collection === this.collection) this.table = table;\n } catch (err) {\n log.debug(`LanceDbBackend update failed: ${err}`);\n }\n }\n\n async embed(): Promise<void> {\n await this.embedCollection(this.collection);\n }\n\n async embedCollection(collection: string): Promise<void> {\n if (!this.embedHelper.isAvailable()) return;\n\n const table = await this.ensureTableForCollection(collection);\n if (!table) return;\n\n try {\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n const allRows = await table.query().select([\"docid\", \"content\", \"vector\", \"vectorProvider\"]).toArray();\n const needsEmbed = allRows.filter((row: any) => {\n if (embeddingProviderIdentity && row.vectorProvider !== embeddingProviderIdentity) {\n return true;\n }\n return !this.isCompatibleStoredVector(row.vector);\n });\n\n if (needsEmbed.length === 0) {\n this.rememberVectorProviderCompatibility(table, embeddingProviderIdentity, true);\n return;\n }\n\n let rowsToEmbed = needsEmbed;\n let embedResult = await this.embedHelper.embedBatchWithProvider(\n rowsToEmbed.map((row: any) => row.content as string),\n );\n if (!embedResult) return;\n if (\n embeddingProviderIdentity &&\n embedResult.providerIdentity !== embeddingProviderIdentity\n ) {\n const effectiveProviderIdentity = embedResult.providerIdentity;\n const originalDocids = new Set(rowsToEmbed.map((row: any) => row.docid));\n const effectiveNeedsEmbed = allRows.filter((row: any) => (\n row.vectorProvider !== effectiveProviderIdentity ||\n !this.isCompatibleStoredVector(row.vector)\n ));\n const sameRows =\n effectiveNeedsEmbed.length === rowsToEmbed.length &&\n effectiveNeedsEmbed.every((row: any) => originalDocids.has(row.docid));\n if (!sameRows) {\n const effectiveTexts = effectiveNeedsEmbed.map((row: any) => row.content as string);\n const effectiveEmbedResult = await this.embedHelper.embedBatchWithProvider(effectiveTexts);\n if (effectiveEmbedResult) {\n rowsToEmbed = effectiveNeedsEmbed;\n embedResult = effectiveEmbedResult;\n }\n }\n }\n const { vectors, providerIdentity } = embedResult;\n\n let allEmbedded = true;\n for (let i = 0; i < rowsToEmbed.length; i++) {\n const vec = vectors[i];\n if (!this.isExpectedDimensionVector(vec)) {\n allEmbedded = false;\n continue;\n }\n const docid = rowsToEmbed[i].docid;\n await table.update({\n where: `docid = '${docid.replace(/'/g, \"''\")}'`,\n values: { vector: vec, vectorProvider: providerIdentity },\n });\n }\n if (allEmbedded) {\n this.rememberVectorProviderCompatibility(table, providerIdentity, true);\n } else {\n this.rememberVectorProviderCompatibility(table, providerIdentity, false);\n }\n } catch (err) {\n log.debug(`LanceDbBackend embed failed: ${err}`);\n }\n }\n\n async ensureCollection(\n _memoryDir: string,\n collectionOrExecution?: string | SearchExecutionOptions,\n execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n const { collection, execution: effectiveExecution } = resolveEnsureCollectionArgs(\n collectionOrExecution,\n execution,\n );\n if (isSearchAborted(effectiveExecution)) return \"skipped\";\n try {\n await this.ensureTableForCollection(collection ?? this.collection);\n return \"present\";\n } catch {\n return \"missing\";\n }\n }\n\n private table: any = null;\n\n private get lanceIndex(): any {\n return this.lanceModule.Index ?? this.lanceModule.default?.Index;\n }\n\n private async ensureDb(): Promise<any> {\n if (this.db) return this.db;\n if (!this.lanceModule) {\n this.lanceModule = await import(\"@lancedb/lancedb\");\n }\n const connect = this.lanceModule.connect ?? this.lanceModule.default?.connect;\n this.db = await connect(this.dbPath);\n return this.db;\n }\n\n private async ensureTableForCollection(collection: string): Promise<any> {\n // For the default collection, use the cached instance\n if (collection === this.collection) return this.ensureTable();\n\n const db = await this.ensureDb();\n const tables = await db.tableNames();\n\n if (tables.includes(collection)) {\n return await db.openTable(collection);\n }\n\n // Create empty table with schema\n const emptyRow = {\n docid: \"__placeholder__\",\n path: \"\",\n content: \"\",\n snippet: \"\",\n vector: new Array(this.embeddingDimension).fill(0),\n vectorProvider: \"\",\n };\n const newTable = await db.createTable(collection, [emptyRow]);\n try {\n await newTable.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail — degrade gracefully\n }\n try {\n await newTable.delete(\"docid = '__placeholder__'\");\n } catch {\n // May fail if delete isn't supported on empty-ish tables\n }\n return newTable;\n }\n\n private async recreateTableForCollection(collection: string): Promise<any> {\n const db = await this.ensureDb();\n try {\n await db.dropTable(collection).catch(() => {});\n } catch {\n // Best-effort legacy schema migration; table creation below may still recover.\n }\n if (collection === this.collection) this.table = null;\n return this.ensureTableForCollection(collection);\n }\n\n private async tableVectorProviderColumnState(table: any): Promise<\"present\" | \"missing\" | \"unknown\"> {\n try {\n await table.query().select([\"vectorProvider\"]).toArray();\n return \"present\";\n } catch (err) {\n if (isMissingVectorProviderColumnError(err)) {\n return \"missing\";\n }\n log.debug(`LanceDbBackend vectorProvider column probe failed: ${err}`);\n return \"unknown\";\n }\n }\n\n private async ensureTable(): Promise<any> {\n if (this.table) return this.table;\n\n const db = await this.ensureDb();\n const tables = await db.tableNames();\n\n if (tables.includes(this.collection)) {\n this.table = await db.openTable(this.collection);\n return this.table;\n }\n\n // Create empty table with schema\n const emptyRow = {\n docid: \"__placeholder__\",\n path: \"\",\n content: \"\",\n snippet: \"\",\n vector: new Array(this.embeddingDimension).fill(0),\n vectorProvider: \"\",\n };\n this.table = await db.createTable(this.collection, [emptyRow]);\n // Create FTS index on content column\n try {\n await this.table.createIndex(\"content\", { config: this.lanceIndex.fts() });\n } catch {\n // FTS index creation may fail — degrade gracefully\n }\n // Remove placeholder row\n try {\n await this.table.delete(\"docid = '__placeholder__'\");\n } catch {\n // May fail if delete isn't supported on empty-ish tables\n }\n return this.table;\n }\n\n private async searchTable(\n table: any,\n query: string,\n mode: \"fts\" | \"vector\" | \"hybrid\",\n limit: number,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n try {\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (mode === \"fts\") {\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n if (mode === \"vector\") {\n const embedResult = await this.resolveCompatibleQueryEmbedding(table, query, execution);\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (!embedResult) {\n // Fall back to FTS\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n const results = await table.search(embedResult.vector).limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n // hybrid — try FTS+vector with RRF reranking\n const embedResult = await this.resolveCompatibleQueryEmbedding(table, query, execution);\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n if (!embedResult) {\n const results = await table.search(query, \"fts\").limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n\n try {\n const results = await table\n .search(query, \"hybrid\")\n .vector(embedResult.vector)\n .limit(limit)\n .toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n } catch {\n // Hybrid may not be supported in all LanceDB versions — fall back to vector\n const results = await table.search(embedResult.vector).limit(limit).toArray();\n throwIfSearchAborted(execution, `LanceDbBackend ${mode} search aborted`);\n return this.mapRows(results);\n }\n } catch (err) {\n log.debug(`LanceDbBackend search (${mode}) failed: ${err}`);\n return [];\n }\n }\n\n private async resolveCompatibleQueryEmbedding(\n table: any,\n query: string,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedResult = await this.embedHelper.embedWithProvider(query, { signal: execution?.signal });\n throwIfSearchAborted(execution, \"LanceDbBackend query embedding aborted\");\n if (!embedResult || !this.isExpectedDimensionVector(embedResult.vector)) return null;\n\n const storedProviderIdentity = await this.findCompatibleStoredVectorProvider(table, execution);\n if (!storedProviderIdentity) {\n this.rememberVectorProviderCompatibility(table, embedResult.providerIdentity, false);\n return null;\n }\n if (storedProviderIdentity === embedResult.providerIdentity) return embedResult;\n\n const fallbackEmbed = await this.embedQueryWithStoredFallbackProvider(query, storedProviderIdentity, execution);\n throwIfSearchAborted(execution, \"LanceDbBackend fallback query embedding aborted\");\n if (\n fallbackEmbed &&\n fallbackEmbed.providerIdentity === storedProviderIdentity &&\n this.isExpectedDimensionVector(fallbackEmbed.vector)\n ) {\n return fallbackEmbed;\n }\n\n this.rememberVectorProviderCompatibility(table, embedResult.providerIdentity, false);\n return null;\n }\n\n private async embedQueryWithStoredFallbackProvider(\n query: string,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedWithIdentity = (this.embedHelper as unknown as {\n embedWithFallbackProviderIdentity?: (\n text: string,\n identity: EmbedProviderIdentity,\n options?: { signal?: AbortSignal },\n ) => Promise<EmbedWithProviderResult | null>;\n }).embedWithFallbackProviderIdentity;\n if (typeof embedWithIdentity !== \"function\") return null;\n return embedWithIdentity.call(this.embedHelper, query, providerIdentity, { signal: execution?.signal });\n }\n\n private async findCompatibleStoredVectorProvider(\n table: any,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedProviderIdentity | null> {\n try {\n const cached = this.vectorProviderCompatibility.get(table);\n if (cached?.compatible) return cached.providerIdentity;\n const rows = await table.query().select([\"vector\", \"vectorProvider\"]).toArray();\n let providerIdentity: EmbedProviderIdentity | null = null;\n let compatible = rows.length > 0;\n for (const row of rows ?? []) {\n throwIfSearchAborted(execution, \"LanceDbBackend vector provider check aborted\");\n if (\n typeof row.vectorProvider !== \"string\" ||\n row.vectorProvider.length === 0 ||\n !this.isCompatibleStoredVector(row.vector)\n ) {\n compatible = false;\n break;\n }\n if (providerIdentity && row.vectorProvider !== providerIdentity) {\n compatible = false;\n break;\n }\n providerIdentity = row.vectorProvider as EmbedProviderIdentity;\n }\n if (compatible && providerIdentity) {\n this.vectorProviderCompatibility.set(table, {\n providerIdentity,\n compatible: true,\n });\n return providerIdentity;\n }\n return null;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`LanceDbBackend stored vector provider check failed: ${err}`);\n return null;\n }\n }\n\n private mapRows(rows: any[]): SearchResult[] {\n return (rows ?? [])\n .filter((row) => row.docid && row.docid !== \"__placeholder__\")\n .map((row) => ({\n docid: row.docid ?? \"\",\n path: row.path ?? \"\",\n snippet: row.snippet ?? row.content?.slice(0, 200) ?? \"\",\n score: row._relevance_score ?? (row._distance != null ? 1 / (1 + (row._distance ?? 0)) : 0.5),\n }));\n }\n\n private async tableHasCompatibleVectors(\n table: any,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<boolean> {\n try {\n const cached = this.vectorProviderCompatibility.get(table);\n if (cached?.providerIdentity === providerIdentity) return cached.compatible;\n const rows = await table.query().select([\"vector\", \"vectorProvider\"]).toArray();\n let compatible = rows.length > 0;\n for (const row of rows ?? []) {\n throwIfSearchAborted(execution, \"LanceDbBackend vector provider check aborted\");\n if (\n row.vectorProvider !== providerIdentity ||\n !this.isCompatibleStoredVector(row.vector)\n ) {\n compatible = false;\n break;\n }\n }\n this.vectorProviderCompatibility.set(table, { providerIdentity, compatible });\n return compatible;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`LanceDbBackend vector provider check failed: ${err}`);\n return false;\n }\n }\n\n private rememberVectorProviderCompatibility(\n table: unknown,\n providerIdentity: EmbedProviderIdentity | null,\n compatible: boolean,\n ): void {\n if (!table || typeof table !== \"object\") return;\n if (!providerIdentity) {\n this.vectorProviderCompatibility.delete(table);\n return;\n }\n this.vectorProviderCompatibility.set(table, { providerIdentity, compatible });\n }\n\n private isExpectedDimensionVector(vector: number[] | null | undefined): vector is number[] {\n return Array.isArray(vector) && vector.length === this.embeddingDimension;\n }\n\n private isCompatibleStoredVector(vector: unknown): boolean {\n if (!vector || typeof vector !== \"object\") return false;\n const arr = Array.from(vector as ArrayLike<number>);\n return (\n arr.length === this.embeddingDimension &&\n arr.every((value) => Number.isFinite(value)) &&\n arr.some((value) => value !== 0)\n );\n }\n}\n\nfunction isMissingVectorProviderColumnError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err);\n return /\\bvectorProvider\\b/i.test(message) &&\n /\\b(column|field|schema|missing|not found|not exist|does not exist|unknown)\\b/i.test(message);\n}\n"],"mappings":"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","names":["embedResult","results"]}
|
|
@@ -105,7 +105,7 @@ function validateEvalBenchmarkManifest(raw, options) {
|
|
|
105
105
|
}
|
|
106
106
|
return {
|
|
107
107
|
schemaVersion: 1,
|
|
108
|
-
benchmarkId: assertString(raw.benchmarkId, "benchmarkId"),
|
|
108
|
+
benchmarkId: assertSafeBenchmarkId(assertString(raw.benchmarkId, "benchmarkId")),
|
|
109
109
|
benchmarkType,
|
|
110
110
|
title: assertString(raw.title, "title"),
|
|
111
111
|
description: typeof raw.description === "string" && raw.description.trim().length > 0 ? raw.description.trim() : void 0,
|
|
@@ -897,4 +897,4 @@ export {
|
|
|
897
897
|
runEvalStoredBaselineCiGate,
|
|
898
898
|
runEvalBenchmarkCiGate
|
|
899
899
|
};
|
|
900
|
-
//# sourceMappingURL=chunk-
|
|
900
|
+
//# sourceMappingURL=chunk-3PY7VHV7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/evals.ts"],"sourcesContent":["import path from \"node:path\";\nimport { cp, mkdir, readFile, readdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { listJsonFiles, listNamedFiles, readJsonFile } from \"./json-store.js\";\n\nexport type EvalRunStatus = \"running\" | \"completed\" | \"failed\" | \"partial\";\n\nexport interface EvalBenchmarkCase {\n id: string;\n prompt: string;\n expectedSignals?: string[];\n notes?: string;\n}\n\nexport type EvalBenchmarkType = \"standard\" | \"memory-red-team\";\n\nexport interface EvalBenchmarkManifest {\n schemaVersion: 1;\n benchmarkId: string;\n benchmarkType?: EvalBenchmarkType;\n title: string;\n description?: string;\n tags?: string[];\n sourceLinks?: string[];\n attackClass?: string;\n targetSurface?: string;\n cases: EvalBenchmarkCase[];\n}\n\nexport interface EvalRunMetrics {\n recallPrecisionAtK?: number;\n actionOutcomeScore?: number;\n objectiveStateCoverage?: number;\n causalPathRecall?: number;\n trustViolationRate?: number;\n creationRecoveryScore?: number;\n}\n\nexport interface EvalRunSummary {\n schemaVersion: 1;\n runId: string;\n benchmarkId: string;\n status: EvalRunStatus;\n startedAt: string;\n completedAt?: string;\n totalCases: number;\n passedCases: number;\n failedCases: number;\n metrics?: EvalRunMetrics;\n notes?: string;\n gitRef?: string;\n}\n\nexport interface EvalShadowRecallRecord {\n schemaVersion: 1;\n traceId: string;\n recordedAt: string;\n sessionKey: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n recallMode: \"no_recall\" | \"minimal\" | \"full\" | \"graph_mode\";\n recallResultLimit: number;\n source: \"none\" | \"hot_qmd\" | \"hot_embedding\" | \"cold_fallback\" | \"recent_scan\";\n recalledMemoryCount: number;\n injected: boolean;\n contextChars: number;\n memoryIds: string[];\n policyVersion?: string;\n identityInjectionMode?: \"recovery_only\" | \"minimal\" | \"full\" | \"none\";\n identityInjectedChars?: number;\n identityInjectionTruncated?: boolean;\n durationMs: number;\n timings?: Record<string, string>;\n}\n\nexport interface EvalHarnessStatus {\n enabled: boolean;\n shadowModeEnabled: boolean;\n rootDir: string;\n benchmarkDir: string;\n runsDir: string;\n benchmarks: {\n total: number;\n valid: number;\n invalid: number;\n redTeam: number;\n totalCases: number;\n attackClasses: string[];\n tags: string[];\n targetSurfaces: string[];\n sourceLinks: string[];\n };\n runs: {\n total: number;\n invalid: number;\n completed: number;\n failed: number;\n partial: number;\n running: number;\n latestRunId?: string;\n latestBenchmarkId?: string;\n latestCompletedAt?: string;\n };\n shadows: {\n total: number;\n invalid: number;\n latestTraceId?: string;\n latestRecordedAt?: string;\n latestSessionKey?: string;\n };\n baselines: {\n enabled: boolean;\n total: number;\n invalid: number;\n latestSnapshotId?: string;\n latestCreatedAt?: string;\n latestBenchmarkCount?: number;\n };\n latestRun?: EvalRunSummary;\n latestShadow?: EvalShadowRecallRecord;\n latestBaseline?: EvalBaselineSnapshot;\n invalidBenchmarks: Array<{\n path: string;\n error: string;\n }>;\n invalidRuns: Array<{\n path: string;\n error: string;\n }>;\n invalidShadows: Array<{\n path: string;\n error: string;\n }>;\n invalidBaselines: Array<{\n path: string;\n error: string;\n }>;\n}\n\nexport interface EvalBenchmarkDelta {\n benchmarkId: string;\n baseRunId: string;\n candidateRunId: string;\n basePassRate: number;\n candidatePassRate: number;\n passRateDelta: number;\n metricDeltas: Partial<Record<keyof EvalRunMetrics, number>>;\n regressions: string[];\n improvements: string[];\n}\n\nexport interface EvalCiGateReport {\n passed: boolean;\n baseRootDir: string;\n candidateRootDir: string;\n comparedBenchmarks: number;\n missingCandidateBenchmarks: string[];\n invalidArtifacts: {\n base: {\n benchmarks: number;\n runs: number;\n shadows: number;\n };\n candidate: {\n benchmarks: number;\n runs: number;\n shadows: number;\n };\n };\n regressions: string[];\n improvements: string[];\n deltas: EvalBenchmarkDelta[];\n}\n\nexport interface EvalBaselineDeltaReport {\n passed: boolean;\n baselineSnapshotId: string;\n baselineCreatedAt: string;\n baselineSourceRootDir: string;\n candidateRootDir: string;\n comparedBenchmarks: number;\n missingCandidateBenchmarks: string[];\n invalidArtifacts: {\n candidate: {\n benchmarks: number;\n runs: number;\n shadows: number;\n baselines: number;\n };\n };\n regressions: string[];\n improvements: string[];\n deltas: EvalBenchmarkDelta[];\n markdownReport: string;\n}\n\nexport interface EvalStoredBaselineCiGateReport extends EvalBaselineDeltaReport {\n baseRootDir: string;\n baselineResolvedFrom: \"base\" | \"candidate\";\n}\n\nexport interface EvalBaselineSnapshotBenchmark {\n benchmarkId: string;\n runId: string;\n completedAt?: string;\n gitRef?: string;\n passRate: number;\n metrics?: EvalRunMetrics;\n}\n\nexport interface EvalBaselineSnapshot {\n schemaVersion: 1;\n snapshotId: string;\n createdAt: string;\n sourceRootDir: string;\n benchmarkCount: number;\n benchmarks: EvalBaselineSnapshotBenchmark[];\n notes?: string;\n gitRef?: string;\n}\n\nexport interface EvalBenchmarkPackSummary {\n sourcePath: string;\n manifestPath: string;\n benchmarkId: string;\n benchmarkType: EvalBenchmarkType;\n title: string;\n attackClass?: string;\n targetSurface?: string;\n totalCases: number;\n tags: string[];\n sourceLinks: string[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${field} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction optionalStringArray(value: unknown, field: string): string[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`${field} must be an array of strings`);\n }\n const out = value\n .filter((item): item is string => typeof item === \"string\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n if (out.length !== value.length) {\n throw new Error(`${field} must be an array of non-empty strings`);\n }\n return out;\n}\n\nexport function resolveEvalStoreDir(memoryDir: string, overrideDir?: string): string {\n if (typeof overrideDir === \"string\" && overrideDir.trim().length > 0) {\n return overrideDir.trim();\n }\n return path.join(memoryDir, \"state\", \"evals\");\n}\n\nfunction assertSafePathSegment(value: string, field: string): string {\n if (value === \".\" || value === \"..\" || value.includes(\"/\") || value.includes(\"\\\\\")) {\n throw new Error(`${field} must be a safe path segment`);\n }\n return value;\n}\n\nfunction assertSafeBenchmarkId(benchmarkId: string): string {\n return assertSafePathSegment(benchmarkId, \"benchmarkId\");\n}\n\nconst ISO_UTC_TIMESTAMP_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\nfunction assertIsoTimestamp(value: unknown, field: string): string {\n const timestamp = assertString(value, field);\n if (!ISO_UTC_TIMESTAMP_RE.test(timestamp)) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n const parsed = Date.parse(timestamp);\n if (!Number.isFinite(parsed)) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n const normalized = new Date(parsed).toISOString();\n if (normalized !== timestamp) {\n throw new Error(`${field} must be a valid ISO timestamp`);\n }\n return normalized;\n}\n\nfunction assertNonNegativeInteger(value: unknown, field: string): number {\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${field} must be a non-negative integer`);\n }\n return parsed;\n}\n\nfunction assertPathWithin(rootDir: string, targetPath: string, field: string): void {\n const resolvedRoot = path.resolve(rootDir);\n const resolvedTarget = path.resolve(targetPath);\n const relative = path.relative(resolvedRoot, resolvedTarget);\n if (relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))) {\n return;\n }\n throw new Error(`${field} must stay within ${rootDir}`);\n}\n\nexport function validateEvalBenchmarkManifest(\n raw: unknown,\n options?: { memoryRedTeamBenchEnabled?: boolean },\n): EvalBenchmarkManifest {\n if (!isRecord(raw)) throw new Error(\"benchmark manifest must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n if (!Array.isArray(raw.cases)) throw new Error(\"cases must be an array\");\n const benchmarkTypeRaw =\n typeof raw.benchmarkType === \"string\" && raw.benchmarkType.trim().length > 0\n ? raw.benchmarkType.trim()\n : \"standard\";\n if (![\"standard\", \"memory-red-team\"].includes(benchmarkTypeRaw)) {\n throw new Error(\"benchmarkType must be one of standard|memory-red-team\");\n }\n\n const cases = raw.cases.map((item, index) => {\n if (!isRecord(item)) throw new Error(`cases[${index}] must be an object`);\n return {\n id: assertString(item.id, `cases[${index}].id`),\n prompt: assertString(item.prompt, `cases[${index}].prompt`),\n expectedSignals: optionalStringArray(item.expectedSignals, `cases[${index}].expectedSignals`),\n notes: typeof item.notes === \"string\" && item.notes.trim().length > 0 ? item.notes.trim() : undefined,\n } satisfies EvalBenchmarkCase;\n });\n\n const benchmarkType = benchmarkTypeRaw as EvalBenchmarkType;\n if (benchmarkType === \"memory-red-team\" && options?.memoryRedTeamBenchEnabled !== true) {\n throw new Error(\"memory-red-team benchmark packs require memoryRedTeamBenchEnabled\");\n }\n const attackClass =\n typeof raw.attackClass === \"string\" && raw.attackClass.trim().length > 0\n ? raw.attackClass.trim()\n : undefined;\n const targetSurface =\n typeof raw.targetSurface === \"string\" && raw.targetSurface.trim().length > 0\n ? raw.targetSurface.trim()\n : undefined;\n if (benchmarkType === \"memory-red-team\" && attackClass === undefined) {\n throw new Error(\"attackClass must be a non-empty string\");\n }\n if (benchmarkType === \"memory-red-team\" && targetSurface === undefined) {\n throw new Error(\"targetSurface must be a non-empty string\");\n }\n\n return {\n schemaVersion: 1,\n benchmarkId: assertSafeBenchmarkId(assertString(raw.benchmarkId, \"benchmarkId\")),\n benchmarkType,\n title: assertString(raw.title, \"title\"),\n description:\n typeof raw.description === \"string\" && raw.description.trim().length > 0\n ? raw.description.trim()\n : undefined,\n tags: optionalStringArray(raw.tags, \"tags\"),\n sourceLinks: optionalStringArray(raw.sourceLinks, \"sourceLinks\"),\n attackClass,\n targetSurface,\n cases,\n };\n}\n\nexport function validateEvalRunSummary(raw: unknown): EvalRunSummary {\n if (!isRecord(raw)) throw new Error(\"eval run summary must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n const status = assertString(raw.status, \"status\");\n if (![\"running\", \"completed\", \"failed\", \"partial\"].includes(status)) {\n throw new Error(\"status must be one of running|completed|failed|partial\");\n }\n\n const totalCases = assertNonNegativeInteger(raw.totalCases, \"totalCases\");\n const passedCases = assertNonNegativeInteger(raw.passedCases, \"passedCases\");\n const failedCases = assertNonNegativeInteger(raw.failedCases, \"failedCases\");\n if (passedCases + failedCases > totalCases) {\n throw new Error(\"passedCases + failedCases must be less than or equal to totalCases\");\n }\n\n const metrics = parseOptionalEvalRunMetrics(raw.metrics);\n const completedAt =\n typeof raw.completedAt === \"string\" && raw.completedAt.trim().length > 0\n ? assertIsoTimestamp(raw.completedAt, \"completedAt\")\n : undefined;\n\n return {\n schemaVersion: 1,\n runId: assertString(raw.runId, \"runId\"),\n benchmarkId: assertString(raw.benchmarkId, \"benchmarkId\"),\n status: status as EvalRunStatus,\n startedAt: assertIsoTimestamp(raw.startedAt, \"startedAt\"),\n completedAt,\n totalCases,\n passedCases,\n failedCases,\n metrics,\n notes: typeof raw.notes === \"string\" && raw.notes.trim().length > 0 ? raw.notes.trim() : undefined,\n gitRef: typeof raw.gitRef === \"string\" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : undefined,\n };\n}\n\nexport function validateEvalBaselineSnapshot(raw: unknown): EvalBaselineSnapshot {\n if (!isRecord(raw)) throw new Error(\"eval baseline snapshot must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n if (!Array.isArray(raw.benchmarks)) throw new Error(\"benchmarks must be an array\");\n\n const benchmarks = raw.benchmarks.map((item, index) => {\n if (!isRecord(item)) throw new Error(`benchmarks[${index}] must be an object`);\n const passRate = Number(item.passRate);\n if (!Number.isFinite(passRate) || passRate < 0 || passRate > 1) {\n throw new Error(`benchmarks[${index}].passRate must be a number between 0 and 1`);\n }\n\n const metrics = parseOptionalEvalRunMetrics(item.metrics);\n\n return {\n benchmarkId: assertString(item.benchmarkId, `benchmarks[${index}].benchmarkId`),\n runId: assertString(item.runId, `benchmarks[${index}].runId`),\n completedAt:\n typeof item.completedAt === \"string\" && item.completedAt.trim().length > 0\n ? assertIsoTimestamp(item.completedAt, `benchmarks[${index}].completedAt`)\n : undefined,\n gitRef:\n typeof item.gitRef === \"string\" && item.gitRef.trim().length > 0\n ? item.gitRef.trim()\n : undefined,\n passRate,\n metrics,\n } satisfies EvalBaselineSnapshotBenchmark;\n });\n\n const benchmarkCount = Number(raw.benchmarkCount);\n if (!Number.isFinite(benchmarkCount) || benchmarkCount < 0) {\n throw new Error(\"benchmarkCount must be a non-negative number\");\n }\n if (benchmarkCount !== benchmarks.length) {\n throw new Error(\"benchmarkCount must match benchmarks.length\");\n }\n\n return {\n schemaVersion: 1,\n snapshotId: assertString(raw.snapshotId, \"snapshotId\"),\n createdAt: assertIsoTimestamp(raw.createdAt, \"createdAt\"),\n sourceRootDir: assertString(raw.sourceRootDir, \"sourceRootDir\"),\n benchmarkCount,\n benchmarks,\n notes: typeof raw.notes === \"string\" && raw.notes.trim().length > 0 ? raw.notes.trim() : undefined,\n gitRef: typeof raw.gitRef === \"string\" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : undefined,\n };\n}\n\nfunction parseOptionalEvalRunMetrics(raw: unknown): EvalRunMetrics | undefined {\n if (!isRecord(raw)) return undefined;\n return {\n recallPrecisionAtK: typeof raw.recallPrecisionAtK === \"number\" ? raw.recallPrecisionAtK : undefined,\n actionOutcomeScore: typeof raw.actionOutcomeScore === \"number\" ? raw.actionOutcomeScore : undefined,\n objectiveStateCoverage: typeof raw.objectiveStateCoverage === \"number\" ? raw.objectiveStateCoverage : undefined,\n causalPathRecall: typeof raw.causalPathRecall === \"number\" ? raw.causalPathRecall : undefined,\n trustViolationRate: typeof raw.trustViolationRate === \"number\" ? raw.trustViolationRate : undefined,\n creationRecoveryScore: typeof raw.creationRecoveryScore === \"number\" ? raw.creationRecoveryScore : undefined,\n } satisfies EvalRunMetrics;\n}\n\nexport function validateEvalShadowRecallRecord(raw: unknown): EvalShadowRecallRecord {\n if (!isRecord(raw)) throw new Error(\"eval shadow recall record must be an object\");\n if (raw.schemaVersion !== 1) throw new Error(\"schemaVersion must be 1\");\n\n const recallMode = assertString(raw.recallMode, \"recallMode\");\n if (![\"no_recall\", \"minimal\", \"full\", \"graph_mode\"].includes(recallMode)) {\n throw new Error(\"recallMode must be one of no_recall|minimal|full|graph_mode\");\n }\n\n const source = assertString(raw.source, \"source\");\n if (![\"none\", \"hot_qmd\", \"hot_embedding\", \"cold_fallback\", \"recent_scan\"].includes(source)) {\n throw new Error(\"source must be one of none|hot_qmd|hot_embedding|cold_fallback|recent_scan\");\n }\n\n const promptLength = Number(raw.promptLength);\n const retrievalQueryLength = Number(raw.retrievalQueryLength);\n const recallResultLimit = Number(raw.recallResultLimit);\n const recalledMemoryCount = Number(raw.recalledMemoryCount);\n const contextChars = Number(raw.contextChars);\n const durationMs = Number(raw.durationMs);\n\n for (const [field, value] of [\n [\"promptLength\", promptLength],\n [\"retrievalQueryLength\", retrievalQueryLength],\n [\"recallResultLimit\", recallResultLimit],\n [\"recalledMemoryCount\", recalledMemoryCount],\n [\"contextChars\", contextChars],\n [\"durationMs\", durationMs],\n ] as const) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`${field} must be a non-negative number`);\n }\n }\n\n const memoryIds = optionalStringArray(raw.memoryIds, \"memoryIds\") ?? [];\n if (typeof raw.injected !== \"boolean\") throw new Error(\"injected must be a boolean\");\n\n let timings: Record<string, string> | undefined;\n if (raw.timings !== undefined) {\n if (!isRecord(raw.timings)) throw new Error(\"timings must be an object of strings\");\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(raw.timings)) {\n if (typeof value !== \"string\") throw new Error(\"timings must be an object of strings\");\n out[key] = value;\n }\n timings = out;\n }\n\n const identityInjectionModeRaw =\n typeof raw.identityInjectionMode === \"string\" && raw.identityInjectionMode.trim().length > 0\n ? raw.identityInjectionMode.trim()\n : undefined;\n if (\n identityInjectionModeRaw !== undefined &&\n ![\"recovery_only\", \"minimal\", \"full\", \"none\"].includes(identityInjectionModeRaw)\n ) {\n throw new Error(\"identityInjectionMode must be one of recovery_only|minimal|full|none\");\n }\n\n return {\n schemaVersion: 1,\n traceId: assertSafePathSegment(assertString(raw.traceId, \"traceId\"), \"traceId\"),\n recordedAt: assertIsoTimestamp(raw.recordedAt, \"recordedAt\"),\n sessionKey: assertString(raw.sessionKey, \"sessionKey\"),\n promptHash: assertString(raw.promptHash, \"promptHash\"),\n promptLength,\n retrievalQueryHash: assertString(raw.retrievalQueryHash, \"retrievalQueryHash\"),\n retrievalQueryLength,\n recallMode: recallMode as EvalShadowRecallRecord[\"recallMode\"],\n recallResultLimit,\n source: source as EvalShadowRecallRecord[\"source\"],\n recalledMemoryCount,\n injected: raw.injected,\n contextChars,\n memoryIds,\n policyVersion:\n typeof raw.policyVersion === \"string\" && raw.policyVersion.trim().length > 0\n ? raw.policyVersion.trim()\n : undefined,\n identityInjectionMode: identityInjectionModeRaw as EvalShadowRecallRecord[\"identityInjectionMode\"],\n identityInjectedChars:\n typeof raw.identityInjectedChars === \"number\" && Number.isFinite(raw.identityInjectedChars)\n ? raw.identityInjectedChars\n : undefined,\n identityInjectionTruncated:\n typeof raw.identityInjectionTruncated === \"boolean\" ? raw.identityInjectionTruncated : undefined,\n durationMs,\n timings,\n };\n}\n\ninterface EvalStoreSnapshot {\n status: EvalHarnessStatus;\n manifests: EvalBenchmarkManifest[];\n runs: EvalRunSummary[];\n shadows: EvalShadowRecallRecord[];\n baselines: EvalBaselineSnapshot[];\n}\n\ninterface EvalStoreSnapshotOptions {\n rootDir: string;\n enabled: boolean;\n shadowModeEnabled: boolean;\n baselineSnapshotsEnabled?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}\n\nconst LOWER_IS_BETTER_METRICS = new Set<keyof EvalRunMetrics>([\"trustViolationRate\"]);\n\nfunction computePassRate(run: EvalRunSummary): number {\n return run.totalCases > 0 ? run.passedCases / run.totalCases : 0;\n}\n\nfunction latestCompletedRunsByBenchmark(runs: EvalRunSummary[]): Map<string, EvalRunSummary> {\n const sorted = [...runs]\n .filter((run) => run.status === \"completed\")\n .sort((a, b) => {\n const aTime = Date.parse(a.completedAt ?? a.startedAt);\n const bTime = Date.parse(b.completedAt ?? b.startedAt);\n return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);\n });\n const out = new Map<string, EvalRunSummary>();\n for (const run of sorted) {\n if (!out.has(run.benchmarkId)) {\n out.set(run.benchmarkId, run);\n }\n }\n return out;\n}\n\nfunction compareMetricDeltas(\n baseMetrics: EvalRunMetrics | undefined,\n candidateMetrics: EvalRunMetrics | undefined,\n): {\n deltas: Partial<Record<keyof EvalRunMetrics, number>>;\n regressions: string[];\n improvements: string[];\n} {\n const deltas: Partial<Record<keyof EvalRunMetrics, number>> = {};\n const regressions: string[] = [];\n const improvements: string[] = [];\n if (!baseMetrics || !candidateMetrics) {\n return { deltas, regressions, improvements };\n }\n\n for (const metric of Object.keys(baseMetrics) as Array<keyof EvalRunMetrics>) {\n const baseValue = baseMetrics[metric];\n const candidateValue = candidateMetrics[metric];\n if (typeof baseValue !== \"number\" || typeof candidateValue !== \"number\") continue;\n const delta = candidateValue - baseValue;\n deltas[metric] = delta;\n if (delta === 0) continue;\n const lowerIsBetter = LOWER_IS_BETTER_METRICS.has(metric);\n const improved = lowerIsBetter ? delta < 0 : delta > 0;\n const summary = `${metric} ${baseValue} -> ${candidateValue}`;\n if (improved) {\n improvements.push(summary);\n } else {\n regressions.push(summary);\n }\n }\n\n return { deltas, regressions, improvements };\n}\n\nfunction formatEvalBaselineDeltaMarkdown(report: EvalBaselineDeltaReport): string {\n const lines = [\n \"# Eval Baseline Delta Report\",\n \"\",\n `- Passed: ${report.passed ? \"yes\" : \"no\"}`,\n `- Baseline snapshot: ${report.baselineSnapshotId}`,\n `- Baseline created: ${report.baselineCreatedAt}`,\n `- Baseline source root: ${report.baselineSourceRootDir}`,\n `- Candidate root: ${report.candidateRootDir}`,\n `- Benchmarks compared: ${report.comparedBenchmarks}`,\n ];\n\n if (report.missingCandidateBenchmarks.length > 0) {\n lines.push(`- Missing candidate benchmarks: ${report.missingCandidateBenchmarks.join(\", \")}`);\n }\n\n lines.push(\n `- Invalid candidate artifacts: benchmarks=${report.invalidArtifacts.candidate.benchmarks}, runs=${report.invalidArtifacts.candidate.runs}, shadows=${report.invalidArtifacts.candidate.shadows}, baselines=${report.invalidArtifacts.candidate.baselines}`,\n \"\",\n \"## Regressions\",\n );\n if (report.regressions.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const regression of report.regressions) lines.push(`- ${regression}`);\n }\n\n lines.push(\"\", \"## Improvements\");\n if (report.improvements.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const improvement of report.improvements) lines.push(`- ${improvement}`);\n }\n\n lines.push(\"\", \"## Benchmark Deltas\");\n if (report.deltas.length === 0) {\n lines.push(\"- none\");\n } else {\n for (const delta of report.deltas) {\n lines.push(\n `- ${delta.benchmarkId}: passRate ${delta.basePassRate} -> ${delta.candidatePassRate} (delta ${delta.passRateDelta})`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nasync function collectEvalStoreSnapshot(options: EvalStoreSnapshotOptions): Promise<EvalStoreSnapshot> {\n const rootDir = options.rootDir;\n const benchmarkDir = path.join(rootDir, \"benchmarks\");\n const runsDir = path.join(rootDir, \"runs\");\n const shadowDir = path.join(rootDir, \"shadow\");\n const baselineDir = path.join(rootDir, \"baselines\");\n const benchmarkFiles = await listNamedFiles(benchmarkDir, \"manifest.json\");\n const runFiles = await listJsonFiles(runsDir);\n const shadowFiles = await listJsonFiles(shadowDir);\n const baselineFiles = await listJsonFiles(baselineDir);\n\n const invalidBenchmarks: Array<{ path: string; error: string }> = [];\n const invalidRuns: Array<{ path: string; error: string }> = [];\n const invalidShadows: Array<{ path: string; error: string }> = [];\n const invalidBaselines: Array<{ path: string; error: string }> = [];\n const manifests: EvalBenchmarkManifest[] = [];\n\n for (const filePath of benchmarkFiles) {\n try {\n manifests.push(\n validateEvalBenchmarkManifest(await readJsonFile(filePath), {\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n }),\n );\n } catch (error) {\n invalidBenchmarks.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const runs: EvalRunSummary[] = [];\n for (const filePath of runFiles) {\n try {\n runs.push(validateEvalRunSummary(await readJsonFile(filePath)));\n } catch (error) {\n invalidRuns.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const shadows: EvalShadowRecallRecord[] = [];\n for (const filePath of shadowFiles) {\n try {\n shadows.push(validateEvalShadowRecallRecord(await readJsonFile(filePath)));\n } catch (error) {\n invalidShadows.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const baselines: EvalBaselineSnapshot[] = [];\n for (const filePath of baselineFiles) {\n try {\n baselines.push(validateEvalBaselineSnapshot(await readJsonFile(filePath)));\n } catch (error) {\n invalidBaselines.push({\n path: filePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n runs.sort((a, b) => {\n const aTime = Date.parse(a.completedAt ?? a.startedAt);\n const bTime = Date.parse(b.completedAt ?? b.startedAt);\n return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);\n });\n shadows.sort((a, b) => b.recordedAt.localeCompare(a.recordedAt));\n baselines.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n\n const tags = new Set<string>();\n const attackClasses = new Set<string>();\n const sourceLinks = new Set<string>();\n const targetSurfaces = new Set<string>();\n let totalCases = 0;\n let redTeam = 0;\n for (const manifest of manifests) {\n totalCases += manifest.cases.length;\n if (manifest.benchmarkType === \"memory-red-team\") {\n redTeam += 1;\n if (manifest.attackClass) attackClasses.add(manifest.attackClass);\n if (manifest.targetSurface) targetSurfaces.add(manifest.targetSurface);\n }\n for (const tag of manifest.tags ?? []) tags.add(tag);\n for (const link of manifest.sourceLinks ?? []) sourceLinks.add(link);\n }\n\n return {\n status: {\n enabled: options.enabled,\n shadowModeEnabled: options.shadowModeEnabled,\n rootDir,\n benchmarkDir,\n runsDir,\n benchmarks: {\n total: benchmarkFiles.length,\n valid: manifests.length,\n invalid: invalidBenchmarks.length,\n redTeam,\n totalCases,\n attackClasses: [...attackClasses].sort(),\n tags: [...tags].sort(),\n targetSurfaces: [...targetSurfaces].sort(),\n sourceLinks: [...sourceLinks].sort(),\n },\n runs: {\n total: runFiles.length,\n invalid: invalidRuns.length,\n completed: runs.filter((run) => run.status === \"completed\").length,\n failed: runs.filter((run) => run.status === \"failed\").length,\n partial: runs.filter((run) => run.status === \"partial\").length,\n running: runs.filter((run) => run.status === \"running\").length,\n latestRunId: runs[0]?.runId,\n latestBenchmarkId: runs[0]?.benchmarkId,\n latestCompletedAt: runs[0]?.completedAt,\n },\n shadows: {\n total: shadowFiles.length,\n invalid: invalidShadows.length,\n latestTraceId: shadows[0]?.traceId,\n latestRecordedAt: shadows[0]?.recordedAt,\n latestSessionKey: shadows[0]?.sessionKey,\n },\n baselines: {\n enabled: options.baselineSnapshotsEnabled === true,\n total: baselineFiles.length,\n invalid: invalidBaselines.length,\n latestSnapshotId: baselines[0]?.snapshotId,\n latestCreatedAt: baselines[0]?.createdAt,\n latestBenchmarkCount: baselines[0]?.benchmarkCount,\n },\n latestRun: runs[0],\n latestShadow: shadows[0],\n latestBaseline: baselines[0],\n invalidBenchmarks,\n invalidRuns,\n invalidShadows,\n invalidBaselines,\n },\n manifests,\n runs,\n shadows,\n baselines,\n };\n}\n\nasync function resolveBenchmarkManifestPath(sourcePath: string): Promise<{ sourceKind: \"file\" | \"directory\"; manifestPath: string }> {\n const info = await stat(sourcePath);\n if (info.isDirectory()) {\n return {\n sourceKind: \"directory\",\n manifestPath: path.join(sourcePath, \"manifest.json\"),\n };\n }\n if (info.isFile()) {\n return {\n sourceKind: \"file\",\n manifestPath: sourcePath,\n };\n }\n throw new Error(\"benchmark pack source must be a file or directory\");\n}\n\nexport async function validateEvalBenchmarkPack(\n sourcePath: string,\n options?: { memoryRedTeamBenchEnabled?: boolean },\n): Promise<EvalBenchmarkPackSummary> {\n const trimmedSourcePath = sourcePath.trim();\n if (trimmedSourcePath.length === 0) {\n throw new Error(\"benchmark pack path must be a non-empty string\");\n }\n const { manifestPath } = await resolveBenchmarkManifestPath(trimmedSourcePath);\n const manifest = validateEvalBenchmarkManifest(await readJsonFile(manifestPath), {\n memoryRedTeamBenchEnabled: options?.memoryRedTeamBenchEnabled,\n });\n return {\n sourcePath: trimmedSourcePath,\n manifestPath,\n benchmarkId: assertSafeBenchmarkId(manifest.benchmarkId),\n benchmarkType: manifest.benchmarkType ?? \"standard\",\n title: manifest.title,\n attackClass: manifest.attackClass,\n targetSurface: manifest.targetSurface,\n totalCases: manifest.cases.length,\n tags: [...(manifest.tags ?? [])],\n sourceLinks: [...(manifest.sourceLinks ?? [])],\n };\n}\n\nexport async function importEvalBenchmarkPack(options: {\n sourcePath: string;\n memoryDir: string;\n evalStoreDir?: string;\n force?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}): Promise<EvalBenchmarkPackSummary & { targetDir: string; overwritten: boolean }> {\n const summary = await validateEvalBenchmarkPack(options.sourcePath, {\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n });\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const benchmarkDir = path.join(rootDir, \"benchmarks\");\n const targetDir = path.join(benchmarkDir, summary.benchmarkId);\n const { sourceKind, manifestPath } = await resolveBenchmarkManifestPath(summary.sourcePath);\n\n let overwritten = false;\n try {\n await stat(targetDir);\n if (options.force !== true) {\n throw new Error(`benchmark pack already exists at ${targetDir}; rerun with force to replace it`);\n }\n overwritten = true;\n await rm(targetDir, { recursive: true, force: true });\n } catch (error) {\n if (!(error instanceof Error) || !(\"code\" in error) || (error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n await mkdir(benchmarkDir, { recursive: true });\n if (sourceKind === \"directory\") {\n await cp(summary.sourcePath, targetDir, { recursive: true });\n } else {\n await mkdir(targetDir, { recursive: true });\n await cp(manifestPath, path.join(targetDir, \"manifest.json\"));\n }\n\n return {\n ...summary,\n targetDir,\n overwritten,\n };\n}\n\nexport async function recordEvalShadowRecall(options: {\n memoryDir: string;\n evalStoreDir?: string;\n record: EvalShadowRecallRecord;\n}): Promise<string> {\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const validated = validateEvalShadowRecallRecord(options.record);\n const day = validated.recordedAt.slice(0, 10);\n const shadowRoot = path.join(rootDir, \"shadow\");\n const shadowDir = path.join(shadowRoot, day);\n const targetPath = path.join(shadowDir, `${validated.traceId}.json`);\n assertPathWithin(shadowRoot, targetPath, \"shadow recall record path\");\n await mkdir(shadowDir, { recursive: true });\n await writeFile(targetPath, JSON.stringify(validated, null, 2), \"utf-8\");\n return targetPath;\n}\n\nexport async function getEvalHarnessStatus(options: {\n memoryDir: string;\n evalStoreDir?: string;\n enabled: boolean;\n shadowModeEnabled: boolean;\n baselineSnapshotsEnabled?: boolean;\n memoryRedTeamBenchEnabled?: boolean;\n}): Promise<EvalHarnessStatus> {\n return (\n await collectEvalStoreSnapshot({\n rootDir: resolveEvalStoreDir(options.memoryDir, options.evalStoreDir),\n enabled: options.enabled,\n shadowModeEnabled: options.shadowModeEnabled,\n baselineSnapshotsEnabled: options.baselineSnapshotsEnabled,\n memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled,\n })\n ).status;\n}\n\nexport async function createEvalBaselineSnapshot(options: {\n memoryDir: string;\n evalStoreDir?: string;\n baselineSnapshotsEnabled: boolean;\n snapshotId: string;\n createdAt?: string;\n notes?: string;\n gitRef?: string;\n}): Promise<{ targetPath: string; snapshot: EvalBaselineSnapshot }> {\n if (options.baselineSnapshotsEnabled !== true) {\n throw new Error(\"benchmark baseline snapshots are disabled\");\n }\n\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const store = await collectEvalStoreSnapshot({\n rootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const latestRuns = latestCompletedRunsByBenchmark(store.runs);\n const benchmarks = [...latestRuns.values()]\n .sort((a, b) => a.benchmarkId.localeCompare(b.benchmarkId))\n .map((run) => ({\n benchmarkId: run.benchmarkId,\n runId: run.runId,\n completedAt: run.completedAt,\n gitRef: run.gitRef,\n passRate: computePassRate(run),\n metrics: run.metrics,\n } satisfies EvalBaselineSnapshotBenchmark));\n\n const snapshot = validateEvalBaselineSnapshot({\n schemaVersion: 1,\n snapshotId,\n createdAt: options.createdAt ?? new Date().toISOString(),\n sourceRootDir: rootDir,\n benchmarkCount: benchmarks.length,\n benchmarks,\n notes: options.notes,\n gitRef: options.gitRef,\n });\n\n const targetPath = path.join(rootDir, \"baselines\", `${snapshot.snapshotId}.json`);\n await mkdir(path.dirname(targetPath), { recursive: true });\n await writeFile(targetPath, JSON.stringify(snapshot, null, 2), \"utf-8\");\n return { targetPath, snapshot };\n}\n\nexport async function runEvalBaselineDeltaReport(options: {\n memoryDir: string;\n evalStoreDir?: string;\n benchmarkDeltaReporterEnabled: boolean;\n snapshotId: string;\n}): Promise<EvalBaselineDeltaReport> {\n if (options.benchmarkDeltaReporterEnabled !== true) {\n throw new Error(\"benchmark delta reporter is disabled\");\n }\n\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const candidateRootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);\n const candidateSnapshot = await collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const baselineSnapshot = candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);\n if (!baselineSnapshot) {\n throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);\n }\n\n return buildEvalBaselineDeltaReport({\n baselineSnapshot,\n candidateSnapshot,\n });\n}\n\nexport async function runEvalStoredBaselineCiGate(options: {\n baseMemoryDir?: string;\n baseEvalStoreDir: string;\n candidateMemoryDir?: string;\n candidateEvalStoreDir: string;\n snapshotId: string;\n}): Promise<EvalStoredBaselineCiGateReport> {\n const snapshotId = assertSafePathSegment(assertString(options.snapshotId, \"snapshotId\"), \"snapshotId\");\n const baseRootDir = resolveEvalStoreDir(options.baseMemoryDir ?? options.baseEvalStoreDir, options.baseEvalStoreDir);\n const candidateRootDir = resolveEvalStoreDir(\n options.candidateMemoryDir ?? options.candidateEvalStoreDir,\n options.candidateEvalStoreDir,\n );\n const [baseSnapshot, candidateSnapshot] = await Promise.all([\n collectEvalStoreSnapshot({\n rootDir: baseRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n }),\n collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n baselineSnapshotsEnabled: true,\n memoryRedTeamBenchEnabled: true,\n }),\n ]);\n const baselineSnapshot =\n baseSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId) ??\n candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);\n if (!baselineSnapshot) {\n throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);\n }\n\n return {\n baseRootDir,\n baselineResolvedFrom: baseSnapshot.baselines.some((snapshot) => snapshot.snapshotId === snapshotId) ? \"base\" : \"candidate\",\n ...buildEvalBaselineDeltaReport({\n baselineSnapshot,\n candidateSnapshot,\n }),\n };\n}\n\nfunction buildEvalBaselineDeltaReport(options: {\n baselineSnapshot: EvalBaselineSnapshot;\n candidateSnapshot: EvalStoreSnapshot;\n}): EvalBaselineDeltaReport {\n const { baselineSnapshot, candidateSnapshot } = options;\n\n const regressions: string[] = [];\n const improvements: string[] = [];\n\n if (candidateSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (candidateSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (candidateSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n if (candidateSnapshot.status.invalidBaselines.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBaselines.length} invalid baseline snapshot file(s)`);\n }\n\n const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);\n const baselineBenchmarks = new Map(\n baselineSnapshot.benchmarks.map((benchmark) => [benchmark.benchmarkId, benchmark] as const),\n );\n const missingCandidateBenchmarks = [...baselineBenchmarks.keys()]\n .filter((benchmarkId) => !candidateRuns.has(benchmarkId))\n .sort();\n for (const benchmarkId of missingCandidateBenchmarks) {\n regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);\n }\n\n const deltas: EvalBenchmarkDelta[] = [];\n for (const benchmarkId of [...baselineBenchmarks.keys()].sort()) {\n const baseBenchmark = baselineBenchmarks.get(benchmarkId);\n const candidateRun = candidateRuns.get(benchmarkId);\n if (!baseBenchmark || !candidateRun) continue;\n\n const passRateDelta = computePassRate(candidateRun) - baseBenchmark.passRate;\n const delta: EvalBenchmarkDelta = {\n benchmarkId,\n baseRunId: baseBenchmark.runId,\n candidateRunId: candidateRun.runId,\n basePassRate: baseBenchmark.passRate,\n candidatePassRate: computePassRate(candidateRun),\n passRateDelta,\n metricDeltas: {},\n regressions: [],\n improvements: [],\n };\n\n if (passRateDelta < 0) {\n delta.regressions.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);\n regressions.push(`${benchmarkId} pass rate regressed (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);\n } else if (passRateDelta > 0) {\n delta.improvements.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);\n improvements.push(`${benchmarkId} pass rate improved (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);\n }\n\n const metricDelta = compareMetricDeltas(baseBenchmark.metrics, candidateRun.metrics);\n delta.metricDeltas = metricDelta.deltas;\n for (const regression of metricDelta.regressions) {\n delta.regressions.push(regression);\n regressions.push(`${benchmarkId} ${regression}`);\n }\n for (const improvement of metricDelta.improvements) {\n delta.improvements.push(improvement);\n improvements.push(`${benchmarkId} ${improvement}`);\n }\n deltas.push(delta);\n }\n\n const report: EvalBaselineDeltaReport = {\n passed: regressions.length === 0,\n baselineSnapshotId: baselineSnapshot.snapshotId,\n baselineCreatedAt: baselineSnapshot.createdAt,\n baselineSourceRootDir: baselineSnapshot.sourceRootDir,\n candidateRootDir: candidateSnapshot.status.rootDir,\n comparedBenchmarks: deltas.length,\n missingCandidateBenchmarks,\n invalidArtifacts: {\n candidate: {\n benchmarks: candidateSnapshot.status.invalidBenchmarks.length,\n runs: candidateSnapshot.status.invalidRuns.length,\n shadows: candidateSnapshot.status.invalidShadows.length,\n baselines: candidateSnapshot.status.invalidBaselines.length,\n },\n },\n regressions,\n improvements,\n deltas,\n markdownReport: \"\",\n };\n report.markdownReport = formatEvalBaselineDeltaMarkdown(report);\n return report;\n}\n\nfunction resolveRequiredEvalStoreRoot(options: { memoryDir?: string; evalStoreDir?: string }, label: string): string {\n if (typeof options.evalStoreDir === \"string\" && options.evalStoreDir.trim().length > 0) {\n return options.evalStoreDir.trim();\n }\n if (typeof options.memoryDir === \"string\" && options.memoryDir.trim().length > 0) {\n return resolveEvalStoreDir(options.memoryDir.trim());\n }\n throw new Error(`${label} requires memoryDir or evalStoreDir`);\n}\n\nexport async function runEvalBenchmarkCiGate(options: {\n baseMemoryDir?: string;\n candidateMemoryDir?: string;\n baseEvalStoreDir?: string;\n candidateEvalStoreDir?: string;\n}): Promise<EvalCiGateReport> {\n const baseRootDir = resolveRequiredEvalStoreRoot(\n { memoryDir: options.baseMemoryDir, evalStoreDir: options.baseEvalStoreDir },\n \"base\",\n );\n const candidateRootDir = resolveRequiredEvalStoreRoot(\n { memoryDir: options.candidateMemoryDir, evalStoreDir: options.candidateEvalStoreDir },\n \"candidate\",\n );\n const baseSnapshot = await collectEvalStoreSnapshot({\n rootDir: baseRootDir,\n enabled: true,\n shadowModeEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n const candidateSnapshot = await collectEvalStoreSnapshot({\n rootDir: candidateRootDir,\n enabled: true,\n shadowModeEnabled: true,\n memoryRedTeamBenchEnabled: true,\n });\n\n const regressions: string[] = [];\n const improvements: string[] = [];\n\n if (baseSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (baseSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (baseSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`base store has ${baseSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n if (candidateSnapshot.status.invalidBenchmarks.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);\n }\n if (candidateSnapshot.status.invalidRuns.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);\n }\n if (candidateSnapshot.status.invalidShadows.length > 0) {\n regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);\n }\n\n const baseRuns = latestCompletedRunsByBenchmark(baseSnapshot.runs);\n const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);\n const missingCandidateBenchmarks = [...baseRuns.keys()]\n .filter((benchmarkId) => !candidateRuns.has(benchmarkId))\n .sort();\n for (const benchmarkId of missingCandidateBenchmarks) {\n regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);\n }\n\n const deltas: EvalBenchmarkDelta[] = [];\n for (const benchmarkId of [...baseRuns.keys()].sort()) {\n const baseRun = baseRuns.get(benchmarkId);\n const candidateRun = candidateRuns.get(benchmarkId);\n if (!baseRun || !candidateRun) continue;\n\n const basePassRate = computePassRate(baseRun);\n const candidatePassRate = computePassRate(candidateRun);\n const passRateDelta = candidatePassRate - basePassRate;\n const delta: EvalBenchmarkDelta = {\n benchmarkId,\n baseRunId: baseRun.runId,\n candidateRunId: candidateRun.runId,\n basePassRate,\n candidatePassRate,\n passRateDelta,\n metricDeltas: {},\n regressions: [],\n improvements: [],\n };\n\n if (passRateDelta < 0) {\n delta.regressions.push(`passRate ${basePassRate} -> ${candidatePassRate}`);\n regressions.push(`${benchmarkId} pass rate regressed (${basePassRate} -> ${candidatePassRate})`);\n } else if (passRateDelta > 0) {\n delta.improvements.push(`passRate ${basePassRate} -> ${candidatePassRate}`);\n improvements.push(`${benchmarkId} pass rate improved (${basePassRate} -> ${candidatePassRate})`);\n }\n\n const metricDelta = compareMetricDeltas(baseRun.metrics, candidateRun.metrics);\n delta.metricDeltas = metricDelta.deltas;\n for (const regression of metricDelta.regressions) {\n delta.regressions.push(regression);\n regressions.push(`${benchmarkId} ${regression}`);\n }\n for (const improvement of metricDelta.improvements) {\n delta.improvements.push(improvement);\n improvements.push(`${benchmarkId} ${improvement}`);\n }\n deltas.push(delta);\n }\n\n return {\n passed: regressions.length === 0,\n baseRootDir: baseSnapshot.status.rootDir,\n candidateRootDir: candidateSnapshot.status.rootDir,\n comparedBenchmarks: deltas.length,\n missingCandidateBenchmarks,\n invalidArtifacts: {\n base: {\n benchmarks: baseSnapshot.status.invalidBenchmarks.length,\n runs: baseSnapshot.status.invalidRuns.length,\n shadows: baseSnapshot.status.invalidShadows.length,\n },\n candidate: {\n benchmarks: candidateSnapshot.status.invalidBenchmarks.length,\n runs: candidateSnapshot.status.invalidRuns.length,\n shadows: candidateSnapshot.status.invalidShadows.length,\n },\n },\n regressions,\n improvements,\n deltas,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseXrayFormat
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PSUB67YB.js";
|
|
4
4
|
import {
|
|
5
5
|
RECALL_DISCLOSURE_LEVELS,
|
|
6
6
|
isRecallDisclosure
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4R4KTDIE.js";
|
|
8
8
|
|
|
9
9
|
// src/recall-xray-cli.ts
|
|
10
10
|
function parseXrayDisclosureFlag(value) {
|
|
@@ -50,4 +50,4 @@ export {
|
|
|
50
50
|
parseXrayBudgetFlag,
|
|
51
51
|
parseXrayCliOptions
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-3QSU4NFF.js.map
|