agentic-qe 3.12.3 → 3.13.1
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/.agents/skills/aqe-plan-quality/SKILL.md +25 -0
- package/.agents/skills/aqe-plan-quality/agents/openai.yaml +4 -0
- package/.agents/skills/aqe-plan-quality/references/qe-routing.md +22 -0
- package/.agents/skills/aqe-review-quality/SKILL.md +24 -0
- package/.agents/skills/aqe-review-quality/agents/openai.yaml +4 -0
- package/.agents/skills/aqe-review-quality/references/quality-gates.md +20 -0
- package/.agents/skills/aqe-test-change/SKILL.md +26 -0
- package/.agents/skills/aqe-test-change/agents/openai.yaml +4 -0
- package/.agents/skills/aqe-test-change/references/test-specialties.md +23 -0
- package/.claude/helpers/.helpers-version +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +430 -430
- package/.claude/helpers/helpers.manifest.json +6 -5
- package/.claude/helpers/hook-handler.cjs +565 -311
- package/.claude/helpers/intelligence.cjs +1058 -1058
- package/.claude/helpers/ruflo-hook.cjs +5 -1
- package/.claude/helpers/statusline.cjs +995 -682
- package/.claude/skills/qe-court/SKILL.md +186 -0
- package/.claude/skills/qe-court/config.json +27 -0
- package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
- package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
- package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
- package/.claude/skills/qe-court/evals/qe-court.yaml +70 -0
- package/.claude/skills/qe-court/schemas/output.json +92 -0
- package/.claude/skills/qe-court/scripts/validate-config.json +30 -0
- package/.claude/skills/skills-manifest.json +9 -8
- package/.codex/hooks/aqe-codex-hook.cjs +69 -0
- package/.codex/hooks/ruflo-codex-hook.cjs +94 -0
- package/.codex/hooks.json +169 -0
- package/CHANGELOG.md +159 -0
- package/README.md +3 -3
- package/assets/skills/qe-court/SKILL.md +186 -0
- package/assets/skills/qe-court/config.json +27 -0
- package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
- package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
- package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
- package/assets/skills/qe-court/evals/qe-court.yaml +70 -0
- package/assets/skills/qe-court/schemas/output.json +92 -0
- package/assets/skills/qe-court/scripts/validate-config.json +30 -0
- package/assets/skills/skills-manifest.json +9 -8
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-VRZNL53W.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-XFAQATTH.js → agent-booster-wasm-4VM3DE42.js} +2 -2
- package/dist/cli/chunks/{agent-handler-2ZV4CA3U.js → agent-handler-ZDLMZQQX.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-6WGP7F5T.js → agent-memory-branch-P72MDHHV.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-XCNMNERX.js +2 -0
- package/dist/cli/chunks/{arena-FWX7XZAE.js → arena-55FZGKEV.js} +4 -4
- package/dist/cli/chunks/{arena-KJUNQK4N.js → arena-GCRBQ26R.js} +2 -2
- package/dist/cli/chunks/{audit-YFUDEOKN.js → audit-VYAYVLIV.js} +3 -3
- package/dist/cli/chunks/base-VZZNR4UR.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-SKTT5KIH.js → better-sqlite3-JDDFYVCX.js} +2 -2
- package/dist/cli/chunks/{brain-handler-ZCK4WTPK.js → brain-handler-IUKMRGWO.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-HTVINRYG.js → branch-enumerator-TUI3RWLX.js} +2 -2
- package/dist/cli/chunks/{browser-WUL2B77M.js → browser-NBQTZYX2.js} +2 -2
- package/dist/cli/chunks/browser-workflow-5DZNIFUY.js +2 -0
- package/dist/cli/chunks/{chunk-IWQHQLT6.js → chunk-23MT7OBY.js} +2 -2
- package/dist/cli/chunks/{chunk-KE3RK35K.js → chunk-2CQAWYYE.js} +1 -1
- package/dist/cli/chunks/{chunk-ADQFQBFJ.js → chunk-2D2XFUKI.js} +2 -2
- package/dist/cli/chunks/{chunk-2YDZXFO2.js → chunk-2G2QWV7B.js} +2 -2
- package/dist/cli/chunks/{chunk-HGJQSTQD.js → chunk-2ISLQU3G.js} +1 -1
- package/dist/cli/chunks/{chunk-6E47R27C.js → chunk-2OM3TDC4.js} +1 -1
- package/dist/cli/chunks/{chunk-WQASUQ5P.js → chunk-2XZ4BHWS.js} +1 -1
- package/dist/cli/chunks/{chunk-E2U3LTGM.js → chunk-3F4XH4ZA.js} +1 -1
- package/dist/cli/chunks/{chunk-YUDGQZJN.js → chunk-3K4YC3GC.js} +2 -2
- package/dist/cli/chunks/chunk-3KGCBAUH.js +2 -0
- package/dist/cli/chunks/{chunk-PXCJDB7J.js → chunk-3Y6CHW67.js} +1 -1
- package/dist/cli/chunks/{chunk-MOX25RZQ.js → chunk-4QMWWYNU.js} +2 -2
- package/dist/cli/chunks/{chunk-XZGOXLZH.js → chunk-4WGSMODQ.js} +1 -1
- package/dist/cli/chunks/{chunk-2CPJCXV6.js → chunk-55WDVSCM.js} +2 -2
- package/dist/cli/chunks/{chunk-EHO52NKU.js → chunk-5BB5DUL4.js} +2 -2
- package/dist/cli/chunks/{chunk-BEPP57C2.js → chunk-6C3MZLYW.js} +2 -2
- package/dist/cli/chunks/{chunk-DTZFZ5M7.js → chunk-6QKQFHS7.js} +2 -2
- package/dist/cli/chunks/{chunk-KXKACV3E.js → chunk-6XZXMEK4.js} +3 -3
- package/dist/cli/chunks/{chunk-L6GZGEFQ.js → chunk-7D7XFZZI.js} +2 -2
- package/dist/cli/chunks/{chunk-NLDLUHOF.js → chunk-7WEHZCSK.js} +2 -2
- package/dist/cli/chunks/{chunk-TXLPOXAN.js → chunk-A2MG3YXO.js} +1 -1
- package/dist/cli/chunks/{chunk-HJ2LG5IH.js → chunk-AHTOWWSE.js} +1 -1
- package/dist/cli/chunks/{chunk-GV2BS5NC.js → chunk-AOMXMFDH.js} +2 -2
- package/dist/cli/chunks/{chunk-EH7TSJPS.js → chunk-ARTLSAXO.js} +2 -2
- package/dist/cli/chunks/{chunk-CXMOIE7D.js → chunk-AY7S7AWN.js} +2 -2
- package/dist/cli/chunks/{chunk-2LNDU7AW.js → chunk-AYYDO52G.js} +2 -2
- package/dist/cli/chunks/chunk-BBLWZT5I.js +2 -0
- package/dist/cli/chunks/{chunk-KRS4KGX5.js → chunk-BF5BKSDU.js} +2 -2
- package/dist/cli/chunks/{chunk-BQ2K4BPD.js → chunk-BOCEOLLJ.js} +2 -2
- package/dist/cli/chunks/{chunk-KKOFH26C.js → chunk-CE6LYEHT.js} +1 -1
- package/dist/cli/chunks/{chunk-GS6G7AVS.js → chunk-CWP4RMOM.js} +2 -2
- package/dist/cli/chunks/{chunk-DCYBV6HV.js → chunk-CWXDL7AH.js} +1 -1
- package/dist/cli/chunks/{chunk-KGHSKDC7.js → chunk-DTRFZD7N.js} +2 -2
- package/dist/cli/chunks/{chunk-CYSBM52D.js → chunk-DVPGQG4W.js} +2 -2
- package/dist/cli/chunks/{chunk-MSDIIRLM.js → chunk-E4D47QTF.js} +2 -2
- package/dist/cli/chunks/{chunk-MB7TZQW3.js → chunk-EAKHU5YX.js} +3 -3
- package/dist/cli/chunks/{chunk-TP3UAWMB.js → chunk-EGMGOWCE.js} +2 -2
- package/dist/cli/chunks/{chunk-4EHW4TNA.js → chunk-ELMUHNXN.js} +2 -2
- package/dist/cli/chunks/chunk-EVDYFGVH.js +2 -0
- package/dist/cli/chunks/{chunk-D4GMAUTP.js → chunk-FDUSWM6O.js} +98 -88
- package/dist/cli/chunks/{chunk-YEC55GO5.js → chunk-FM272B4O.js} +2 -2
- package/dist/cli/chunks/{chunk-DMD6WVJ2.js → chunk-FQUUMC57.js} +2 -2
- package/dist/cli/chunks/{chunk-Y625LP6K.js → chunk-FQXQJMSF.js} +2 -2
- package/dist/cli/chunks/{chunk-Z3SXMYVI.js → chunk-FRAGSKXQ.js} +3 -3
- package/dist/cli/chunks/{chunk-MOXKKY5Q.js → chunk-GASOBSNB.js} +4 -4
- package/dist/cli/chunks/{chunk-PTPN6HQ7.js → chunk-GJEEPKAT.js} +2 -2
- package/dist/cli/chunks/{chunk-WFPGIP4N.js → chunk-GOV2MHLV.js} +2 -2
- package/dist/cli/chunks/{chunk-NKTLKMUB.js → chunk-GTPZVLL6.js} +1 -1
- package/dist/cli/chunks/chunk-H7YZ2YF2.js +3 -0
- package/dist/cli/chunks/{chunk-WKE6WL5C.js → chunk-HFI5PHG5.js} +3 -3
- package/dist/cli/chunks/chunk-HUMQU4ES.js +153 -0
- package/dist/cli/chunks/{chunk-5FAWIIWF.js → chunk-HYIRFJDB.js} +2 -2
- package/dist/cli/chunks/{chunk-DZ775UGW.js → chunk-IBSBOHUX.js} +2 -2
- package/dist/cli/chunks/{chunk-NAMJGRGC.js → chunk-IJA4WS7B.js} +2 -2
- package/dist/cli/chunks/{chunk-XUUVAAHV.js → chunk-IJP42OGW.js} +2 -2
- package/dist/cli/chunks/{chunk-UZ7FXVH5.js → chunk-IMQKEFW6.js} +1 -1
- package/dist/cli/chunks/{chunk-MZ7SIO6R.js → chunk-INYS35DV.js} +2 -2
- package/dist/cli/chunks/{chunk-MS6VOSPY.js → chunk-IV2VCR75.js} +5 -5
- package/dist/cli/chunks/{chunk-UAPUA6OY.js → chunk-IZO6TPGX.js} +2 -2
- package/dist/cli/chunks/{chunk-XBOCRCC6.js → chunk-J45DX3IK.js} +1 -1
- package/dist/cli/chunks/{chunk-RE42RJYR.js → chunk-J4T6D2OQ.js} +2 -2
- package/dist/cli/chunks/{chunk-Y5L37K7X.js → chunk-JAPOMPFD.js} +2 -2
- package/dist/cli/chunks/{chunk-M7W6VJ65.js → chunk-JELNVHBF.js} +1 -1
- package/dist/cli/chunks/{chunk-YDYKFSD2.js → chunk-JOTNKZ7A.js} +87 -87
- package/dist/cli/chunks/{chunk-VUCVSKJC.js → chunk-KNWDXI3I.js} +2 -2
- package/dist/cli/chunks/{chunk-SPI4LUJ6.js → chunk-KW5NBORV.js} +2 -2
- package/dist/cli/chunks/{chunk-2OX74DOO.js → chunk-L7IOTWWY.js} +1 -1
- package/dist/cli/chunks/{chunk-VFYMWDSJ.js → chunk-LJQ27PUE.js} +1 -1
- package/dist/cli/chunks/{chunk-NT66CT73.js → chunk-LSKQUUUN.js} +2 -2
- package/dist/cli/chunks/{chunk-ROFCS47F.js → chunk-LSZZQ7H6.js} +1 -1
- package/dist/cli/chunks/{chunk-Y6XNISHP.js → chunk-LTKNCYMO.js} +2 -2
- package/dist/cli/chunks/{chunk-7WF3TW3G.js → chunk-LTWT4GZD.js} +4 -4
- package/dist/cli/chunks/chunk-LVHMXGDI.js +29 -0
- package/dist/cli/chunks/{chunk-3YC4YUGB.js → chunk-M3T6FB54.js} +2 -2
- package/dist/cli/chunks/{chunk-M32DTUZM.js → chunk-MAYZTGJ2.js} +3 -3
- package/dist/cli/chunks/{chunk-RLBNAB6Y.js → chunk-MCIO7BDK.js} +1 -1
- package/dist/cli/chunks/{chunk-SFS3UHNF.js → chunk-MPD7RR4P.js} +1 -1
- package/dist/cli/chunks/{chunk-DDYP6FBC.js → chunk-MUFYDKVC.js} +2 -2
- package/dist/cli/chunks/{chunk-ZFLE4D4X.js → chunk-MX5ZDKRR.js} +2 -2
- package/dist/cli/chunks/{chunk-WBZNLFTV.js → chunk-MXKHIZVM.js} +5 -5
- package/dist/cli/chunks/chunk-MY47CR27.js +2 -0
- package/dist/cli/chunks/chunk-N7WAZ2Y6.js +2 -0
- package/dist/cli/chunks/{chunk-2HCMRGMO.js → chunk-NHV4PTG6.js} +2 -2
- package/dist/cli/chunks/{chunk-HJ4U64BL.js → chunk-NP4CP3LR.js} +2 -2
- package/dist/cli/chunks/{chunk-UIHZ34SJ.js → chunk-OCKTPTQ7.js} +2 -2
- package/dist/cli/chunks/{chunk-SGMJ277D.js → chunk-OE4B6LDZ.js} +1 -1
- package/dist/cli/chunks/{chunk-SV7J5FDW.js → chunk-OPQY2333.js} +2 -2
- package/dist/cli/chunks/{chunk-FTM562PF.js → chunk-ORDH4VPL.js} +1 -1
- package/dist/cli/chunks/{chunk-YOG5KQZF.js → chunk-P4Y3G6OB.js} +2 -2
- package/dist/cli/chunks/{chunk-LHAUFY4Y.js → chunk-PIOO2M4W.js} +2 -2
- package/dist/cli/chunks/{chunk-UGW23T6S.js → chunk-PKMCZFET.js} +2 -2
- package/dist/cli/chunks/{chunk-OPG2HV2W.js → chunk-QES4QHQW.js} +1 -1
- package/dist/cli/chunks/{chunk-BDGKB2PT.js → chunk-QG6BXSNJ.js} +2 -2
- package/dist/cli/chunks/{chunk-BSNNTOHY.js → chunk-QLOOW23R.js} +3 -3
- package/dist/cli/chunks/{chunk-AIWRYWK2.js → chunk-RSCGBHLM.js} +2 -2
- package/dist/cli/chunks/{chunk-LCM7TY76.js → chunk-RZ6CO3RZ.js} +2 -2
- package/dist/cli/chunks/chunk-S6F3IJMK.js +2 -0
- package/dist/cli/chunks/{chunk-WUE53ZPH.js → chunk-S6VNPKHO.js} +1 -1
- package/dist/cli/chunks/{chunk-L2X3BWMN.js → chunk-SHWXADCI.js} +2 -2
- package/dist/cli/chunks/{chunk-GMFFMJD6.js → chunk-SPJQJWGK.js} +2 -2
- package/dist/cli/chunks/{chunk-KVHCWH4H.js → chunk-SS6K4FBH.js} +2 -2
- package/dist/cli/chunks/{chunk-ZGKQCUPB.js → chunk-SXADKQJN.js} +2 -2
- package/dist/cli/chunks/{chunk-LGYEOYQJ.js → chunk-TBQTGQ75.js} +2 -2
- package/dist/cli/chunks/{chunk-J2RJOJ5Q.js → chunk-TDGE52HJ.js} +1 -1
- package/dist/cli/chunks/chunk-THFLRJT6.js +54 -0
- package/dist/cli/chunks/{chunk-GGTCD4MA.js → chunk-TQ2MA3SR.js} +1 -1
- package/dist/cli/chunks/{chunk-NOSQI2OW.js → chunk-UCQ66N6M.js} +3 -3
- package/dist/cli/chunks/{chunk-CL6SNCFF.js → chunk-UHGMS2PJ.js} +1 -1
- package/dist/cli/chunks/{chunk-XDHGCBTS.js → chunk-UHKXKWMD.js} +2 -2
- package/dist/cli/chunks/{chunk-PEHEANAM.js → chunk-UJ6TMZC6.js} +2 -2
- package/dist/cli/chunks/{chunk-PSDH7CIL.js → chunk-UKBDH27A.js} +1 -1
- package/dist/cli/chunks/{chunk-ZTKCGEB6.js → chunk-UMCEEXQN.js} +1 -1
- package/dist/cli/chunks/{chunk-KA4EAMMQ.js → chunk-USUFTHHT.js} +3 -3
- package/dist/cli/chunks/{chunk-QILF6BZH.js → chunk-V32MDID3.js} +2 -2
- package/dist/cli/chunks/{chunk-6SUSRXXF.js → chunk-VAJT6QWX.js} +1 -1
- package/dist/cli/chunks/{chunk-7Q74K3HZ.js → chunk-VLUJWI56.js} +1 -1
- package/dist/cli/chunks/{chunk-DW7OI5IF.js → chunk-WINA3XUT.js} +2 -2
- package/dist/cli/chunks/{chunk-S47YGWXK.js → chunk-WWCH5SSF.js} +2 -2
- package/dist/cli/chunks/{chunk-FJACKKRL.js → chunk-WWP2VXYJ.js} +2 -2
- package/dist/cli/chunks/{chunk-N4ML23ZG.js → chunk-WZROSTQZ.js} +1 -1
- package/dist/cli/chunks/{chunk-FXOOOJQD.js → chunk-XFUF654L.js} +1 -1
- package/dist/cli/chunks/{chunk-PDX7IYTJ.js → chunk-XN2CD5S6.js} +2 -2
- package/dist/cli/chunks/{chunk-DHUZHT5D.js → chunk-XOQQGZFY.js} +1 -1
- package/dist/cli/chunks/{chunk-4HP7N6SP.js → chunk-XSCOEY4C.js} +2 -2
- package/dist/cli/chunks/{chunk-KNWBRMLL.js → chunk-Y734CWHJ.js} +2 -2
- package/dist/cli/chunks/{chunk-NJDLJ3KD.js → chunk-YBPCBFEE.js} +2 -2
- package/dist/cli/chunks/{chunk-67BCEHU5.js → chunk-YLAEIS6F.js} +1 -1
- package/dist/cli/chunks/{chunk-E53UR2EW.js → chunk-YMMVCOPF.js} +3 -3
- package/dist/cli/chunks/{chunk-VSD6JE2H.js → chunk-YQCAXYBF.js} +2 -2
- package/dist/cli/chunks/{chunk-32L7DKNQ.js → chunk-YRVUYM62.js} +2 -2
- package/dist/cli/chunks/{chunk-LNIHLNW4.js → chunk-YVKMHXQK.js} +3 -3
- package/dist/cli/chunks/{chunk-CHFTHSMM.js → chunk-ZCLFAOVT.js} +2 -2
- package/dist/cli/chunks/{chunk-AZ24ONMX.js → chunk-ZH6ZBDVV.js} +1 -1
- package/dist/cli/chunks/{chunk-R6WMGSEK.js → chunk-ZHEKGB4A.js} +2 -2
- package/dist/cli/chunks/{chunk-EOUJ6X5H.js → chunk-ZIBW7CB4.js} +1 -1
- package/dist/cli/chunks/{chunk-OBL6W4Z5.js → chunk-ZLCATRXI.js} +2 -2
- package/dist/cli/chunks/{chunk-UGXHMQ6P.js → chunk-ZXX2VFMA.js} +2 -2
- package/dist/cli/chunks/{chunk-72QQDR3Y.js → chunk-ZYPESQ4M.js} +2 -2
- package/dist/cli/chunks/{ci-MMLUV6L6.js → ci-HHL5WQXQ.js} +2 -2
- package/dist/cli/chunks/{ci-output-25GS6RXR.js → ci-output-HVOJC2KN.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-4OWAN6R6.js → circuit-breaker-HRXMIY2G.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-LR3SRBX6.js → claude-flow-setup-3I7WVMZN.js} +2 -2
- package/dist/cli/chunks/client-EY2IYQDL.js +2 -0
- package/dist/cli/chunks/{cline-installer-YSZWRZUI.js → cline-installer-NBREL4QT.js} +2 -2
- package/dist/cli/chunks/{code-UUWUIXI7.js → code-TX4E2RWU.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-2LSPQORU.js → code-index-extractor-YELOFLSL.js} +2 -2
- package/dist/cli/chunks/codex-installer-HEX3KFRB.js +10 -0
- package/dist/cli/chunks/{completions-YKXBKZSO.js → completions-72GGFRGG.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-HNT2QRWB.js → complexity-analyzer-WRAKDYUK.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-AW5VCB66.js → continuedev-installer-UGYKSKTI.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-B6SVZXQT.js → copilot-installer-RPCRUKIJ.js} +2 -2
- package/dist/cli/chunks/core-handlers-G4GLA4DT.js +2 -0
- package/dist/cli/chunks/{cost-tracker-POZMBN2V.js → cost-tracker-CNHJ7G4M.js} +2 -2
- package/dist/cli/chunks/{coverage-V5BGPN5Q.js → coverage-RHIQ4XEX.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-P3K4IH5H.js +2 -0
- package/dist/cli/chunks/{cursor-installer-EYBI4QVK.js → cursor-installer-KSRVA4V2.js} +2 -2
- package/dist/cli/chunks/{daemon-CF6ENQB2.js → daemon-IT4AAFBW.js} +3 -3
- package/dist/cli/chunks/{daemon-HKARXY2W.js → daemon-QBXSJABV.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-XIL5IAP7.js → dag-attention-scheduler-F7WCQTLY.js} +2 -2
- package/dist/cli/chunks/{detect-RRX2U2KK.js → detect-2IYU332U.js} +2 -2
- package/dist/cli/chunks/{dist-node-DOANNRCS.js → dist-node-CIYNYCYN.js} +2 -2
- package/dist/cli/chunks/{domain-handler-QMTJV5OR.js → domain-handler-QRYQO2QK.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-FSNH75XW.js → domain-transfer-2OQDOD3G.js} +2 -2
- package/dist/cli/chunks/dream-IT4ZQGEO.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-NI7PGONV.js → embed-and-insert-pattern-P2IFC7JL.js} +2 -2
- package/dist/cli/chunks/{eval-6ZAF2RY3.js → eval-SBPK37IB.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-JMXR7N5G.js → experience-capture-middleware-3GMFND3F.js} +3 -3
- package/dist/cli/chunks/{fast-paths-YB7XZZ76.js → fast-paths-4OYYII2F.js} +2 -2
- package/dist/cli/chunks/{feature-flags-2RC4GFC4.js → feature-flags-BM6QTMMC.js} +2 -2
- package/dist/cli/chunks/{feature-flags-KJSP7KR6.js → feature-flags-NFCAYUWO.js} +2 -2
- package/dist/cli/chunks/{file-discovery-SUPBXFYI.js → file-discovery-2M3ZUAGC.js} +2 -2
- package/dist/cli/chunks/{fleet-KSXFOLFW.js → fleet-QMGGVIDV.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-DFZ5KPPK.js → gnn-wrapper-WGMAGZMO.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-G3EADK2H.js → heartbeat-handler-5RSMEZGG.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-UUWSPHF2.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-YUJVSFPD.js +2 -0
- package/dist/cli/chunks/hnsw-index-FQZ47RSJ.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-MA676GER.js → hnsw-legacy-bridge-TYPQ2T6P.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-FE55OGYB.js → hnswlib-node-GMRPPMDM.js} +2 -2
- package/dist/cli/chunks/{hooks-HTCPMZNZ.js → hooks-NUC5P3OJ.js} +10 -10
- package/dist/cli/chunks/hybrid-router-T5MF73NF.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-QPB3IH4A.js → hypergraph-engine-OIB7WK54.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-GBFSVD7N.js → hypergraph-handler-XX2N75QC.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-AEGELYMD.js +2 -0
- package/dist/cli/chunks/{init-handler-XYBTBCPD.js → init-handler-AKSTJMZY.js} +6 -6
- package/dist/cli/chunks/init-wizard-WKX3OGWM.js +2 -0
- package/dist/cli/chunks/kernel-5CVWFIGR.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-LY6JOBFY.js → kilocode-installer-375V5ZZB.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-JF6NXTJL.js → kiro-installer-GKY5GB5Q.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-EGPMNDMT.js +2 -0
- package/dist/cli/chunks/{learning-BIISN67N.js → learning-2CQE3QP6.js} +3 -3
- package/dist/cli/chunks/{llm-router-YZUNVZQE.js → llm-router-FTQNRF45.js} +5 -5
- package/dist/cli/chunks/llm-router-service-H4LXOARB.js +2 -0
- package/dist/cli/chunks/{load-MTWNBNLL.js → load-3DBAO5ZG.js} +2 -2
- package/dist/cli/chunks/load-test-OOOGITSN.js +2 -0
- package/dist/cli/chunks/{mcp-37PYMNHQ.js → mcp-AWR6TDXM.js} +2 -2
- package/dist/cli/chunks/{memory-IXUUDCI3.js → memory-GI4LCNXY.js} +5 -5
- package/dist/cli/chunks/memory-backend-O2YOT4LW.js +2 -0
- package/dist/cli/chunks/{memory-handlers-RM2VOFJX.js → memory-handlers-MALKG7GP.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-RKKS5XYG.js → multi-model-executor-SWFT5U72.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-3VXI5MTR.js → opencode-installer-EYXGYJX5.js} +2 -2
- package/dist/cli/chunks/{orchestrator-UO3ZOGFZ.js → orchestrator-MP3EAZVC.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-WBOHE2XL.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-YJKRL2GI.js → pattern-usage-recorder-25P3R3W7.js} +2 -2
- package/dist/cli/chunks/{pipeline-GJQJKXWX.js → pipeline-LSAFL25D.js} +2 -2
- package/dist/cli/chunks/{platform-RHVCZK6C.js → platform-IJ6DJ2PG.js} +2 -2
- package/dist/cli/chunks/{plugin-ZKAIW7O6.js → plugin-OXOZRZW2.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-4X3DSKQV.js → prime-radiant-advanced-wasm-HJNJQQ3R.js} +2 -2
- package/dist/cli/chunks/protocol-executor-JCNTPW5J.js +2 -0
- package/dist/cli/chunks/{protocol-handler-KKYQZMB2.js → protocol-handler-TCMUH2HL.js} +2 -2
- package/dist/cli/chunks/{prove-OD6RPKWX.js → prove-ADXQ2GOX.js} +2 -2
- package/dist/cli/chunks/provider-manager-LPGQ5GOO.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-FWVYVSPP.js +2 -0
- package/dist/cli/chunks/{quality-ZRWBXCKO.js → quality-EWP36ORX.js} +2 -2
- package/dist/cli/chunks/{quality-gate-Y6BWQV7J.js → quality-gate-3BIG7PVU.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-UXNALRVD.js +2 -0
- package/dist/cli/chunks/{real-embeddings-YYEUO4P2.js → real-embeddings-D4NBT7W5.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-JBCPS3FK.js → roocode-installer-DOPWH6YV.js} +2 -2
- package/dist/cli/chunks/router-C6LUIQYY.js +2 -0
- package/dist/cli/chunks/routing-feedback-KMSGGDVD.js +2 -0
- package/dist/cli/chunks/{routing-handler-KTPJOSBJ.js → routing-handler-5ADEFOHS.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-SCZZVRE7.js → ruvector-commands-PLMEIHSN.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-IP7GELQJ.js → rvf-dual-writer-EQWKVNQB.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-WLFTDARU.js → rvf-migration-adapter-2OWFUUCG.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-MGFDQ5WD.js → rvf-migration-coordinator-URAETAPU.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-K54BELUE.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-OTOAGT5W.js → rvf-store-integrity-4AWPW4TF.js} +2 -2
- package/dist/cli/chunks/safe-db-NGOZWF2D.js +2 -0
- package/dist/cli/chunks/schedule-B3Y5P64E.js +2 -0
- package/dist/cli/chunks/scheduler-Z6QVRMTB.js +2 -0
- package/dist/cli/chunks/{security-B2CLZKRB.js → security-HDLZVM62.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-2PMFAQMN.js → shared-rvf-adapter-YQT7PF7X.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-B6P732AV.js → shared-rvf-dual-writer-N5D3NSJ7.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-PLOUGATS.js +2 -0
- package/dist/cli/chunks/{status-handler-M6SN2W2D.js → status-handler-KLYRJ2MR.js} +2 -2
- package/dist/cli/chunks/{structural-health-YCCTGI3K.js → structural-health-6LKVRP6Y.js} +2 -2
- package/dist/cli/chunks/sync-7VMFPBVB.js +2 -0
- package/dist/cli/chunks/{sync-KSRF77ID.js → sync-YYOW6L6W.js} +2 -2
- package/dist/cli/chunks/{task-handler-MIKRB2SL.js → task-handler-RKQDGFN2.js} +2 -2
- package/dist/cli/chunks/{task-handlers-YXKRUBQ4.js → task-handlers-6YJ4QTEP.js} +3 -3
- package/dist/cli/chunks/{test-MLOLQCB7.js → test-ASPUIUJH.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-3KXESUZS.js → test-scheduling-I7ABQBBU.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-6V2PMDBJ.js → token-bootstrap-2XZBTODN.js} +2 -2
- package/dist/cli/chunks/{token-usage-DP6THJ3I.js → token-usage-TMUE6PTF.js} +2 -2
- package/dist/cli/chunks/transformers-FDHHH4SL.js +2 -0
- package/dist/cli/chunks/{tree-sitter-wasm-parser-COK2XERS.js → tree-sitter-wasm-parser-G7PGZA5C.js} +2 -2
- package/dist/cli/chunks/{types-PYHUCVOZ.js → types-JGT57UFP.js} +2 -2
- package/dist/cli/chunks/unified-memory-P5YVLMFI.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-7HI43A2O.js +2 -0
- package/dist/cli/chunks/unified-persistence-U26YP3N3.js +2 -0
- package/dist/cli/chunks/{upgrade-ONP2HNGL.js → upgrade-V6UQODJF.js} +2 -2
- package/dist/cli/chunks/{validate-NWSICDAY.js → validate-UBZAE5RW.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-KXS5P3U7.js → validate-swarm-TSO2MI5X.js} +2 -2
- package/dist/cli/chunks/{vibium-TZSGZRCQ.js → vibium-7G3VYSQA.js} +2 -2
- package/dist/cli/chunks/visual-security-6FCDY5FF.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-V2FADNRA.js → web-tree-sitter-MIYJSF2L.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-GQM7KWDC.js → windsurf-installer-5TLZSQIJ.js} +2 -2
- package/dist/cli/chunks/witness-chain-I3K3WQID.js +2 -0
- package/dist/cli/chunks/{witness-chain-GTITDIA2.js → witness-chain-LTV7H2HM.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-AHRM2M52.js → witness-key-manager-PAJ2J4AL.js} +2 -2
- package/dist/cli/chunks/{workflow-XCGHEL3I.js → workflow-DL3ESR2H.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-MAALP4WA.js +2 -0
- package/dist/cli/chunks/{wrappers-VGO2GO4J.js → wrappers-5HSU665E.js} +2 -2
- package/dist/cli/commands/llm-router.js +1 -0
- package/dist/cli/handlers/init-handler.js +1 -1
- package/dist/coordination/handlers/coverage-collection.d.ts +161 -0
- package/dist/coordination/handlers/coverage-collection.js +639 -0
- package/dist/coordination/handlers/coverage-handlers.js +199 -146
- package/dist/coordination/handlers/handler-types.d.ts +6 -1
- package/dist/coordination/handlers/handler-utils.js +10 -3
- package/dist/coordination/handlers/security-handlers.js +17 -2
- package/dist/coordination/handlers/test-execution-handlers.js +16 -1
- package/dist/coordination/result-saver.js +119 -97
- package/dist/coordination/task-executor.d.ts +26 -1
- package/dist/coordination/task-executor.js +52 -4
- package/dist/domains/code-intelligence/services/knowledge-graph.js +8 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +4 -0
- package/dist/domains/coverage-analysis/services/gap-detector.js +4 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js +4 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +4 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.js +4 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.js +4 -0
- package/dist/domains/security-compliance/services/scanners/sast-scanner.js +4 -0
- package/dist/domains/test-generation/index.js +17 -2
- package/dist/domains/test-generation/services/test-generator.js +31 -9
- package/dist/init/codex-installer.d.ts +13 -0
- package/dist/init/codex-installer.js +122 -1
- package/dist/init/phases/09-assets.js +4 -0
- package/dist/init/phases/phase-interface.d.ts +1 -1
- package/dist/init/skills-installer.js +1 -0
- package/dist/integrations/embeddings/base/EmbeddingGenerator.js +13 -1
- package/dist/kernel/unified-memory.js +4 -0
- package/dist/learning/qe-flywheel/corpus-scorer.js +10 -7
- package/dist/learning/qe-flywheel/generation.d.ts +7 -0
- package/dist/learning/qe-flywheel/generation.js +5 -0
- package/dist/learning/qe-flywheel/witness-verify.d.ts +86 -0
- package/dist/learning/qe-flywheel/witness-verify.js +156 -0
- package/dist/learning/real-embeddings.js +15 -1
- package/dist/mcp/bundle.js +455 -434
- package/dist/mcp/handlers/domain-handler-configs.js +79 -14
- package/dist/mcp/types.d.ts +42 -4
- package/dist/optimization/session-cache.d.ts +13 -1
- package/dist/optimization/session-cache.js +27 -2
- package/dist/shared/db-recovery.d.ts +55 -0
- package/dist/shared/db-recovery.js +184 -0
- package/dist/shared/llm/billing-modes.js +5 -2
- package/dist/shared/llm/cost-tracker.js +1 -0
- package/dist/shared/llm/interfaces.d.ts +14 -1
- package/dist/shared/llm/llm-router-service.js +59 -4
- package/dist/shared/llm/provider-manager.d.ts +1 -1
- package/dist/shared/llm/provider-manager.js +7 -3
- package/dist/shared/llm/providers/claude-code.js +12 -3
- package/dist/shared/llm/providers/codex.d.ts +58 -0
- package/dist/shared/llm/providers/codex.js +305 -0
- package/dist/shared/llm/providers/index.d.ts +1 -0
- package/dist/shared/llm/providers/index.js +1 -0
- package/dist/shared/llm/router/agent-router-config.d.ts +46 -2
- package/dist/shared/llm/router/agent-router-config.js +124 -2
- package/dist/shared/llm/router/config-store.d.ts +17 -1
- package/dist/shared/llm/router/config-store.js +108 -0
- package/dist/shared/llm/router/hybrid-router.js +2 -2
- package/dist/shared/llm/router/index.d.ts +2 -2
- package/dist/shared/llm/router/index.js +2 -0
- package/dist/shared/llm/router/types.d.ts +44 -0
- package/dist/shared/llm/router/types.js +1 -0
- package/dist/shared/llm/spend-ledger.d.ts +24 -0
- package/dist/shared/llm/spend-ledger.js +86 -15
- package/dist/shared/llm/translation/message-formatter.js +1 -0
- package/dist/shared/safe-db.d.ts +10 -0
- package/dist/shared/safe-db.js +17 -0
- package/dist/skills/qe-court/referee.d.ts +62 -0
- package/dist/skills/qe-court/referee.js +78 -0
- package/dist/validation/gate-reexecute.d.ts +9 -0
- package/dist/validation/gate-reexecute.js +61 -0
- package/dist/validation/paired-bootstrap.d.ts +36 -0
- package/dist/validation/paired-bootstrap.js +58 -0
- package/package.json +9 -2
- package/dist/cli/chunks/adapter-D657MKZY.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-AFR6OZJK.js +0 -2
- package/dist/cli/chunks/base-K5QRGZWE.js +0 -2
- package/dist/cli/chunks/browser-workflow-ZMMKCGYW.js +0 -2
- package/dist/cli/chunks/chunk-6HQDPDN5.js +0 -2
- package/dist/cli/chunks/chunk-6SQ72FG7.js +0 -2
- package/dist/cli/chunks/chunk-7XUM4LBC.js +0 -2
- package/dist/cli/chunks/chunk-FHHCH7WL.js +0 -2
- package/dist/cli/chunks/chunk-G5OGKVLO.js +0 -2
- package/dist/cli/chunks/chunk-ILRKO6A5.js +0 -43
- package/dist/cli/chunks/chunk-NX522PRH.js +0 -153
- package/dist/cli/chunks/chunk-PPUDKQ4X.js +0 -29
- package/dist/cli/chunks/chunk-RSZOCQOL.js +0 -2
- package/dist/cli/chunks/chunk-ULQCEM7K.js +0 -2
- package/dist/cli/chunks/chunk-XQ5JT7KM.js +0 -3
- package/dist/cli/chunks/client-WI7RRUZO.js +0 -2
- package/dist/cli/chunks/codex-installer-E5BVXZVA.js +0 -8
- package/dist/cli/chunks/core-handlers-T6URR57V.js +0 -2
- package/dist/cli/chunks/cross-domain-router-WHTTKHWM.js +0 -2
- package/dist/cli/chunks/dream-QUL6SURC.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-VZNKE33K.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-LGWLDZLC.js +0 -2
- package/dist/cli/chunks/hnsw-index-66FOOI7U.js +0 -2
- package/dist/cli/chunks/hybrid-router-I5MEVQDF.js +0 -2
- package/dist/cli/chunks/impact-analyzer-K6ANYIY3.js +0 -2
- package/dist/cli/chunks/init-wizard-URHGXJ32.js +0 -2
- package/dist/cli/chunks/kernel-OKI5ZY5P.js +0 -2
- package/dist/cli/chunks/knowledge-graph-VQQSK7T5.js +0 -2
- package/dist/cli/chunks/llm-router-service-TISH33SY.js +0 -2
- package/dist/cli/chunks/load-test-KWKWC4Q7.js +0 -2
- package/dist/cli/chunks/memory-backend-JSQQMXVS.js +0 -2
- package/dist/cli/chunks/pattern-null-store-SXBIUKE5.js +0 -2
- package/dist/cli/chunks/protocol-executor-D3Q5P3WY.js +0 -2
- package/dist/cli/chunks/provider-manager-2EIX7E5Q.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-ITOW2ZHC.js +0 -2
- package/dist/cli/chunks/queen-coordinator-TO5X2EXL.js +0 -2
- package/dist/cli/chunks/router-GZJQEJU3.js +0 -2
- package/dist/cli/chunks/routing-feedback-CRXSKFNS.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-WHADT5HX.js +0 -2
- package/dist/cli/chunks/safe-db-MIZ2OFWC.js +0 -2
- package/dist/cli/chunks/schedule-XFILYTYC.js +0 -2
- package/dist/cli/chunks/scheduler-EIPJ777A.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-PFU3GSRD.js +0 -2
- package/dist/cli/chunks/sync-3SDMVAIU.js +0 -2
- package/dist/cli/chunks/transformers-QFOBOP2Y.js +0 -2
- package/dist/cli/chunks/unified-memory-OUVCMFGK.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-YGQPOHXB.js +0 -2
- package/dist/cli/chunks/unified-persistence-GFRZVDOW.js +0 -2
- package/dist/cli/chunks/visual-security-LVOOYQ64.js +0 -2
- package/dist/cli/chunks/witness-chain-QNFPV4UL.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-MIVBCALG.js +0 -2
|
@@ -22,6 +22,47 @@
|
|
|
22
22
|
import { ProviderManager } from './provider-manager.js';
|
|
23
23
|
import { HybridRouter } from './router/hybrid-router.js';
|
|
24
24
|
import { loadRouterConfig, shouldEnableRouter, detectAvailableProvidersFromEnv, } from './router/config-store.js';
|
|
25
|
+
import { setAgentProviderOverrides, createOverrideRoutingRules, } from './router/agent-router-config.js';
|
|
26
|
+
import { DEFAULT_QE_ROUTING_RULES } from './router/routing-rules.js';
|
|
27
|
+
import { createLogger } from '../../logging/logger-factory.js';
|
|
28
|
+
const routerServiceLogger = createLogger('llm/router-service');
|
|
29
|
+
/**
|
|
30
|
+
* Issue #568: make `.agentic-qe/llm-config.json`'s `agentOverrides` map actually
|
|
31
|
+
* take effect.
|
|
32
|
+
*
|
|
33
|
+
* Two steps, and both are needed:
|
|
34
|
+
* 1. install the map so `getPreferredModelForAgent()` consults it, and
|
|
35
|
+
* 2. materialize a routing rule per overridden agent and put it *ahead* of the
|
|
36
|
+
* rules the router would otherwise evaluate.
|
|
37
|
+
*
|
|
38
|
+
* Step 2 is the part that was missing before: `HybridRouter` only ever evaluates
|
|
39
|
+
* `config.rules` (falling back to `DEFAULT_QE_ROUTING_RULES`), and the generated
|
|
40
|
+
* per-agent ruleset was never installed into either — which is why the whole
|
|
41
|
+
* `agent-router-config` mechanism was unreachable from outside a single call
|
|
42
|
+
* stack.
|
|
43
|
+
*
|
|
44
|
+
* No overrides on disk => returns the config untouched.
|
|
45
|
+
*/
|
|
46
|
+
function applyAgentOverrides(config) {
|
|
47
|
+
// Pass each provider's own default model so a `{ "provider": "ollama" }`
|
|
48
|
+
// override resolves to a model ollama can serve, not the Claude model id the
|
|
49
|
+
// agent's category default happened to carry.
|
|
50
|
+
const providerDefaultModels = {};
|
|
51
|
+
for (const [provider, cfg] of Object.entries(config.providers ?? {})) {
|
|
52
|
+
if (cfg?.defaultModel) {
|
|
53
|
+
providerDefaultModels[provider] = cfg.defaultModel;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
setAgentProviderOverrides(config.agentOverrides, providerDefaultModels);
|
|
57
|
+
const overrideRules = createOverrideRoutingRules();
|
|
58
|
+
if (overrideRules.length === 0) {
|
|
59
|
+
return config;
|
|
60
|
+
}
|
|
61
|
+
// Mirror HybridRouter's own fallback so materializing overrides never has the
|
|
62
|
+
// side effect of dropping the default QE rules.
|
|
63
|
+
const baseRules = config.rules.length > 0 ? config.rules : DEFAULT_QE_ROUTING_RULES;
|
|
64
|
+
return { ...config, rules: [...overrideRules, ...baseRules] };
|
|
65
|
+
}
|
|
25
66
|
/**
|
|
26
67
|
* Order in which we pick fallbacks when the user hasn't specified any.
|
|
27
68
|
* Local-first (free), then cheapest cloud, then richer providers. This
|
|
@@ -46,11 +87,11 @@ const FALLBACK_PRIORITY = [
|
|
|
46
87
|
export async function createLLMRouterService(options = {}) {
|
|
47
88
|
// Honor the test-injected ProviderManager path first.
|
|
48
89
|
if (options.providerManager) {
|
|
49
|
-
const config = loadRouterConfig({
|
|
90
|
+
const config = applyAgentOverrides(loadRouterConfig({
|
|
50
91
|
projectRoot: options.projectRoot,
|
|
51
92
|
override: options.override,
|
|
52
93
|
env: options.env,
|
|
53
|
-
});
|
|
94
|
+
}));
|
|
54
95
|
const router = new HybridRouter(options.providerManager, config);
|
|
55
96
|
await router.initialize();
|
|
56
97
|
return {
|
|
@@ -63,15 +104,29 @@ export async function createLLMRouterService(options = {}) {
|
|
|
63
104
|
if (!shouldEnableRouter({ projectRoot: options.projectRoot, env: options.env })) {
|
|
64
105
|
return null;
|
|
65
106
|
}
|
|
66
|
-
const config = loadRouterConfig({
|
|
107
|
+
const config = applyAgentOverrides(loadRouterConfig({
|
|
67
108
|
projectRoot: options.projectRoot,
|
|
68
109
|
override: options.override,
|
|
69
110
|
env: options.env,
|
|
70
|
-
});
|
|
111
|
+
}));
|
|
71
112
|
const enabled = pickEnabledProviders(config, options.env ?? process.env);
|
|
72
113
|
if (enabled.length === 0) {
|
|
73
114
|
return null;
|
|
74
115
|
}
|
|
116
|
+
// Issue #568: an override naming a provider that isn't enabled would silently
|
|
117
|
+
// fall through to the default chain — the exact "configured it and nothing
|
|
118
|
+
// happened" failure this feature exists to avoid. Say so out loud. We do NOT
|
|
119
|
+
// auto-enable it: that would opt the user into a provider (and possibly paid
|
|
120
|
+
// billing) they never turned on.
|
|
121
|
+
const enabledSet = new Set(enabled);
|
|
122
|
+
for (const [agentType, override] of Object.entries(config.agentOverrides ?? {})) {
|
|
123
|
+
if (override.provider && !enabledSet.has(override.provider)) {
|
|
124
|
+
routerServiceLogger.warn(`[llm-config] agentOverrides["${agentType}"] routes to provider ` +
|
|
125
|
+
`"${override.provider}", which is not enabled (no API key detected and not ` +
|
|
126
|
+
`enabled in .agentic-qe/llm-config.json). This override will not take effect ` +
|
|
127
|
+
`until that provider is available.`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
75
130
|
const { primary, fallbacks } = pickPrimaryAndFallbacks(config, enabled);
|
|
76
131
|
const providerManagerConfig = {
|
|
77
132
|
primary: primary,
|
|
@@ -70,7 +70,7 @@ export declare class ProviderManager {
|
|
|
70
70
|
*/
|
|
71
71
|
assertWithinBudget(input: string | Message[], options?: GenerateOptions | CompleteOptions): void;
|
|
72
72
|
/** ADR-123: public spend recorder for those same bypassing callers. */
|
|
73
|
-
recordResponseSpend(response: LLMResponse): void;
|
|
73
|
+
recordResponseSpend(response: LLMResponse, agent?: string): void;
|
|
74
74
|
/**
|
|
75
75
|
* Generate text using the best available provider
|
|
76
76
|
*/
|
|
@@ -18,6 +18,7 @@ import { createDefaultSpendLedger, InMemorySpendLedger, } from './spend-ledger';
|
|
|
18
18
|
import { resolveBillingMode, billingNotice } from './billing-modes';
|
|
19
19
|
import { ClaudeProvider } from './providers/claude';
|
|
20
20
|
import { ClaudeCodeProvider } from './providers/claude-code';
|
|
21
|
+
import { CodexProvider } from './providers/codex';
|
|
21
22
|
import { CognitumProvider } from './providers/cognitum';
|
|
22
23
|
import { OpenAIProvider } from './providers/openai';
|
|
23
24
|
import { OllamaProvider } from './providers/ollama';
|
|
@@ -169,7 +170,7 @@ export class ProviderManager {
|
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
172
|
/** ADR-123: persist a completed charge to the cross-process ledger. */
|
|
172
|
-
recordSpend(response) {
|
|
173
|
+
recordSpend(response, agent) {
|
|
173
174
|
if (!this.spendLedger)
|
|
174
175
|
return;
|
|
175
176
|
this.spendLedger.record({
|
|
@@ -180,6 +181,7 @@ export class ProviderManager {
|
|
|
180
181
|
promptTokens: response.usage.promptTokens,
|
|
181
182
|
completionTokens: response.usage.completionTokens,
|
|
182
183
|
requestId: response.requestId,
|
|
184
|
+
agent, // ADR-124 M2.3: per-agent attribution when the caller has context.
|
|
183
185
|
});
|
|
184
186
|
}
|
|
185
187
|
/**
|
|
@@ -192,8 +194,8 @@ export class ProviderManager {
|
|
|
192
194
|
this.enforceBudget(input, options);
|
|
193
195
|
}
|
|
194
196
|
/** ADR-123: public spend recorder for those same bypassing callers. */
|
|
195
|
-
recordResponseSpend(response) {
|
|
196
|
-
this.recordSpend(response);
|
|
197
|
+
recordResponseSpend(response, agent) {
|
|
198
|
+
this.recordSpend(response, agent);
|
|
197
199
|
}
|
|
198
200
|
/**
|
|
199
201
|
* Generate text using the best available provider
|
|
@@ -417,6 +419,8 @@ export class ProviderManager {
|
|
|
417
419
|
return new ClaudeProvider(this.config.providers.claude);
|
|
418
420
|
case 'claude-code':
|
|
419
421
|
return new ClaudeCodeProvider(this.config.providers['claude-code']);
|
|
422
|
+
case 'codex':
|
|
423
|
+
return new CodexProvider(this.config.providers.codex);
|
|
420
424
|
case 'cognitum':
|
|
421
425
|
return new CognitumProvider(this.config.providers.cognitum);
|
|
422
426
|
case 'openai':
|
|
@@ -285,10 +285,19 @@ export class ClaudeCodeProvider {
|
|
|
285
285
|
clearTimeout(timer);
|
|
286
286
|
resolve({ code: code ?? 0, stdout, stderr });
|
|
287
287
|
});
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
// EPIPE guard (qe-court finding): if `claude` exits before reading stdin,
|
|
289
|
+
// an unhandled 'error' on the stdin stream crashes the calling process. The
|
|
290
|
+
// 'close'/'error' handlers above already capture the real outcome.
|
|
291
|
+
child.stdin.on('error', () => { });
|
|
292
|
+
try {
|
|
293
|
+
if (stdin !== undefined) {
|
|
294
|
+
child.stdin.write(stdin);
|
|
295
|
+
}
|
|
296
|
+
child.stdin.end();
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
/* stream already torn down — process handlers report the failure */
|
|
290
300
|
}
|
|
291
|
-
child.stdin.end();
|
|
292
301
|
});
|
|
293
302
|
}
|
|
294
303
|
/** Simple semaphore so we don't spawn unbounded `claude` subprocesses. */
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 — Codex CLI (subscription) Provider (ADR-123 / ADR-124 M3.5)
|
|
3
|
+
*
|
|
4
|
+
* Runs QE analysis on the user's ChatGPT subscription by shelling out to the
|
|
5
|
+
* Codex CLI (`codex exec`) instead of calling the OpenAI API with a paid key.
|
|
6
|
+
* The CLI authenticates with the user's existing ChatGPT login (~/.codex/auth.json)
|
|
7
|
+
* and draws from the subscription allowance, so the worst case is "hit the plan
|
|
8
|
+
* limit and pause" rather than a per-token bill. Mirrors the claude-code provider.
|
|
9
|
+
*
|
|
10
|
+
* WHY: gives AQE a cross-vendor (GPT-family) engine — used as a provider fallback
|
|
11
|
+
* and, crucially, as an independent prosecutor/juror in qe-court (ADR-124), where
|
|
12
|
+
* a non-Claude, non-Cognitum brain is the strongest form of writer≠juror.
|
|
13
|
+
*
|
|
14
|
+
* LOAD-BEARING: the child process env has OPENAI_API_KEY / CODEX_API_KEY stripped.
|
|
15
|
+
* If present, the CLI could revert to API-key billing and this provider would be
|
|
16
|
+
* a lie. `parity` test coverage asserts the strip.
|
|
17
|
+
*/
|
|
18
|
+
import { LLMProvider, LLMProviderType, BillingMode, CodexConfig, Message, GenerateOptions, EmbedOptions, CompleteOptions, LLMResponse, EmbeddingResponse, CompletionResponse, HealthCheckResult } from '../interfaces';
|
|
19
|
+
export type { CodexConfig };
|
|
20
|
+
/** Env vars whose presence could flip the CLI from subscription to API billing. */
|
|
21
|
+
export declare const API_BILLING_ENV_VARS: readonly ["OPENAI_API_KEY", "CODEX_API_KEY"];
|
|
22
|
+
/** Sentinel meaning "let Codex use its own configured default model". */
|
|
23
|
+
export declare const CODEX_DEFAULT_MODEL = "default";
|
|
24
|
+
export declare const DEFAULT_CODEX_CONFIG: CodexConfig;
|
|
25
|
+
export declare class CodexProvider implements LLMProvider {
|
|
26
|
+
readonly type: LLMProviderType;
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly billingMode: BillingMode;
|
|
29
|
+
private config;
|
|
30
|
+
private requestId;
|
|
31
|
+
private availabilityCache?;
|
|
32
|
+
private active;
|
|
33
|
+
private readonly queue;
|
|
34
|
+
constructor(config?: Partial<CodexConfig>);
|
|
35
|
+
isAvailable(): Promise<boolean>;
|
|
36
|
+
healthCheck(): Promise<HealthCheckResult>;
|
|
37
|
+
generate(input: string | Message[], options?: GenerateOptions): Promise<LLMResponse>;
|
|
38
|
+
embed(_text: string, _options?: EmbedOptions): Promise<EmbeddingResponse>;
|
|
39
|
+
complete(prompt: string, options?: CompleteOptions): Promise<CompletionResponse>;
|
|
40
|
+
getConfig(): CodexConfig;
|
|
41
|
+
getSupportedModels(): string[];
|
|
42
|
+
getCostPerToken(): {
|
|
43
|
+
input: number;
|
|
44
|
+
output: number;
|
|
45
|
+
};
|
|
46
|
+
dispose(): Promise<void>;
|
|
47
|
+
private flatten;
|
|
48
|
+
private classifyError;
|
|
49
|
+
/**
|
|
50
|
+
* Build the child env with API-billing keys stripped (LOAD-BEARING).
|
|
51
|
+
* Exported logic tested by parity/env-strip tests.
|
|
52
|
+
*/
|
|
53
|
+
static childEnv(base?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
54
|
+
private runProcess;
|
|
55
|
+
/** Simple semaphore so we don't spawn unbounded `codex` subprocesses. */
|
|
56
|
+
private withConcurrency;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 — Codex CLI (subscription) Provider (ADR-123 / ADR-124 M3.5)
|
|
3
|
+
*
|
|
4
|
+
* Runs QE analysis on the user's ChatGPT subscription by shelling out to the
|
|
5
|
+
* Codex CLI (`codex exec`) instead of calling the OpenAI API with a paid key.
|
|
6
|
+
* The CLI authenticates with the user's existing ChatGPT login (~/.codex/auth.json)
|
|
7
|
+
* and draws from the subscription allowance, so the worst case is "hit the plan
|
|
8
|
+
* limit and pause" rather than a per-token bill. Mirrors the claude-code provider.
|
|
9
|
+
*
|
|
10
|
+
* WHY: gives AQE a cross-vendor (GPT-family) engine — used as a provider fallback
|
|
11
|
+
* and, crucially, as an independent prosecutor/juror in qe-court (ADR-124), where
|
|
12
|
+
* a non-Claude, non-Cognitum brain is the strongest form of writer≠juror.
|
|
13
|
+
*
|
|
14
|
+
* LOAD-BEARING: the child process env has OPENAI_API_KEY / CODEX_API_KEY stripped.
|
|
15
|
+
* If present, the CLI could revert to API-key billing and this provider would be
|
|
16
|
+
* a lie. `parity` test coverage asserts the strip.
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from 'node:child_process';
|
|
19
|
+
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
20
|
+
import { tmpdir } from 'node:os';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { createLLMError, } from '../interfaces';
|
|
23
|
+
import { TokenMetricsCollector } from '../../../learning/token-tracker.js';
|
|
24
|
+
/** Env vars whose presence could flip the CLI from subscription to API billing. */
|
|
25
|
+
export const API_BILLING_ENV_VARS = ['OPENAI_API_KEY', 'CODEX_API_KEY'];
|
|
26
|
+
/** Sentinel meaning "let Codex use its own configured default model". */
|
|
27
|
+
export const CODEX_DEFAULT_MODEL = 'default';
|
|
28
|
+
export const DEFAULT_CODEX_CONFIG = {
|
|
29
|
+
model: CODEX_DEFAULT_MODEL,
|
|
30
|
+
maxTokens: 4096,
|
|
31
|
+
temperature: 0.7,
|
|
32
|
+
timeoutMs: 180000,
|
|
33
|
+
maxRetries: 1,
|
|
34
|
+
binaryPath: 'codex',
|
|
35
|
+
maxConcurrency: 2,
|
|
36
|
+
};
|
|
37
|
+
export class CodexProvider {
|
|
38
|
+
type = 'codex';
|
|
39
|
+
name = 'Codex CLI (subscription)';
|
|
40
|
+
billingMode = 'subscription';
|
|
41
|
+
config;
|
|
42
|
+
requestId = 0;
|
|
43
|
+
availabilityCache;
|
|
44
|
+
active = 0;
|
|
45
|
+
queue = [];
|
|
46
|
+
constructor(config = {}) {
|
|
47
|
+
this.config = { ...DEFAULT_CODEX_CONFIG, ...config };
|
|
48
|
+
const envConc = Number.parseInt(process.env.AQE_CODEX_CONCURRENCY ?? '', 10);
|
|
49
|
+
if (Number.isFinite(envConc) && envConc > 0) {
|
|
50
|
+
this.config.maxConcurrency = envConc;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async isAvailable() {
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
if (this.availabilityCache && now - this.availabilityCache.at < 60_000) {
|
|
56
|
+
return this.availabilityCache.available;
|
|
57
|
+
}
|
|
58
|
+
let available = false;
|
|
59
|
+
try {
|
|
60
|
+
const { code } = await this.runProcess(['--version'], undefined, undefined, 5000);
|
|
61
|
+
available = code === 0;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
available = false;
|
|
65
|
+
}
|
|
66
|
+
this.availabilityCache = { at: now, available };
|
|
67
|
+
return available;
|
|
68
|
+
}
|
|
69
|
+
async healthCheck() {
|
|
70
|
+
const start = Date.now();
|
|
71
|
+
const available = await this.isAvailable();
|
|
72
|
+
const latencyMs = Date.now() - start;
|
|
73
|
+
if (!available) {
|
|
74
|
+
return {
|
|
75
|
+
healthy: false,
|
|
76
|
+
latencyMs,
|
|
77
|
+
error: `Codex CLI ("${this.config.binaryPath}") not found or not runnable. ` +
|
|
78
|
+
`Install Codex and log in with your ChatGPT account (\`codex login\`).`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
healthy: true,
|
|
83
|
+
latencyMs,
|
|
84
|
+
models: this.getSupportedModels(),
|
|
85
|
+
details: { binaryPath: this.config.binaryPath, billing: 'subscription' },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async generate(input, options) {
|
|
89
|
+
const model = options?.model ?? this.config.model ?? CODEX_DEFAULT_MODEL;
|
|
90
|
+
const requestId = `codex-${++this.requestId}-${Date.now()}`;
|
|
91
|
+
const { prompt } = this.flatten(input, options?.systemPrompt);
|
|
92
|
+
// `codex exec` is agentic; keep it read-only and non-interactive. We capture
|
|
93
|
+
// just the final assistant message via -o <file> to avoid parsing the noisy
|
|
94
|
+
// JSONL event stream.
|
|
95
|
+
const tmp = mkdtempSync(join(tmpdir(), 'aqe-codex-'));
|
|
96
|
+
const outFile = join(tmp, 'last-message.txt');
|
|
97
|
+
const args = [
|
|
98
|
+
'exec',
|
|
99
|
+
'--skip-git-repo-check',
|
|
100
|
+
'--sandbox', 'read-only',
|
|
101
|
+
'-o', outFile,
|
|
102
|
+
];
|
|
103
|
+
if (model && model !== CODEX_DEFAULT_MODEL) {
|
|
104
|
+
args.push('-m', model);
|
|
105
|
+
}
|
|
106
|
+
const start = Date.now();
|
|
107
|
+
const timeoutMs = options?.timeoutMs ?? this.config.timeoutMs ?? 180000;
|
|
108
|
+
try {
|
|
109
|
+
const { code, stderr } = await this.withConcurrency(() => this.runProcess(args, prompt, undefined, timeoutMs));
|
|
110
|
+
const latencyMs = Date.now() - start;
|
|
111
|
+
let content = '';
|
|
112
|
+
try {
|
|
113
|
+
content = readFileSync(outFile, 'utf8').trim();
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
content = '';
|
|
117
|
+
}
|
|
118
|
+
if (code !== 0 && !content) {
|
|
119
|
+
throw this.classifyError(stderr || `codex exited with code ${code}`, model);
|
|
120
|
+
}
|
|
121
|
+
// Subscription: no per-token receipt. Estimate usage from text length for
|
|
122
|
+
// visibility only (≈4 chars/token); marginal monetary cost is $0.
|
|
123
|
+
const promptTokens = Math.ceil(prompt.length / 4);
|
|
124
|
+
const completionTokens = Math.ceil(content.length / 4);
|
|
125
|
+
const usage = {
|
|
126
|
+
promptTokens,
|
|
127
|
+
completionTokens,
|
|
128
|
+
totalTokens: promptTokens + completionTokens,
|
|
129
|
+
cacheCreationTokens: 0,
|
|
130
|
+
cacheReadTokens: 0,
|
|
131
|
+
};
|
|
132
|
+
TokenMetricsCollector.recordTokenUsage(requestId, 'codex-provider', 'llm', 'generate', {
|
|
133
|
+
inputTokens: usage.promptTokens,
|
|
134
|
+
outputTokens: usage.completionTokens,
|
|
135
|
+
totalTokens: usage.totalTokens,
|
|
136
|
+
estimatedCostUsd: 0,
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
content,
|
|
140
|
+
model: model === CODEX_DEFAULT_MODEL ? 'codex-default' : model,
|
|
141
|
+
provider: 'codex',
|
|
142
|
+
usage,
|
|
143
|
+
// Subscription billing: marginal cost is $0 and we know it authoritatively.
|
|
144
|
+
cost: { inputCost: 0, outputCost: 0, totalCost: 0, currency: 'USD', source: 'provider-receipt' },
|
|
145
|
+
latencyMs,
|
|
146
|
+
finishReason: 'stop',
|
|
147
|
+
cached: false,
|
|
148
|
+
requestId,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async embed(_text, _options) {
|
|
156
|
+
throw createLLMError('Codex provider does not support embeddings. Use openai, ollama, or cognitum.', 'MODEL_NOT_FOUND', { provider: 'codex', retryable: false });
|
|
157
|
+
}
|
|
158
|
+
async complete(prompt, options) {
|
|
159
|
+
const response = await this.generate(prompt, {
|
|
160
|
+
model: options?.model,
|
|
161
|
+
temperature: options?.temperature ?? 0.2,
|
|
162
|
+
maxTokens: options?.maxTokens ?? 256,
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
completion: response.content,
|
|
166
|
+
model: response.model,
|
|
167
|
+
provider: 'codex',
|
|
168
|
+
usage: response.usage,
|
|
169
|
+
latencyMs: response.latencyMs,
|
|
170
|
+
cached: response.cached,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
getConfig() {
|
|
174
|
+
return { ...this.config };
|
|
175
|
+
}
|
|
176
|
+
getSupportedModels() {
|
|
177
|
+
// Codex resolves the concrete model from its profile/login; these are the
|
|
178
|
+
// common ids accepted via -m. `default` = whatever the CLI is configured to.
|
|
179
|
+
return [CODEX_DEFAULT_MODEL, 'gpt-5-codex', 'o3', 'o4-mini'];
|
|
180
|
+
}
|
|
181
|
+
getCostPerToken() {
|
|
182
|
+
return { input: 0, output: 0 };
|
|
183
|
+
}
|
|
184
|
+
async dispose() {
|
|
185
|
+
// No persistent resources.
|
|
186
|
+
}
|
|
187
|
+
// -- internals -------------------------------------------------------------
|
|
188
|
+
flatten(input, systemPromptOpt) {
|
|
189
|
+
if (typeof input === 'string') {
|
|
190
|
+
return { prompt: systemPromptOpt ? `${systemPromptOpt}\n\n${input}` : input };
|
|
191
|
+
}
|
|
192
|
+
const systemParts = input.filter((m) => m.role === 'system').map((m) => m.content);
|
|
193
|
+
if (systemPromptOpt)
|
|
194
|
+
systemParts.unshift(systemPromptOpt);
|
|
195
|
+
const convo = input
|
|
196
|
+
.filter((m) => m.role !== 'system')
|
|
197
|
+
.map((m) => `${m.role === 'assistant' ? 'Assistant' : 'User'}: ${m.content}`)
|
|
198
|
+
.join('\n\n');
|
|
199
|
+
const preamble = systemParts.length > 0 ? `${systemParts.join('\n\n')}\n\n` : '';
|
|
200
|
+
return { prompt: `${preamble}${convo}` };
|
|
201
|
+
}
|
|
202
|
+
classifyError(message, model) {
|
|
203
|
+
const lower = message.toLowerCase();
|
|
204
|
+
if (lower.includes('rate limit') ||
|
|
205
|
+
lower.includes('usage limit') ||
|
|
206
|
+
lower.includes('429') ||
|
|
207
|
+
lower.includes('quota')) {
|
|
208
|
+
return createLLMError(message, 'RATE_LIMITED', {
|
|
209
|
+
provider: 'codex',
|
|
210
|
+
model,
|
|
211
|
+
retryable: true,
|
|
212
|
+
retryAfterMs: 60_000,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return createLLMError(message, 'PROVIDER_UNAVAILABLE', {
|
|
216
|
+
provider: 'codex',
|
|
217
|
+
model,
|
|
218
|
+
retryable: true,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Build the child env with API-billing keys stripped (LOAD-BEARING).
|
|
223
|
+
* Exported logic tested by parity/env-strip tests.
|
|
224
|
+
*/
|
|
225
|
+
static childEnv(base = process.env) {
|
|
226
|
+
const env = { ...base };
|
|
227
|
+
for (const key of API_BILLING_ENV_VARS) {
|
|
228
|
+
delete env[key];
|
|
229
|
+
}
|
|
230
|
+
return env;
|
|
231
|
+
}
|
|
232
|
+
runProcess(args, stdin, _unused, timeoutMs) {
|
|
233
|
+
return new Promise((resolve, reject) => {
|
|
234
|
+
const child = spawn(this.config.binaryPath ?? 'codex', args, {
|
|
235
|
+
env: CodexProvider.childEnv(),
|
|
236
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
237
|
+
});
|
|
238
|
+
let stdout = '';
|
|
239
|
+
let stderr = '';
|
|
240
|
+
let settled = false;
|
|
241
|
+
const timer = setTimeout(() => {
|
|
242
|
+
if (settled)
|
|
243
|
+
return;
|
|
244
|
+
settled = true;
|
|
245
|
+
child.kill('SIGKILL');
|
|
246
|
+
reject(createLLMError('codex exec timed out', 'TIMEOUT', {
|
|
247
|
+
provider: 'codex',
|
|
248
|
+
retryable: true,
|
|
249
|
+
}));
|
|
250
|
+
}, timeoutMs);
|
|
251
|
+
child.stdout.on('data', (d) => (stdout += d.toString()));
|
|
252
|
+
child.stderr.on('data', (d) => (stderr += d.toString()));
|
|
253
|
+
child.on('error', (err) => {
|
|
254
|
+
if (settled)
|
|
255
|
+
return;
|
|
256
|
+
settled = true;
|
|
257
|
+
clearTimeout(timer);
|
|
258
|
+
reject(createLLMError(`Failed to spawn codex: ${err.message}`, 'PROVIDER_UNAVAILABLE', {
|
|
259
|
+
provider: 'codex',
|
|
260
|
+
retryable: false,
|
|
261
|
+
cause: err,
|
|
262
|
+
}));
|
|
263
|
+
});
|
|
264
|
+
child.on('close', (code) => {
|
|
265
|
+
if (settled)
|
|
266
|
+
return;
|
|
267
|
+
settled = true;
|
|
268
|
+
clearTimeout(timer);
|
|
269
|
+
resolve({ code: code ?? 0, stdout, stderr });
|
|
270
|
+
});
|
|
271
|
+
// EPIPE guard: if codex exits before reading stdin (e.g. not logged in),
|
|
272
|
+
// the write/end can emit 'error' on the stdin stream. Without a listener
|
|
273
|
+
// Node throws an uncaught exception that crashes the calling process. The
|
|
274
|
+
// 'close'/'error' handlers above already capture the real outcome.
|
|
275
|
+
child.stdin.on('error', () => { });
|
|
276
|
+
try {
|
|
277
|
+
if (stdin !== undefined) {
|
|
278
|
+
child.stdin.write(stdin);
|
|
279
|
+
}
|
|
280
|
+
child.stdin.end();
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
/* stream already torn down — the process handlers report the failure */
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/** Simple semaphore so we don't spawn unbounded `codex` subprocesses. */
|
|
288
|
+
async withConcurrency(fn) {
|
|
289
|
+
const limit = this.config.maxConcurrency ?? 2;
|
|
290
|
+
if (this.active >= limit) {
|
|
291
|
+
await new Promise((resolve) => this.queue.push(resolve));
|
|
292
|
+
}
|
|
293
|
+
this.active++;
|
|
294
|
+
try {
|
|
295
|
+
return await fn();
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
this.active--;
|
|
299
|
+
const next = this.queue.shift();
|
|
300
|
+
if (next)
|
|
301
|
+
next();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ClaudeProvider, DEFAULT_CLAUDE_CONFIG } from './claude';
|
|
6
6
|
export { ClaudeCodeProvider, DEFAULT_CLAUDE_CODE_CONFIG, API_BILLING_ENV_VARS, type ClaudeCodeConfig, } from './claude-code';
|
|
7
|
+
export { CodexProvider, DEFAULT_CODEX_CONFIG, CODEX_DEFAULT_MODEL, type CodexConfig, } from './codex';
|
|
7
8
|
export { CognitumProvider, DEFAULT_COGNITUM_CONFIG, type CognitumConfig, type CognitumBudget, } from './cognitum';
|
|
8
9
|
export { OpenAIProvider, DEFAULT_OPENAI_CONFIG } from './openai';
|
|
9
10
|
export { OllamaProvider, DEFAULT_OLLAMA_CONFIG } from './ollama';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ClaudeProvider, DEFAULT_CLAUDE_CONFIG } from './claude';
|
|
6
6
|
export { ClaudeCodeProvider, DEFAULT_CLAUDE_CODE_CONFIG, API_BILLING_ENV_VARS, } from './claude-code';
|
|
7
|
+
export { CodexProvider, DEFAULT_CODEX_CONFIG, CODEX_DEFAULT_MODEL, } from './codex';
|
|
7
8
|
export { CognitumProvider, DEFAULT_COGNITUM_CONFIG, } from './cognitum';
|
|
8
9
|
export { OpenAIProvider, DEFAULT_OPENAI_CONFIG } from './openai';
|
|
9
10
|
export { OllamaProvider, DEFAULT_OLLAMA_CONFIG } from './ollama';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Override mechanism for specific tasks
|
|
9
9
|
* - Agent category detection and preferred model resolution
|
|
10
10
|
*/
|
|
11
|
-
import { ExtendedProviderType, RoutingRule, TaskComplexity } from './types';
|
|
11
|
+
import { ExtendedProviderType, RoutingRule, TaskComplexity, AgentProviderOverride } from './types';
|
|
12
12
|
/**
|
|
13
13
|
* Agent categories for routing decisions
|
|
14
14
|
*/
|
|
@@ -120,7 +120,34 @@ export declare const DEFAULT_CATEGORY_CAPABILITIES: Record<AgentCategory, AgentC
|
|
|
120
120
|
*/
|
|
121
121
|
export declare function getAgentRoutingCategory(agentType: string): AgentCategory;
|
|
122
122
|
/**
|
|
123
|
-
*
|
|
123
|
+
* Install the on-disk per-agent overrides (issue #568). Called by the router
|
|
124
|
+
* service after `loadRouterConfig()` has validated them.
|
|
125
|
+
*
|
|
126
|
+
* Replaces the whole map rather than merging, so reloading a config that
|
|
127
|
+
* removed an entry actually removes it.
|
|
128
|
+
*
|
|
129
|
+
* @param overrides validated `agentOverrides` map
|
|
130
|
+
* @param defaultModels per-provider default model ids, so a provider-only
|
|
131
|
+
* override resolves to a model that provider can actually serve
|
|
132
|
+
*/
|
|
133
|
+
export declare function setAgentProviderOverrides(overrides: Record<string, AgentProviderOverride> | undefined, defaultModels?: Partial<Record<ExtendedProviderType, string>>): void;
|
|
134
|
+
/** Current on-disk per-agent overrides. Primarily for diagnostics and tests. */
|
|
135
|
+
export declare function getAgentProviderOverrides(): Readonly<Record<string, AgentProviderOverride>>;
|
|
136
|
+
/** Clear installed overrides. For tests. */
|
|
137
|
+
export declare function resetAgentProviderOverrides(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Get the preferred model for an agent type.
|
|
140
|
+
*
|
|
141
|
+
* Resolution order (issue #568):
|
|
142
|
+
* 1. `agentOverrides[agentType]` from `.agentic-qe/llm-config.json` — the
|
|
143
|
+
* user's explicit, hand-written intent, so it wins.
|
|
144
|
+
* 2. the agent's category default (`AGENT_CATEGORY_MAP` ->
|
|
145
|
+
* `DEFAULT_CATEGORY_MODELS`).
|
|
146
|
+
*
|
|
147
|
+
* An override is a *partial*: fields it does not set keep their category
|
|
148
|
+
* default, so `{ "provider": "ollama" }` re-provisions the provider without
|
|
149
|
+
* forcing the user to also restate temperature, token budget, and priority.
|
|
150
|
+
*
|
|
124
151
|
* @param agentType - The agent type identifier
|
|
125
152
|
* @returns The model preference configuration
|
|
126
153
|
*/
|
|
@@ -161,6 +188,23 @@ export declare function isLatencySensitive(agentType: string): boolean;
|
|
|
161
188
|
* @returns A routing rule for this agent type
|
|
162
189
|
*/
|
|
163
190
|
export declare function createAgentRoutingRule(agentType: string): RoutingRule;
|
|
191
|
+
/**
|
|
192
|
+
* Build routing rules for exactly the agent types the user overrode on disk
|
|
193
|
+
* (issue #568).
|
|
194
|
+
*
|
|
195
|
+
* Why a separate builder rather than `createAgentRoutingRule`: that one also
|
|
196
|
+
* constrains on `requiresReasoning`, which is right for the generated
|
|
197
|
+
* whole-roster ruleset but wrong here — a user who wrote
|
|
198
|
+
* `"qe-mutation-tester": { "provider": "ollama" }` means *always*, not "only when
|
|
199
|
+
* the request happens to be flagged as needing reasoning". These rules match on
|
|
200
|
+
* agent type alone.
|
|
201
|
+
*
|
|
202
|
+
* Returns `[]` when nothing is overridden, so a project without the key gets the
|
|
203
|
+
* exact rule set it got before.
|
|
204
|
+
*
|
|
205
|
+
* @returns Routing rules, highest priority first
|
|
206
|
+
*/
|
|
207
|
+
export declare function createOverrideRoutingRules(): RoutingRule[];
|
|
164
208
|
/**
|
|
165
209
|
* Create routing rules for all agents in a category
|
|
166
210
|
* @param category - The agent category
|