agentic-qe 3.12.1 → 3.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +87 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-D657MKZY.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-P4VYM5KK.js → agent-booster-wasm-XFAQATTH.js} +2 -2
- package/dist/cli/chunks/{agent-handler-PBQ7L2TO.js → agent-handler-2ZV4CA3U.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-UPWO3X6V.js → agent-memory-branch-6WGP7F5T.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-AFR6OZJK.js +2 -0
- package/dist/cli/chunks/{arena-QYTP3FG6.js → arena-FWX7XZAE.js} +4 -4
- package/dist/cli/chunks/{arena-LEUTILZ7.js → arena-KJUNQK4N.js} +2 -2
- package/dist/cli/chunks/{audit-TB6M2YLK.js → audit-YFUDEOKN.js} +3 -3
- package/dist/cli/chunks/base-K5QRGZWE.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-62RTSHAY.js → better-sqlite3-FE55OGYB.js} +2 -2
- package/dist/cli/chunks/brain-handler-ZCK4WTPK.js +89 -0
- package/dist/cli/chunks/{branch-enumerator-WEIP3DXB.js → branch-enumerator-HTVINRYG.js} +2 -2
- package/dist/cli/chunks/{browser-HY6VLXHZ.js → browser-WUL2B77M.js} +2 -2
- package/dist/cli/chunks/browser-workflow-ZMMKCGYW.js +2 -0
- package/dist/cli/chunks/{chunk-NHRBKOYD.js → chunk-2CPJCXV6.js} +2 -2
- package/dist/cli/chunks/{chunk-D72N5V2S.js → chunk-2HCMRGMO.js} +2 -2
- package/dist/cli/chunks/{chunk-UBPJQKYS.js → chunk-2LNDU7AW.js} +2 -2
- package/dist/cli/chunks/{chunk-ONSNNY6J.js → chunk-2OX74DOO.js} +1 -1
- package/dist/cli/chunks/{chunk-QORWBION.js → chunk-2YDZXFO2.js} +2 -2
- package/dist/cli/chunks/{chunk-QJXUK54J.js → chunk-32L7DKNQ.js} +2 -2
- package/dist/cli/chunks/{chunk-UZXDYT6O.js → chunk-3YC4YUGB.js} +2 -2
- package/dist/cli/chunks/{chunk-NOCPO55P.js → chunk-4EHW4TNA.js} +2 -2
- package/dist/cli/chunks/{chunk-QZBPXJ5C.js → chunk-4HP7N6SP.js} +2 -2
- package/dist/cli/chunks/{chunk-XTAXSKPC.js → chunk-5FAWIIWF.js} +2 -2
- package/dist/cli/chunks/{chunk-YGB3MT3R.js → chunk-67BCEHU5.js} +1 -1
- package/dist/cli/chunks/{chunk-3W2FZXFD.js → chunk-6E47R27C.js} +1 -1
- package/dist/cli/chunks/{chunk-74VIADSJ.js → chunk-6HQDPDN5.js} +2 -2
- package/dist/cli/chunks/chunk-6SQ72FG7.js +2 -0
- package/dist/cli/chunks/{chunk-RJ7TU2MP.js → chunk-6SUSRXXF.js} +1 -1
- package/dist/cli/chunks/{chunk-FFSS3Y6W.js → chunk-72QQDR3Y.js} +2 -2
- package/dist/cli/chunks/{chunk-CP4GSICY.js → chunk-7Q74K3HZ.js} +1 -1
- package/dist/cli/chunks/{chunk-UEC53US3.js → chunk-7WF3TW3G.js} +4 -4
- package/dist/cli/chunks/chunk-7XUM4LBC.js +2 -0
- package/dist/cli/chunks/{chunk-UGPBL7LX.js → chunk-ADQFQBFJ.js} +2 -2
- package/dist/cli/chunks/{chunk-BALFQQB7.js → chunk-AIWRYWK2.js} +2 -2
- package/dist/cli/chunks/{chunk-XJTGLG7G.js → chunk-AZ24ONMX.js} +1 -1
- package/dist/cli/chunks/{chunk-LRWBOJ5Y.js → chunk-BDGKB2PT.js} +2 -2
- package/dist/cli/chunks/{chunk-NK2Z6FGF.js → chunk-BEPP57C2.js} +2 -2
- package/dist/cli/chunks/{chunk-HGKSU4QV.js → chunk-BQ2K4BPD.js} +2 -2
- package/dist/cli/chunks/{chunk-QOAI6ETC.js → chunk-BSNNTOHY.js} +3 -3
- package/dist/cli/chunks/chunk-CHFTHSMM.js +9 -0
- package/dist/cli/chunks/{chunk-IHWWZOHP.js → chunk-CL6SNCFF.js} +1 -1
- package/dist/cli/chunks/{chunk-7N2SCRWJ.js → chunk-CXMOIE7D.js} +2 -2
- package/dist/cli/chunks/{chunk-PZ3Q34OT.js → chunk-CYSBM52D.js} +2 -2
- package/dist/cli/chunks/{chunk-X2CEX4KC.js → chunk-D4GMAUTP.js} +10 -10
- package/dist/cli/chunks/{chunk-JDZIBSMY.js → chunk-DCYBV6HV.js} +1 -1
- package/dist/cli/chunks/chunk-DDYP6FBC.js +2 -0
- package/dist/cli/chunks/{chunk-SFQFBLWQ.js → chunk-DHUZHT5D.js} +1 -1
- package/dist/cli/chunks/{chunk-X2K3BTI4.js → chunk-DMD6WVJ2.js} +2 -2
- package/dist/cli/chunks/{chunk-GW3M7GQH.js → chunk-DTZFZ5M7.js} +2 -2
- package/dist/cli/chunks/{chunk-WBDV4V3H.js → chunk-DW7OI5IF.js} +2 -2
- package/dist/cli/chunks/{chunk-CYYT6YEV.js → chunk-DZ775UGW.js} +2 -2
- package/dist/cli/chunks/{chunk-BNMV5DCM.js → chunk-E2U3LTGM.js} +1 -1
- package/dist/cli/chunks/{chunk-KQV5644J.js → chunk-E53UR2EW.js} +3 -3
- package/dist/cli/chunks/{chunk-XYV6YUWS.js → chunk-EH7TSJPS.js} +2 -2
- package/dist/cli/chunks/{chunk-42GFB7VX.js → chunk-EHO52NKU.js} +2 -2
- package/dist/cli/chunks/{chunk-75AVUS5U.js → chunk-EOUJ6X5H.js} +1 -1
- package/dist/cli/chunks/{chunk-ZNITDSWL.js → chunk-FHHCH7WL.js} +1 -1
- package/dist/cli/chunks/{chunk-PQ4NSXZM.js → chunk-FJACKKRL.js} +2 -2
- package/dist/cli/chunks/{chunk-45QNHMTP.js → chunk-FTM562PF.js} +1 -1
- package/dist/cli/chunks/{chunk-4KI72C2E.js → chunk-FXOOOJQD.js} +1 -1
- package/dist/cli/chunks/chunk-G5OGKVLO.js +2 -0
- package/dist/cli/chunks/{chunk-42PYEEYQ.js → chunk-GGTCD4MA.js} +1 -1
- package/dist/cli/chunks/{chunk-GASACVTU.js → chunk-GMFFMJD6.js} +2 -2
- package/dist/cli/chunks/{chunk-JRNDFC23.js → chunk-GS6G7AVS.js} +2 -2
- package/dist/cli/chunks/{chunk-BKKJEKNT.js → chunk-GV2BS5NC.js} +2 -2
- package/dist/cli/chunks/{chunk-JRHRC2MP.js → chunk-HGJQSTQD.js} +1 -1
- package/dist/cli/chunks/{chunk-M5P5WNXA.js → chunk-HJ2LG5IH.js} +1 -1
- package/dist/cli/chunks/{chunk-UR655D4K.js → chunk-HJ4U64BL.js} +2 -2
- package/dist/cli/chunks/chunk-ILRKO6A5.js +43 -0
- package/dist/cli/chunks/{chunk-LZ6TJ7XL.js → chunk-IWQHQLT6.js} +2 -2
- package/dist/cli/chunks/{chunk-SHKOPOPD.js → chunk-J2RJOJ5Q.js} +1 -1
- package/dist/cli/chunks/{chunk-JIM4VSLF.js → chunk-KA4EAMMQ.js} +3 -3
- package/dist/cli/chunks/{chunk-6432JORM.js → chunk-KE3RK35K.js} +1 -1
- package/dist/cli/chunks/{chunk-VTFYY4SH.js → chunk-KGHSKDC7.js} +2 -2
- package/dist/cli/chunks/{chunk-3I3Z4C5X.js → chunk-KKOFH26C.js} +1 -1
- package/dist/cli/chunks/{chunk-AGWKCY42.js → chunk-KNWBRMLL.js} +2 -2
- package/dist/cli/chunks/{chunk-C7HGYLNF.js → chunk-KRS4KGX5.js} +2 -2
- package/dist/cli/chunks/{chunk-VHJCQBD2.js → chunk-KVHCWH4H.js} +2 -2
- package/dist/cli/chunks/{chunk-N3PSRG6F.js → chunk-KXKACV3E.js} +2 -2
- package/dist/cli/chunks/{chunk-BLU7OLQZ.js → chunk-L2X3BWMN.js} +2 -2
- package/dist/cli/chunks/{chunk-4U5MJX2H.js → chunk-L6GZGEFQ.js} +2 -2
- package/dist/cli/chunks/{chunk-DSNFOX22.js → chunk-LCM7TY76.js} +2 -2
- package/dist/cli/chunks/{chunk-NVXSM7UO.js → chunk-LGYEOYQJ.js} +2 -2
- package/dist/cli/chunks/{chunk-J4IAMQZI.js → chunk-LHAUFY4Y.js} +2 -2
- package/dist/cli/chunks/{chunk-OJORNYN3.js → chunk-LNIHLNW4.js} +3 -3
- package/dist/cli/chunks/{chunk-PRA73XZY.js → chunk-M32DTUZM.js} +2 -2
- package/dist/cli/chunks/{chunk-GGF5FZWS.js → chunk-M7W6VJ65.js} +1 -1
- package/dist/cli/chunks/{chunk-HZGFER4N.js → chunk-MB7TZQW3.js} +3 -3
- package/dist/cli/chunks/{chunk-RIASOMB2.js → chunk-MOX25RZQ.js} +2 -2
- package/dist/cli/chunks/{chunk-BPM7NEHS.js → chunk-MOXKKY5Q.js} +6 -6
- package/dist/cli/chunks/{chunk-UKF4V7LE.js → chunk-MS6VOSPY.js} +5 -5
- package/dist/cli/chunks/{chunk-QXZOUETY.js → chunk-MSDIIRLM.js} +2 -2
- package/dist/cli/chunks/{chunk-BBNQDHGF.js → chunk-MZ7SIO6R.js} +2 -2
- package/dist/cli/chunks/{chunk-HDI3FD4G.js → chunk-N4ML23ZG.js} +1 -1
- package/dist/cli/chunks/{chunk-7KHIOWBN.js → chunk-NAMJGRGC.js} +1 -1
- package/dist/cli/chunks/{chunk-IE6FDICX.js → chunk-NJDLJ3KD.js} +2 -2
- package/dist/cli/chunks/{chunk-4LKQZW2H.js → chunk-NKTLKMUB.js} +1 -1
- package/dist/cli/chunks/{chunk-CXUHD2O5.js → chunk-NLDLUHOF.js} +2 -2
- package/dist/cli/chunks/{chunk-XDRAU3W6.js → chunk-NOSQI2OW.js} +2 -2
- package/dist/cli/chunks/{chunk-ZCDGLNJ7.js → chunk-NT66CT73.js} +2 -2
- package/dist/cli/chunks/{chunk-JWZNWVLG.js → chunk-NX522PRH.js} +2 -2
- package/dist/cli/chunks/{chunk-O65OPAZH.js → chunk-OBL6W4Z5.js} +2 -2
- package/dist/cli/chunks/chunk-OPG2HV2W.js +2 -0
- package/dist/cli/chunks/{chunk-BCBITOMT.js → chunk-PDX7IYTJ.js} +2 -2
- package/dist/cli/chunks/{chunk-IC6SOVGO.js → chunk-PEHEANAM.js} +2 -2
- package/dist/cli/chunks/{chunk-J6ZCULWG.js → chunk-PPUDKQ4X.js} +2 -2
- package/dist/cli/chunks/{chunk-WPEGG6DX.js → chunk-PSDH7CIL.js} +1 -1
- package/dist/cli/chunks/{chunk-NTMN2ZJY.js → chunk-PTPN6HQ7.js} +2 -2
- package/dist/cli/chunks/{chunk-C2K4LQI5.js → chunk-PXCJDB7J.js} +1 -1
- package/dist/cli/chunks/{chunk-WPG5LXR7.js → chunk-QILF6BZH.js} +2 -2
- package/dist/cli/chunks/{chunk-BAHXVVX3.js → chunk-R6WMGSEK.js} +2 -2
- package/dist/cli/chunks/{chunk-2PQ7YADF.js → chunk-RE42RJYR.js} +2 -2
- package/dist/cli/chunks/{chunk-BWNMAXV7.js → chunk-RLBNAB6Y.js} +1 -1
- package/dist/cli/chunks/{chunk-BXIJY6SB.js → chunk-ROFCS47F.js} +1 -1
- package/dist/cli/chunks/{chunk-7KK6XSYK.js → chunk-RSZOCQOL.js} +2 -2
- package/dist/cli/chunks/{chunk-NEXJUTHF.js → chunk-S47YGWXK.js} +2 -2
- package/dist/cli/chunks/{chunk-5H5A74U2.js → chunk-SFS3UHNF.js} +1 -1
- package/dist/cli/chunks/{chunk-U5ITD7ZD.js → chunk-SGMJ277D.js} +1 -1
- package/dist/cli/chunks/{chunk-OXVAGR64.js → chunk-SPI4LUJ6.js} +2 -2
- package/dist/cli/chunks/{chunk-FBYFDD7L.js → chunk-SV7J5FDW.js} +2 -2
- package/dist/cli/chunks/{chunk-S42RFOZJ.js → chunk-TP3UAWMB.js} +2 -2
- package/dist/cli/chunks/{chunk-OEXSBR72.js → chunk-TXLPOXAN.js} +1 -1
- package/dist/cli/chunks/{chunk-R4A6PY5D.js → chunk-UAPUA6OY.js} +2 -2
- package/dist/cli/chunks/{chunk-55MQ2SFP.js → chunk-UGW23T6S.js} +2 -2
- package/dist/cli/chunks/{chunk-774X6OJY.js → chunk-UGXHMQ6P.js} +2 -2
- package/dist/cli/chunks/{chunk-GLO53MUQ.js → chunk-UIHZ34SJ.js} +2 -2
- package/dist/cli/chunks/{chunk-TMPRR3FZ.js → chunk-ULQCEM7K.js} +2 -2
- package/dist/cli/chunks/{chunk-YNXQMJGJ.js → chunk-UZ7FXVH5.js} +1 -1
- package/dist/cli/chunks/{chunk-LAJHHR3Q.js → chunk-VFYMWDSJ.js} +1 -1
- package/dist/cli/chunks/{chunk-XS6BIOPQ.js → chunk-VSD6JE2H.js} +2 -2
- package/dist/cli/chunks/{chunk-MIAY35K6.js → chunk-VUCVSKJC.js} +2 -2
- package/dist/cli/chunks/{chunk-I4BZLVFE.js → chunk-WBZNLFTV.js} +3 -3
- package/dist/cli/chunks/{chunk-PDS5P5QD.js → chunk-WFPGIP4N.js} +2 -2
- package/dist/cli/chunks/{chunk-PZZDAECU.js → chunk-WKE6WL5C.js} +3 -3
- package/dist/cli/chunks/{chunk-VFRWLSQO.js → chunk-WQASUQ5P.js} +1 -1
- package/dist/cli/chunks/{chunk-GXMNCW2M.js → chunk-WUE53ZPH.js} +1 -1
- package/dist/cli/chunks/{chunk-UBWSYDO5.js → chunk-XBOCRCC6.js} +1 -1
- package/dist/cli/chunks/{chunk-HHMTQQUE.js → chunk-XDHGCBTS.js} +2 -2
- package/dist/cli/chunks/chunk-XQ5JT7KM.js +3 -0
- package/dist/cli/chunks/{chunk-USTUWUCE.js → chunk-XUUVAAHV.js} +2 -2
- package/dist/cli/chunks/{chunk-6RX5QZMU.js → chunk-XZGOXLZH.js} +1 -1
- package/dist/cli/chunks/{chunk-DQ3J7ZT6.js → chunk-Y5L37K7X.js} +2 -2
- package/dist/cli/chunks/{chunk-5HMGDB7B.js → chunk-Y625LP6K.js} +3 -3
- package/dist/cli/chunks/{chunk-REJGZP27.js → chunk-Y6XNISHP.js} +2 -2
- package/dist/cli/chunks/{chunk-LF5XOYR7.js → chunk-YDYKFSD2.js} +11 -11
- package/dist/cli/chunks/{chunk-U55X2ZUM.js → chunk-YEC55GO5.js} +2 -2
- package/dist/cli/chunks/{chunk-6ONUCDVL.js → chunk-YOG5KQZF.js} +2 -2
- package/dist/cli/chunks/{chunk-6BCVKCG5.js → chunk-YUDGQZJN.js} +2 -2
- package/dist/cli/chunks/{chunk-EOBZJDJR.js → chunk-Z3SXMYVI.js} +3 -3
- package/dist/cli/chunks/chunk-ZFLE4D4X.js +18 -0
- package/dist/cli/chunks/{chunk-W52R3G22.js → chunk-ZGKQCUPB.js} +2 -2
- package/dist/cli/chunks/{chunk-MCUILJ33.js → chunk-ZTKCGEB6.js} +1 -1
- package/dist/cli/chunks/{ci-IU5HVUL5.js → ci-MMLUV6L6.js} +2 -2
- package/dist/cli/chunks/{ci-output-CLI4A43F.js → ci-output-25GS6RXR.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-ZR5OFMW7.js → circuit-breaker-4OWAN6R6.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-UBMA6ZHJ.js → claude-flow-setup-LR3SRBX6.js} +2 -2
- package/dist/cli/chunks/client-WI7RRUZO.js +2 -0
- package/dist/cli/chunks/{cline-installer-EWYELOBI.js → cline-installer-YSZWRZUI.js} +2 -2
- package/dist/cli/chunks/{code-YSPF4MXN.js → code-UUWUIXI7.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-WW5OKSTN.js → code-index-extractor-2LSPQORU.js} +2 -2
- package/dist/cli/chunks/{codex-installer-GLADK5PY.js → codex-installer-E5BVXZVA.js} +2 -2
- package/dist/cli/chunks/{completions-2KTWZ3AK.js → completions-YKXBKZSO.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-KMX4OWKB.js → complexity-analyzer-HNT2QRWB.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-4FHU4OEJ.js → continuedev-installer-AW5VCB66.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-AKR4WE7B.js → copilot-installer-B6SVZXQT.js} +2 -2
- package/dist/cli/chunks/core-handlers-T6URR57V.js +2 -0
- package/dist/cli/chunks/{cost-tracker-BUJ6WEWY.js → cost-tracker-POZMBN2V.js} +2 -2
- package/dist/cli/chunks/{coverage-OB6HVQS4.js → coverage-V5BGPN5Q.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-WHTTKHWM.js +2 -0
- package/dist/cli/chunks/{cursor-installer-3AOE4O3Q.js → cursor-installer-EYBI4QVK.js} +2 -2
- package/dist/cli/chunks/{daemon-4RAL5URG.js → daemon-CF6ENQB2.js} +3 -3
- package/dist/cli/chunks/{daemon-JGSPLYGO.js → daemon-HKARXY2W.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-DSBTHIMH.js → dag-attention-scheduler-XIL5IAP7.js} +2 -2
- package/dist/cli/chunks/{detect-6CVW2VUQ.js → detect-RRX2U2KK.js} +2 -2
- package/dist/cli/chunks/{dist-node-EWPKBTYA.js → dist-node-DOANNRCS.js} +2 -2
- package/dist/cli/chunks/{domain-handler-HLVIJU25.js → domain-handler-QMTJV5OR.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-7Y3BR3YU.js → domain-transfer-FSNH75XW.js} +2 -2
- package/dist/cli/chunks/dream-QUL6SURC.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-ZMJ3263X.js → embed-and-insert-pattern-NI7PGONV.js} +2 -2
- package/dist/cli/chunks/eval-6ZAF2RY3.js +17 -0
- package/dist/cli/chunks/{experience-capture-middleware-OGJ3JOSQ.js → experience-capture-middleware-JMXR7N5G.js} +3 -3
- package/dist/cli/chunks/{fast-paths-5XCY3Y6U.js → fast-paths-YB7XZZ76.js} +2 -2
- package/dist/cli/chunks/{feature-flags-R5V2FRJR.js → feature-flags-2RC4GFC4.js} +2 -2
- package/dist/cli/chunks/{feature-flags-VULQI6KY.js → feature-flags-KJSP7KR6.js} +2 -2
- package/dist/cli/chunks/{file-discovery-HW33C3HC.js → file-discovery-SUPBXFYI.js} +2 -2
- package/dist/cli/chunks/{fleet-NH3XR5OY.js → fleet-KSXFOLFW.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-L3XMLPTG.js → gnn-wrapper-DFZ5KPPK.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-TIQFBT4D.js → heartbeat-handler-G3EADK2H.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-VZNKE33K.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-LGWLDZLC.js +2 -0
- package/dist/cli/chunks/hnsw-index-66FOOI7U.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-YL2SUIPA.js → hnsw-legacy-bridge-MA676GER.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-IPKCAVLS.js → hnswlib-node-SKTT5KIH.js} +2 -2
- package/dist/cli/chunks/{hooks-UR2ZF54G.js → hooks-HTCPMZNZ.js} +10 -10
- package/dist/cli/chunks/hybrid-router-I5MEVQDF.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-NX45AOPY.js → hypergraph-engine-QPB3IH4A.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-LUM4YI4K.js → hypergraph-handler-GBFSVD7N.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-K6ANYIY3.js +2 -0
- package/dist/cli/chunks/{init-handler-YTKKNTVV.js → init-handler-XYBTBCPD.js} +6 -6
- package/dist/cli/chunks/init-wizard-URHGXJ32.js +2 -0
- package/dist/cli/chunks/kernel-OKI5ZY5P.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-ZW7DVH7T.js → kilocode-installer-LY6JOBFY.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-IA7INW4N.js → kiro-installer-JF6NXTJL.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-VQQSK7T5.js +2 -0
- package/dist/cli/chunks/{learning-4AZ5PGTT.js → learning-BIISN67N.js} +3 -3
- package/dist/cli/chunks/{llm-router-WQ4E3AOP.js → llm-router-YZUNVZQE.js} +5 -5
- package/dist/cli/chunks/llm-router-service-TISH33SY.js +2 -0
- package/dist/cli/chunks/{load-4FAH7CZO.js → load-MTWNBNLL.js} +2 -2
- package/dist/cli/chunks/load-test-KWKWC4Q7.js +2 -0
- package/dist/cli/chunks/{mcp-KLLHI6DG.js → mcp-37PYMNHQ.js} +2 -2
- package/dist/cli/chunks/{memory-Q5HLIUC6.js → memory-IXUUDCI3.js} +5 -5
- package/dist/cli/chunks/memory-backend-JSQQMXVS.js +2 -0
- package/dist/cli/chunks/memory-handlers-RM2VOFJX.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-ABI73AFV.js → multi-model-executor-RKKS5XYG.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-KRPQ6JOJ.js → opencode-installer-3VXI5MTR.js} +2 -2
- package/dist/cli/chunks/{orchestrator-SUPEONRG.js → orchestrator-UO3ZOGFZ.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-SXBIUKE5.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-R4GKK6RZ.js → pattern-usage-recorder-YJKRL2GI.js} +2 -2
- package/dist/cli/chunks/{pipeline-LCUETNGD.js → pipeline-GJQJKXWX.js} +2 -2
- package/dist/cli/chunks/{platform-WJDIB4X3.js → platform-RHVCZK6C.js} +2 -2
- package/dist/cli/chunks/{plugin-2X5NY2RF.js → plugin-ZKAIW7O6.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-3T665QC6.js → prime-radiant-advanced-wasm-4X3DSKQV.js} +2 -2
- package/dist/cli/chunks/protocol-executor-D3Q5P3WY.js +2 -0
- package/dist/cli/chunks/{protocol-handler-JTXRF7GU.js → protocol-handler-KKYQZMB2.js} +2 -2
- package/dist/cli/chunks/{prove-BFPWWPOC.js → prove-OD6RPKWX.js} +2 -2
- package/dist/cli/chunks/provider-manager-2EIX7E5Q.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-ITOW2ZHC.js +2 -0
- package/dist/cli/chunks/{quality-F7UZU4RN.js → quality-ZRWBXCKO.js} +2 -2
- package/dist/cli/chunks/{quality-gate-R5L4UZIX.js → quality-gate-Y6BWQV7J.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-TO5X2EXL.js +2 -0
- package/dist/cli/chunks/{real-embeddings-LZD6HTQF.js → real-embeddings-YYEUO4P2.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-6TTG7VSH.js → roocode-installer-JBCPS3FK.js} +2 -2
- package/dist/cli/chunks/router-GZJQEJU3.js +2 -0
- package/dist/cli/chunks/routing-feedback-CRXSKFNS.js +2 -0
- package/dist/cli/chunks/{routing-handler-SW442GK7.js → routing-handler-KTPJOSBJ.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-CLFGKXMW.js → ruvector-commands-SCZZVRE7.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-EVPPXXXS.js → rvf-dual-writer-IP7GELQJ.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-NOHDIRIP.js → rvf-migration-adapter-WLFTDARU.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-BYJ3M7WZ.js → rvf-migration-coordinator-MGFDQ5WD.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-WHADT5HX.js +2 -0
- package/dist/cli/chunks/rvf-store-integrity-OTOAGT5W.js +2 -0
- package/dist/cli/chunks/safe-db-MIZ2OFWC.js +2 -0
- package/dist/cli/chunks/schedule-XFILYTYC.js +2 -0
- package/dist/cli/chunks/scheduler-EIPJ777A.js +2 -0
- package/dist/cli/chunks/{security-IXDKBPSG.js → security-B2CLZKRB.js} +3 -3
- package/dist/cli/chunks/shared-rvf-adapter-2PMFAQMN.js +2 -0
- package/dist/cli/chunks/{shared-rvf-dual-writer-FFKBKYNL.js → shared-rvf-dual-writer-B6P732AV.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-PFU3GSRD.js +2 -0
- package/dist/cli/chunks/status-handler-M6SN2W2D.js +47 -0
- package/dist/cli/chunks/{structural-health-55X6BTLT.js → structural-health-YCCTGI3K.js} +2 -2
- package/dist/cli/chunks/{sync-BUGDXW3Y.js → sync-3SDMVAIU.js} +2 -2
- package/dist/cli/chunks/{sync-NUG67HGK.js → sync-KSRF77ID.js} +2 -2
- package/dist/cli/chunks/{task-handler-T6ZKXV4S.js → task-handler-MIKRB2SL.js} +2 -2
- package/dist/cli/chunks/{task-handlers-H63TB2UI.js → task-handlers-YXKRUBQ4.js} +3 -3
- package/dist/cli/chunks/{test-VEK76SBT.js → test-MLOLQCB7.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-QZM6PNZH.js → test-scheduling-3KXESUZS.js} +3 -3
- package/dist/cli/chunks/token-bootstrap-6V2PMDBJ.js +2 -0
- package/dist/cli/chunks/{token-usage-OBY6UEUR.js → token-usage-DP6THJ3I.js} +2 -2
- package/dist/cli/chunks/{transformers-EFNY2MRX.js → transformers-QFOBOP2Y.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-EU2S5NVM.js → tree-sitter-wasm-parser-COK2XERS.js} +2 -2
- package/dist/cli/chunks/{types-3DYRKX23.js → types-PYHUCVOZ.js} +2 -2
- package/dist/cli/chunks/unified-memory-OUVCMFGK.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-YGQPOHXB.js +2 -0
- package/dist/cli/chunks/unified-persistence-GFRZVDOW.js +2 -0
- package/dist/cli/chunks/{upgrade-H5V53FRF.js → upgrade-ONP2HNGL.js} +2 -2
- package/dist/cli/chunks/{validate-IL22VB5I.js → validate-NWSICDAY.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-WZKECK3W.js → validate-swarm-KXS5P3U7.js} +2 -2
- package/dist/cli/chunks/{vibium-KKM23OTQ.js → vibium-TZSGZRCQ.js} +2 -2
- package/dist/cli/chunks/visual-security-LVOOYQ64.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-NJM5YBOY.js → web-tree-sitter-V2FADNRA.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-SLP43TVT.js → windsurf-installer-GQM7KWDC.js} +2 -2
- package/dist/cli/chunks/{witness-chain-XBEPT4XD.js → witness-chain-GTITDIA2.js} +2 -2
- package/dist/cli/chunks/witness-chain-QNFPV4UL.js +2 -0
- package/dist/cli/chunks/{witness-key-manager-DAAMNYOW.js → witness-key-manager-AHRM2M52.js} +2 -2
- package/dist/cli/chunks/{workflow-SZOOU6D3.js → workflow-XCGHEL3I.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-MIVBCALG.js +2 -0
- package/dist/cli/chunks/{wrappers-I2CBKWGF.js → wrappers-VGO2GO4J.js} +2 -2
- package/dist/cli/commands/eval.js +73 -3
- package/dist/cli/commands/llm-router.js +2 -0
- package/dist/cli/handlers/status-handler.d.ts +5 -0
- package/dist/cli/handlers/status-handler.js +35 -0
- package/dist/coordination/consensus/providers/index.js +11 -0
- package/dist/integrations/ruvector/brain-rvf-exporter.js +115 -13
- package/dist/integrations/ruvector/rvf-dual-writer.js +20 -3
- package/dist/integrations/ruvector/rvf-store-integrity.d.ts +49 -0
- package/dist/integrations/ruvector/rvf-store-integrity.js +137 -0
- package/dist/integrations/ruvector/shared-rvf-adapter.js +23 -5
- package/dist/learning/pattern-store.js +23 -5
- package/dist/learning/qe-flywheel/platform-signer.d.ts +32 -0
- package/dist/learning/qe-flywheel/platform-signer.js +60 -0
- package/dist/learning/qe-flywheel/receipt.js +9 -2
- package/dist/mcp/bundle.js +425 -406
- package/dist/shared/llm/billing-modes.d.ts +24 -0
- package/dist/shared/llm/billing-modes.js +56 -0
- package/dist/shared/llm/cost-tracker.js +2 -0
- package/dist/shared/llm/interfaces.d.ts +61 -3
- package/dist/shared/llm/provider-manager.d.ts +34 -0
- package/dist/shared/llm/provider-manager.js +152 -3
- package/dist/shared/llm/providers/claude-code.d.ts +57 -0
- package/dist/shared/llm/providers/claude-code.js +312 -0
- package/dist/shared/llm/providers/cognitum.d.ts +64 -0
- package/dist/shared/llm/providers/cognitum.js +369 -0
- package/dist/shared/llm/providers/index.d.ts +2 -0
- package/dist/shared/llm/providers/index.js +2 -0
- package/dist/shared/llm/router/config-store.d.ts +31 -11
- package/dist/shared/llm/router/config-store.js +82 -12
- package/dist/shared/llm/router/hybrid-router.js +16 -0
- package/dist/shared/llm/router/types.js +7 -0
- package/dist/shared/llm/spend-ledger.d.ts +64 -0
- package/dist/shared/llm/spend-ledger.js +115 -0
- package/dist/shared/llm/translation/message-formatter.js +2 -0
- package/dist/shared/llm/translation/prompt-translator.js +2 -0
- package/dist/shared/llm/translation/tool-translator.js +2 -0
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +2 -0
- package/dist/validation/provider-llm-executor.d.ts +45 -0
- package/dist/validation/provider-llm-executor.js +98 -0
- package/package.json +2 -2
- package/dist/cli/chunks/adapter-X4UEC6UJ.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-5FG7JCY7.js +0 -2
- package/dist/cli/chunks/base-CWPMFSZG.js +0 -2
- package/dist/cli/chunks/brain-handler-JF3OK35F.js +0 -89
- package/dist/cli/chunks/browser-workflow-A77OFBVY.js +0 -2
- package/dist/cli/chunks/chunk-CDVKFAYP.js +0 -18
- package/dist/cli/chunks/chunk-CJTXZI37.js +0 -2
- package/dist/cli/chunks/chunk-FNMEVLSN.js +0 -2
- package/dist/cli/chunks/chunk-P7G5LGUE.js +0 -3
- package/dist/cli/chunks/chunk-R7XEACKR.js +0 -2
- package/dist/cli/chunks/chunk-RAS7WRN5.js +0 -24
- package/dist/cli/chunks/chunk-TGIKKD43.js +0 -9
- package/dist/cli/chunks/client-KKCFGD7R.js +0 -2
- package/dist/cli/chunks/core-handlers-KRSSJEO5.js +0 -2
- package/dist/cli/chunks/cross-domain-router-27QGWU27.js +0 -2
- package/dist/cli/chunks/dream-M6K47Q4H.js +0 -2
- package/dist/cli/chunks/eval-73XW2WJD.js +0 -15
- package/dist/cli/chunks/heartbeat-scheduler-URXBF5RW.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-WWAGM6HK.js +0 -2
- package/dist/cli/chunks/hnsw-index-UFV2HSZE.js +0 -2
- package/dist/cli/chunks/hybrid-router-3U6Q6OTL.js +0 -2
- package/dist/cli/chunks/impact-analyzer-EUEX6ZRO.js +0 -2
- package/dist/cli/chunks/init-wizard-POKY2LRY.js +0 -2
- package/dist/cli/chunks/kernel-HPAONLZY.js +0 -2
- package/dist/cli/chunks/knowledge-graph-2WCUFG63.js +0 -2
- package/dist/cli/chunks/llm-router-service-D5VMG6SD.js +0 -2
- package/dist/cli/chunks/load-test-DHG26REU.js +0 -2
- package/dist/cli/chunks/memory-backend-GLWQ4DAL.js +0 -2
- package/dist/cli/chunks/memory-handlers-P72I4VV4.js +0 -2
- package/dist/cli/chunks/pattern-null-store-Y2YFTE3V.js +0 -2
- package/dist/cli/chunks/protocol-executor-HNT67NN5.js +0 -2
- package/dist/cli/chunks/provider-manager-5YGPZIEZ.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-Z5UGOA3F.js +0 -2
- package/dist/cli/chunks/queen-coordinator-P5LU5NWI.js +0 -2
- package/dist/cli/chunks/router-CRGHUAVR.js +0 -2
- package/dist/cli/chunks/routing-feedback-BVX5ZBCF.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-FZJSQOJM.js +0 -2
- package/dist/cli/chunks/safe-db-USYNEOC6.js +0 -2
- package/dist/cli/chunks/schedule-KCRCQ3PS.js +0 -2
- package/dist/cli/chunks/scheduler-CX3UHI4U.js +0 -2
- package/dist/cli/chunks/shared-rvf-adapter-VCOK3OVD.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-K23C4TFH.js +0 -2
- package/dist/cli/chunks/status-handler-M5W64S5U.js +0 -46
- package/dist/cli/chunks/token-bootstrap-W5IAMJW4.js +0 -2
- package/dist/cli/chunks/unified-memory-NCDBQLLF.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-T7NSGQ2H.js +0 -2
- package/dist/cli/chunks/unified-persistence-XUAYDCMM.js +0 -2
- package/dist/cli/chunks/visual-security-3TUC4GPP.js +0 -2
- package/dist/cli/chunks/witness-chain-QLOKUZXC.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-6JAYTZ7L.js +0 -2
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 — Cognitum Provider (ADR-123)
|
|
3
|
+
*
|
|
4
|
+
* api.cognitum.one is an OpenAI-compatible (and Anthropic-compatible) LLM
|
|
5
|
+
* gateway with two properties that matter for issue #557:
|
|
6
|
+
* 1. Every response carries an `x_cognitum` receipt with an authoritative
|
|
7
|
+
* per-request `price_usd` — so cost is a provider receipt, not a local
|
|
8
|
+
* price-table estimate.
|
|
9
|
+
* 2. It enforces a server-side hard spend cap (`/v1/usage` → `hardCapUsd`),
|
|
10
|
+
* so the worst case is "provider pauses at the cap", not a surprise bill.
|
|
11
|
+
*
|
|
12
|
+
* Models are tiers (`cognitum-auto|low|mid|high`); the gateway resolves each
|
|
13
|
+
* to a concrete model and reports it back in the receipt (`resolved_model`).
|
|
14
|
+
*/
|
|
15
|
+
import { createLLMError, } from '../interfaces';
|
|
16
|
+
import { TokenMetricsCollector } from '../../../learning/token-tracker.js';
|
|
17
|
+
import { toError } from '../../error-utils.js';
|
|
18
|
+
import { backoffDelay } from '../retry.js';
|
|
19
|
+
export const DEFAULT_COGNITUM_CONFIG = {
|
|
20
|
+
model: 'cognitum-auto',
|
|
21
|
+
maxTokens: 4096,
|
|
22
|
+
temperature: 0.7,
|
|
23
|
+
timeoutMs: 60000,
|
|
24
|
+
maxRetries: 3,
|
|
25
|
+
enableCache: true,
|
|
26
|
+
enableCircuitBreaker: true,
|
|
27
|
+
};
|
|
28
|
+
export class CognitumProvider {
|
|
29
|
+
type = 'cognitum';
|
|
30
|
+
name = 'Cognitum';
|
|
31
|
+
billingMode = 'metered-capped';
|
|
32
|
+
config;
|
|
33
|
+
requestId = 0;
|
|
34
|
+
constructor(config = {}) {
|
|
35
|
+
this.config = { ...DEFAULT_COGNITUM_CONFIG, ...config };
|
|
36
|
+
}
|
|
37
|
+
async isAvailable() {
|
|
38
|
+
if (!this.getApiKey())
|
|
39
|
+
return false;
|
|
40
|
+
try {
|
|
41
|
+
return (await this.healthCheck()).healthy;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async healthCheck() {
|
|
48
|
+
const apiKey = this.getApiKey();
|
|
49
|
+
if (!apiKey) {
|
|
50
|
+
return {
|
|
51
|
+
healthy: false,
|
|
52
|
+
error: 'API key not configured. Set COGNITUM_API_KEY environment variable.',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const start = Date.now();
|
|
56
|
+
try {
|
|
57
|
+
const response = await this.fetchWithTimeout(`${this.getBaseUrl()}/v1/models`, { method: 'GET', headers: this.getHeaders() }, 5000);
|
|
58
|
+
const latencyMs = Date.now() - start;
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
return { healthy: false, latencyMs, error: `API error: ${response.status}` };
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
healthy: true,
|
|
64
|
+
latencyMs,
|
|
65
|
+
models: this.getSupportedModels(),
|
|
66
|
+
details: { billing: 'metered-capped', baseUrl: this.getBaseUrl() },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return { healthy: false, error: error instanceof Error ? error.message : 'Unknown error' };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async generate(input, options) {
|
|
74
|
+
const apiKey = this.getApiKey();
|
|
75
|
+
if (!apiKey) {
|
|
76
|
+
throw createLLMError('Cognitum API key not configured', 'API_KEY_MISSING', {
|
|
77
|
+
provider: 'cognitum',
|
|
78
|
+
retryable: false,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const messages = this.formatMessages(input, options?.systemPrompt);
|
|
82
|
+
const model = options?.model ?? this.config.model;
|
|
83
|
+
const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 4096;
|
|
84
|
+
const temperature = options?.temperature ?? this.config.temperature ?? 0.7;
|
|
85
|
+
const requestId = `cognitum-${++this.requestId}-${Date.now()}`;
|
|
86
|
+
const start = Date.now();
|
|
87
|
+
const body = { model, max_tokens: maxTokens, temperature, messages };
|
|
88
|
+
if (options?.stopSequences?.length)
|
|
89
|
+
body.stop = options.stopSequences;
|
|
90
|
+
try {
|
|
91
|
+
const response = await this.fetchWithRetry(`${this.getBaseUrl()}/v1/chat/completions`, { method: 'POST', headers: this.getHeaders(), body: JSON.stringify(body) }, options?.timeoutMs ?? this.config.timeoutMs ?? 60000, this.config.maxRetries ?? 3);
|
|
92
|
+
const latencyMs = Date.now() - start;
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw await this.toApiError(response, model);
|
|
95
|
+
}
|
|
96
|
+
const data = (await response.json());
|
|
97
|
+
const receipt = data.x_cognitum;
|
|
98
|
+
const usage = {
|
|
99
|
+
promptTokens: data.usage.prompt_tokens,
|
|
100
|
+
completionTokens: data.usage.completion_tokens,
|
|
101
|
+
totalTokens: data.usage.total_tokens,
|
|
102
|
+
cacheReadTokens: data.usage.cache_read_tokens ?? 0,
|
|
103
|
+
};
|
|
104
|
+
const cost = this.receiptCost(receipt);
|
|
105
|
+
TokenMetricsCollector.recordTokenUsage(requestId, 'cognitum-provider', 'llm', 'generate', {
|
|
106
|
+
inputTokens: usage.promptTokens,
|
|
107
|
+
outputTokens: usage.completionTokens,
|
|
108
|
+
totalTokens: usage.totalTokens,
|
|
109
|
+
estimatedCostUsd: cost.totalCost,
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
content: data.choices[0]?.message?.content ?? '',
|
|
113
|
+
// Prefer the concrete resolved model from the receipt over the tier name.
|
|
114
|
+
model: receipt?.resolved_model ?? data.model,
|
|
115
|
+
provider: 'cognitum',
|
|
116
|
+
usage,
|
|
117
|
+
cost,
|
|
118
|
+
latencyMs,
|
|
119
|
+
finishReason: this.mapFinishReason(data.choices[0]?.finish_reason),
|
|
120
|
+
cached: receipt?.cache === 'hit',
|
|
121
|
+
requestId,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof Error && 'code' in error)
|
|
126
|
+
throw error;
|
|
127
|
+
throw createLLMError(error instanceof Error ? error.message : 'Request failed', 'NETWORK_ERROR', { provider: 'cognitum', model, retryable: true, cause: error });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async embed(text, options) {
|
|
131
|
+
const apiKey = this.getApiKey();
|
|
132
|
+
if (!apiKey) {
|
|
133
|
+
throw createLLMError('Cognitum API key not configured', 'API_KEY_MISSING', {
|
|
134
|
+
provider: 'cognitum',
|
|
135
|
+
retryable: false,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const model = options?.model ?? 'cognitum-embed';
|
|
139
|
+
const start = Date.now();
|
|
140
|
+
try {
|
|
141
|
+
const response = await this.fetchWithTimeout(`${this.getBaseUrl()}/v1/embeddings`, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: this.getHeaders(),
|
|
144
|
+
body: JSON.stringify({ model, input: text }),
|
|
145
|
+
}, options?.timeoutMs ?? this.config.timeoutMs ?? 30000);
|
|
146
|
+
const latencyMs = Date.now() - start;
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
throw await this.toApiError(response, model);
|
|
149
|
+
}
|
|
150
|
+
const data = (await response.json());
|
|
151
|
+
return {
|
|
152
|
+
embedding: data.data[0].embedding,
|
|
153
|
+
model: data.x_cognitum?.resolved_model ?? data.model,
|
|
154
|
+
provider: 'cognitum',
|
|
155
|
+
tokenCount: data.usage.total_tokens,
|
|
156
|
+
latencyMs,
|
|
157
|
+
cached: false,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (error instanceof Error && 'code' in error)
|
|
162
|
+
throw error;
|
|
163
|
+
throw createLLMError(error instanceof Error ? error.message : 'Embedding request failed', 'NETWORK_ERROR', { provider: 'cognitum', model, retryable: true, cause: error });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async complete(prompt, options) {
|
|
167
|
+
const response = await this.generate(prompt, {
|
|
168
|
+
model: options?.model,
|
|
169
|
+
temperature: options?.temperature ?? 0.2,
|
|
170
|
+
maxTokens: options?.maxTokens ?? 256,
|
|
171
|
+
stopSequences: options?.stopSequences,
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
completion: response.content,
|
|
175
|
+
model: response.model,
|
|
176
|
+
provider: 'cognitum',
|
|
177
|
+
usage: response.usage,
|
|
178
|
+
latencyMs: response.latencyMs,
|
|
179
|
+
cached: response.cached,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
getConfig() {
|
|
183
|
+
return { ...this.config };
|
|
184
|
+
}
|
|
185
|
+
getSupportedModels() {
|
|
186
|
+
return ['cognitum-auto', 'cognitum-low', 'cognitum-mid', 'cognitum-high'];
|
|
187
|
+
}
|
|
188
|
+
getCostPerToken() {
|
|
189
|
+
// Cost is per-request from the receipt, not a fixed per-token table.
|
|
190
|
+
return { input: 0, output: 0 };
|
|
191
|
+
}
|
|
192
|
+
async dispose() {
|
|
193
|
+
// No persistent resources.
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* ADR-123: read the provider's server-side budget so `aqe health` and the
|
|
197
|
+
* billing notice can show real remaining headroom. Returns undefined on any
|
|
198
|
+
* failure (best-effort — never throws).
|
|
199
|
+
*/
|
|
200
|
+
async getRemoteBudget() {
|
|
201
|
+
try {
|
|
202
|
+
const response = await this.fetchWithTimeout(`${this.getBaseUrl()}/v1/usage`, { method: 'GET', headers: this.getHeaders() }, 5000);
|
|
203
|
+
if (!response.ok)
|
|
204
|
+
return undefined;
|
|
205
|
+
const data = (await response.json());
|
|
206
|
+
const b = data.budget;
|
|
207
|
+
if (!b)
|
|
208
|
+
return undefined;
|
|
209
|
+
return {
|
|
210
|
+
servingBudgetUsd: b.servingBudgetUsd ?? 0,
|
|
211
|
+
hardCapUsd: b.hardCapUsd ?? 0,
|
|
212
|
+
committedUsd: b.committedUsd ?? 0,
|
|
213
|
+
headroomUsd: b.headroomUsd ?? 0,
|
|
214
|
+
status: b.status ?? 'unknown',
|
|
215
|
+
headroomExhausted: b.headroomExhausted ?? false,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// -- internals -------------------------------------------------------------
|
|
223
|
+
/** Build a CostInfo from the authoritative receipt price. */
|
|
224
|
+
receiptCost(receipt) {
|
|
225
|
+
const total = receipt?.price_usd ?? 0;
|
|
226
|
+
return {
|
|
227
|
+
inputCost: 0,
|
|
228
|
+
outputCost: 0,
|
|
229
|
+
totalCost: total,
|
|
230
|
+
currency: 'USD',
|
|
231
|
+
source: receipt?.price_usd !== undefined ? 'provider-receipt' : 'local-estimate',
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
getApiKey() {
|
|
235
|
+
return this.config.apiKey ?? process.env.COGNITUM_API_KEY;
|
|
236
|
+
}
|
|
237
|
+
getBaseUrl() {
|
|
238
|
+
return (this.config.baseUrl ?? process.env.COGNITUM_BASE_URL ?? 'https://api.cognitum.one').replace(/\/$/, '');
|
|
239
|
+
}
|
|
240
|
+
getHeaders() {
|
|
241
|
+
return {
|
|
242
|
+
'Content-Type': 'application/json',
|
|
243
|
+
'X-API-Key': this.getApiKey(),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
formatMessages(input, systemPrompt) {
|
|
247
|
+
const messages = [];
|
|
248
|
+
if (typeof input === 'string') {
|
|
249
|
+
if (systemPrompt)
|
|
250
|
+
messages.push({ role: 'system', content: systemPrompt });
|
|
251
|
+
messages.push({ role: 'user', content: input });
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
const hasSystem = input.some((m) => m.role === 'system');
|
|
255
|
+
if (systemPrompt && !hasSystem)
|
|
256
|
+
messages.push({ role: 'system', content: systemPrompt });
|
|
257
|
+
for (const m of input)
|
|
258
|
+
messages.push({ role: m.role, content: m.content });
|
|
259
|
+
}
|
|
260
|
+
return messages;
|
|
261
|
+
}
|
|
262
|
+
mapFinishReason(reason) {
|
|
263
|
+
switch (reason) {
|
|
264
|
+
case 'length':
|
|
265
|
+
return 'length';
|
|
266
|
+
case 'content_filter':
|
|
267
|
+
return 'content_filter';
|
|
268
|
+
case 'stop':
|
|
269
|
+
default:
|
|
270
|
+
return 'stop';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async toApiError(response, model) {
|
|
274
|
+
const text = await response.text().catch(() => '');
|
|
275
|
+
let message = text;
|
|
276
|
+
try {
|
|
277
|
+
const parsed = JSON.parse(text);
|
|
278
|
+
message = parsed.error ?? text;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
// non-JSON body
|
|
282
|
+
}
|
|
283
|
+
switch (response.status) {
|
|
284
|
+
case 401:
|
|
285
|
+
case 403:
|
|
286
|
+
return createLLMError(message || 'Unauthorized', 'API_KEY_INVALID', {
|
|
287
|
+
provider: 'cognitum',
|
|
288
|
+
model,
|
|
289
|
+
retryable: false,
|
|
290
|
+
});
|
|
291
|
+
case 402:
|
|
292
|
+
// Payment required / budget cap reached — the metered-capped pause.
|
|
293
|
+
return createLLMError(message || 'Budget cap reached', 'COST_LIMIT_EXCEEDED', {
|
|
294
|
+
provider: 'cognitum',
|
|
295
|
+
model,
|
|
296
|
+
retryable: false,
|
|
297
|
+
});
|
|
298
|
+
case 429:
|
|
299
|
+
return createLLMError(message || 'Rate limited', 'RATE_LIMITED', {
|
|
300
|
+
provider: 'cognitum',
|
|
301
|
+
model,
|
|
302
|
+
retryable: true,
|
|
303
|
+
retryAfterMs: 60000,
|
|
304
|
+
});
|
|
305
|
+
case 500:
|
|
306
|
+
case 502:
|
|
307
|
+
case 503:
|
|
308
|
+
return createLLMError(message || 'Provider unavailable', 'PROVIDER_UNAVAILABLE', {
|
|
309
|
+
provider: 'cognitum',
|
|
310
|
+
model,
|
|
311
|
+
retryable: true,
|
|
312
|
+
retryAfterMs: 5000,
|
|
313
|
+
});
|
|
314
|
+
default:
|
|
315
|
+
return createLLMError(message || `HTTP ${response.status}`, 'UNKNOWN', {
|
|
316
|
+
provider: 'cognitum',
|
|
317
|
+
model,
|
|
318
|
+
retryable: false,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async fetchWithTimeout(url, options, timeoutMs) {
|
|
323
|
+
const controller = new AbortController();
|
|
324
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
325
|
+
try {
|
|
326
|
+
return await fetch(url, { ...options, signal: controller.signal });
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
330
|
+
throw createLLMError('Request timed out', 'TIMEOUT', {
|
|
331
|
+
provider: 'cognitum',
|
|
332
|
+
retryable: true,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
finally {
|
|
338
|
+
clearTimeout(timeoutId);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async fetchWithRetry(url, options, timeoutMs, maxRetries) {
|
|
342
|
+
let lastError;
|
|
343
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
344
|
+
try {
|
|
345
|
+
const response = await this.fetchWithTimeout(url, options, timeoutMs);
|
|
346
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
347
|
+
return response;
|
|
348
|
+
}
|
|
349
|
+
if (response.status >= 500 || response.status === 429) {
|
|
350
|
+
if (attempt < maxRetries - 1) {
|
|
351
|
+
await this.sleep(backoffDelay(attempt));
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return response;
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
lastError = toError(error);
|
|
359
|
+
if (attempt < maxRetries - 1)
|
|
360
|
+
await this.sleep(backoffDelay(attempt));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
throw lastError ?? new Error('Request failed after retries');
|
|
364
|
+
}
|
|
365
|
+
sleep(ms) {
|
|
366
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=cognitum.js.map
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Export all provider implementations
|
|
4
4
|
*/
|
|
5
5
|
export { ClaudeProvider, DEFAULT_CLAUDE_CONFIG } from './claude';
|
|
6
|
+
export { ClaudeCodeProvider, DEFAULT_CLAUDE_CODE_CONFIG, API_BILLING_ENV_VARS, type ClaudeCodeConfig, } from './claude-code';
|
|
7
|
+
export { CognitumProvider, DEFAULT_COGNITUM_CONFIG, type CognitumConfig, type CognitumBudget, } from './cognitum';
|
|
6
8
|
export { OpenAIProvider, DEFAULT_OPENAI_CONFIG } from './openai';
|
|
7
9
|
export { OllamaProvider, DEFAULT_OLLAMA_CONFIG } from './ollama';
|
|
8
10
|
export { OpenRouterProvider, DEFAULT_OPENROUTER_CONFIG, OPENROUTER_PRICING, type OpenRouterConfig, } from './openrouter';
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Export all provider implementations
|
|
4
4
|
*/
|
|
5
5
|
export { ClaudeProvider, DEFAULT_CLAUDE_CONFIG } from './claude';
|
|
6
|
+
export { ClaudeCodeProvider, DEFAULT_CLAUDE_CODE_CONFIG, API_BILLING_ENV_VARS, } from './claude-code';
|
|
7
|
+
export { CognitumProvider, DEFAULT_COGNITUM_CONFIG, } from './cognitum';
|
|
6
8
|
export { OpenAIProvider, DEFAULT_OPENAI_CONFIG } from './openai';
|
|
7
9
|
export { OllamaProvider, DEFAULT_OLLAMA_CONFIG } from './ollama';
|
|
8
10
|
export { OpenRouterProvider, DEFAULT_OPENROUTER_CONFIG, OPENROUTER_PRICING, } from './openrouter';
|
|
@@ -58,19 +58,39 @@ export declare function mergeRouterConfig(base: RouterConfig, override: Partial<
|
|
|
58
58
|
* GOOGLE_API_KEY doesn't also have to remember to flip gemini.enabled
|
|
59
59
|
* to true). Providers without keys are left at their existing setting.
|
|
60
60
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
61
|
+
* ADR-123 AMENDMENT to ADR-043's addendum: env presence force-enables a
|
|
62
|
+
* provider ONLY when the user has not *explicitly* disabled it on disk. An
|
|
63
|
+
* explicit `enabled: false` in `.agentic-qe/llm-config.json` now wins over
|
|
64
|
+
* key presence — the previous behavior (env always overrides disk) meant
|
|
65
|
+
* merely exporting `ANTHROPIC_API_KEY` silently opted a user into paid API
|
|
66
|
+
* billing even after they had turned the provider off (issue #557). A
|
|
67
|
+
* provider left unset on disk is still force-enabled when its key is present
|
|
68
|
+
* (the convenient default). To disable a provider that has a key in env, set
|
|
69
|
+
* `enabled: false` for it on disk, unset the env key, or use the env-only
|
|
70
|
+
* kill-switch `AQE_LLM_ROUTER_DISABLED=1` (disables the whole router).
|
|
71
|
+
*
|
|
72
|
+
* @param explicitlyDisabled providers the user set to `enabled: false` in the
|
|
73
|
+
* raw on-disk config; these are never force-enabled by env detection.
|
|
74
|
+
*/
|
|
75
|
+
export declare function applyEnvProviderDetection(config: RouterConfig, env?: NodeJS.ProcessEnv, explicitlyDisabled?: ReadonlySet<ExtendedProviderType>): RouterConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Collect providers the user *explicitly* set to `enabled: false` in the raw
|
|
78
|
+
* on-disk config (as opposed to a default `false`). Used so env detection
|
|
79
|
+
* doesn't resurrect a provider the user deliberately turned off (ADR-123).
|
|
80
|
+
*/
|
|
81
|
+
export declare function collectExplicitlyDisabled(onDisk: Partial<RouterConfig>): Set<ExtendedProviderType>;
|
|
82
|
+
/**
|
|
83
|
+
* ADR-123: highest-precedence provider selector. `AQE_LLM_PROVIDER=<type>`
|
|
84
|
+
* (e.g. `claude-code`, `cognitum`, `openai`) overrides `defaultProvider` and
|
|
85
|
+
* force-enables that provider, so a user can switch the execution provider for
|
|
86
|
+
* a single run without editing `llm-config.json`. `anthropic` is accepted as
|
|
87
|
+
* an alias for `claude`. Unknown values are ignored (a warning is logged).
|
|
68
88
|
*/
|
|
69
|
-
export declare function
|
|
89
|
+
export declare function resolveProviderOverrideFromEnv(env?: NodeJS.ProcessEnv): ExtendedProviderType | undefined;
|
|
70
90
|
/**
|
|
71
|
-
* The full load path: defaults <- disk <- env detection <-
|
|
72
|
-
* This is what the kernel and CLI both call.
|
|
73
|
-
* RouterConfig ready to hand to HybridRouter.
|
|
91
|
+
* The full load path: defaults <- disk <- env detection <- AQE_LLM_PROVIDER
|
|
92
|
+
* override <- explicit override. This is what the kernel and CLI both call.
|
|
93
|
+
* Returns a fully-resolved RouterConfig ready to hand to HybridRouter.
|
|
74
94
|
*/
|
|
75
95
|
export declare function loadRouterConfig(options?: {
|
|
76
96
|
projectRoot?: string;
|
|
@@ -34,12 +34,18 @@ export const ROUTER_CONFIG_FILENAME = 'llm-config.json';
|
|
|
34
34
|
*/
|
|
35
35
|
const PROVIDER_ENV_KEYS = {
|
|
36
36
|
claude: ['ANTHROPIC_API_KEY', 'CLAUDE_API_KEY'],
|
|
37
|
+
// ADR-123: claude-code authenticates via the user's Claude Code OAuth login
|
|
38
|
+
// (subscription), NOT an env key. Empty array = "no key required"; actual
|
|
39
|
+
// availability is gated on the `claude` binary being on PATH (see the
|
|
40
|
+
// provider's isAvailable()).
|
|
41
|
+
'claude-code': [],
|
|
37
42
|
openai: ['OPENAI_API_KEY'],
|
|
38
43
|
ollama: [], // ollama is local; no key required
|
|
39
44
|
openrouter: ['OPENROUTER_API_KEY'],
|
|
40
45
|
gemini: ['GOOGLE_AI_API_KEY', 'GEMINI_API_KEY', 'GOOGLE_API_KEY'],
|
|
41
46
|
'azure-openai': ['AZURE_OPENAI_API_KEY'],
|
|
42
47
|
bedrock: ['AWS_ACCESS_KEY_ID'], // bedrock auth is more complex; presence is a hint
|
|
48
|
+
cognitum: ['COGNITUM_API_KEY'], // ADR-123: metered-capped gateway
|
|
43
49
|
onnx: [], // local
|
|
44
50
|
};
|
|
45
51
|
/**
|
|
@@ -52,12 +58,14 @@ const PROVIDER_ENV_KEYS = {
|
|
|
52
58
|
*/
|
|
53
59
|
const RUNTIME_CONSTRUCTIBLE_PROVIDERS = new Set([
|
|
54
60
|
'claude',
|
|
61
|
+
'claude-code',
|
|
55
62
|
'openai',
|
|
56
63
|
'ollama',
|
|
57
64
|
'openrouter',
|
|
58
65
|
'gemini',
|
|
59
66
|
'azure-openai',
|
|
60
67
|
'bedrock',
|
|
68
|
+
'cognitum',
|
|
61
69
|
]);
|
|
62
70
|
/**
|
|
63
71
|
* Return the resolved config-file path for a project.
|
|
@@ -197,15 +205,21 @@ export function mergeRouterConfig(base, override) {
|
|
|
197
205
|
* GOOGLE_API_KEY doesn't also have to remember to flip gemini.enabled
|
|
198
206
|
* to true). Providers without keys are left at their existing setting.
|
|
199
207
|
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
208
|
+
* ADR-123 AMENDMENT to ADR-043's addendum: env presence force-enables a
|
|
209
|
+
* provider ONLY when the user has not *explicitly* disabled it on disk. An
|
|
210
|
+
* explicit `enabled: false` in `.agentic-qe/llm-config.json` now wins over
|
|
211
|
+
* key presence — the previous behavior (env always overrides disk) meant
|
|
212
|
+
* merely exporting `ANTHROPIC_API_KEY` silently opted a user into paid API
|
|
213
|
+
* billing even after they had turned the provider off (issue #557). A
|
|
214
|
+
* provider left unset on disk is still force-enabled when its key is present
|
|
215
|
+
* (the convenient default). To disable a provider that has a key in env, set
|
|
216
|
+
* `enabled: false` for it on disk, unset the env key, or use the env-only
|
|
217
|
+
* kill-switch `AQE_LLM_ROUTER_DISABLED=1` (disables the whole router).
|
|
218
|
+
*
|
|
219
|
+
* @param explicitlyDisabled providers the user set to `enabled: false` in the
|
|
220
|
+
* raw on-disk config; these are never force-enabled by env detection.
|
|
207
221
|
*/
|
|
208
|
-
export function applyEnvProviderDetection(config, env = process.env) {
|
|
222
|
+
export function applyEnvProviderDetection(config, env = process.env, explicitlyDisabled = new Set()) {
|
|
209
223
|
const available = detectAvailableProvidersFromEnv(env);
|
|
210
224
|
const merged = {
|
|
211
225
|
...config,
|
|
@@ -215,6 +229,8 @@ export function applyEnvProviderDetection(config, env = process.env) {
|
|
|
215
229
|
const keys = PROVIDER_ENV_KEYS[provider];
|
|
216
230
|
if (keys.length === 0)
|
|
217
231
|
continue; // local provider, leave default
|
|
232
|
+
if (explicitlyDisabled.has(provider))
|
|
233
|
+
continue; // ADR-123: honor explicit off
|
|
218
234
|
const current = merged.providers[provider] ?? { enabled: false };
|
|
219
235
|
if (!current.enabled) {
|
|
220
236
|
merged.providers[provider] = { ...current, enabled: true };
|
|
@@ -223,14 +239,68 @@ export function applyEnvProviderDetection(config, env = process.env) {
|
|
|
223
239
|
return merged;
|
|
224
240
|
}
|
|
225
241
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
242
|
+
* Collect providers the user *explicitly* set to `enabled: false` in the raw
|
|
243
|
+
* on-disk config (as opposed to a default `false`). Used so env detection
|
|
244
|
+
* doesn't resurrect a provider the user deliberately turned off (ADR-123).
|
|
245
|
+
*/
|
|
246
|
+
export function collectExplicitlyDisabled(onDisk) {
|
|
247
|
+
const disabled = new Set();
|
|
248
|
+
if (!onDisk.providers)
|
|
249
|
+
return disabled;
|
|
250
|
+
for (const [provider, cfg] of Object.entries(onDisk.providers)) {
|
|
251
|
+
if (cfg && cfg.enabled === false) {
|
|
252
|
+
disabled.add(provider);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return disabled;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* ADR-123: highest-precedence provider selector. `AQE_LLM_PROVIDER=<type>`
|
|
259
|
+
* (e.g. `claude-code`, `cognitum`, `openai`) overrides `defaultProvider` and
|
|
260
|
+
* force-enables that provider, so a user can switch the execution provider for
|
|
261
|
+
* a single run without editing `llm-config.json`. `anthropic` is accepted as
|
|
262
|
+
* an alias for `claude`. Unknown values are ignored (a warning is logged).
|
|
263
|
+
*/
|
|
264
|
+
export function resolveProviderOverrideFromEnv(env = process.env) {
|
|
265
|
+
const raw = (env.AQE_LLM_PROVIDER ?? '').trim().toLowerCase();
|
|
266
|
+
if (!raw)
|
|
267
|
+
return undefined;
|
|
268
|
+
const normalized = raw === 'anthropic' ? 'claude' : raw;
|
|
269
|
+
if (ALL_PROVIDER_TYPES.includes(normalized)) {
|
|
270
|
+
return normalized;
|
|
271
|
+
}
|
|
272
|
+
// eslint-disable-next-line no-console
|
|
273
|
+
console.warn(`[router-config] Ignoring AQE_LLM_PROVIDER="${raw}": not a known provider. ` +
|
|
274
|
+
`Valid values: ${ALL_PROVIDER_TYPES.join(', ')}.`);
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* The full load path: defaults <- disk <- env detection <- AQE_LLM_PROVIDER
|
|
279
|
+
* override <- explicit override. This is what the kernel and CLI both call.
|
|
280
|
+
* Returns a fully-resolved RouterConfig ready to hand to HybridRouter.
|
|
229
281
|
*/
|
|
230
282
|
export function loadRouterConfig(options = {}) {
|
|
283
|
+
const env = options.env ?? process.env;
|
|
231
284
|
const onDisk = loadRouterConfigFile(options.projectRoot);
|
|
232
285
|
const merged = mergeRouterConfig(DEFAULT_ROUTER_CONFIG, onDisk);
|
|
233
|
-
|
|
286
|
+
// ADR-123: an explicit `enabled: false` on disk is never resurrected by env.
|
|
287
|
+
const explicitlyDisabled = collectExplicitlyDisabled(onDisk);
|
|
288
|
+
let withEnv = applyEnvProviderDetection(merged, env, explicitlyDisabled);
|
|
289
|
+
// ADR-123: AQE_LLM_PROVIDER pins the default provider and enables it.
|
|
290
|
+
const providerOverride = resolveProviderOverrideFromEnv(env);
|
|
291
|
+
if (providerOverride) {
|
|
292
|
+
withEnv = {
|
|
293
|
+
...withEnv,
|
|
294
|
+
defaultProvider: providerOverride,
|
|
295
|
+
providers: {
|
|
296
|
+
...withEnv.providers,
|
|
297
|
+
[providerOverride]: {
|
|
298
|
+
...(withEnv.providers?.[providerOverride] ?? {}),
|
|
299
|
+
enabled: true,
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
234
304
|
return options.override ? mergeRouterConfig(withEnv, options.override) : withEnv;
|
|
235
305
|
}
|
|
236
306
|
/**
|
|
@@ -489,6 +489,15 @@ export class HybridRouter {
|
|
|
489
489
|
order = toolCapable;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
+
// ADR-123 (issue #557): enforce the spend budget on the PRIMARY QE
|
|
493
|
+
// execution path. Domains call HybridRouter.chat() directly, which runs
|
|
494
|
+
// provider.generate() below — bypassing ProviderManager.generate() where
|
|
495
|
+
// the budget is otherwise checked. Gate once per request (not per fallback
|
|
496
|
+
// attempt); throws COST_LIMIT_EXCEEDED, or no-ops when no budget is set.
|
|
497
|
+
this.providerManager.assertWithinBudget(params.messages, {
|
|
498
|
+
model: order[0]?.model,
|
|
499
|
+
maxTokens: params.maxTokens,
|
|
500
|
+
});
|
|
492
501
|
// Execute with fallback
|
|
493
502
|
for (const { provider: providerType, model } of order) {
|
|
494
503
|
if (attempts >= fallbackBehavior.maxAttempts)
|
|
@@ -508,6 +517,9 @@ export class HybridRouter {
|
|
|
508
517
|
skipCache: params.skipCache,
|
|
509
518
|
metadata: params.metadata,
|
|
510
519
|
});
|
|
520
|
+
// ADR-123: persist the charge to the cross-process ledger so budgets
|
|
521
|
+
// hold across a fleet of processes.
|
|
522
|
+
this.providerManager.recordResponseSpend(response);
|
|
511
523
|
const callLatency = Date.now() - callStartTime;
|
|
512
524
|
// Record success in legacy tracker
|
|
513
525
|
this.metrics.recordSuccess(providerType);
|
|
@@ -609,8 +621,12 @@ export class HybridRouter {
|
|
|
609
621
|
*/
|
|
610
622
|
resolveModelIds(model, providerType) {
|
|
611
623
|
// Map provider type to model-mapping provider format
|
|
624
|
+
// Partial: claude-code shares Anthropic model IDs; cognitum uses its own
|
|
625
|
+
// tier names (cognitum-low/mid/high) that aren't in the mapping table, so
|
|
626
|
+
// it falls through the `!mappingProvider` guard below to pass-through.
|
|
612
627
|
const providerMapping = {
|
|
613
628
|
claude: 'anthropic',
|
|
629
|
+
'claude-code': 'anthropic',
|
|
614
630
|
openai: 'openai',
|
|
615
631
|
ollama: 'ollama',
|
|
616
632
|
openrouter: 'openrouter',
|
|
@@ -23,12 +23,14 @@
|
|
|
23
23
|
*/
|
|
24
24
|
export const ALL_PROVIDER_TYPES = [
|
|
25
25
|
'claude',
|
|
26
|
+
'claude-code', // ADR-123: subscription-billed via `claude -p`
|
|
26
27
|
'openai',
|
|
27
28
|
'ollama',
|
|
28
29
|
'openrouter',
|
|
29
30
|
'gemini',
|
|
30
31
|
'azure-openai',
|
|
31
32
|
'bedrock',
|
|
33
|
+
'cognitum', // ADR-123: metered-capped gateway (api.cognitum.one)
|
|
32
34
|
'onnx',
|
|
33
35
|
];
|
|
34
36
|
/**
|
|
@@ -133,12 +135,17 @@ export const DEFAULT_ROUTER_CONFIG = {
|
|
|
133
135
|
fallbackBehavior: DEFAULT_FALLBACK_BEHAVIOR,
|
|
134
136
|
providers: {
|
|
135
137
|
claude: { enabled: true, defaultModel: 'claude-sonnet-4-6' },
|
|
138
|
+
// ADR-123: opt-in (issue #557 — don't default the subscription/fleet path
|
|
139
|
+
// on). Enabled explicitly via AQE_LLM_PROVIDER=claude-code or disk config.
|
|
140
|
+
'claude-code': { enabled: false, defaultModel: 'claude-sonnet-4-6' },
|
|
136
141
|
openai: { enabled: true, defaultModel: 'gpt-4o' },
|
|
137
142
|
ollama: { enabled: true, defaultModel: 'llama3.1' },
|
|
138
143
|
openrouter: { enabled: true, defaultModel: 'anthropic/claude-sonnet-4' },
|
|
139
144
|
gemini: { enabled: false, defaultModel: 'gemini-pro' },
|
|
140
145
|
'azure-openai': { enabled: false },
|
|
141
146
|
bedrock: { enabled: false },
|
|
147
|
+
// ADR-123: opt-in; enabled when COGNITUM_API_KEY present or via override.
|
|
148
|
+
cognitum: { enabled: false, defaultModel: 'cognitum-auto' },
|
|
142
149
|
onnx: { enabled: true, defaultModel: 'phi-4' },
|
|
143
150
|
},
|
|
144
151
|
enableMetrics: true,
|