agentic-qe 3.9.30 → 3.9.32
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/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +208 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/bridge/captured-experience-bridge.js +31 -2
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-CDQOF5TF.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-TOSXWTUQ.js → agent-booster-wasm-WKS3E6KT.js} +2 -2
- package/dist/cli/chunks/{agent-handler-2BU6TYZZ.js → agent-handler-LYCAWE7S.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-JFG3BXZY.js → agent-memory-branch-XF7IOMRK.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-RZK22CJB.js +2 -0
- package/dist/cli/chunks/{audit-4IGZZKUW.js → audit-D2AY3HFP.js} +2 -2
- package/dist/cli/chunks/base-UGH6TVO4.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-STKRZIU3.js → better-sqlite3-K2VWFDKT.js} +2 -2
- package/dist/cli/chunks/{brain-handler-RIDW27HH.js → brain-handler-NNW4TAO2.js} +4 -4
- package/dist/cli/chunks/{branch-enumerator-GMYHLLWD.js → branch-enumerator-OM5HNZKV.js} +2 -2
- package/dist/cli/chunks/{browser-N76A3I2P.js → browser-Y2FU2NV4.js} +2 -2
- package/dist/cli/chunks/browser-workflow-SGOL3FCJ.js +2 -0
- package/dist/cli/chunks/{chunk-ETEHVG76.js → chunk-2L5GAOST.js} +2 -2
- package/dist/cli/chunks/{chunk-ECX6VXMW.js → chunk-2XC4XVCI.js} +1 -1
- package/dist/cli/chunks/{chunk-L7X3A36M.js → chunk-2Z2IQBIJ.js} +1 -1
- package/dist/cli/chunks/{chunk-UYLHIGNC.js → chunk-33PGBYTC.js} +2 -2
- package/dist/cli/chunks/{chunk-OOFWYDG6.js → chunk-3MHWBCSC.js} +1 -1
- package/dist/cli/chunks/{chunk-FI4HRS2G.js → chunk-3R4CMTWF.js} +2 -2
- package/dist/cli/chunks/{chunk-IP6ZTXNJ.js → chunk-45N22VAB.js} +2 -2
- package/dist/cli/chunks/{chunk-FG5GL26L.js → chunk-4H4PEZUX.js} +2 -2
- package/dist/cli/chunks/{chunk-CNNVL5W4.js → chunk-4VAZSCTZ.js} +2 -2
- package/dist/cli/chunks/{chunk-AWWD3EI3.js → chunk-5A6LBGRU.js} +2 -2
- package/dist/cli/chunks/{chunk-ER6BT4GS.js → chunk-5DSANX6S.js} +2 -2
- package/dist/cli/chunks/chunk-5R5WOLZM.js +5 -0
- package/dist/cli/chunks/{chunk-RNO6CE7I.js → chunk-5WR42V5O.js} +2 -2
- package/dist/cli/chunks/{chunk-UEXOMDRS.js → chunk-5XY6SULI.js} +2 -2
- package/dist/cli/chunks/{chunk-WVODEWH5.js → chunk-62UXGD5J.js} +14 -8
- package/dist/cli/chunks/{chunk-EWNJ6OAT.js → chunk-667I4RTC.js} +1 -1
- package/dist/cli/chunks/{chunk-ND6VCNN5.js → chunk-6EKXBWJD.js} +2 -2
- package/dist/cli/chunks/{chunk-Y57V4FDT.js → chunk-6R6QCGNU.js} +2 -2
- package/dist/cli/chunks/{chunk-VRP4GB4Y.js → chunk-6SYP7QX6.js} +4 -4
- package/dist/cli/chunks/{chunk-BFJLKG3D.js → chunk-6YGFAJ3X.js} +1 -1
- package/dist/cli/chunks/{chunk-UWWX4RK7.js → chunk-6ZG6TBWF.js} +4 -4
- package/dist/cli/chunks/{chunk-QSV4ROZD.js → chunk-7AISRWBS.js} +2 -2
- package/dist/cli/chunks/{chunk-SJCEPKZO.js → chunk-7IDPVSTF.js} +1 -1
- package/dist/cli/chunks/{chunk-HQIWLMDS.js → chunk-7PTW3M67.js} +2 -2
- package/dist/cli/chunks/{chunk-TA3QYAZ6.js → chunk-A4UNK5SY.js} +2 -2
- package/dist/cli/chunks/chunk-A6VI5BZU.js +95 -0
- package/dist/cli/chunks/{chunk-XVTZXCHI.js → chunk-BBPOTFIY.js} +2 -2
- package/dist/cli/chunks/{chunk-OEGFOMXP.js → chunk-BDXEL3GM.js} +2 -2
- package/dist/cli/chunks/{chunk-YETPSL6H.js → chunk-BGRC4676.js} +3 -3
- package/dist/cli/chunks/chunk-BQML7B4W.js +180 -0
- package/dist/cli/chunks/{chunk-DEDFPHJL.js → chunk-BV3SGEV7.js} +1 -1
- package/dist/cli/chunks/{chunk-FGMHVSLV.js → chunk-DBE2LIYG.js} +2 -2
- package/dist/cli/chunks/{chunk-2GBBZLXT.js → chunk-DFY7F4TE.js} +1 -1
- package/dist/cli/chunks/{chunk-LDGNVPBZ.js → chunk-EFEJLZDN.js} +1 -1
- package/dist/cli/chunks/{chunk-ZKZTSYPU.js → chunk-ESNBKAT6.js} +2 -2
- package/dist/cli/chunks/{chunk-5F26LSG2.js → chunk-EVSUZKD5.js} +2 -2
- package/dist/cli/chunks/{chunk-QOJ7EAF5.js → chunk-FFBF5BLQ.js} +1 -1
- package/dist/cli/chunks/{chunk-3AICELMQ.js → chunk-FIONYUVH.js} +2 -2
- package/dist/cli/chunks/{chunk-UROPIIB2.js → chunk-FNQCWEVJ.js} +2 -2
- package/dist/cli/chunks/{chunk-5DJAJPBG.js → chunk-FV2MU6CY.js} +2 -2
- package/dist/cli/chunks/{chunk-QTS2DS42.js → chunk-FWEYOD3S.js} +2 -2
- package/dist/cli/chunks/{chunk-XK6YXCS7.js → chunk-G6AJMFWL.js} +3 -3
- package/dist/cli/chunks/{chunk-R57J3O6I.js → chunk-G6VVOUUF.js} +2 -2
- package/dist/cli/chunks/{chunk-2O5TT3UT.js → chunk-G77CYF7H.js} +3 -3
- package/dist/cli/chunks/{chunk-TULNR2AH.js → chunk-H7YKTJMY.js} +2 -2
- package/dist/cli/chunks/{chunk-GEXVUFK4.js → chunk-HGWQC7PR.js} +2 -2
- package/dist/cli/chunks/{chunk-QLNS6DGB.js → chunk-HHBFI3YA.js} +2 -2
- package/dist/cli/chunks/{chunk-WP6X67YI.js → chunk-HPQZSXED.js} +1 -1
- package/dist/cli/chunks/{chunk-HA7N45KB.js → chunk-HR6NX6DW.js} +2 -2
- package/dist/cli/chunks/{chunk-HB52S6IV.js → chunk-I6Q6BPVH.js} +1 -1
- package/dist/cli/chunks/{chunk-BM73MJLE.js → chunk-IGEZVFOM.js} +2 -2
- package/dist/cli/chunks/{chunk-QBDXUI2H.js → chunk-IGQPGXP7.js} +2 -2
- package/dist/cli/chunks/{chunk-Q26GG6WO.js → chunk-IJQJV7BC.js} +3 -3
- package/dist/cli/chunks/chunk-JDW6GN3A.js +2 -0
- package/dist/cli/chunks/{chunk-GZ3U2QT2.js → chunk-JRYNHFZA.js} +1 -1
- package/dist/cli/chunks/{chunk-MV3NUANS.js → chunk-KHZRNJ3A.js} +1 -1
- package/dist/cli/chunks/chunk-LHDTXTS7.js +2 -0
- package/dist/cli/chunks/{chunk-52TRKIAQ.js → chunk-LI2IOJMM.js} +1 -1
- package/dist/cli/chunks/{heartbeat-scheduler-CNJBAO5C.js → chunk-LR5VW3OS.js} +2 -2
- package/dist/cli/chunks/{chunk-2NFGUFYU.js → chunk-LTSNDM5N.js} +2 -2
- package/dist/cli/chunks/{chunk-3EP2YZSY.js → chunk-M5PYPGBC.js} +2 -2
- package/dist/cli/chunks/{chunk-JCWHX4XV.js → chunk-MEHNT37H.js} +2 -2
- package/dist/cli/chunks/{chunk-QHKK2H4H.js → chunk-MERMCKPG.js} +1 -1
- package/dist/cli/chunks/{chunk-Q53UMLLC.js → chunk-MIHQIAVK.js} +2 -2
- package/dist/cli/chunks/{chunk-VOBNJWZF.js → chunk-MMVSERJQ.js} +2 -2
- package/dist/cli/chunks/{chunk-37I6K7QO.js → chunk-MQQANXFS.js} +2 -2
- package/dist/cli/chunks/{chunk-YKFURJNP.js → chunk-MTOHV22P.js} +1 -1
- package/dist/cli/chunks/{chunk-MOLOWMON.js → chunk-NVZHCAEB.js} +2 -2
- package/dist/cli/chunks/{chunk-YXR5RYRE.js → chunk-NW5FYGDE.js} +2 -2
- package/dist/cli/chunks/{chunk-NMBHF7ZD.js → chunk-NZRJWK5H.js} +61 -121
- package/dist/cli/chunks/chunk-O5NEZCTB.js +2 -0
- package/dist/cli/chunks/{chunk-E7UHOKKL.js → chunk-O5UGJ3OI.js} +2 -2
- package/dist/cli/chunks/{chunk-Q4HJRYQB.js → chunk-OK2TFTXP.js} +2 -2
- package/dist/cli/chunks/{chunk-FGDEM4HU.js → chunk-OKEHGXIS.js} +2 -2
- package/dist/cli/chunks/{chunk-C6TNYLD7.js → chunk-OKRY4LNE.js} +3 -3
- package/dist/cli/chunks/{chunk-3WIU2E2Y.js → chunk-OMOGD2NN.js} +2 -2
- package/dist/cli/chunks/{chunk-DJRWVNHK.js → chunk-ONNTJXU7.js} +2 -2
- package/dist/cli/chunks/chunk-OPOGZAN5.js +14 -0
- package/dist/cli/chunks/{chunk-OTFJCZNY.js → chunk-PG5F2VHA.js} +2 -2
- package/dist/cli/chunks/{chunk-MYF7F3ZP.js → chunk-PHRMWRXA.js} +2 -2
- package/dist/cli/chunks/{chunk-7D2DM23U.js → chunk-PIXUX2NR.js} +2 -2
- package/dist/cli/chunks/{chunk-IWC6GR24.js → chunk-PLGMPG7S.js} +2 -2
- package/dist/cli/chunks/{chunk-T2DIMSQF.js → chunk-PPS6VN24.js} +1 -1
- package/dist/cli/chunks/{chunk-AUNNGKLN.js → chunk-PQAYCK2U.js} +2 -2
- package/dist/cli/chunks/{chunk-FU74OETU.js → chunk-PS6ISBED.js} +2 -2
- package/dist/cli/chunks/{chunk-JNRRDG7O.js → chunk-QPYNQSWD.js} +2 -2
- package/dist/cli/chunks/{chunk-MHPK4ZPK.js → chunk-QRTZ67BC.js} +2 -2
- package/dist/cli/chunks/{chunk-Z3TXQOS7.js → chunk-REW3W3ZW.js} +1 -1
- package/dist/cli/chunks/{chunk-3PZDXE5E.js → chunk-RHXYZ6AZ.js} +127 -127
- package/dist/cli/chunks/{chunk-IEGAEXQX.js → chunk-RZXAXWBD.js} +2 -2
- package/dist/cli/chunks/{chunk-4UZQSPR4.js → chunk-S4M7U6CZ.js} +2 -2
- package/dist/cli/chunks/{chunk-H27XUYWZ.js → chunk-SJETAUZA.js} +1 -1
- package/dist/cli/chunks/{chunk-MZ7M2CDV.js → chunk-SLH7LFVY.js} +2 -2
- package/dist/cli/chunks/{chunk-6EP3GHED.js → chunk-SRJ5N7LD.js} +2 -2
- package/dist/cli/chunks/{chunk-XDYTQPJM.js → chunk-T5ADVYPH.js} +1 -1
- package/dist/cli/chunks/{chunk-TYZGEVP6.js → chunk-THYGFSTA.js} +12 -6
- package/dist/cli/chunks/{chunk-XKH4E2IQ.js → chunk-TX2DBLTL.js} +1 -1
- package/dist/cli/chunks/{chunk-HJDHQBMJ.js → chunk-UJMGNO6L.js} +1 -1
- package/dist/cli/chunks/{chunk-MCXRS2TZ.js → chunk-UUQ3SOKM.js} +1 -1
- package/dist/cli/chunks/{chunk-USN2JKUW.js → chunk-V5RLGPEW.js} +2 -2
- package/dist/cli/chunks/chunk-V6HM2BKJ.js +2 -0
- package/dist/cli/chunks/{chunk-R5IW5ARI.js → chunk-V7I6FTLG.js} +1 -1
- package/dist/cli/chunks/{chunk-2MKSEL6F.js → chunk-V7ZBPSVG.js} +1 -1
- package/dist/cli/chunks/{chunk-IOINZWNA.js → chunk-VJL7DNUU.js} +29 -17
- package/dist/cli/chunks/{chunk-JCDEMPJS.js → chunk-VKCWWR6C.js} +1 -1
- package/dist/cli/chunks/chunk-VKNCMGOJ.js +29 -0
- package/dist/cli/chunks/{chunk-GRPEDIYG.js → chunk-W2VTHUDK.js} +2 -2
- package/dist/cli/chunks/{chunk-SAVITYEX.js → chunk-W3JB3G7C.js} +2 -2
- package/dist/cli/chunks/{chunk-WTXRPYNN.js → chunk-WQ4MT74X.js} +1 -1
- package/dist/cli/chunks/{chunk-GY4EGQO3.js → chunk-WTNM7NA4.js} +1 -1
- package/dist/cli/chunks/chunk-XB3SIYGU.js +62 -0
- package/dist/cli/chunks/{chunk-IHRFR5SV.js → chunk-XCUNQ3FK.js} +2 -2
- package/dist/cli/chunks/{chunk-ITBPDVK5.js → chunk-XHQFVTFD.js} +1 -1
- package/dist/cli/chunks/{chunk-KJZXBZQR.js → chunk-YBUUAFKR.js} +1 -1
- package/dist/cli/chunks/{chunk-KR2PGNXX.js → chunk-YJV6TTCW.js} +2 -2
- package/dist/cli/chunks/{chunk-BQLFOJ5G.js → chunk-YUSGT2CU.js} +1 -1
- package/dist/cli/chunks/{chunk-5E3YCZC5.js → chunk-YUTSN5BK.js} +2 -2
- package/dist/cli/chunks/{chunk-DDMFTEJP.js → chunk-YVMJTBXB.js} +3 -3
- package/dist/cli/chunks/chunk-YVQ4PR4H.js +2 -0
- package/dist/cli/chunks/{chunk-RYMHYTOK.js → chunk-Z2EDNMCQ.js} +3 -3
- package/dist/cli/chunks/{chunk-QNSUPXUU.js → chunk-ZESMMAKZ.js} +2 -2
- package/dist/cli/chunks/chunk-ZIVOT3B7.js +2 -0
- package/dist/cli/chunks/{ci-BYCH3NPL.js → ci-NSF6OHB4.js} +2 -2
- package/dist/cli/chunks/{ci-output-P7P4XH6F.js → ci-output-ZPDJ42U3.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-VLX556ZI.js → circuit-breaker-Y2RUJDYG.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-JPR425PL.js → claude-flow-setup-OH6G6KM2.js} +2 -2
- package/dist/cli/chunks/client-QQGRKAY7.js +2 -0
- package/dist/cli/chunks/{cline-installer-FOY47NSH.js → cline-installer-IHH4F27G.js} +2 -2
- package/dist/cli/chunks/{code-57SN4ZDY.js → code-SFAHWFTX.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-GT7UFRYU.js → code-index-extractor-GXECMOM2.js} +2 -2
- package/dist/cli/chunks/{codex-installer-JAGWONAV.js → codex-installer-UPMSAFCQ.js} +2 -2
- package/dist/cli/chunks/{completions-7YLHPGSV.js → completions-5TX6LDHY.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-TQUF6BEI.js → complexity-analyzer-J2ZR3XZB.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-TICV6IGT.js → continuedev-installer-GWYZKB5A.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-A6PDMI52.js → copilot-installer-DQZMQWI7.js} +2 -2
- package/dist/cli/chunks/{cost-tracker-NZPNHNV2.js → cost-tracker-V7KIGCLZ.js} +2 -2
- package/dist/cli/chunks/{coverage-HBEB2LKS.js → coverage-3X6LA2GZ.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-3SHAGRVP.js +2 -0
- package/dist/cli/chunks/{cursor-installer-R4FM7MGN.js → cursor-installer-ENDG4JIU.js} +2 -2
- package/dist/cli/chunks/daemon-4XVAO7GT.js +16 -0
- package/dist/cli/chunks/daemon-TC65CQFK.js +10 -0
- package/dist/cli/chunks/{dag-attention-scheduler-2L7VCYZ3.js → dag-attention-scheduler-JOSCDRZC.js} +2 -2
- package/dist/cli/chunks/{detect-EEWB4IYE.js → detect-KWZX3OMK.js} +2 -2
- package/dist/cli/chunks/{dist-node-7RM6BB2X.js → dist-node-R4U2PJ47.js} +2 -2
- package/dist/cli/chunks/{domain-handler-RVGHBDUJ.js → domain-handler-BMYYZO2L.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-M5MERQG5.js → domain-transfer-MSDBBDLC.js} +2 -2
- package/dist/cli/chunks/dream-OCZK42FM.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-MS55QS73.js → embed-and-insert-pattern-MFINPOLS.js} +2 -2
- package/dist/cli/chunks/{eval-MBTMI7KN.js → eval-OER6UNUY.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-Z5XB7D6A.js → experience-capture-middleware-F5I77ECG.js} +3 -3
- package/dist/cli/chunks/{fast-paths-FSWLHI4I.js → fast-paths-P3KT5DUQ.js} +2 -2
- package/dist/cli/chunks/{feature-flags-QUPNH2J5.js → feature-flags-5EBWQ5WU.js} +2 -2
- package/dist/cli/chunks/{feature-flags-ATYOPR5D.js → feature-flags-DYFZSQLV.js} +2 -2
- package/dist/cli/chunks/{file-discovery-SOJJEQ2E.js → file-discovery-MOBVABSM.js} +2 -2
- package/dist/cli/chunks/{fleet-PWBTDWVG.js → fleet-J3R3NQNC.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-2N67VQOQ.js → gnn-wrapper-QD76SULF.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-5PSG2UPO.js → heartbeat-handler-AJEWTPZ4.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-EAVZR6TJ.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-BY4XB7FB.js +2 -0
- package/dist/cli/chunks/hnsw-index-657CZRG7.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-YIXH5T4U.js → hnsw-legacy-bridge-5VRM5N7K.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-3U2AVWQ3.js → hnswlib-node-BWUH4OQT.js} +2 -2
- package/dist/cli/chunks/hooks-7PMVKQOE.js +248 -0
- package/dist/cli/chunks/{hybrid-router-RL47S47Z.js → hybrid-router-2K2LW45J.js} +2 -2
- package/dist/cli/chunks/{hypergraph-engine-XW2IHFWW.js → hypergraph-engine-2CQ735JO.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-AQXKY4UF.js → hypergraph-handler-AQ53GVIW.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-GI6UVAMT.js +2 -0
- package/dist/cli/chunks/{init-handler-KXYGJQI5.js → init-handler-ZOVJPAWO.js} +6 -6
- package/dist/cli/chunks/init-wizard-HOH577MH.js +2 -0
- package/dist/cli/chunks/kernel-JDYBG5GE.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-VSULDGRO.js → kilocode-installer-GWQCNLKI.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-SH4D2UXW.js → kiro-installer-6KVES4MO.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-RAQOWLG3.js +2 -0
- package/dist/cli/chunks/learning-6XMNWXRT.js +117 -0
- package/dist/cli/chunks/{llm-router-YXXSQX5K.js → llm-router-GS4AZJJC.js} +4 -4
- package/dist/cli/chunks/{load-S52R2SLL.js → load-FEMEQNE6.js} +2 -2
- package/dist/cli/chunks/load-test-3MEJ43U2.js +2 -0
- package/dist/cli/chunks/{mcp-ZWMAJIU7.js → mcp-6V2H7EXU.js} +2 -2
- package/dist/cli/chunks/{memory-4YTWWDK7.js → memory-YLGPOB2H.js} +5 -5
- package/dist/cli/chunks/memory-backend-2A47ZRGO.js +2 -0
- package/dist/cli/chunks/memory-handlers-UBTBC7D2.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-F3VEM2UF.js → multi-model-executor-SL2EKAH2.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-Z2CUJQ6D.js → opencode-installer-ADOJVGNA.js} +2 -2
- package/dist/cli/chunks/{orchestrator-UPXR2XOF.js → orchestrator-O4IWW2VU.js} +37 -18
- package/dist/cli/chunks/{pipeline-6MEMAIXM.js → pipeline-5BD5YQNQ.js} +2 -2
- package/dist/cli/chunks/{platform-H72FLOM7.js → platform-HXSUOOJH.js} +2 -2
- package/dist/cli/chunks/{plugin-GIMQFDVR.js → plugin-HOLH5CUH.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-DM5FR5SV.js → prime-radiant-advanced-wasm-PJTL7OLS.js} +2 -2
- package/dist/cli/chunks/protocol-executor-3FR7FBVM.js +2 -0
- package/dist/cli/chunks/{protocol-handler-YW3N333B.js → protocol-handler-K27YGLC7.js} +2 -2
- package/dist/cli/chunks/{prove-IJY524KK.js → prove-MHCLHQQ6.js} +2 -2
- package/dist/cli/chunks/{provider-manager-FNG6YR2V.js → provider-manager-3645PPXX.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-CHNYPYQW.js +2 -0
- package/dist/cli/chunks/{quality-EZLAMSCP.js → quality-NDE6EDOY.js} +2 -2
- package/dist/cli/chunks/queen-coordinator-J6ZRYTBX.js +2 -0
- package/dist/cli/chunks/{real-embeddings-MFRCC6GH.js → real-embeddings-VD3EVV3U.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-H3ZIRGWU.js → roocode-installer-63Y45UUG.js} +2 -2
- package/dist/cli/chunks/router-23HRN2Z6.js +2 -0
- package/dist/cli/chunks/routing-feedback-R6A4B6ZG.js +2 -0
- package/dist/cli/chunks/{routing-handler-T2A7FYHW.js → routing-handler-76XISU2E.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-TCLWBP2M.js → ruvector-commands-AEKOZZHZ.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-BE3JCPYC.js → rvf-dual-writer-4DMUIZQF.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-MLUX5YGR.js → rvf-migration-adapter-YUTXFOZ3.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-OAQXTASZ.js → rvf-migration-coordinator-XJ5N2W37.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-QINEJZM7.js +2 -0
- package/dist/cli/chunks/safe-db-YXMCSKFH.js +2 -0
- package/dist/cli/chunks/schedule-XVFD27P5.js +2 -0
- package/dist/cli/chunks/scheduler-NWH2IDEU.js +2 -0
- package/dist/cli/chunks/{security-SHWJWJ4M.js → security-6YS6GQGO.js} +3 -3
- package/dist/cli/chunks/shared-rvf-adapter-FTZY35WI.js +2 -0
- package/dist/cli/chunks/{shared-rvf-dual-writer-BKSR2FFK.js → shared-rvf-dual-writer-MH2Y65HA.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-BR6YJF5P.js +2 -0
- package/dist/cli/chunks/{status-handler-QK5KMKYC.js → status-handler-57JQMPY5.js} +2 -2
- package/dist/cli/chunks/{structural-health-3BRNCAYQ.js → structural-health-34D5VWRD.js} +2 -2
- package/dist/cli/chunks/sync-HJD2US5P.js +2 -0
- package/dist/cli/chunks/sync-TTQ6ZB5D.js +17 -0
- package/dist/cli/chunks/{task-handler-VH2CLUIA.js → task-handler-4RF57637.js} +2 -2
- package/dist/cli/chunks/{task-handlers-BUZNV2VX.js → task-handlers-BRSK7HDE.js} +3 -3
- package/dist/cli/chunks/{test-K24JQQZ2.js → test-GMUW2VR3.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-MHXRV5VI.js → test-scheduling-7LF24IFV.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-3NZDLG52.js → token-bootstrap-VYT4RTHU.js} +2 -2
- package/dist/cli/chunks/{token-usage-C4BGA2O7.js → token-usage-NFNCPQGW.js} +2 -2
- package/dist/cli/chunks/{transformers-ZIIFB2V4.js → transformers-GGD5GIEY.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-GES2AV7A.js → tree-sitter-wasm-parser-GKYG6NKT.js} +2 -2
- package/dist/cli/chunks/{types-L3MO5VNC.js → types-WJ3ZTRD5.js} +2 -2
- package/dist/cli/chunks/unified-memory-AT3Z4CY7.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-6FOIGINN.js +2 -0
- package/dist/cli/chunks/unified-persistence-TCJB7MQS.js +2 -0
- package/dist/cli/chunks/{upgrade-EKJYS5S5.js → upgrade-IMBT4F6K.js} +2 -2
- package/dist/cli/chunks/{validate-WYWWB5PQ.js → validate-76OVF45Z.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-SBSWKJ3H.js → validate-swarm-HH2ZYWXA.js} +2 -2
- package/dist/cli/chunks/{vibium-VEMTLNFV.js → vibium-74WQNDBX.js} +2 -2
- package/dist/cli/chunks/visual-security-IBAUX2K5.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-STW2WR2J.js → web-tree-sitter-W6RGE4SL.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-6ZXMJASZ.js → windsurf-installer-7DMSFCA2.js} +2 -2
- package/dist/cli/chunks/{witness-chain-PTULB4MR.js → witness-chain-BLZ4ZKAD.js} +2 -2
- package/dist/cli/chunks/witness-chain-GNNF23XU.js +2 -0
- package/dist/cli/chunks/{workflow-TEBAAHNR.js → workflow-RNSDKRZ4.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-S2YONHGM.js +2 -0
- package/dist/cli/chunks/{wrappers-DVMVRKXK.js → wrappers-J7RXMIOY.js} +2 -2
- package/dist/cli/commands/hooks-handlers/editing-hooks.js +9 -3
- package/dist/cli/commands/hooks-handlers/hooks-dream-learning.js +16 -24
- package/dist/cli/commands/hooks-handlers/hooks-shared.d.ts +1 -1
- package/dist/cli/commands/hooks-handlers/hooks-shared.js +8 -1
- package/dist/cli/commands/hooks-handlers/routing-hooks.js +15 -3
- package/dist/cli/commands/hooks-handlers/task-hooks.js +37 -46
- package/dist/cli/commands/learning.js +194 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.js +37 -17
- package/dist/init/phases/10-workers.js +20 -1
- package/dist/kernel/hybrid-backend.d.ts +17 -7
- package/dist/kernel/hybrid-backend.js +24 -10
- package/dist/kernel/interfaces.d.ts +33 -6
- package/dist/kernel/kernel.d.ts +1 -0
- package/dist/kernel/kernel.js +57 -0
- package/dist/kernel/memory-backend.d.ts +5 -5
- package/dist/kernel/memory-backend.js +14 -7
- package/dist/kernel/unified-memory-schemas.d.ts +1 -1
- package/dist/kernel/unified-memory-schemas.js +7 -1
- package/dist/learning/agent-routing.d.ts +134 -1
- package/dist/learning/agent-routing.js +185 -2
- package/dist/learning/dream/dream-insights-pruner.d.ts +49 -0
- package/dist/learning/dream/dream-insights-pruner.js +53 -0
- package/dist/learning/dream/dream-scheduler.js +17 -0
- package/dist/learning/loop-health.d.ts +84 -0
- package/dist/learning/loop-health.js +91 -0
- package/dist/learning/pattern-usage-recorder.d.ts +58 -0
- package/dist/learning/pattern-usage-recorder.js +72 -0
- package/dist/learning/qe-reasoning-bank-types.d.ts +11 -0
- package/dist/learning/qe-reasoning-bank.d.ts +11 -0
- package/dist/learning/qe-reasoning-bank.js +86 -3
- package/dist/learning/routing-topology-gate.d.ts +40 -0
- package/dist/learning/routing-topology-gate.js +55 -0
- package/dist/learning/sqlite-persistence.d.ts +6 -1
- package/dist/learning/sqlite-persistence.js +14 -20
- package/dist/mcp/bundle.js +3837 -3811
- package/dist/mcp/handlers/core-handlers.js +21 -0
- package/dist/routing/routing-feedback.js +7 -3
- package/dist/routing/routing-outcomes-migration.d.ts +31 -0
- package/dist/routing/routing-outcomes-migration.js +60 -0
- package/dist/workers/interfaces.d.ts +26 -0
- package/dist/workers/worker-manager.d.ts +15 -12
- package/dist/workers/worker-manager.js +11 -0
- package/dist/workers/workers/learning-consolidation.d.ts +28 -0
- package/dist/workers/workers/learning-consolidation.js +302 -71
- package/package.json +3 -1
- package/dist/cli/chunks/adapter-HV42JOZD.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-GL22PE2V.js +0 -2
- package/dist/cli/chunks/base-4KQ2FGUX.js +0 -2
- package/dist/cli/chunks/browser-workflow-CTE7BDM4.js +0 -2
- package/dist/cli/chunks/chunk-3NGNSKL3.js +0 -14
- package/dist/cli/chunks/chunk-6HSFZ6SL.js +0 -180
- package/dist/cli/chunks/chunk-7Z3GBQNV.js +0 -2
- package/dist/cli/chunks/chunk-AQJ6XS34.js +0 -2
- package/dist/cli/chunks/chunk-H2IMXQCJ.js +0 -2
- package/dist/cli/chunks/chunk-SPCANEJY.js +0 -95
- package/dist/cli/chunks/client-FRVNMXQO.js +0 -2
- package/dist/cli/chunks/cross-domain-router-BVCPAWG2.js +0 -2
- package/dist/cli/chunks/daemon-PHIZPZIE.js +0 -19
- package/dist/cli/chunks/dream-77ODIFIF.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-CQGQS3V7.js +0 -2
- package/dist/cli/chunks/hnsw-index-2ACF6FOJ.js +0 -2
- package/dist/cli/chunks/hooks-YROFO6PE.js +0 -259
- package/dist/cli/chunks/impact-analyzer-LWEGK23B.js +0 -2
- package/dist/cli/chunks/init-wizard-7BS3QMWR.js +0 -2
- package/dist/cli/chunks/kernel-TX67WXSI.js +0 -2
- package/dist/cli/chunks/knowledge-graph-TDSP2UE2.js +0 -2
- package/dist/cli/chunks/learning-RRWV3SEL.js +0 -107
- package/dist/cli/chunks/load-test-GEBBBUMV.js +0 -2
- package/dist/cli/chunks/memory-backend-WQS2MLW2.js +0 -2
- package/dist/cli/chunks/memory-handlers-RTY5MBA5.js +0 -2
- package/dist/cli/chunks/protocol-executor-DT7XHMLL.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-LDNETZVA.js +0 -2
- package/dist/cli/chunks/queen-coordinator-AF7HCQSM.js +0 -2
- package/dist/cli/chunks/router-OWQ5EI72.js +0 -2
- package/dist/cli/chunks/routing-feedback-B43DEQMK.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-XBJDXHNI.js +0 -2
- package/dist/cli/chunks/safe-db-RT3LEDUG.js +0 -2
- package/dist/cli/chunks/schedule-EHUDCKS2.js +0 -2
- package/dist/cli/chunks/scheduler-GEGZ4J3C.js +0 -2
- package/dist/cli/chunks/shared-rvf-adapter-LNBUNRAM.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-3DGRJH3K.js +0 -2
- package/dist/cli/chunks/sync-5CDYOT3H.js +0 -23
- package/dist/cli/chunks/unified-memory-ZSBX4LYU.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-Y6EKAMRP.js +0 -2
- package/dist/cli/chunks/unified-persistence-2PDVU2U5.js +0 -2
- package/dist/cli/chunks/visual-security-RHMFLKVQ.js +0 -2
- package/dist/cli/chunks/witness-chain-QO237QOF.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-RHM5MIGE.js +0 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-Learning Loop Health (#488 B.2)
|
|
3
|
+
*
|
|
4
|
+
* Records per-component liveness signals for the AQE self-learning loop:
|
|
5
|
+
*
|
|
6
|
+
* captured_experiences (SQLite)
|
|
7
|
+
* → CapturedExperienceBridge.drain (component: 'bridge')
|
|
8
|
+
* → learning:experience:* kv
|
|
9
|
+
* → LearningConsolidationWorker.tick (component: 'learningWorker')
|
|
10
|
+
* → learning:pattern:* kv
|
|
11
|
+
* → DreamScheduler.tick (component: 'dreamScheduler')
|
|
12
|
+
* → dream_insights / qe_patterns
|
|
13
|
+
*
|
|
14
|
+
* Each tick records `{ success: true }` so operators can answer "is the
|
|
15
|
+
* loop closing end-to-end?" without DB-mining `dream_cycles`, `kv_store`,
|
|
16
|
+
* and `routing_outcomes` separately. Cumulative counters in `aqe learning
|
|
17
|
+
* stats` are not enough: they grow forever and can't distinguish "healthy
|
|
18
|
+
* loop" from "loop wedged 3 hours ago with stale totals".
|
|
19
|
+
*
|
|
20
|
+
* Persists as a single JSON value under `learning:loop-health` in the
|
|
21
|
+
* unified memory. Cheap to write (~200 bytes), cheap to read.
|
|
22
|
+
*/
|
|
23
|
+
import type { MemoryBackend } from '../kernel/interfaces.js';
|
|
24
|
+
export declare const LOOP_HEALTH_KEY = "learning:loop-health";
|
|
25
|
+
export type LoopComponent = 'bridge' | 'dreamScheduler' | 'learningWorker';
|
|
26
|
+
export interface ComponentHealth {
|
|
27
|
+
/** ISO timestamp of the most recent successful tick. Empty string when never succeeded. */
|
|
28
|
+
lastSuccessAt: string;
|
|
29
|
+
/** Total ticks attempted since this loop-health record was created. */
|
|
30
|
+
ticksSinceBoot: number;
|
|
31
|
+
/** Total successful ticks since this loop-health record was created. */
|
|
32
|
+
successesSinceBoot: number;
|
|
33
|
+
/** Most recent error captured during a failed tick. Cleared on next success. */
|
|
34
|
+
lastError?: {
|
|
35
|
+
message: string;
|
|
36
|
+
at: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface LoopHealth {
|
|
40
|
+
/** Max(lastSuccessAt across components). Empty string when nothing has succeeded yet. */
|
|
41
|
+
overallLastSuccess: string;
|
|
42
|
+
/** ISO timestamp when this record was first written. */
|
|
43
|
+
bootedAt: string;
|
|
44
|
+
/** Per-component status. Components are added on first tick — absence means never invoked. */
|
|
45
|
+
components: {
|
|
46
|
+
bridge?: ComponentHealth;
|
|
47
|
+
dreamScheduler?: ComponentHealth;
|
|
48
|
+
learningWorker?: ComponentHealth;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Minimal memory interface this module needs. Both `MemoryBackend` (kernel)
|
|
53
|
+
* and `WorkerMemory` (worker context) satisfy this — the helper stays
|
|
54
|
+
* transport-agnostic so writers can call it without knowing which they hold.
|
|
55
|
+
*/
|
|
56
|
+
export interface LoopHealthMemory {
|
|
57
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
58
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Record one tick of a component. Always best-effort: a write failure here
|
|
62
|
+
* MUST NOT propagate to the calling component (the bridge / worker should
|
|
63
|
+
* keep running even if the health key can't be persisted).
|
|
64
|
+
*/
|
|
65
|
+
export declare function recordLoopHealth(memory: LoopHealthMemory | MemoryBackend, component: LoopComponent, result: {
|
|
66
|
+
success: boolean;
|
|
67
|
+
error?: Error | string;
|
|
68
|
+
}): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Read the current loop-health record. Returns undefined if no tick has
|
|
71
|
+
* ever fired — operators reading via `aqe learning loop-health` should
|
|
72
|
+
* interpret undefined as "the loop hasn't started yet (or workers aren't
|
|
73
|
+
* running)" rather than "the loop is healthy".
|
|
74
|
+
*/
|
|
75
|
+
export declare function getLoopHealth(memory: LoopHealthMemory | MemoryBackend): Promise<LoopHealth | undefined>;
|
|
76
|
+
/**
|
|
77
|
+
* Compute a staleness verdict per component given a "stale after" threshold.
|
|
78
|
+
* Caller chooses the threshold based on the component's expected cadence:
|
|
79
|
+
* - bridge: 5s poll → stale after ~30s
|
|
80
|
+
* - learningWorker: 30 min tick → stale after ~2h
|
|
81
|
+
* - dreamScheduler: variable → caller's call
|
|
82
|
+
*/
|
|
83
|
+
export declare function isComponentStale(health: ComponentHealth | undefined, staleAfterMs: number, now?: Date): boolean;
|
|
84
|
+
//# sourceMappingURL=loop-health.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-Learning Loop Health (#488 B.2)
|
|
3
|
+
*
|
|
4
|
+
* Records per-component liveness signals for the AQE self-learning loop:
|
|
5
|
+
*
|
|
6
|
+
* captured_experiences (SQLite)
|
|
7
|
+
* → CapturedExperienceBridge.drain (component: 'bridge')
|
|
8
|
+
* → learning:experience:* kv
|
|
9
|
+
* → LearningConsolidationWorker.tick (component: 'learningWorker')
|
|
10
|
+
* → learning:pattern:* kv
|
|
11
|
+
* → DreamScheduler.tick (component: 'dreamScheduler')
|
|
12
|
+
* → dream_insights / qe_patterns
|
|
13
|
+
*
|
|
14
|
+
* Each tick records `{ success: true }` so operators can answer "is the
|
|
15
|
+
* loop closing end-to-end?" without DB-mining `dream_cycles`, `kv_store`,
|
|
16
|
+
* and `routing_outcomes` separately. Cumulative counters in `aqe learning
|
|
17
|
+
* stats` are not enough: they grow forever and can't distinguish "healthy
|
|
18
|
+
* loop" from "loop wedged 3 hours ago with stale totals".
|
|
19
|
+
*
|
|
20
|
+
* Persists as a single JSON value under `learning:loop-health` in the
|
|
21
|
+
* unified memory. Cheap to write (~200 bytes), cheap to read.
|
|
22
|
+
*/
|
|
23
|
+
export const LOOP_HEALTH_KEY = 'learning:loop-health';
|
|
24
|
+
/**
|
|
25
|
+
* Record one tick of a component. Always best-effort: a write failure here
|
|
26
|
+
* MUST NOT propagate to the calling component (the bridge / worker should
|
|
27
|
+
* keep running even if the health key can't be persisted).
|
|
28
|
+
*/
|
|
29
|
+
export async function recordLoopHealth(memory, component, result) {
|
|
30
|
+
try {
|
|
31
|
+
const now = new Date().toISOString();
|
|
32
|
+
const state = (await memory.get(LOOP_HEALTH_KEY)) ?? {
|
|
33
|
+
overallLastSuccess: '',
|
|
34
|
+
bootedAt: now,
|
|
35
|
+
components: {},
|
|
36
|
+
};
|
|
37
|
+
const existing = state.components[component] ?? {
|
|
38
|
+
lastSuccessAt: '',
|
|
39
|
+
ticksSinceBoot: 0,
|
|
40
|
+
successesSinceBoot: 0,
|
|
41
|
+
};
|
|
42
|
+
existing.ticksSinceBoot += 1;
|
|
43
|
+
if (result.success) {
|
|
44
|
+
existing.lastSuccessAt = now;
|
|
45
|
+
existing.successesSinceBoot += 1;
|
|
46
|
+
delete existing.lastError;
|
|
47
|
+
}
|
|
48
|
+
else if (result.error) {
|
|
49
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error);
|
|
50
|
+
existing.lastError = { message, at: now };
|
|
51
|
+
}
|
|
52
|
+
state.components[component] = existing;
|
|
53
|
+
// Recompute overallLastSuccess as max(component.lastSuccessAt). ISO 8601
|
|
54
|
+
// strings sort lexicographically the same as chronologically.
|
|
55
|
+
const successTimes = Object.values(state.components)
|
|
56
|
+
.map((c) => c?.lastSuccessAt ?? '')
|
|
57
|
+
.filter((t) => t !== '');
|
|
58
|
+
state.overallLastSuccess = successTimes.length > 0 ? successTimes.sort().pop() : '';
|
|
59
|
+
await memory.set(LOOP_HEALTH_KEY, state);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Loop-health is itself best-effort observability. Never throw.
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Read the current loop-health record. Returns undefined if no tick has
|
|
67
|
+
* ever fired — operators reading via `aqe learning loop-health` should
|
|
68
|
+
* interpret undefined as "the loop hasn't started yet (or workers aren't
|
|
69
|
+
* running)" rather than "the loop is healthy".
|
|
70
|
+
*/
|
|
71
|
+
export async function getLoopHealth(memory) {
|
|
72
|
+
try {
|
|
73
|
+
return await memory.get(LOOP_HEALTH_KEY);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Compute a staleness verdict per component given a "stale after" threshold.
|
|
81
|
+
* Caller chooses the threshold based on the component's expected cadence:
|
|
82
|
+
* - bridge: 5s poll → stale after ~30s
|
|
83
|
+
* - learningWorker: 30 min tick → stale after ~2h
|
|
84
|
+
* - dreamScheduler: variable → caller's call
|
|
85
|
+
*/
|
|
86
|
+
export function isComponentStale(health, staleAfterMs, now = new Date()) {
|
|
87
|
+
if (!health || !health.lastSuccessAt)
|
|
88
|
+
return true;
|
|
89
|
+
return now.getTime() - new Date(health.lastSuccessAt).getTime() > staleAfterMs;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=loop-health.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Usage Recorder
|
|
3
|
+
* ADR-021: QE ReasoningBank for Pattern Learning (single-writer extension)
|
|
4
|
+
*
|
|
5
|
+
* Single source of truth for "pattern was used in a task" accounting:
|
|
6
|
+
*
|
|
7
|
+
* - INSERTs a row into qe_pattern_usage (per-use audit trail)
|
|
8
|
+
* - UPDATEs qe_patterns.{usage_count, successful_uses, success_rate,
|
|
9
|
+
* quality_score, last_used_at, updated_at}
|
|
10
|
+
*
|
|
11
|
+
* Both writes happen inside ONE transaction so the audit trail and the
|
|
12
|
+
* aggregate columns never disagree on count.
|
|
13
|
+
*
|
|
14
|
+
* Before this helper, two parallel writers existed (#486 Gap B):
|
|
15
|
+
* - SQLitePatternStore.recordUsage — did BOTH INSERT and UPDATE atomically
|
|
16
|
+
* - hooks-dream-learning.ts inline UPDATE — did UPDATE only, skipping the
|
|
17
|
+
* audit INSERT. Hook-driven usage stayed invisible in qe_pattern_usage
|
|
18
|
+
* even as qe_patterns.usage_count incremented.
|
|
19
|
+
*
|
|
20
|
+
* Quality formula (mirrors pattern-lifecycle.ts and the legacy inline hook):
|
|
21
|
+
* quality_score = confidence * 0.3 + min(usage_count/100, 1) * 0.2 + success_rate * 0.5
|
|
22
|
+
*/
|
|
23
|
+
import type { Database as DatabaseType } from 'better-sqlite3';
|
|
24
|
+
export interface PatternUsageRecord {
|
|
25
|
+
patternId: string;
|
|
26
|
+
success: boolean;
|
|
27
|
+
metrics?: Record<string, unknown>;
|
|
28
|
+
feedback?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PatternUsageResult {
|
|
31
|
+
/**
|
|
32
|
+
* Whether the helper found and updated the pattern row.
|
|
33
|
+
* False (no throw) if patternId doesn't exist, since hook subprocesses
|
|
34
|
+
* iterate over selectedPatternIds that may include stale UUIDs from
|
|
35
|
+
* the routing kv. Callers who want strict semantics should check this
|
|
36
|
+
* flag and throw themselves.
|
|
37
|
+
*/
|
|
38
|
+
updated: boolean;
|
|
39
|
+
/** Post-update usage_count. Undefined if !updated. */
|
|
40
|
+
usageCount?: number;
|
|
41
|
+
/** Post-update successful_uses. Undefined if !updated. */
|
|
42
|
+
successfulUses?: number;
|
|
43
|
+
/** Post-update success_rate. Undefined if !updated. */
|
|
44
|
+
successRate?: number;
|
|
45
|
+
/** Post-update quality_score. Undefined if !updated. */
|
|
46
|
+
qualityScore?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Record one use of a pattern atomically across qe_pattern_usage and qe_patterns.
|
|
50
|
+
*
|
|
51
|
+
* Idempotency: each call inserts ONE audit row and increments usage_count by ONE.
|
|
52
|
+
* The transaction makes the two writes atomic — if either fails, neither lands.
|
|
53
|
+
*
|
|
54
|
+
* Concurrency: better-sqlite3 transactions are serialized at the connection
|
|
55
|
+
* level. Multiple concurrent callers on the same connection will queue.
|
|
56
|
+
*/
|
|
57
|
+
export declare function recordPatternUsage(db: DatabaseType, record: PatternUsageRecord): PatternUsageResult;
|
|
58
|
+
//# sourceMappingURL=pattern-usage-recorder.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Usage Recorder
|
|
3
|
+
* ADR-021: QE ReasoningBank for Pattern Learning (single-writer extension)
|
|
4
|
+
*
|
|
5
|
+
* Single source of truth for "pattern was used in a task" accounting:
|
|
6
|
+
*
|
|
7
|
+
* - INSERTs a row into qe_pattern_usage (per-use audit trail)
|
|
8
|
+
* - UPDATEs qe_patterns.{usage_count, successful_uses, success_rate,
|
|
9
|
+
* quality_score, last_used_at, updated_at}
|
|
10
|
+
*
|
|
11
|
+
* Both writes happen inside ONE transaction so the audit trail and the
|
|
12
|
+
* aggregate columns never disagree on count.
|
|
13
|
+
*
|
|
14
|
+
* Before this helper, two parallel writers existed (#486 Gap B):
|
|
15
|
+
* - SQLitePatternStore.recordUsage — did BOTH INSERT and UPDATE atomically
|
|
16
|
+
* - hooks-dream-learning.ts inline UPDATE — did UPDATE only, skipping the
|
|
17
|
+
* audit INSERT. Hook-driven usage stayed invisible in qe_pattern_usage
|
|
18
|
+
* even as qe_patterns.usage_count incremented.
|
|
19
|
+
*
|
|
20
|
+
* Quality formula (mirrors pattern-lifecycle.ts and the legacy inline hook):
|
|
21
|
+
* quality_score = confidence * 0.3 + min(usage_count/100, 1) * 0.2 + success_rate * 0.5
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Record one use of a pattern atomically across qe_pattern_usage and qe_patterns.
|
|
25
|
+
*
|
|
26
|
+
* Idempotency: each call inserts ONE audit row and increments usage_count by ONE.
|
|
27
|
+
* The transaction makes the two writes atomic — if either fails, neither lands.
|
|
28
|
+
*
|
|
29
|
+
* Concurrency: better-sqlite3 transactions are serialized at the connection
|
|
30
|
+
* level. Multiple concurrent callers on the same connection will queue.
|
|
31
|
+
*/
|
|
32
|
+
export function recordPatternUsage(db, record) {
|
|
33
|
+
const pattern = db
|
|
34
|
+
.prepare(`SELECT confidence, usage_count, successful_uses FROM qe_patterns WHERE id = ?`)
|
|
35
|
+
.get(record.patternId);
|
|
36
|
+
if (!pattern) {
|
|
37
|
+
return { updated: false };
|
|
38
|
+
}
|
|
39
|
+
const successInc = record.success ? 1 : 0;
|
|
40
|
+
const newUsageCount = pattern.usage_count + 1;
|
|
41
|
+
const newSuccessfulUses = pattern.successful_uses + successInc;
|
|
42
|
+
const newSuccessRate = newSuccessfulUses / newUsageCount;
|
|
43
|
+
const usageScore = Math.min(1, newUsageCount / 100);
|
|
44
|
+
const newQualityScore = pattern.confidence * 0.3 + usageScore * 0.2 + newSuccessRate * 0.5;
|
|
45
|
+
const insertUsage = db.prepare(`
|
|
46
|
+
INSERT INTO qe_pattern_usage (pattern_id, success, metrics_json, feedback)
|
|
47
|
+
VALUES (?, ?, ?, ?)
|
|
48
|
+
`);
|
|
49
|
+
const updatePattern = db.prepare(`
|
|
50
|
+
UPDATE qe_patterns SET
|
|
51
|
+
usage_count = ?,
|
|
52
|
+
successful_uses = ?,
|
|
53
|
+
success_rate = ?,
|
|
54
|
+
quality_score = ?,
|
|
55
|
+
last_used_at = datetime('now'),
|
|
56
|
+
updated_at = datetime('now')
|
|
57
|
+
WHERE id = ?
|
|
58
|
+
`);
|
|
59
|
+
const txn = db.transaction(() => {
|
|
60
|
+
insertUsage.run(record.patternId, successInc, record.metrics ? JSON.stringify(record.metrics) : null, record.feedback ?? null);
|
|
61
|
+
updatePattern.run(newUsageCount, newSuccessfulUses, newSuccessRate, newQualityScore, record.patternId);
|
|
62
|
+
});
|
|
63
|
+
txn();
|
|
64
|
+
return {
|
|
65
|
+
updated: true,
|
|
66
|
+
usageCount: newUsageCount,
|
|
67
|
+
successfulUses: newSuccessfulUses,
|
|
68
|
+
successRate: newSuccessRate,
|
|
69
|
+
qualityScore: newQualityScore,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=pattern-usage-recorder.js.map
|
|
@@ -79,6 +79,17 @@ export interface QERoutingResult {
|
|
|
79
79
|
guidance: string[];
|
|
80
80
|
/** Reasoning for the recommendation */
|
|
81
81
|
reasoning: string;
|
|
82
|
+
/**
|
|
83
|
+
* ADR-095 telemetry — all optional, populated by routeTask when the
|
|
84
|
+
* exploration / Q-value path runs. Callers persist these into
|
|
85
|
+
* routing_outcomes for retrospective analysis.
|
|
86
|
+
*/
|
|
87
|
+
/** True if ε-greedy promoted an alternative over the greedy winner. */
|
|
88
|
+
exploration?: boolean;
|
|
89
|
+
/** Mincut safety multiplier in effect (1.0 = full rate, 0.2 = dampened). */
|
|
90
|
+
criticality?: number;
|
|
91
|
+
/** Average qWeight across the scored agents — proxy for Q-table maturity. */
|
|
92
|
+
qWeight?: number;
|
|
82
93
|
}
|
|
83
94
|
/**
|
|
84
95
|
* Pattern learning outcome
|
|
@@ -118,6 +118,17 @@ export declare class QEReasoningBank implements IQEReasoningBank {
|
|
|
118
118
|
* Route a task to optimal agent
|
|
119
119
|
*/
|
|
120
120
|
routeTask(request: QERoutingRequest): Promise<Result<QERoutingResult>>;
|
|
121
|
+
/**
|
|
122
|
+
* ADR-095: Build a per-agent Q-value lookup closure for the current
|
|
123
|
+
* routing decision. The closure executes a prepared-statement query
|
|
124
|
+
* against `rl_q_values` for each agent considered.
|
|
125
|
+
*
|
|
126
|
+
* Returns a no-op lookup when the unified memory backend is unavailable
|
|
127
|
+
* (e.g. during early boot or in tests that don't initialize SQLite).
|
|
128
|
+
* The no-op causes `calculateAgentScores` to fall back to pure-static
|
|
129
|
+
* scoring — identical to pre-ADR-095 behavior.
|
|
130
|
+
*/
|
|
131
|
+
private buildQValueLookup;
|
|
121
132
|
/**
|
|
122
133
|
* Get guidance for a domain
|
|
123
134
|
*/
|
|
@@ -25,7 +25,9 @@ import { getWitnessChain } from '../audit/witness-chain.js';
|
|
|
25
25
|
// Import extracted modules
|
|
26
26
|
import { DEFAULT_QE_REASONING_BANK_CONFIG } from './qe-reasoning-bank-types.js';
|
|
27
27
|
import { PRETRAINED_PATTERNS } from './pretrained-patterns.js';
|
|
28
|
-
import { AGENT_CAPABILITIES, calculateAgentScores, } from './agent-routing.js';
|
|
28
|
+
import { AGENT_CAPABILITIES, calculateAgentScores, applyExplorationPolicy, resolveExplorationRate, deriveTaskType, buildRoutingStateKey, deriveComplexityBucket, } from './agent-routing.js';
|
|
29
|
+
import { resolveTopologyCriticalFromSharedMincut } from './routing-topology-gate.js';
|
|
30
|
+
import { getUnifiedMemory } from '../kernel/unified-memory.js';
|
|
29
31
|
import { resizeEmbedding, hashEmbedding } from './embedding-utils.js';
|
|
30
32
|
import { checkPatternPromotionWithCoherence, promotePattern as promotePatternFn, seedCrossDomainPatterns as seedCrossDomainPatternsFn, } from './pattern-promotion.js';
|
|
31
33
|
// ============================================================================
|
|
@@ -395,8 +397,35 @@ export class QEReasoningBank {
|
|
|
395
397
|
agentDomainPatternCounts.set(agentType, count);
|
|
396
398
|
}
|
|
397
399
|
}
|
|
398
|
-
//
|
|
399
|
-
|
|
400
|
+
// ADR-095: build the Q-value lookup closure from the task's state_key.
|
|
401
|
+
// The state_key MUST match what `updateHookRouterQValue` writes from
|
|
402
|
+
// post-task — buildRoutingStateKey enforces that.
|
|
403
|
+
const stateKey = buildRoutingStateKey({
|
|
404
|
+
taskType: deriveTaskType(request.task),
|
|
405
|
+
priority: 'normal',
|
|
406
|
+
domain: detectedDomains[0],
|
|
407
|
+
complexityBucket: deriveComplexityBucket(request.task),
|
|
408
|
+
});
|
|
409
|
+
const qValueLookup = this.buildQValueLookup(stateKey);
|
|
410
|
+
// 4. Calculate agent scores (now Q-blended when lookup available)
|
|
411
|
+
const agentScores = calculateAgentScores(detectedDomains, request.capabilities, agentDomainPatternCounts, this.config.routingWeights, AGENT_CAPABILITIES, request.context?.language, qValueLookup);
|
|
412
|
+
// ADR-095: ε-greedy exploration with mincut safety gate.
|
|
413
|
+
// The exploration is best-effort — failures fall through to greedy.
|
|
414
|
+
// Topology check uses `resolveTopologyCriticalFromSharedMincut` —
|
|
415
|
+
// see that module for the empty-graph regression context.
|
|
416
|
+
let safetyMultiplier = 1.0;
|
|
417
|
+
try {
|
|
418
|
+
const topologyCritical = resolveTopologyCriticalFromSharedMincut();
|
|
419
|
+
const rateInfo = resolveExplorationRate({
|
|
420
|
+
envOverride: process.env.AQE_ROUTER_EXPLORATION_RATE,
|
|
421
|
+
topologyCritical,
|
|
422
|
+
});
|
|
423
|
+
safetyMultiplier = rateInfo.safetyMultiplier;
|
|
424
|
+
applyExplorationPolicy(agentScores, rateInfo.epsilon);
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
// Exploration failures are non-fatal; greedy order stands.
|
|
428
|
+
}
|
|
400
429
|
const recommended = agentScores[0];
|
|
401
430
|
const alternatives = agentScores.slice(1, 4);
|
|
402
431
|
// Generate guidance
|
|
@@ -411,6 +440,11 @@ export class QEReasoningBank {
|
|
|
411
440
|
}
|
|
412
441
|
// Update stats
|
|
413
442
|
this.stats.totalRoutingConfidence += recommended.score;
|
|
443
|
+
// ADR-095 telemetry: average qWeight across the scored agents — a
|
|
444
|
+
// proxy for Q-table maturity. Operators can correlate this with
|
|
445
|
+
// routing_outcomes.quality_score over time to see if learning helps.
|
|
446
|
+
const totalQWeight = agentScores.reduce((acc, a) => acc + (a.qWeight ?? 0), 0);
|
|
447
|
+
const avgQWeight = agentScores.length > 0 ? totalQWeight / agentScores.length : 0;
|
|
414
448
|
const result = {
|
|
415
449
|
recommendedAgent: recommended.agent,
|
|
416
450
|
confidence: recommended.score,
|
|
@@ -419,6 +453,9 @@ export class QEReasoningBank {
|
|
|
419
453
|
patterns,
|
|
420
454
|
guidance,
|
|
421
455
|
reasoning: recommended.reasoning.join('; '),
|
|
456
|
+
exploration: recommended.exploration === true,
|
|
457
|
+
criticality: safetyMultiplier,
|
|
458
|
+
qWeight: avgQWeight,
|
|
422
459
|
};
|
|
423
460
|
return ok(result);
|
|
424
461
|
}
|
|
@@ -426,6 +463,52 @@ export class QEReasoningBank {
|
|
|
426
463
|
return err(toError(error));
|
|
427
464
|
}
|
|
428
465
|
}
|
|
466
|
+
/**
|
|
467
|
+
* ADR-095: Build a per-agent Q-value lookup closure for the current
|
|
468
|
+
* routing decision. The closure executes a prepared-statement query
|
|
469
|
+
* against `rl_q_values` for each agent considered.
|
|
470
|
+
*
|
|
471
|
+
* Returns a no-op lookup when the unified memory backend is unavailable
|
|
472
|
+
* (e.g. during early boot or in tests that don't initialize SQLite).
|
|
473
|
+
* The no-op causes `calculateAgentScores` to fall back to pure-static
|
|
474
|
+
* scoring — identical to pre-ADR-095 behavior.
|
|
475
|
+
*/
|
|
476
|
+
buildQValueLookup(stateKey) {
|
|
477
|
+
try {
|
|
478
|
+
const um = getUnifiedMemory();
|
|
479
|
+
if (!um.isInitialized())
|
|
480
|
+
return () => undefined;
|
|
481
|
+
const db = um.getDatabase();
|
|
482
|
+
// Verify the Q-table exists; many CLI commands run without ever
|
|
483
|
+
// initializing the schema and the SELECT below would throw.
|
|
484
|
+
const tableExists = db
|
|
485
|
+
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='rl_q_values'")
|
|
486
|
+
.get();
|
|
487
|
+
if (!tableExists)
|
|
488
|
+
return () => undefined;
|
|
489
|
+
const stmt = db.prepare(`
|
|
490
|
+
SELECT q_value, visits FROM rl_q_values
|
|
491
|
+
WHERE algorithm = 'q-learning'
|
|
492
|
+
AND agent_id = 'aqe-hook-router'
|
|
493
|
+
AND state_key = ?
|
|
494
|
+
AND action_key = ?
|
|
495
|
+
`);
|
|
496
|
+
return (agentType) => {
|
|
497
|
+
try {
|
|
498
|
+
const row = stmt.get(stateKey, agentType);
|
|
499
|
+
if (!row)
|
|
500
|
+
return undefined;
|
|
501
|
+
return { qValue: row.q_value, visits: row.visits };
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
return undefined;
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
return () => undefined;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
429
512
|
/**
|
|
430
513
|
* Get guidance for a domain
|
|
431
514
|
*/
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing Topology Safety Gate (ADR-095 — CRITICAL #1 follow-up)
|
|
3
|
+
*
|
|
4
|
+
* Resolves whether the agent dependency graph is in a "critical" topology
|
|
5
|
+
* state for the purpose of dampening exploration in QEReasoningBank.routeTask.
|
|
6
|
+
*
|
|
7
|
+
* Why this lives in its own module:
|
|
8
|
+
*
|
|
9
|
+
* 1. Testability. The reasoning-bank's full init path (real embeddings,
|
|
10
|
+
* HNSW, pretrained patterns) is OOM-heavy in test environments. Putting
|
|
11
|
+
* the topology gate here lets us unit-test it against a fresh
|
|
12
|
+
* SwarmGraph singleton without spinning up the kernel + bank stack.
|
|
13
|
+
*
|
|
14
|
+
* 2. The empty-graph regression. `MinCutCalculator.getMinCutValue` returns
|
|
15
|
+
* 0 on an empty graph; `MinCutHealthMonitor.isCritical()` is defined as
|
|
16
|
+
* `minCutValue < warningThreshold`, so an empty graph reports as
|
|
17
|
+
* critical. CLI hook routing — the only place this gate fires in
|
|
18
|
+
* practice — sees an empty graph because Queen coordinator activity
|
|
19
|
+
* is what populates it. Without the emptiness check, exploration is
|
|
20
|
+
* permanently dampened in the exact deployment case ADR-095 was meant
|
|
21
|
+
* to help.
|
|
22
|
+
*
|
|
23
|
+
* Treat empty/uninitialized graph as "no signal" (full ε rate). Only
|
|
24
|
+
* consult `isCritical()` when the graph has actual vertices.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Returns true ONLY when:
|
|
28
|
+
* 1. The shared monitor + graph are both initialized
|
|
29
|
+
* 2. The graph has at least one vertex (so the mincut value is real,
|
|
30
|
+
* not the degenerate 0 of an empty graph)
|
|
31
|
+
* 3. The monitor's `isCritical()` returns true
|
|
32
|
+
*
|
|
33
|
+
* Any other state returns false (full ε rate / no dampening).
|
|
34
|
+
*
|
|
35
|
+
* All errors are swallowed — the gate is a best-effort signal that must
|
|
36
|
+
* never block routing. Caller defaults safetyMultiplier to 1.0 when this
|
|
37
|
+
* returns false.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveTopologyCriticalFromSharedMincut(): boolean;
|
|
40
|
+
//# sourceMappingURL=routing-topology-gate.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing Topology Safety Gate (ADR-095 — CRITICAL #1 follow-up)
|
|
3
|
+
*
|
|
4
|
+
* Resolves whether the agent dependency graph is in a "critical" topology
|
|
5
|
+
* state for the purpose of dampening exploration in QEReasoningBank.routeTask.
|
|
6
|
+
*
|
|
7
|
+
* Why this lives in its own module:
|
|
8
|
+
*
|
|
9
|
+
* 1. Testability. The reasoning-bank's full init path (real embeddings,
|
|
10
|
+
* HNSW, pretrained patterns) is OOM-heavy in test environments. Putting
|
|
11
|
+
* the topology gate here lets us unit-test it against a fresh
|
|
12
|
+
* SwarmGraph singleton without spinning up the kernel + bank stack.
|
|
13
|
+
*
|
|
14
|
+
* 2. The empty-graph regression. `MinCutCalculator.getMinCutValue` returns
|
|
15
|
+
* 0 on an empty graph; `MinCutHealthMonitor.isCritical()` is defined as
|
|
16
|
+
* `minCutValue < warningThreshold`, so an empty graph reports as
|
|
17
|
+
* critical. CLI hook routing — the only place this gate fires in
|
|
18
|
+
* practice — sees an empty graph because Queen coordinator activity
|
|
19
|
+
* is what populates it. Without the emptiness check, exploration is
|
|
20
|
+
* permanently dampened in the exact deployment case ADR-095 was meant
|
|
21
|
+
* to help.
|
|
22
|
+
*
|
|
23
|
+
* Treat empty/uninitialized graph as "no signal" (full ε rate). Only
|
|
24
|
+
* consult `isCritical()` when the graph has actual vertices.
|
|
25
|
+
*/
|
|
26
|
+
import { getSharedMinCutGraph, getSharedMinCutMonitor, isSharedMinCutGraphInitialized, isSharedMinCutMonitorInitialized, } from '../coordination/mincut/shared-singleton.js';
|
|
27
|
+
/**
|
|
28
|
+
* Returns true ONLY when:
|
|
29
|
+
* 1. The shared monitor + graph are both initialized
|
|
30
|
+
* 2. The graph has at least one vertex (so the mincut value is real,
|
|
31
|
+
* not the degenerate 0 of an empty graph)
|
|
32
|
+
* 3. The monitor's `isCritical()` returns true
|
|
33
|
+
*
|
|
34
|
+
* Any other state returns false (full ε rate / no dampening).
|
|
35
|
+
*
|
|
36
|
+
* All errors are swallowed — the gate is a best-effort signal that must
|
|
37
|
+
* never block routing. Caller defaults safetyMultiplier to 1.0 when this
|
|
38
|
+
* returns false.
|
|
39
|
+
*/
|
|
40
|
+
export function resolveTopologyCriticalFromSharedMincut() {
|
|
41
|
+
try {
|
|
42
|
+
if (!isSharedMinCutMonitorInitialized())
|
|
43
|
+
return false;
|
|
44
|
+
if (!isSharedMinCutGraphInitialized())
|
|
45
|
+
return false;
|
|
46
|
+
const graph = getSharedMinCutGraph();
|
|
47
|
+
if (graph.isEmpty())
|
|
48
|
+
return false;
|
|
49
|
+
return getSharedMinCutMonitor().isCritical();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=routing-topology-gate.js.map
|
|
@@ -115,7 +115,12 @@ export declare class SQLitePatternStore {
|
|
|
115
115
|
embedding: number[];
|
|
116
116
|
}>;
|
|
117
117
|
/**
|
|
118
|
-
* Record pattern usage
|
|
118
|
+
* Record pattern usage.
|
|
119
|
+
*
|
|
120
|
+
* Delegates to {@link recordPatternUsage} so the hook path
|
|
121
|
+
* (hooks-dream-learning.ts) and the canonical pattern-store path share a
|
|
122
|
+
* single writer — #486 Gap B. Preserves the previous throw-on-missing
|
|
123
|
+
* contract by checking the helper's `updated` flag.
|
|
119
124
|
*/
|
|
120
125
|
recordUsage(patternId: string, success: boolean, metrics?: Record<string, unknown>, feedback?: string): void;
|
|
121
126
|
/**
|
|
@@ -17,6 +17,7 @@ import { safeJsonParse } from '../shared/safe-json.js';
|
|
|
17
17
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
18
18
|
import { getUnifiedMemory } from '../kernel/unified-memory.js';
|
|
19
19
|
import { computeBatchEmbeddings, getEmbeddingDimension } from './real-embeddings.js';
|
|
20
|
+
import { recordPatternUsage } from './pattern-usage-recorder.js';
|
|
20
21
|
export const DEFAULT_SQLITE_CONFIG = {
|
|
21
22
|
// LEGACY: Ignored when useUnified=true (the default). All data goes to memory.db
|
|
22
23
|
dbPath: '.agentic-qe/memory.db',
|
|
@@ -518,32 +519,25 @@ export class SQLitePatternStore {
|
|
|
518
519
|
}));
|
|
519
520
|
}
|
|
520
521
|
/**
|
|
521
|
-
* Record pattern usage
|
|
522
|
+
* Record pattern usage.
|
|
523
|
+
*
|
|
524
|
+
* Delegates to {@link recordPatternUsage} so the hook path
|
|
525
|
+
* (hooks-dream-learning.ts) and the canonical pattern-store path share a
|
|
526
|
+
* single writer — #486 Gap B. Preserves the previous throw-on-missing
|
|
527
|
+
* contract by checking the helper's `updated` flag.
|
|
522
528
|
*/
|
|
523
529
|
recordUsage(patternId, success, metrics, feedback) {
|
|
524
530
|
if (!this.db)
|
|
525
531
|
throw new Error('Database not initialized');
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
if (!pattern) {
|
|
532
|
+
const result = recordPatternUsage(this.db, {
|
|
533
|
+
patternId,
|
|
534
|
+
success,
|
|
535
|
+
metrics,
|
|
536
|
+
feedback,
|
|
537
|
+
});
|
|
538
|
+
if (!result.updated) {
|
|
534
539
|
throw new Error(`Pattern not found: ${patternId}`);
|
|
535
540
|
}
|
|
536
|
-
const newUsageCount = pattern.usageCount + 1;
|
|
537
|
-
const newSuccessfulUses = pattern.successfulUses + (success ? 1 : 0);
|
|
538
|
-
const newSuccessRate = newSuccessfulUses / newUsageCount;
|
|
539
|
-
// Quality score: confidence * 0.3 + usage * 0.2 + success_rate * 0.5
|
|
540
|
-
const usageScore = Math.min(1, newUsageCount / 100);
|
|
541
|
-
const qualityScore = pattern.confidence * 0.3 + usageScore * 0.2 + newSuccessRate * 0.5;
|
|
542
|
-
const transaction = this.db.transaction(() => {
|
|
543
|
-
insertUsage.run(patternId, success ? 1 : 0, metrics ? JSON.stringify(metrics) : null, feedback || null);
|
|
544
|
-
updatePattern.run(success ? 1 : 0, success ? 1 : 0, qualityScore, patternId);
|
|
545
|
-
});
|
|
546
|
-
transaction();
|
|
547
541
|
}
|
|
548
542
|
/**
|
|
549
543
|
* Delete a pattern and its related data (embedding, usage history)
|