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.
Files changed (442) hide show
  1. package/.agents/skills/aqe-plan-quality/SKILL.md +25 -0
  2. package/.agents/skills/aqe-plan-quality/agents/openai.yaml +4 -0
  3. package/.agents/skills/aqe-plan-quality/references/qe-routing.md +22 -0
  4. package/.agents/skills/aqe-review-quality/SKILL.md +24 -0
  5. package/.agents/skills/aqe-review-quality/agents/openai.yaml +4 -0
  6. package/.agents/skills/aqe-review-quality/references/quality-gates.md +20 -0
  7. package/.agents/skills/aqe-test-change/SKILL.md +26 -0
  8. package/.agents/skills/aqe-test-change/agents/openai.yaml +4 -0
  9. package/.agents/skills/aqe-test-change/references/test-specialties.md +23 -0
  10. package/.claude/helpers/.helpers-version +1 -1
  11. package/.claude/helpers/auto-memory-hook.mjs +430 -430
  12. package/.claude/helpers/helpers.manifest.json +6 -5
  13. package/.claude/helpers/hook-handler.cjs +565 -311
  14. package/.claude/helpers/intelligence.cjs +1058 -1058
  15. package/.claude/helpers/ruflo-hook.cjs +5 -1
  16. package/.claude/helpers/statusline.cjs +995 -682
  17. package/.claude/skills/qe-court/SKILL.md +186 -0
  18. package/.claude/skills/qe-court/config.json +27 -0
  19. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
  20. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
  21. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
  22. package/.claude/skills/qe-court/evals/qe-court.yaml +70 -0
  23. package/.claude/skills/qe-court/schemas/output.json +92 -0
  24. package/.claude/skills/qe-court/scripts/validate-config.json +30 -0
  25. package/.claude/skills/skills-manifest.json +9 -8
  26. package/.codex/hooks/aqe-codex-hook.cjs +69 -0
  27. package/.codex/hooks/ruflo-codex-hook.cjs +94 -0
  28. package/.codex/hooks.json +169 -0
  29. package/CHANGELOG.md +159 -0
  30. package/README.md +3 -3
  31. package/assets/skills/qe-court/SKILL.md +186 -0
  32. package/assets/skills/qe-court/config.json +27 -0
  33. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
  34. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
  35. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
  36. package/assets/skills/qe-court/evals/qe-court.yaml +70 -0
  37. package/assets/skills/qe-court/schemas/output.json +92 -0
  38. package/assets/skills/qe-court/scripts/validate-config.json +30 -0
  39. package/assets/skills/skills-manifest.json +9 -8
  40. package/dist/cli/bundle.js +5 -5
  41. package/dist/cli/chunks/adapter-VRZNL53W.js +2 -0
  42. package/dist/cli/chunks/{agent-booster-wasm-XFAQATTH.js → agent-booster-wasm-4VM3DE42.js} +2 -2
  43. package/dist/cli/chunks/{agent-handler-2ZV4CA3U.js → agent-handler-ZDLMZQQX.js} +2 -2
  44. package/dist/cli/chunks/{agent-memory-branch-6WGP7F5T.js → agent-memory-branch-P72MDHHV.js} +2 -2
  45. package/dist/cli/chunks/aqe-learning-engine-XCNMNERX.js +2 -0
  46. package/dist/cli/chunks/{arena-FWX7XZAE.js → arena-55FZGKEV.js} +4 -4
  47. package/dist/cli/chunks/{arena-KJUNQK4N.js → arena-GCRBQ26R.js} +2 -2
  48. package/dist/cli/chunks/{audit-YFUDEOKN.js → audit-VYAYVLIV.js} +3 -3
  49. package/dist/cli/chunks/base-VZZNR4UR.js +2 -0
  50. package/dist/cli/chunks/{hnswlib-node-SKTT5KIH.js → better-sqlite3-JDDFYVCX.js} +2 -2
  51. package/dist/cli/chunks/{brain-handler-ZCK4WTPK.js → brain-handler-IUKMRGWO.js} +3 -3
  52. package/dist/cli/chunks/{branch-enumerator-HTVINRYG.js → branch-enumerator-TUI3RWLX.js} +2 -2
  53. package/dist/cli/chunks/{browser-WUL2B77M.js → browser-NBQTZYX2.js} +2 -2
  54. package/dist/cli/chunks/browser-workflow-5DZNIFUY.js +2 -0
  55. package/dist/cli/chunks/{chunk-IWQHQLT6.js → chunk-23MT7OBY.js} +2 -2
  56. package/dist/cli/chunks/{chunk-KE3RK35K.js → chunk-2CQAWYYE.js} +1 -1
  57. package/dist/cli/chunks/{chunk-ADQFQBFJ.js → chunk-2D2XFUKI.js} +2 -2
  58. package/dist/cli/chunks/{chunk-2YDZXFO2.js → chunk-2G2QWV7B.js} +2 -2
  59. package/dist/cli/chunks/{chunk-HGJQSTQD.js → chunk-2ISLQU3G.js} +1 -1
  60. package/dist/cli/chunks/{chunk-6E47R27C.js → chunk-2OM3TDC4.js} +1 -1
  61. package/dist/cli/chunks/{chunk-WQASUQ5P.js → chunk-2XZ4BHWS.js} +1 -1
  62. package/dist/cli/chunks/{chunk-E2U3LTGM.js → chunk-3F4XH4ZA.js} +1 -1
  63. package/dist/cli/chunks/{chunk-YUDGQZJN.js → chunk-3K4YC3GC.js} +2 -2
  64. package/dist/cli/chunks/chunk-3KGCBAUH.js +2 -0
  65. package/dist/cli/chunks/{chunk-PXCJDB7J.js → chunk-3Y6CHW67.js} +1 -1
  66. package/dist/cli/chunks/{chunk-MOX25RZQ.js → chunk-4QMWWYNU.js} +2 -2
  67. package/dist/cli/chunks/{chunk-XZGOXLZH.js → chunk-4WGSMODQ.js} +1 -1
  68. package/dist/cli/chunks/{chunk-2CPJCXV6.js → chunk-55WDVSCM.js} +2 -2
  69. package/dist/cli/chunks/{chunk-EHO52NKU.js → chunk-5BB5DUL4.js} +2 -2
  70. package/dist/cli/chunks/{chunk-BEPP57C2.js → chunk-6C3MZLYW.js} +2 -2
  71. package/dist/cli/chunks/{chunk-DTZFZ5M7.js → chunk-6QKQFHS7.js} +2 -2
  72. package/dist/cli/chunks/{chunk-KXKACV3E.js → chunk-6XZXMEK4.js} +3 -3
  73. package/dist/cli/chunks/{chunk-L6GZGEFQ.js → chunk-7D7XFZZI.js} +2 -2
  74. package/dist/cli/chunks/{chunk-NLDLUHOF.js → chunk-7WEHZCSK.js} +2 -2
  75. package/dist/cli/chunks/{chunk-TXLPOXAN.js → chunk-A2MG3YXO.js} +1 -1
  76. package/dist/cli/chunks/{chunk-HJ2LG5IH.js → chunk-AHTOWWSE.js} +1 -1
  77. package/dist/cli/chunks/{chunk-GV2BS5NC.js → chunk-AOMXMFDH.js} +2 -2
  78. package/dist/cli/chunks/{chunk-EH7TSJPS.js → chunk-ARTLSAXO.js} +2 -2
  79. package/dist/cli/chunks/{chunk-CXMOIE7D.js → chunk-AY7S7AWN.js} +2 -2
  80. package/dist/cli/chunks/{chunk-2LNDU7AW.js → chunk-AYYDO52G.js} +2 -2
  81. package/dist/cli/chunks/chunk-BBLWZT5I.js +2 -0
  82. package/dist/cli/chunks/{chunk-KRS4KGX5.js → chunk-BF5BKSDU.js} +2 -2
  83. package/dist/cli/chunks/{chunk-BQ2K4BPD.js → chunk-BOCEOLLJ.js} +2 -2
  84. package/dist/cli/chunks/{chunk-KKOFH26C.js → chunk-CE6LYEHT.js} +1 -1
  85. package/dist/cli/chunks/{chunk-GS6G7AVS.js → chunk-CWP4RMOM.js} +2 -2
  86. package/dist/cli/chunks/{chunk-DCYBV6HV.js → chunk-CWXDL7AH.js} +1 -1
  87. package/dist/cli/chunks/{chunk-KGHSKDC7.js → chunk-DTRFZD7N.js} +2 -2
  88. package/dist/cli/chunks/{chunk-CYSBM52D.js → chunk-DVPGQG4W.js} +2 -2
  89. package/dist/cli/chunks/{chunk-MSDIIRLM.js → chunk-E4D47QTF.js} +2 -2
  90. package/dist/cli/chunks/{chunk-MB7TZQW3.js → chunk-EAKHU5YX.js} +3 -3
  91. package/dist/cli/chunks/{chunk-TP3UAWMB.js → chunk-EGMGOWCE.js} +2 -2
  92. package/dist/cli/chunks/{chunk-4EHW4TNA.js → chunk-ELMUHNXN.js} +2 -2
  93. package/dist/cli/chunks/chunk-EVDYFGVH.js +2 -0
  94. package/dist/cli/chunks/{chunk-D4GMAUTP.js → chunk-FDUSWM6O.js} +98 -88
  95. package/dist/cli/chunks/{chunk-YEC55GO5.js → chunk-FM272B4O.js} +2 -2
  96. package/dist/cli/chunks/{chunk-DMD6WVJ2.js → chunk-FQUUMC57.js} +2 -2
  97. package/dist/cli/chunks/{chunk-Y625LP6K.js → chunk-FQXQJMSF.js} +2 -2
  98. package/dist/cli/chunks/{chunk-Z3SXMYVI.js → chunk-FRAGSKXQ.js} +3 -3
  99. package/dist/cli/chunks/{chunk-MOXKKY5Q.js → chunk-GASOBSNB.js} +4 -4
  100. package/dist/cli/chunks/{chunk-PTPN6HQ7.js → chunk-GJEEPKAT.js} +2 -2
  101. package/dist/cli/chunks/{chunk-WFPGIP4N.js → chunk-GOV2MHLV.js} +2 -2
  102. package/dist/cli/chunks/{chunk-NKTLKMUB.js → chunk-GTPZVLL6.js} +1 -1
  103. package/dist/cli/chunks/chunk-H7YZ2YF2.js +3 -0
  104. package/dist/cli/chunks/{chunk-WKE6WL5C.js → chunk-HFI5PHG5.js} +3 -3
  105. package/dist/cli/chunks/chunk-HUMQU4ES.js +153 -0
  106. package/dist/cli/chunks/{chunk-5FAWIIWF.js → chunk-HYIRFJDB.js} +2 -2
  107. package/dist/cli/chunks/{chunk-DZ775UGW.js → chunk-IBSBOHUX.js} +2 -2
  108. package/dist/cli/chunks/{chunk-NAMJGRGC.js → chunk-IJA4WS7B.js} +2 -2
  109. package/dist/cli/chunks/{chunk-XUUVAAHV.js → chunk-IJP42OGW.js} +2 -2
  110. package/dist/cli/chunks/{chunk-UZ7FXVH5.js → chunk-IMQKEFW6.js} +1 -1
  111. package/dist/cli/chunks/{chunk-MZ7SIO6R.js → chunk-INYS35DV.js} +2 -2
  112. package/dist/cli/chunks/{chunk-MS6VOSPY.js → chunk-IV2VCR75.js} +5 -5
  113. package/dist/cli/chunks/{chunk-UAPUA6OY.js → chunk-IZO6TPGX.js} +2 -2
  114. package/dist/cli/chunks/{chunk-XBOCRCC6.js → chunk-J45DX3IK.js} +1 -1
  115. package/dist/cli/chunks/{chunk-RE42RJYR.js → chunk-J4T6D2OQ.js} +2 -2
  116. package/dist/cli/chunks/{chunk-Y5L37K7X.js → chunk-JAPOMPFD.js} +2 -2
  117. package/dist/cli/chunks/{chunk-M7W6VJ65.js → chunk-JELNVHBF.js} +1 -1
  118. package/dist/cli/chunks/{chunk-YDYKFSD2.js → chunk-JOTNKZ7A.js} +87 -87
  119. package/dist/cli/chunks/{chunk-VUCVSKJC.js → chunk-KNWDXI3I.js} +2 -2
  120. package/dist/cli/chunks/{chunk-SPI4LUJ6.js → chunk-KW5NBORV.js} +2 -2
  121. package/dist/cli/chunks/{chunk-2OX74DOO.js → chunk-L7IOTWWY.js} +1 -1
  122. package/dist/cli/chunks/{chunk-VFYMWDSJ.js → chunk-LJQ27PUE.js} +1 -1
  123. package/dist/cli/chunks/{chunk-NT66CT73.js → chunk-LSKQUUUN.js} +2 -2
  124. package/dist/cli/chunks/{chunk-ROFCS47F.js → chunk-LSZZQ7H6.js} +1 -1
  125. package/dist/cli/chunks/{chunk-Y6XNISHP.js → chunk-LTKNCYMO.js} +2 -2
  126. package/dist/cli/chunks/{chunk-7WF3TW3G.js → chunk-LTWT4GZD.js} +4 -4
  127. package/dist/cli/chunks/chunk-LVHMXGDI.js +29 -0
  128. package/dist/cli/chunks/{chunk-3YC4YUGB.js → chunk-M3T6FB54.js} +2 -2
  129. package/dist/cli/chunks/{chunk-M32DTUZM.js → chunk-MAYZTGJ2.js} +3 -3
  130. package/dist/cli/chunks/{chunk-RLBNAB6Y.js → chunk-MCIO7BDK.js} +1 -1
  131. package/dist/cli/chunks/{chunk-SFS3UHNF.js → chunk-MPD7RR4P.js} +1 -1
  132. package/dist/cli/chunks/{chunk-DDYP6FBC.js → chunk-MUFYDKVC.js} +2 -2
  133. package/dist/cli/chunks/{chunk-ZFLE4D4X.js → chunk-MX5ZDKRR.js} +2 -2
  134. package/dist/cli/chunks/{chunk-WBZNLFTV.js → chunk-MXKHIZVM.js} +5 -5
  135. package/dist/cli/chunks/chunk-MY47CR27.js +2 -0
  136. package/dist/cli/chunks/chunk-N7WAZ2Y6.js +2 -0
  137. package/dist/cli/chunks/{chunk-2HCMRGMO.js → chunk-NHV4PTG6.js} +2 -2
  138. package/dist/cli/chunks/{chunk-HJ4U64BL.js → chunk-NP4CP3LR.js} +2 -2
  139. package/dist/cli/chunks/{chunk-UIHZ34SJ.js → chunk-OCKTPTQ7.js} +2 -2
  140. package/dist/cli/chunks/{chunk-SGMJ277D.js → chunk-OE4B6LDZ.js} +1 -1
  141. package/dist/cli/chunks/{chunk-SV7J5FDW.js → chunk-OPQY2333.js} +2 -2
  142. package/dist/cli/chunks/{chunk-FTM562PF.js → chunk-ORDH4VPL.js} +1 -1
  143. package/dist/cli/chunks/{chunk-YOG5KQZF.js → chunk-P4Y3G6OB.js} +2 -2
  144. package/dist/cli/chunks/{chunk-LHAUFY4Y.js → chunk-PIOO2M4W.js} +2 -2
  145. package/dist/cli/chunks/{chunk-UGW23T6S.js → chunk-PKMCZFET.js} +2 -2
  146. package/dist/cli/chunks/{chunk-OPG2HV2W.js → chunk-QES4QHQW.js} +1 -1
  147. package/dist/cli/chunks/{chunk-BDGKB2PT.js → chunk-QG6BXSNJ.js} +2 -2
  148. package/dist/cli/chunks/{chunk-BSNNTOHY.js → chunk-QLOOW23R.js} +3 -3
  149. package/dist/cli/chunks/{chunk-AIWRYWK2.js → chunk-RSCGBHLM.js} +2 -2
  150. package/dist/cli/chunks/{chunk-LCM7TY76.js → chunk-RZ6CO3RZ.js} +2 -2
  151. package/dist/cli/chunks/chunk-S6F3IJMK.js +2 -0
  152. package/dist/cli/chunks/{chunk-WUE53ZPH.js → chunk-S6VNPKHO.js} +1 -1
  153. package/dist/cli/chunks/{chunk-L2X3BWMN.js → chunk-SHWXADCI.js} +2 -2
  154. package/dist/cli/chunks/{chunk-GMFFMJD6.js → chunk-SPJQJWGK.js} +2 -2
  155. package/dist/cli/chunks/{chunk-KVHCWH4H.js → chunk-SS6K4FBH.js} +2 -2
  156. package/dist/cli/chunks/{chunk-ZGKQCUPB.js → chunk-SXADKQJN.js} +2 -2
  157. package/dist/cli/chunks/{chunk-LGYEOYQJ.js → chunk-TBQTGQ75.js} +2 -2
  158. package/dist/cli/chunks/{chunk-J2RJOJ5Q.js → chunk-TDGE52HJ.js} +1 -1
  159. package/dist/cli/chunks/chunk-THFLRJT6.js +54 -0
  160. package/dist/cli/chunks/{chunk-GGTCD4MA.js → chunk-TQ2MA3SR.js} +1 -1
  161. package/dist/cli/chunks/{chunk-NOSQI2OW.js → chunk-UCQ66N6M.js} +3 -3
  162. package/dist/cli/chunks/{chunk-CL6SNCFF.js → chunk-UHGMS2PJ.js} +1 -1
  163. package/dist/cli/chunks/{chunk-XDHGCBTS.js → chunk-UHKXKWMD.js} +2 -2
  164. package/dist/cli/chunks/{chunk-PEHEANAM.js → chunk-UJ6TMZC6.js} +2 -2
  165. package/dist/cli/chunks/{chunk-PSDH7CIL.js → chunk-UKBDH27A.js} +1 -1
  166. package/dist/cli/chunks/{chunk-ZTKCGEB6.js → chunk-UMCEEXQN.js} +1 -1
  167. package/dist/cli/chunks/{chunk-KA4EAMMQ.js → chunk-USUFTHHT.js} +3 -3
  168. package/dist/cli/chunks/{chunk-QILF6BZH.js → chunk-V32MDID3.js} +2 -2
  169. package/dist/cli/chunks/{chunk-6SUSRXXF.js → chunk-VAJT6QWX.js} +1 -1
  170. package/dist/cli/chunks/{chunk-7Q74K3HZ.js → chunk-VLUJWI56.js} +1 -1
  171. package/dist/cli/chunks/{chunk-DW7OI5IF.js → chunk-WINA3XUT.js} +2 -2
  172. package/dist/cli/chunks/{chunk-S47YGWXK.js → chunk-WWCH5SSF.js} +2 -2
  173. package/dist/cli/chunks/{chunk-FJACKKRL.js → chunk-WWP2VXYJ.js} +2 -2
  174. package/dist/cli/chunks/{chunk-N4ML23ZG.js → chunk-WZROSTQZ.js} +1 -1
  175. package/dist/cli/chunks/{chunk-FXOOOJQD.js → chunk-XFUF654L.js} +1 -1
  176. package/dist/cli/chunks/{chunk-PDX7IYTJ.js → chunk-XN2CD5S6.js} +2 -2
  177. package/dist/cli/chunks/{chunk-DHUZHT5D.js → chunk-XOQQGZFY.js} +1 -1
  178. package/dist/cli/chunks/{chunk-4HP7N6SP.js → chunk-XSCOEY4C.js} +2 -2
  179. package/dist/cli/chunks/{chunk-KNWBRMLL.js → chunk-Y734CWHJ.js} +2 -2
  180. package/dist/cli/chunks/{chunk-NJDLJ3KD.js → chunk-YBPCBFEE.js} +2 -2
  181. package/dist/cli/chunks/{chunk-67BCEHU5.js → chunk-YLAEIS6F.js} +1 -1
  182. package/dist/cli/chunks/{chunk-E53UR2EW.js → chunk-YMMVCOPF.js} +3 -3
  183. package/dist/cli/chunks/{chunk-VSD6JE2H.js → chunk-YQCAXYBF.js} +2 -2
  184. package/dist/cli/chunks/{chunk-32L7DKNQ.js → chunk-YRVUYM62.js} +2 -2
  185. package/dist/cli/chunks/{chunk-LNIHLNW4.js → chunk-YVKMHXQK.js} +3 -3
  186. package/dist/cli/chunks/{chunk-CHFTHSMM.js → chunk-ZCLFAOVT.js} +2 -2
  187. package/dist/cli/chunks/{chunk-AZ24ONMX.js → chunk-ZH6ZBDVV.js} +1 -1
  188. package/dist/cli/chunks/{chunk-R6WMGSEK.js → chunk-ZHEKGB4A.js} +2 -2
  189. package/dist/cli/chunks/{chunk-EOUJ6X5H.js → chunk-ZIBW7CB4.js} +1 -1
  190. package/dist/cli/chunks/{chunk-OBL6W4Z5.js → chunk-ZLCATRXI.js} +2 -2
  191. package/dist/cli/chunks/{chunk-UGXHMQ6P.js → chunk-ZXX2VFMA.js} +2 -2
  192. package/dist/cli/chunks/{chunk-72QQDR3Y.js → chunk-ZYPESQ4M.js} +2 -2
  193. package/dist/cli/chunks/{ci-MMLUV6L6.js → ci-HHL5WQXQ.js} +2 -2
  194. package/dist/cli/chunks/{ci-output-25GS6RXR.js → ci-output-HVOJC2KN.js} +2 -2
  195. package/dist/cli/chunks/{circuit-breaker-4OWAN6R6.js → circuit-breaker-HRXMIY2G.js} +2 -2
  196. package/dist/cli/chunks/{claude-flow-setup-LR3SRBX6.js → claude-flow-setup-3I7WVMZN.js} +2 -2
  197. package/dist/cli/chunks/client-EY2IYQDL.js +2 -0
  198. package/dist/cli/chunks/{cline-installer-YSZWRZUI.js → cline-installer-NBREL4QT.js} +2 -2
  199. package/dist/cli/chunks/{code-UUWUIXI7.js → code-TX4E2RWU.js} +2 -2
  200. package/dist/cli/chunks/{code-index-extractor-2LSPQORU.js → code-index-extractor-YELOFLSL.js} +2 -2
  201. package/dist/cli/chunks/codex-installer-HEX3KFRB.js +10 -0
  202. package/dist/cli/chunks/{completions-YKXBKZSO.js → completions-72GGFRGG.js} +2 -2
  203. package/dist/cli/chunks/{complexity-analyzer-HNT2QRWB.js → complexity-analyzer-WRAKDYUK.js} +2 -2
  204. package/dist/cli/chunks/{continuedev-installer-AW5VCB66.js → continuedev-installer-UGYKSKTI.js} +2 -2
  205. package/dist/cli/chunks/{copilot-installer-B6SVZXQT.js → copilot-installer-RPCRUKIJ.js} +2 -2
  206. package/dist/cli/chunks/core-handlers-G4GLA4DT.js +2 -0
  207. package/dist/cli/chunks/{cost-tracker-POZMBN2V.js → cost-tracker-CNHJ7G4M.js} +2 -2
  208. package/dist/cli/chunks/{coverage-V5BGPN5Q.js → coverage-RHIQ4XEX.js} +3 -3
  209. package/dist/cli/chunks/cross-domain-router-P3K4IH5H.js +2 -0
  210. package/dist/cli/chunks/{cursor-installer-EYBI4QVK.js → cursor-installer-KSRVA4V2.js} +2 -2
  211. package/dist/cli/chunks/{daemon-CF6ENQB2.js → daemon-IT4AAFBW.js} +3 -3
  212. package/dist/cli/chunks/{daemon-HKARXY2W.js → daemon-QBXSJABV.js} +4 -4
  213. package/dist/cli/chunks/{dag-attention-scheduler-XIL5IAP7.js → dag-attention-scheduler-F7WCQTLY.js} +2 -2
  214. package/dist/cli/chunks/{detect-RRX2U2KK.js → detect-2IYU332U.js} +2 -2
  215. package/dist/cli/chunks/{dist-node-DOANNRCS.js → dist-node-CIYNYCYN.js} +2 -2
  216. package/dist/cli/chunks/{domain-handler-QMTJV5OR.js → domain-handler-QRYQO2QK.js} +2 -2
  217. package/dist/cli/chunks/{domain-transfer-FSNH75XW.js → domain-transfer-2OQDOD3G.js} +2 -2
  218. package/dist/cli/chunks/dream-IT4ZQGEO.js +2 -0
  219. package/dist/cli/chunks/{embed-and-insert-pattern-NI7PGONV.js → embed-and-insert-pattern-P2IFC7JL.js} +2 -2
  220. package/dist/cli/chunks/{eval-6ZAF2RY3.js → eval-SBPK37IB.js} +2 -2
  221. package/dist/cli/chunks/{experience-capture-middleware-JMXR7N5G.js → experience-capture-middleware-3GMFND3F.js} +3 -3
  222. package/dist/cli/chunks/{fast-paths-YB7XZZ76.js → fast-paths-4OYYII2F.js} +2 -2
  223. package/dist/cli/chunks/{feature-flags-2RC4GFC4.js → feature-flags-BM6QTMMC.js} +2 -2
  224. package/dist/cli/chunks/{feature-flags-KJSP7KR6.js → feature-flags-NFCAYUWO.js} +2 -2
  225. package/dist/cli/chunks/{file-discovery-SUPBXFYI.js → file-discovery-2M3ZUAGC.js} +2 -2
  226. package/dist/cli/chunks/{fleet-KSXFOLFW.js → fleet-QMGGVIDV.js} +3 -3
  227. package/dist/cli/chunks/{gnn-wrapper-DFZ5KPPK.js → gnn-wrapper-WGMAGZMO.js} +2 -2
  228. package/dist/cli/chunks/{heartbeat-handler-G3EADK2H.js → heartbeat-handler-5RSMEZGG.js} +4 -4
  229. package/dist/cli/chunks/heartbeat-scheduler-UUWSPHF2.js +2 -0
  230. package/dist/cli/chunks/hnsw-adapter-YUJVSFPD.js +2 -0
  231. package/dist/cli/chunks/hnsw-index-FQZ47RSJ.js +2 -0
  232. package/dist/cli/chunks/{hnsw-legacy-bridge-MA676GER.js → hnsw-legacy-bridge-TYPQ2T6P.js} +2 -2
  233. package/dist/cli/chunks/{better-sqlite3-FE55OGYB.js → hnswlib-node-GMRPPMDM.js} +2 -2
  234. package/dist/cli/chunks/{hooks-HTCPMZNZ.js → hooks-NUC5P3OJ.js} +10 -10
  235. package/dist/cli/chunks/hybrid-router-T5MF73NF.js +2 -0
  236. package/dist/cli/chunks/{hypergraph-engine-QPB3IH4A.js → hypergraph-engine-OIB7WK54.js} +2 -2
  237. package/dist/cli/chunks/{hypergraph-handler-GBFSVD7N.js → hypergraph-handler-XX2N75QC.js} +3 -3
  238. package/dist/cli/chunks/impact-analyzer-AEGELYMD.js +2 -0
  239. package/dist/cli/chunks/{init-handler-XYBTBCPD.js → init-handler-AKSTJMZY.js} +6 -6
  240. package/dist/cli/chunks/init-wizard-WKX3OGWM.js +2 -0
  241. package/dist/cli/chunks/kernel-5CVWFIGR.js +2 -0
  242. package/dist/cli/chunks/{kilocode-installer-LY6JOBFY.js → kilocode-installer-375V5ZZB.js} +2 -2
  243. package/dist/cli/chunks/{kiro-installer-JF6NXTJL.js → kiro-installer-GKY5GB5Q.js} +2 -2
  244. package/dist/cli/chunks/knowledge-graph-EGPMNDMT.js +2 -0
  245. package/dist/cli/chunks/{learning-BIISN67N.js → learning-2CQE3QP6.js} +3 -3
  246. package/dist/cli/chunks/{llm-router-YZUNVZQE.js → llm-router-FTQNRF45.js} +5 -5
  247. package/dist/cli/chunks/llm-router-service-H4LXOARB.js +2 -0
  248. package/dist/cli/chunks/{load-MTWNBNLL.js → load-3DBAO5ZG.js} +2 -2
  249. package/dist/cli/chunks/load-test-OOOGITSN.js +2 -0
  250. package/dist/cli/chunks/{mcp-37PYMNHQ.js → mcp-AWR6TDXM.js} +2 -2
  251. package/dist/cli/chunks/{memory-IXUUDCI3.js → memory-GI4LCNXY.js} +5 -5
  252. package/dist/cli/chunks/memory-backend-O2YOT4LW.js +2 -0
  253. package/dist/cli/chunks/{memory-handlers-RM2VOFJX.js → memory-handlers-MALKG7GP.js} +2 -2
  254. package/dist/cli/chunks/{multi-model-executor-RKKS5XYG.js → multi-model-executor-SWFT5U72.js} +2 -2
  255. package/dist/cli/chunks/{opencode-installer-3VXI5MTR.js → opencode-installer-EYXGYJX5.js} +2 -2
  256. package/dist/cli/chunks/{orchestrator-UO3ZOGFZ.js → orchestrator-MP3EAZVC.js} +5 -5
  257. package/dist/cli/chunks/pattern-null-store-WBOHE2XL.js +2 -0
  258. package/dist/cli/chunks/{pattern-usage-recorder-YJKRL2GI.js → pattern-usage-recorder-25P3R3W7.js} +2 -2
  259. package/dist/cli/chunks/{pipeline-GJQJKXWX.js → pipeline-LSAFL25D.js} +2 -2
  260. package/dist/cli/chunks/{platform-RHVCZK6C.js → platform-IJ6DJ2PG.js} +2 -2
  261. package/dist/cli/chunks/{plugin-ZKAIW7O6.js → plugin-OXOZRZW2.js} +2 -2
  262. package/dist/cli/chunks/{prime-radiant-advanced-wasm-4X3DSKQV.js → prime-radiant-advanced-wasm-HJNJQQ3R.js} +2 -2
  263. package/dist/cli/chunks/protocol-executor-JCNTPW5J.js +2 -0
  264. package/dist/cli/chunks/{protocol-handler-KKYQZMB2.js → protocol-handler-TCMUH2HL.js} +2 -2
  265. package/dist/cli/chunks/{prove-OD6RPKWX.js → prove-ADXQ2GOX.js} +2 -2
  266. package/dist/cli/chunks/provider-manager-LPGQ5GOO.js +2 -0
  267. package/dist/cli/chunks/qe-reasoning-bank-FWVYVSPP.js +2 -0
  268. package/dist/cli/chunks/{quality-ZRWBXCKO.js → quality-EWP36ORX.js} +2 -2
  269. package/dist/cli/chunks/{quality-gate-Y6BWQV7J.js → quality-gate-3BIG7PVU.js} +3 -3
  270. package/dist/cli/chunks/queen-coordinator-UXNALRVD.js +2 -0
  271. package/dist/cli/chunks/{real-embeddings-YYEUO4P2.js → real-embeddings-D4NBT7W5.js} +2 -2
  272. package/dist/cli/chunks/{roocode-installer-JBCPS3FK.js → roocode-installer-DOPWH6YV.js} +2 -2
  273. package/dist/cli/chunks/router-C6LUIQYY.js +2 -0
  274. package/dist/cli/chunks/routing-feedback-KMSGGDVD.js +2 -0
  275. package/dist/cli/chunks/{routing-handler-KTPJOSBJ.js → routing-handler-5ADEFOHS.js} +2 -2
  276. package/dist/cli/chunks/{ruvector-commands-SCZZVRE7.js → ruvector-commands-PLMEIHSN.js} +2 -2
  277. package/dist/cli/chunks/{rvf-dual-writer-IP7GELQJ.js → rvf-dual-writer-EQWKVNQB.js} +2 -2
  278. package/dist/cli/chunks/{rvf-migration-adapter-WLFTDARU.js → rvf-migration-adapter-2OWFUUCG.js} +2 -2
  279. package/dist/cli/chunks/{rvf-migration-coordinator-MGFDQ5WD.js → rvf-migration-coordinator-URAETAPU.js} +2 -2
  280. package/dist/cli/chunks/rvf-native-adapter-K54BELUE.js +2 -0
  281. package/dist/cli/chunks/{rvf-store-integrity-OTOAGT5W.js → rvf-store-integrity-4AWPW4TF.js} +2 -2
  282. package/dist/cli/chunks/safe-db-NGOZWF2D.js +2 -0
  283. package/dist/cli/chunks/schedule-B3Y5P64E.js +2 -0
  284. package/dist/cli/chunks/scheduler-Z6QVRMTB.js +2 -0
  285. package/dist/cli/chunks/{security-B2CLZKRB.js → security-HDLZVM62.js} +3 -3
  286. package/dist/cli/chunks/{shared-rvf-adapter-2PMFAQMN.js → shared-rvf-adapter-YQT7PF7X.js} +2 -2
  287. package/dist/cli/chunks/{shared-rvf-dual-writer-B6P732AV.js → shared-rvf-dual-writer-N5D3NSJ7.js} +2 -2
  288. package/dist/cli/chunks/sqlite-persistence-PLOUGATS.js +2 -0
  289. package/dist/cli/chunks/{status-handler-M6SN2W2D.js → status-handler-KLYRJ2MR.js} +2 -2
  290. package/dist/cli/chunks/{structural-health-YCCTGI3K.js → structural-health-6LKVRP6Y.js} +2 -2
  291. package/dist/cli/chunks/sync-7VMFPBVB.js +2 -0
  292. package/dist/cli/chunks/{sync-KSRF77ID.js → sync-YYOW6L6W.js} +2 -2
  293. package/dist/cli/chunks/{task-handler-MIKRB2SL.js → task-handler-RKQDGFN2.js} +2 -2
  294. package/dist/cli/chunks/{task-handlers-YXKRUBQ4.js → task-handlers-6YJ4QTEP.js} +3 -3
  295. package/dist/cli/chunks/{test-MLOLQCB7.js → test-ASPUIUJH.js} +4 -4
  296. package/dist/cli/chunks/{test-scheduling-3KXESUZS.js → test-scheduling-I7ABQBBU.js} +3 -3
  297. package/dist/cli/chunks/{token-bootstrap-6V2PMDBJ.js → token-bootstrap-2XZBTODN.js} +2 -2
  298. package/dist/cli/chunks/{token-usage-DP6THJ3I.js → token-usage-TMUE6PTF.js} +2 -2
  299. package/dist/cli/chunks/transformers-FDHHH4SL.js +2 -0
  300. package/dist/cli/chunks/{tree-sitter-wasm-parser-COK2XERS.js → tree-sitter-wasm-parser-G7PGZA5C.js} +2 -2
  301. package/dist/cli/chunks/{types-PYHUCVOZ.js → types-JGT57UFP.js} +2 -2
  302. package/dist/cli/chunks/unified-memory-P5YVLMFI.js +2 -0
  303. package/dist/cli/chunks/unified-memory-hnsw-7HI43A2O.js +2 -0
  304. package/dist/cli/chunks/unified-persistence-U26YP3N3.js +2 -0
  305. package/dist/cli/chunks/{upgrade-ONP2HNGL.js → upgrade-V6UQODJF.js} +2 -2
  306. package/dist/cli/chunks/{validate-NWSICDAY.js → validate-UBZAE5RW.js} +2 -2
  307. package/dist/cli/chunks/{validate-swarm-KXS5P3U7.js → validate-swarm-TSO2MI5X.js} +2 -2
  308. package/dist/cli/chunks/{vibium-TZSGZRCQ.js → vibium-7G3VYSQA.js} +2 -2
  309. package/dist/cli/chunks/visual-security-6FCDY5FF.js +2 -0
  310. package/dist/cli/chunks/{web-tree-sitter-V2FADNRA.js → web-tree-sitter-MIYJSF2L.js} +2 -2
  311. package/dist/cli/chunks/{windsurf-installer-GQM7KWDC.js → windsurf-installer-5TLZSQIJ.js} +2 -2
  312. package/dist/cli/chunks/witness-chain-I3K3WQID.js +2 -0
  313. package/dist/cli/chunks/{witness-chain-GTITDIA2.js → witness-chain-LTV7H2HM.js} +2 -2
  314. package/dist/cli/chunks/{witness-key-manager-AHRM2M52.js → witness-key-manager-PAJ2J4AL.js} +2 -2
  315. package/dist/cli/chunks/{workflow-XCGHEL3I.js → workflow-DL3ESR2H.js} +4 -4
  316. package/dist/cli/chunks/workflow-orchestrator-MAALP4WA.js +2 -0
  317. package/dist/cli/chunks/{wrappers-VGO2GO4J.js → wrappers-5HSU665E.js} +2 -2
  318. package/dist/cli/commands/llm-router.js +1 -0
  319. package/dist/cli/handlers/init-handler.js +1 -1
  320. package/dist/coordination/handlers/coverage-collection.d.ts +161 -0
  321. package/dist/coordination/handlers/coverage-collection.js +639 -0
  322. package/dist/coordination/handlers/coverage-handlers.js +199 -146
  323. package/dist/coordination/handlers/handler-types.d.ts +6 -1
  324. package/dist/coordination/handlers/handler-utils.js +10 -3
  325. package/dist/coordination/handlers/security-handlers.js +17 -2
  326. package/dist/coordination/handlers/test-execution-handlers.js +16 -1
  327. package/dist/coordination/result-saver.js +119 -97
  328. package/dist/coordination/task-executor.d.ts +26 -1
  329. package/dist/coordination/task-executor.js +52 -4
  330. package/dist/domains/code-intelligence/services/knowledge-graph.js +8 -0
  331. package/dist/domains/coverage-analysis/services/coverage-analyzer.js +4 -0
  332. package/dist/domains/coverage-analysis/services/gap-detector.js +4 -0
  333. package/dist/domains/defect-intelligence/services/defect-predictor.js +4 -0
  334. package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +4 -0
  335. package/dist/domains/quality-assessment/services/deployment-advisor.js +4 -0
  336. package/dist/domains/quality-assessment/services/quality-analyzer.js +4 -0
  337. package/dist/domains/security-compliance/services/scanners/sast-scanner.js +4 -0
  338. package/dist/domains/test-generation/index.js +17 -2
  339. package/dist/domains/test-generation/services/test-generator.js +31 -9
  340. package/dist/init/codex-installer.d.ts +13 -0
  341. package/dist/init/codex-installer.js +122 -1
  342. package/dist/init/phases/09-assets.js +4 -0
  343. package/dist/init/phases/phase-interface.d.ts +1 -1
  344. package/dist/init/skills-installer.js +1 -0
  345. package/dist/integrations/embeddings/base/EmbeddingGenerator.js +13 -1
  346. package/dist/kernel/unified-memory.js +4 -0
  347. package/dist/learning/qe-flywheel/corpus-scorer.js +10 -7
  348. package/dist/learning/qe-flywheel/generation.d.ts +7 -0
  349. package/dist/learning/qe-flywheel/generation.js +5 -0
  350. package/dist/learning/qe-flywheel/witness-verify.d.ts +86 -0
  351. package/dist/learning/qe-flywheel/witness-verify.js +156 -0
  352. package/dist/learning/real-embeddings.js +15 -1
  353. package/dist/mcp/bundle.js +455 -434
  354. package/dist/mcp/handlers/domain-handler-configs.js +79 -14
  355. package/dist/mcp/types.d.ts +42 -4
  356. package/dist/optimization/session-cache.d.ts +13 -1
  357. package/dist/optimization/session-cache.js +27 -2
  358. package/dist/shared/db-recovery.d.ts +55 -0
  359. package/dist/shared/db-recovery.js +184 -0
  360. package/dist/shared/llm/billing-modes.js +5 -2
  361. package/dist/shared/llm/cost-tracker.js +1 -0
  362. package/dist/shared/llm/interfaces.d.ts +14 -1
  363. package/dist/shared/llm/llm-router-service.js +59 -4
  364. package/dist/shared/llm/provider-manager.d.ts +1 -1
  365. package/dist/shared/llm/provider-manager.js +7 -3
  366. package/dist/shared/llm/providers/claude-code.js +12 -3
  367. package/dist/shared/llm/providers/codex.d.ts +58 -0
  368. package/dist/shared/llm/providers/codex.js +305 -0
  369. package/dist/shared/llm/providers/index.d.ts +1 -0
  370. package/dist/shared/llm/providers/index.js +1 -0
  371. package/dist/shared/llm/router/agent-router-config.d.ts +46 -2
  372. package/dist/shared/llm/router/agent-router-config.js +124 -2
  373. package/dist/shared/llm/router/config-store.d.ts +17 -1
  374. package/dist/shared/llm/router/config-store.js +108 -0
  375. package/dist/shared/llm/router/hybrid-router.js +2 -2
  376. package/dist/shared/llm/router/index.d.ts +2 -2
  377. package/dist/shared/llm/router/index.js +2 -0
  378. package/dist/shared/llm/router/types.d.ts +44 -0
  379. package/dist/shared/llm/router/types.js +1 -0
  380. package/dist/shared/llm/spend-ledger.d.ts +24 -0
  381. package/dist/shared/llm/spend-ledger.js +86 -15
  382. package/dist/shared/llm/translation/message-formatter.js +1 -0
  383. package/dist/shared/safe-db.d.ts +10 -0
  384. package/dist/shared/safe-db.js +17 -0
  385. package/dist/skills/qe-court/referee.d.ts +62 -0
  386. package/dist/skills/qe-court/referee.js +78 -0
  387. package/dist/validation/gate-reexecute.d.ts +9 -0
  388. package/dist/validation/gate-reexecute.js +61 -0
  389. package/dist/validation/paired-bootstrap.d.ts +36 -0
  390. package/dist/validation/paired-bootstrap.js +58 -0
  391. package/package.json +9 -2
  392. package/dist/cli/chunks/adapter-D657MKZY.js +0 -2
  393. package/dist/cli/chunks/aqe-learning-engine-AFR6OZJK.js +0 -2
  394. package/dist/cli/chunks/base-K5QRGZWE.js +0 -2
  395. package/dist/cli/chunks/browser-workflow-ZMMKCGYW.js +0 -2
  396. package/dist/cli/chunks/chunk-6HQDPDN5.js +0 -2
  397. package/dist/cli/chunks/chunk-6SQ72FG7.js +0 -2
  398. package/dist/cli/chunks/chunk-7XUM4LBC.js +0 -2
  399. package/dist/cli/chunks/chunk-FHHCH7WL.js +0 -2
  400. package/dist/cli/chunks/chunk-G5OGKVLO.js +0 -2
  401. package/dist/cli/chunks/chunk-ILRKO6A5.js +0 -43
  402. package/dist/cli/chunks/chunk-NX522PRH.js +0 -153
  403. package/dist/cli/chunks/chunk-PPUDKQ4X.js +0 -29
  404. package/dist/cli/chunks/chunk-RSZOCQOL.js +0 -2
  405. package/dist/cli/chunks/chunk-ULQCEM7K.js +0 -2
  406. package/dist/cli/chunks/chunk-XQ5JT7KM.js +0 -3
  407. package/dist/cli/chunks/client-WI7RRUZO.js +0 -2
  408. package/dist/cli/chunks/codex-installer-E5BVXZVA.js +0 -8
  409. package/dist/cli/chunks/core-handlers-T6URR57V.js +0 -2
  410. package/dist/cli/chunks/cross-domain-router-WHTTKHWM.js +0 -2
  411. package/dist/cli/chunks/dream-QUL6SURC.js +0 -2
  412. package/dist/cli/chunks/heartbeat-scheduler-VZNKE33K.js +0 -2
  413. package/dist/cli/chunks/hnsw-adapter-LGWLDZLC.js +0 -2
  414. package/dist/cli/chunks/hnsw-index-66FOOI7U.js +0 -2
  415. package/dist/cli/chunks/hybrid-router-I5MEVQDF.js +0 -2
  416. package/dist/cli/chunks/impact-analyzer-K6ANYIY3.js +0 -2
  417. package/dist/cli/chunks/init-wizard-URHGXJ32.js +0 -2
  418. package/dist/cli/chunks/kernel-OKI5ZY5P.js +0 -2
  419. package/dist/cli/chunks/knowledge-graph-VQQSK7T5.js +0 -2
  420. package/dist/cli/chunks/llm-router-service-TISH33SY.js +0 -2
  421. package/dist/cli/chunks/load-test-KWKWC4Q7.js +0 -2
  422. package/dist/cli/chunks/memory-backend-JSQQMXVS.js +0 -2
  423. package/dist/cli/chunks/pattern-null-store-SXBIUKE5.js +0 -2
  424. package/dist/cli/chunks/protocol-executor-D3Q5P3WY.js +0 -2
  425. package/dist/cli/chunks/provider-manager-2EIX7E5Q.js +0 -2
  426. package/dist/cli/chunks/qe-reasoning-bank-ITOW2ZHC.js +0 -2
  427. package/dist/cli/chunks/queen-coordinator-TO5X2EXL.js +0 -2
  428. package/dist/cli/chunks/router-GZJQEJU3.js +0 -2
  429. package/dist/cli/chunks/routing-feedback-CRXSKFNS.js +0 -2
  430. package/dist/cli/chunks/rvf-native-adapter-WHADT5HX.js +0 -2
  431. package/dist/cli/chunks/safe-db-MIZ2OFWC.js +0 -2
  432. package/dist/cli/chunks/schedule-XFILYTYC.js +0 -2
  433. package/dist/cli/chunks/scheduler-EIPJ777A.js +0 -2
  434. package/dist/cli/chunks/sqlite-persistence-PFU3GSRD.js +0 -2
  435. package/dist/cli/chunks/sync-3SDMVAIU.js +0 -2
  436. package/dist/cli/chunks/transformers-QFOBOP2Y.js +0 -2
  437. package/dist/cli/chunks/unified-memory-OUVCMFGK.js +0 -2
  438. package/dist/cli/chunks/unified-memory-hnsw-YGQPOHXB.js +0 -2
  439. package/dist/cli/chunks/unified-persistence-GFRZVDOW.js +0 -2
  440. package/dist/cli/chunks/visual-security-LVOOYQ64.js +0 -2
  441. package/dist/cli/chunks/witness-chain-QNFPV4UL.js +0 -2
  442. 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
- if (stdin !== undefined) {
289
- child.stdin.write(stdin);
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
- * Get the preferred model for an agent type
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