@iowarp/clio-coder 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/CONTRIBUTING.md +142 -52
  3. package/README.md +434 -473
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-H2NGRPWO.js} +12 -12
  6. package/dist/{agents-HYWGBGQR.js → agents-TL5LLUQP.js} +56 -55
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-E5SW4HMS.js} +23 -21
  9. package/dist/builtins-IA7V7FUC.js +22 -0
  10. package/dist/{chunk-7RY5VZPH.js → chunk-2APPQIER.js} +8 -8
  11. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  12. package/dist/{chunk-JA5QWE4Z.js → chunk-2UG5F4C5.js} +1973 -1664
  13. package/dist/{chunk-5YHDIDBP.js → chunk-2UH2KFUP.js} +2 -2
  14. package/dist/{chunk-CTJ4RNAA.js → chunk-2VIKGWFZ.js} +2 -2
  15. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  16. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  17. package/dist/chunk-3EBYEESD.js +314 -0
  18. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  19. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  20. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  21. package/dist/chunk-4UVU7BJ5.js +39 -0
  22. package/dist/{chunk-VKRH2TCS.js → chunk-4WR7VSYB.js} +2 -2
  23. package/dist/{chunk-BBTJOK6Y.js → chunk-54CBCGIR.js} +5 -5
  24. package/dist/{chunk-AP73CFDC.js → chunk-5ICU3EUH.js} +2 -2
  25. package/dist/chunk-5MEZN6CB.js +1334 -0
  26. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  27. package/dist/{chunk-ABLSQ6JX.js → chunk-64I3JVYM.js} +8 -2
  28. package/dist/{chunk-AFKWHWXF.js → chunk-6PTFB5VS.js} +39 -22
  29. package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
  30. package/dist/chunk-7DRAWPTZ.js +360 -0
  31. package/dist/chunk-7E7I3WLS.js +3762 -0
  32. package/dist/{chunk-BJGUKIG4.js → chunk-7ZYNNDKC.js} +7 -7
  33. package/dist/{chunk-XKA2ICR3.js → chunk-AF4YM7Z4.js} +652 -252
  34. package/dist/{chunk-GVQJ5CCZ.js → chunk-AX2THNSA.js} +12 -12
  35. package/dist/{chunk-IG7BCQBA.js → chunk-B4OAX3SI.js} +65 -3
  36. package/dist/{chunk-TD3PGPQA.js → chunk-B4VEBZKF.js} +3 -3
  37. package/dist/{chunk-74YWRRU5.js → chunk-BEPZRGGU.js} +10 -10
  38. package/dist/{chunk-FEFIFZTL.js → chunk-CE5AX47J.js} +2 -2
  39. package/dist/{chunk-UAPGZHYC.js → chunk-DWUOQKRU.js} +25 -11
  40. package/dist/{chunk-THYWACCR.js → chunk-E3TPLWFX.js} +3 -3
  41. package/dist/{chunk-7EPLI7VL.js → chunk-EKCHAPYA.js} +2 -2
  42. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  43. package/dist/{chunk-PJJ6MY27.js → chunk-F5JHEYZM.js} +7 -7
  44. package/dist/{chunk-6CCS4G3W.js → chunk-FTMGRKEF.js} +3 -3
  45. package/dist/{chunk-SINK3QR6.js → chunk-G76U63X4.js} +17 -17
  46. package/dist/{chunk-EIMVLWB3.js → chunk-GHS5EBTQ.js} +64 -9
  47. package/dist/{chunk-QMXC4JB7.js → chunk-GI7YYQ3F.js} +187 -1419
  48. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  49. package/dist/{chunk-6HMJX2VU.js → chunk-GWZNEVM2.js} +44 -12
  50. package/dist/chunk-GYV6VZOC.js +26 -0
  51. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  52. package/dist/{chunk-UXN6JT4W.js → chunk-HEQY7ZFI.js} +3 -3
  53. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  54. package/dist/{chunk-GCSMB2KY.js → chunk-I7ZPNEJM.js} +145 -102
  55. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  56. package/dist/{chunk-QTFGO774.js → chunk-IGLP3ODT.js} +29 -16
  57. package/dist/chunk-IJNZMHLA.js +101 -0
  58. package/dist/{chunk-BDPT6GTK.js → chunk-INY6HTFL.js} +7 -7
  59. package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
  60. package/dist/{chunk-6NJQITNH.js → chunk-IWT4SF4R.js} +6 -3
  61. package/dist/{chunk-R23Z6K6I.js → chunk-JDAY6FIL.js} +19 -19
  62. package/dist/chunk-JEQ3XTHC.js +42 -0
  63. package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
  64. package/dist/{chunk-TVH4ONAM.js → chunk-JKKCYP3C.js} +10 -10
  65. package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
  66. package/dist/{chunk-C537JADH.js → chunk-KK4JZPBQ.js} +19 -141
  67. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  68. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-L47TF46W.js} +5 -7
  70. package/dist/{chunk-HUAS7ITX.js → chunk-LDJG7DW3.js} +91 -42
  71. package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
  72. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  73. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  74. package/dist/{chunk-VKFQTNDV.js → chunk-MUW2BDDH.js} +4 -4
  75. package/dist/{chunk-E67WX76H.js → chunk-MWUZBSAQ.js} +104 -152
  76. package/dist/{chunk-OJTRZGR3.js → chunk-N2Z7HLVY.js} +21 -21
  77. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  78. package/dist/{chunk-FYUN5KZ3.js → chunk-NIQJ66N4.js} +21 -21
  79. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  80. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  81. package/dist/{chunk-VEGN6WIQ.js → chunk-O5CVSAG5.js} +3 -3
  82. package/dist/{chunk-MOPSG2X7.js → chunk-OML5D5V5.js} +8 -8
  83. package/dist/{chunk-2VG7KLYV.js → chunk-PAJQJ7BS.js} +5816 -3255
  84. package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
  85. package/dist/{chunk-BTGG6BG2.js → chunk-QWGDJJYJ.js} +158 -19
  86. package/dist/chunk-R6Q67RJH.js +134 -0
  87. package/dist/{chunk-ZJLUDYFY.js → chunk-RRNP2ANY.js} +6 -6
  88. package/dist/{chunk-PVAMAVBB.js → chunk-RSJ25QSL.js} +102 -2
  89. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  90. package/dist/chunk-SKHCAU7K.js +385 -0
  91. package/dist/chunk-SZAA6XDG.js +30 -0
  92. package/dist/{chunk-J4HBWF6Y.js → chunk-TM6LQDI3.js} +131 -28
  93. package/dist/chunk-UOIZ7DA4.js +41 -0
  94. package/dist/{chunk-MA3H6DM5.js → chunk-UPZU6GE4.js} +25 -3
  95. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  96. package/dist/{chunk-N5UK64DP.js → chunk-V2ANDPVT.js} +4 -4
  97. package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
  98. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  99. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  100. package/dist/{chunk-QKIFBZKT.js → chunk-VW6DOEDG.js} +497 -81
  101. package/dist/{chunk-SCYB3HA4.js → chunk-W6RRQCPQ.js} +63 -19
  102. package/dist/{chunk-2NM363SV.js → chunk-WBKFA554.js} +10 -10
  103. package/dist/{chunk-R32CLGZ6.js → chunk-WCXUNS7U.js} +82 -21
  104. package/dist/{chunk-GPPB3JBE.js → chunk-WRBAGUNF.js} +3 -3
  105. package/dist/{chunk-IXJT6DCX.js → chunk-XIVNBFZS.js} +85 -30
  106. package/dist/{chunk-UEDMSP56.js → chunk-XPWWI35G.js} +417 -201
  107. package/dist/chunk-XRZT5WY5.js +47 -0
  108. package/dist/{chunk-3QSOM6PA.js → chunk-Y3CBHOR6.js} +2 -2
  109. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  110. package/dist/{chunk-AKB4GYDL.js → chunk-YQWYVTMC.js} +5 -5
  111. package/dist/{chunk-6I5ILFOF.js → chunk-ZA4VCIGV.js} +3 -3
  112. package/dist/{chunk-7OBGU7UB.js → chunk-ZDN3Y73Y.js} +12 -18
  113. package/dist/{chunk-3I5NY75V.js → chunk-ZWPRK62N.js} +8 -5
  114. package/dist/cli/index.js +41 -39
  115. package/dist/{clio-IT3G3VQH.js → clio-CMMK4KRR.js} +9 -9
  116. package/dist/{code-nav-RK6S7F6E.js → code-nav-MDZNQS33.js} +89 -21
  117. package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
  118. package/dist/{config-3QZRWZJF.js → config-SVM5P5YI.js} +131 -84
  119. package/dist/{configure-FL7Y3KJF.js → configure-LE3IK2TJ.js} +28 -26
  120. package/dist/{context-5HE7ODYK.js → context-2OHRKS42.js} +69 -64
  121. package/dist/{context-KYQFRVDC.js → context-E3VC7RX5.js} +15 -11
  122. package/dist/{context-XNHL75JV.js → context-VNCR7KAG.js} +93 -65
  123. package/dist/{context-clear-N545L53A.js → context-clear-BW4O37TG.js} +64 -60
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-VDS25HXZ.js} +19 -18
  126. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-5AHT53RF.js} +93 -82
  127. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  128. package/dist/{doctor-ZGPEGHIP.js → doctor-WNNVO6FY.js} +48 -47
  129. package/dist/{eval-GXLL44RD.js → eval-7G7SGAYO.js} +287 -115
  130. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-Y6QRFOH5.js} +4 -4
  131. package/dist/{evidence-HWLBRH3Q.js → evidence-VD6736FQ.js} +67 -64
  132. package/dist/{evolve-FTZBMNVW.js → evolve-AL3NGVRL.js} +65 -62
  133. package/dist/{extensions-VHRBEID7.js → extensions-MOVJ32NM.js} +9 -7
  134. package/dist/{fleet-CKZHJWZJ.js → fleet-QZHUMAGI.js} +114 -111
  135. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-BAYT5FJZ.js} +10 -10
  136. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-IREVMRU4.js} +7 -6
  137. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-YCTT3HTI.js} +22 -19
  138. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-QVJTDAVB.js} +58 -55
  139. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-25QAFPK4.js} +4 -4
  140. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-5O57AAJ7.js} +26 -23
  141. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-CPH2W2T6.js} +59 -56
  142. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-SWBR3VGQ.js} +58 -55
  143. package/dist/{init-5XQRBOFV.js → init-J477LKZH.js} +82 -79
  144. package/dist/{interop-34TVO25M.js → interop-3FCM6XLG.js} +11 -11
  145. package/dist/{library-3QY6KF57.js → library-QUQEIUG6.js} +30 -27
  146. package/dist/{memory-L4UTIIIW.js → memory-SGGSEP65.js} +67 -64
  147. package/dist/{models-ZVX3QOWE.js → models-HEKUAXXK.js} +53 -46
  148. package/dist/{monitor-CEKVSYTS.js → monitor-HKU57TYQ.js} +63 -60
  149. package/dist/{orchestrator-77BAP6BC.js → orchestrator-VDFAEFAI.js} +1831 -1057
  150. package/dist/{panes-7STHOAUJ.js → panes-DN2SSFOH.js} +5 -5
  151. package/dist/{panes-SHAUIRXY.js → panes-TALGNPZT.js} +29 -14
  152. package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
  153. package/dist/reset-EAJFFJVB.js +344 -0
  154. package/dist/{resources-74GKTLSF.js → resources-OVKSEFVE.js} +29 -20
  155. package/dist/{run-HBAUJNNZ.js → run-7DP7ZF2J.js} +120 -115
  156. package/dist/{share-G3APVLVP.js → share-WML67FT3.js} +32 -27
  157. package/dist/{skills-35HHUKCR.js → skills-SG662R2K.js} +41 -31
  158. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-VVZEUU46.js} +78 -77
  159. package/dist/{skills-inventory-J357J34F.js → skills-inventory-I2E23GET.js} +23 -20
  160. package/dist/{slash-commands-JZZCQA32.js → slash-commands-S7MBJDQK.js} +40 -36
  161. package/dist/{steer-XAVHJM22.js → steer-2LQOMCPB.js} +3 -3
  162. package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
  163. package/dist/{targets-DSM6CY3M.js → targets-4QC3HIEW.js} +54 -54
  164. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-TUHIJ6Y2.js} +5 -5
  165. package/dist/{tools-MKNWVPBH.js → tools-TFGJICCU.js} +10 -10
  166. package/dist/{trace-ECQ7TIYZ.js → trace-FXMXUZUF.js} +55 -7
  167. package/dist/uninstall-5PEVOE5B.js +408 -0
  168. package/dist/upgrade-M4WXY6KN.js +303 -0
  169. package/dist/{usage-X52N3IDJ.js → usage-N7ZNVLEM.js} +151 -104
  170. package/dist/{verifiers-EJTVVSMA.js → verifiers-DJTP4XX6.js} +15 -15
  171. package/dist/{verify-YJL6XET2.js → verify-RWE4PPEK.js} +9 -9
  172. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  173. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-C7IQOXSP.js} +89 -86
  174. package/dist/{with-panes-OBOBFIIR.js → with-panes-4GCGSL7J.js} +53 -257
  175. package/dist/worker/entry.js +90 -74
  176. package/docs/README.md +176 -81
  177. package/docs/{acp.md → architecture/acp.md} +36 -20
  178. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  179. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  180. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +27 -23
  181. package/docs/architecture/artifact-versions.md +90 -0
  182. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  183. package/docs/{context-engine.md → architecture/context-engine.md} +29 -25
  184. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  185. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  186. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  187. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  188. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  189. package/docs/{model-catalog.md → architecture/model-catalog.md} +61 -27
  190. package/docs/{observability.md → architecture/observability.md} +38 -14
  191. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  192. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +57 -20
  193. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +99 -25
  194. package/docs/{safety-model.md → architecture/safety-model.md} +35 -20
  195. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  196. package/docs/architecture/time-conventions.md +125 -0
  197. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  198. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  199. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  200. package/docs/{built-in-agents.md → guide/built-in-agents.md} +65 -35
  201. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +66 -61
  202. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +323 -297
  203. package/docs/guide/configuration-reference.md +1163 -0
  204. package/docs/{environment-variables.md → guide/environment-variables.md} +33 -28
  205. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  206. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  207. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  208. package/docs/{glossary.md → guide/glossary.md} +14 -11
  209. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +81 -17
  210. package/docs/guide/panes-and-files.md +290 -0
  211. package/docs/{proactive-memory.md → guide/proactive-memory.md} +131 -107
  212. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  213. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +25 -3
  214. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  215. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  216. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  217. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  218. package/docs/process/development-pipeline.md +152 -0
  219. package/docs/process/documentation-coverage.md +100 -0
  220. package/docs/process/documentation-guide.md +187 -0
  221. package/docs/{eval-runner.md → process/eval-runner.md} +108 -53
  222. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  223. package/docs/{evolution.md → process/evolution.md} +2 -2
  224. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  225. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  226. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  227. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  228. package/evals/README.md +2 -2
  229. package/evals/behavioral-model.yaml +3 -2
  230. package/package.json +10 -8
  231. package/skills/README.md +52 -41
  232. package/skills/coding/ast-grep/SKILL.md +102 -31
  233. package/skills/coding/ast-grep/evals.md +26 -0
  234. package/skills/coding/coding-standards/SKILL.md +41 -6
  235. package/skills/coding/coding-standards/evals.md +23 -0
  236. package/skills/coding/prototype/SKILL.md +88 -29
  237. package/skills/coding/prototype/evals.md +19 -0
  238. package/skills/coding/tdd/SKILL.md +81 -54
  239. package/skills/coding/tdd/evals.md +20 -0
  240. package/skills/context/context-handoff/SKILL.md +44 -3
  241. package/skills/context/context-handoff/evals.md +44 -0
  242. package/skills/context/context-prime/SKILL.md +46 -16
  243. package/skills/context/context-prime/evals.md +45 -0
  244. package/skills/git/branch-closeout/SKILL.md +132 -0
  245. package/skills/git/branch-closeout/evals.md +133 -0
  246. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  247. package/skills/git/file-ticket/SKILL.md +78 -64
  248. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  249. package/skills/git/file-ticket/evals.md +31 -26
  250. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  251. package/skills/git/fix-issue/SKILL.md +88 -65
  252. package/skills/git/fix-issue/evals.md +35 -31
  253. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  254. package/skills/git/resolve-merge-conflicts/SKILL.md +101 -52
  255. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  256. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  257. package/skills/git/ship/SKILL.md +103 -67
  258. package/skills/git/ship/assets/pr-template.md +21 -0
  259. package/skills/git/ship/evals.md +44 -28
  260. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  261. package/skills/git/worktree-create/SKILL.md +80 -50
  262. package/skills/git/worktree-create/evals.md +40 -33
  263. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  264. package/skills/git/worktree-merge/SKILL.md +112 -65
  265. package/skills/git/worktree-merge/evals.md +42 -34
  266. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  267. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  268. package/skills/meta/clio-coder-dev/evals.md +3 -2
  269. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  270. package/skills/meta/clio-coder-test/evals.md +9 -4
  271. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  272. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  273. package/skills/meta/credentials/SKILL.md +2 -2
  274. package/skills/meta/find-skills/SKILL.md +2 -2
  275. package/skills/meta/herdr/SKILL.md +2 -2
  276. package/skills/meta/skill-craft/SKILL.md +22 -16
  277. package/skills/planning/archify/SKILL.md +196 -0
  278. package/skills/planning/archify/evals.md +65 -0
  279. package/skills/planning/architecture/SKILL.md +62 -13
  280. package/skills/planning/architecture/evals.md +65 -0
  281. package/skills/planning/backlog/SKILL.md +131 -15
  282. package/skills/planning/backlog/evals.md +142 -0
  283. package/skills/planning/prd/SKILL.md +47 -7
  284. package/skills/planning/prd/evals.md +54 -0
  285. package/skills/planning/product-intent/SKILL.md +58 -3
  286. package/skills/planning/product-intent/evals.md +70 -0
  287. package/skills/planning/tech-spec/SKILL.md +54 -3
  288. package/skills/planning/tech-spec/evals.md +73 -0
  289. package/skills/registry.yaml +70 -62
  290. package/skills/remote.yaml +13 -0
  291. package/skills/research/arxiv-literature/SKILL.md +77 -19
  292. package/skills/research/arxiv-literature/evals.md +50 -0
  293. package/skills/research/experiment-protocol/SKILL.md +21 -2
  294. package/skills/research/experiment-protocol/evals.md +23 -0
  295. package/skills/research/scientific-debugging/SKILL.md +24 -2
  296. package/skills/research/scientific-debugging/evals.md +18 -0
  297. package/skills/research/scientific-modernization/SKILL.md +27 -2
  298. package/skills/research/scientific-modernization/evals.md +27 -0
  299. package/skills/skill-marketplace.json +97 -62
  300. package/skills/workflow/cut-it/SKILL.md +66 -6
  301. package/skills/workflow/cut-it/evals.md +101 -0
  302. package/skills/workflow/design-council/SKILL.md +118 -28
  303. package/skills/workflow/design-council/evals.md +161 -0
  304. package/skills/workflow/grill-me/SKILL.md +87 -11
  305. package/skills/workflow/grill-me/evals.md +153 -0
  306. package/skills/workflow/workflow-distiller/SKILL.md +77 -18
  307. package/skills/workflow/workflow-distiller/evals.md +118 -0
  308. package/src/cli/args.ts +2 -2
  309. package/src/cli/bootstrap-generate.ts +1 -1
  310. package/src/cli/config-inspect.ts +65 -12
  311. package/src/cli/configure-interop.ts +105 -13
  312. package/src/cli/configure-oauth.ts +57 -0
  313. package/src/cli/configure-onboarding.ts +980 -0
  314. package/src/cli/configure-target.ts +594 -0
  315. package/src/cli/configure.ts +1082 -532
  316. package/src/cli/context-map.ts +114 -0
  317. package/src/cli/context.ts +4 -0
  318. package/src/cli/docs.ts +22 -14
  319. package/src/cli/doctor-naming.ts +5 -5
  320. package/src/cli/doctor-toolchain.ts +3 -3
  321. package/src/cli/eval.ts +1 -2
  322. package/src/cli/extensions.ts +2 -1
  323. package/src/cli/fleet.ts +1 -1
  324. package/src/cli/index.ts +3 -1
  325. package/src/cli/internal-dispatch.ts +3 -4
  326. package/src/cli/lifecycle-presenter.ts +436 -0
  327. package/src/cli/models.ts +10 -2
  328. package/src/cli/modes/print.ts +5 -1
  329. package/src/cli/panes.ts +19 -5
  330. package/src/cli/reset.ts +228 -106
  331. package/src/cli/run.ts +9 -4
  332. package/src/cli/select.ts +664 -0
  333. package/src/cli/share.ts +5 -1
  334. package/src/cli/skills-eval.ts +3 -3
  335. package/src/cli/skills.ts +9 -2
  336. package/src/cli/targets.ts +5 -6
  337. package/src/cli/trace.ts +55 -4
  338. package/src/cli/uninstall.ts +233 -165
  339. package/src/cli/upgrade.ts +204 -149
  340. package/src/cli/usage.ts +86 -27
  341. package/src/cli/validate-model.ts +3 -3
  342. package/src/cli/wiki-generate.ts +1 -1
  343. package/src/core/artifact-paths.ts +1 -1
  344. package/src/core/bash-exec.ts +131 -86
  345. package/src/core/bus-events.ts +51 -6
  346. package/src/core/config.ts +61 -1
  347. package/src/core/defaults.ts +7 -4
  348. package/src/core/dispatch-outcome.ts +16 -0
  349. package/src/core/external-diagnostic.ts +44 -0
  350. package/src/core/gateway-routing.ts +157 -0
  351. package/src/core/guardrails.ts +10 -49
  352. package/src/core/prompt-hint.ts +9 -0
  353. package/src/core/safe-exec.ts +17 -2
  354. package/src/core/skill-activation.ts +89 -2
  355. package/src/domains/agents/builtins/architect.md +2 -3
  356. package/src/domains/agents/builtins/coder.md +3 -2
  357. package/src/domains/agents/builtins/debugger.md +2 -2
  358. package/src/domains/agents/builtins/documenter.md +2 -2
  359. package/src/domains/agents/builtins/git-master.md +1 -1
  360. package/src/domains/agents/builtins/oracle.md +1 -1
  361. package/src/domains/agents/builtins/provenance.md +1 -1
  362. package/src/domains/agents/builtins/researcher.md +1 -1
  363. package/src/domains/agents/builtins/scout.md +1 -1
  364. package/src/domains/agents/builtins/tester.md +2 -2
  365. package/src/domains/agents/builtins/verifier.md +2 -2
  366. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  367. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  368. package/src/domains/agents/catalog.ts +13 -15
  369. package/src/domains/agents/contract.ts +2 -0
  370. package/src/domains/agents/extension.ts +23 -1
  371. package/src/domains/agents/result-contract.ts +70 -0
  372. package/src/domains/config/keybindings.ts +8 -0
  373. package/src/domains/context/extension.ts +0 -3
  374. package/src/domains/context/wiki/map-seed.ts +589 -0
  375. package/src/domains/context/wiki/plan.ts +2 -2
  376. package/src/domains/context/working-set/path-index.ts +1 -0
  377. package/src/domains/dispatch/admission.ts +29 -0
  378. package/src/domains/dispatch/agent-candidates.ts +10 -0
  379. package/src/domains/dispatch/budget-envelope.ts +86 -1
  380. package/src/domains/dispatch/capability-match.ts +11 -0
  381. package/src/domains/dispatch/capacity-lease.ts +17 -0
  382. package/src/domains/dispatch/contract.ts +11 -1
  383. package/src/domains/dispatch/extension.ts +237 -49
  384. package/src/domains/dispatch/host-verification.ts +435 -39
  385. package/src/domains/dispatch/intent-requirements.ts +10 -0
  386. package/src/domains/dispatch/intent.ts +18 -1
  387. package/src/domains/dispatch/path-scope.ts +235 -24
  388. package/src/domains/dispatch/run-event-journal.ts +4 -15
  389. package/src/domains/dispatch/state.ts +2 -3
  390. package/src/domains/dispatch/transport.ts +45 -21
  391. package/src/domains/dispatch/types.ts +58 -3
  392. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  393. package/src/domains/eval/artifacts/store.ts +5 -0
  394. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  395. package/src/domains/eval/metrics/token-stream.ts +201 -31
  396. package/src/domains/eval/metrics/tracked.ts +40 -4
  397. package/src/domains/eval/runners/clio-run.ts +5 -2
  398. package/src/domains/eval/schema/suite.ts +28 -0
  399. package/src/domains/eval/schema/verdict.ts +2 -2
  400. package/src/domains/eval/store.ts +8 -1
  401. package/src/domains/eval/suites/resolve.ts +13 -1
  402. package/src/domains/eval/suites/run.ts +24 -3
  403. package/src/domains/evidence/trust-status.ts +10 -1
  404. package/src/domains/extensions/contract.ts +15 -1
  405. package/src/domains/extensions/discovery.ts +238 -41
  406. package/src/domains/extensions/extension.ts +105 -6
  407. package/src/domains/extensions/index.ts +24 -0
  408. package/src/domains/extensions/integrity.ts +189 -0
  409. package/src/domains/extensions/manager.ts +17 -1
  410. package/src/domains/extensions/resource-path.ts +27 -0
  411. package/src/domains/extensions/resources.ts +18 -38
  412. package/src/domains/extensions/snapshot-store.ts +39 -0
  413. package/src/domains/extensions/snapshot.ts +180 -0
  414. package/src/domains/extensions/state.ts +385 -57
  415. package/src/domains/extensions/types.ts +118 -1
  416. package/src/domains/interop/registry.ts +6 -2
  417. package/src/domains/interop/types.ts +4 -0
  418. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  419. package/src/domains/lifecycle/migrations/index.ts +6 -0
  420. package/src/domains/lifecycle/naming-resources.ts +19 -4
  421. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  422. package/src/domains/memory/task-memory-policy.ts +70 -26
  423. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  424. package/src/domains/middleware/contract.ts +26 -0
  425. package/src/domains/middleware/extension.ts +24 -24
  426. package/src/domains/middleware/hook-receipts.ts +27 -4
  427. package/src/domains/middleware/hooks-io.ts +65 -32
  428. package/src/domains/middleware/hooks.ts +64 -0
  429. package/src/domains/middleware/index.ts +28 -5
  430. package/src/domains/middleware/marketplace-offer.ts +3 -35
  431. package/src/domains/middleware/memory-intervention.ts +127 -32
  432. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  433. package/src/domains/middleware/registrations.ts +326 -0
  434. package/src/domains/middleware/runtime.ts +28 -0
  435. package/src/domains/middleware/skills-reminder.ts +31 -2
  436. package/src/domains/middleware/snapshot.ts +20 -7
  437. package/src/domains/mux/contract.ts +38 -0
  438. package/src/domains/mux/detect.ts +6 -13
  439. package/src/domains/mux/index.ts +1 -1
  440. package/src/domains/mux/operations.ts +44 -5
  441. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  442. package/src/domains/mux/yazi/session.ts +53 -4
  443. package/src/domains/mux/yazi/theme.ts +117 -17
  444. package/src/domains/observability/compaction-usage.ts +118 -0
  445. package/src/domains/observability/contract.ts +10 -11
  446. package/src/domains/observability/cost.ts +1 -1
  447. package/src/domains/observability/extension.ts +17 -4
  448. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  449. package/src/domains/observability/projection.ts +14 -90
  450. package/src/domains/observability/trace-store.ts +43 -7
  451. package/src/domains/prompts/compiler.ts +73 -53
  452. package/src/domains/prompts/contract.ts +15 -3
  453. package/src/domains/prompts/extension.ts +97 -9
  454. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  455. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  456. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  457. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  458. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  459. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  460. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  461. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  462. package/src/domains/providers/contract.ts +4 -1
  463. package/src/domains/providers/extension.ts +40 -9
  464. package/src/domains/providers/index.ts +1 -1
  465. package/src/domains/providers/model-capabilities.ts +9 -0
  466. package/src/domains/providers/model-discovery.ts +2 -0
  467. package/src/domains/providers/model-runtime-capabilities.ts +99 -25
  468. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +699 -114
  469. package/src/domains/providers/runtime-resolution.ts +31 -0
  470. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  471. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  472. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  473. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  474. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  475. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  476. package/src/domains/providers/support.ts +11 -5
  477. package/src/domains/providers/target-model-cache.ts +25 -2
  478. package/src/domains/providers/types/capability-flags.ts +2 -0
  479. package/src/domains/providers/types/cost-provenance.ts +19 -0
  480. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  481. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  482. package/src/domains/providers/types/target-descriptor.ts +19 -0
  483. package/src/domains/resources/index.ts +3 -0
  484. package/src/domains/resources/skills/install.ts +72 -7
  485. package/src/domains/resources/skills/loader.ts +23 -19
  486. package/src/domains/resources/skills/marketplace.ts +63 -11
  487. package/src/domains/safety/autonomy.ts +15 -0
  488. package/src/domains/safety/call-target.ts +1 -1
  489. package/src/domains/safety/index.ts +1 -0
  490. package/src/domains/safety/loop-detector.ts +7 -4
  491. package/src/domains/safety/path-policy.ts +1 -1
  492. package/src/domains/safety/policy-engine.ts +34 -11
  493. package/src/domains/safety/protected-artifacts.ts +191 -88
  494. package/src/domains/safety/run-effects.ts +2 -22
  495. package/src/domains/safety/skill-authority.ts +55 -0
  496. package/src/domains/session/compaction/compact.ts +72 -22
  497. package/src/domains/session/entries.ts +6 -0
  498. package/src/domains/session/task-board.ts +10 -9
  499. package/src/domains/session/usage.ts +3 -3
  500. package/src/domains/share/archive.ts +164 -7
  501. package/src/engine/acp/server.ts +62 -9
  502. package/src/engine/agent.ts +13 -3
  503. package/src/engine/ai.ts +26 -8
  504. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  505. package/src/engine/api-registry.ts +3 -0
  506. package/src/engine/apis/llamacpp-residency.ts +3 -4
  507. package/src/engine/apis/lmstudio.ts +3 -3
  508. package/src/engine/apis/ollama-native.ts +6 -6
  509. package/src/engine/apis/openai-completions.ts +145 -39
  510. package/src/engine/apis/output-budget.ts +8 -18
  511. package/src/engine/apis/residency.ts +8 -27
  512. package/src/engine/external-subprocess.ts +114 -6
  513. package/src/engine/gemma-channel-filter.ts +19 -0
  514. package/src/engine/loop-guard.ts +92 -12
  515. package/src/engine/worker-runtime.ts +40 -11
  516. package/src/engine/worker-tools.ts +3 -1
  517. package/src/entry/background-model-metadata.ts +18 -0
  518. package/src/entry/compaction-prompt.ts +57 -0
  519. package/src/entry/extension-hook-sources.ts +28 -0
  520. package/src/entry/extension-reload.ts +309 -0
  521. package/src/entry/orchestrator.ts +464 -251
  522. package/src/entry/task-memory-lifecycle.ts +35 -0
  523. package/src/interactive/application-controller.ts +2 -1
  524. package/src/interactive/bus-notices.ts +8 -1
  525. package/src/interactive/chat-loop-messages.ts +16 -17
  526. package/src/interactive/chat-loop.ts +75 -3
  527. package/src/interactive/chat-panel.ts +36 -13
  528. package/src/interactive/chat-renderer.ts +72 -7
  529. package/src/interactive/cost-overlay.ts +26 -2
  530. package/src/interactive/dispatch-board.ts +6 -11
  531. package/src/interactive/footer/widgets.ts +13 -0
  532. package/src/interactive/interactive-application.ts +39 -4
  533. package/src/interactive/interactive-input-runtime.ts +4 -0
  534. package/src/interactive/interactive-presentation.ts +2 -2
  535. package/src/interactive/interactive-slash-runtime.ts +4 -1
  536. package/src/interactive/overlays/extensions.ts +9 -1
  537. package/src/interactive/overlays/help-reference.ts +13 -0
  538. package/src/interactive/overlays/settings.ts +27 -16
  539. package/src/interactive/panes-runtime.ts +111 -35
  540. package/src/interactive/prompt-cache-identity.ts +88 -0
  541. package/src/interactive/renderers/worker-entry.ts +32 -0
  542. package/src/interactive/slash-commands.ts +153 -20
  543. package/src/interactive/stream-pacing-policy.ts +0 -23
  544. package/src/interactive/theme/labels.ts +19 -13
  545. package/src/interactive/turn-context.ts +39 -20
  546. package/src/interactive/turn-recovery.ts +8 -0
  547. package/src/interactive/turn-runtime.ts +27 -11
  548. package/src/interactive/turn-state.ts +7 -0
  549. package/src/interactive/worker-receipts.ts +1 -0
  550. package/src/interactive/worker-stream.ts +6 -1
  551. package/src/interactive/yazi-bridge.ts +60 -6
  552. package/src/tools/agent-tools.ts +30 -1
  553. package/src/tools/artifact.ts +2 -2
  554. package/src/tools/ask-user.ts +3 -3
  555. package/src/tools/bash.ts +1 -1
  556. package/src/tools/bootstrap.ts +4 -0
  557. package/src/tools/builtin-tool-catalog.ts +52 -22
  558. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  559. package/src/tools/codewiki/code-nav.ts +99 -13
  560. package/src/tools/context/docs-engine.ts +20 -7
  561. package/src/tools/context/index.ts +59 -21
  562. package/src/tools/core-bootstrap.ts +28 -6
  563. package/src/tools/credential-present.ts +1 -2
  564. package/src/tools/dispatch-arguments.ts +6 -1
  565. package/src/tools/dispatch-event-text.ts +10 -0
  566. package/src/tools/dispatch-plan.ts +49 -4
  567. package/src/tools/dispatch-run-events.ts +1 -1
  568. package/src/tools/dispatch-runner.ts +12 -0
  569. package/src/tools/dispatch-schema.ts +338 -0
  570. package/src/tools/dispatch-types.ts +3 -0
  571. package/src/tools/dispatch.ts +9 -254
  572. package/src/tools/ledger.ts +3 -5
  573. package/src/tools/monitor-surface.ts +5 -13
  574. package/src/tools/observation.ts +4 -5
  575. package/src/tools/panes-surface.ts +4 -11
  576. package/src/tools/panes.ts +4 -2
  577. package/src/tools/policy.ts +15 -2
  578. package/src/tools/read.ts +5 -6
  579. package/src/tools/registry.ts +41 -12
  580. package/src/tools/result-shaping.ts +18 -14
  581. package/src/tools/steer-surface.ts +1 -1
  582. package/src/tools/tasks.ts +1 -1
  583. package/src/tools/truncate.ts +6 -5
  584. package/src/tools/verify/surface.ts +6 -12
  585. package/src/tools/web-fetch-surface.ts +1 -3
  586. package/src/tools/worker-evidence.ts +3 -1
  587. package/src/worker/spec-contract.ts +4 -0
  588. package/dist/builtins-UJLMOVOV.js +0 -17
  589. package/dist/chunk-5QIAJV2D.js +0 -48
  590. package/dist/chunk-JZWT5J3Y.js +0 -814
  591. package/dist/chunk-K7VKOLQQ.js +0 -15
  592. package/dist/chunk-PMZCIOCJ.js +0 -25
  593. package/dist/chunk-SUW5DORT.js +0 -819
  594. package/dist/chunk-UOV2BYIW.js +0 -107
  595. package/dist/chunk-WR6U3OVP.js +0 -45
  596. package/dist/chunk-Y45G3AXC.js +0 -1558
  597. package/dist/reset-EOLM7GVE.js +0 -230
  598. package/dist/uninstall-N34PCTGJ.js +0 -331
  599. package/dist/upgrade-H7TOM7YL.js +0 -323
  600. package/docs/artifact-versions.md +0 -67
  601. package/docs/development-pipeline.md +0 -121
  602. package/docs/documentation-coverage.md +0 -46
  603. package/docs/documentation-guide.md +0 -167
  604. package/docs/time-conventions.md +0 -101
@@ -4,11 +4,11 @@
4
4
  * This is a separate runtime from `openai-compat` rather than a target flag on
5
5
  * it, because a gateway answers two questions the generic protocol cannot.
6
6
  *
7
- * First, capability discovery. A gateway publishes semantic aliases: the client
8
- * asks for `code` and the proxy decides that means `katcoder2.5-35b-moe` on one
9
- * particular host. LiteLLM's `/v1/models` is the plain OpenAI listing, so every
10
- * row flattens to a bare id and the context window, tool support, and modality
11
- * of the model actually behind the alias are all erased. Reached over
7
+ * First, capability discovery. A gateway may publish aliases or truthful
8
+ * physical names such as `dynamo/qwen3.8-27b`. LiteLLM's `/v1/models` is the
9
+ * plain OpenAI listing, so every row flattens to a bare id and the context
10
+ * window, tool support, and modality of the model behind it are all erased.
11
+ * Reached over
12
12
  * `openai-compat`, a 262k tool-calling coder is indistinguishable from a 4k
13
13
  * chat toy, and Clio plans the session against its own assumed floor. LiteLLM
14
14
  * publishes the real numbers on `/v1/model/info` instead, which is what this
@@ -26,7 +26,8 @@
26
26
  * and rejected HTTP 400 by LM Studio, and the same prompt with no
27
27
  * `response_format` returned plain prose. `drop_params: true` did not strip
28
28
  * either spelling. The standard `json_schema` dialect is therefore the one that
29
- * holds across every upstream, and it is what this runtime declares.
29
+ * holds across every measured upstream, and a gateway must publish that fact
30
+ * explicitly per route in `model_info` before Clio relies on it.
30
31
  */
31
32
 
32
33
  import { CLIO_MIN_CONTEXT_WINDOW, CLIO_MIN_MAX_OUTPUT_TOKENS } from "../../../../core/context-floor.js";
@@ -55,7 +56,7 @@ const defaultCapabilities: CapabilityFlags = {
55
56
  embeddings: false,
56
57
  rerank: false,
57
58
  fim: false,
58
- structuredOutputs: "json-schema",
59
+ structuredOutputs: "none",
59
60
  contextWindow: CLIO_MIN_CONTEXT_WINDOW,
60
61
  maxTokens: CLIO_MIN_MAX_OUTPUT_TOKENS,
61
62
  };
@@ -106,8 +107,11 @@ function boolean(value: unknown): boolean | undefined {
106
107
  * so the caller can tell "the gateway says this model has no vision" apart from
107
108
  * "the gateway did not say", and merge accordingly.
108
109
  */
109
- function capabilitiesFromLiteLLMModelInfo(info: Record<string, unknown>): Partial<CapabilityFlags> {
110
+ export function capabilitiesFromLiteLLMModelInfo(info: Record<string, unknown>): Partial<CapabilityFlags> {
110
111
  const caps: Partial<CapabilityFlags> = {};
112
+ // This is a deployment declaration, never inferred from a URL, port or alias.
113
+ if (info.runtime === "lm-studio") caps.thinkingControlRuntime = "lmstudio";
114
+ else if (info.runtime === "llama.cpp") caps.thinkingControlRuntime = "llamacpp";
111
115
  const contextWindow = positiveInteger(info.max_input_tokens) ?? positiveInteger(info.max_tokens);
112
116
  if (contextWindow !== undefined) caps.contextWindow = contextWindow;
113
117
  const maxTokens = positiveInteger(info.max_output_tokens);
@@ -132,20 +136,77 @@ function capabilitiesFromLiteLLMModelInfo(info: Record<string, unknown>): Partia
132
136
  caps.rerank = true;
133
137
  }
134
138
  if (info.mode === "chat") caps.chat = true;
135
- // Measured, not inferred: see the module header.
136
- if (boolean(info.supports_response_schema) === true) caps.structuredOutputs = "json-schema";
139
+ // Measured, not inferred: see the module header. An explicit false must
140
+ // override this runtime's measured default for an upstream that cannot
141
+ // preserve the schema contract.
142
+ const responseSchema = boolean(info.supports_response_schema);
143
+ if (responseSchema !== undefined) caps.structuredOutputs = responseSchema ? "json-schema" : "none";
137
144
  return caps;
138
145
  }
139
146
 
147
+ const BOOLEAN_CAPABILITIES = [
148
+ "chat",
149
+ "tools",
150
+ "reasoning",
151
+ "vision",
152
+ "audio",
153
+ "embeddings",
154
+ "rerank",
155
+ "fim",
156
+ ] as const satisfies ReadonlyArray<keyof CapabilityFlags>;
157
+
158
+ /**
159
+ * One alias may load-balance across heterogeneous deployments. Clio can only
160
+ * promise what every possible route supports: numerical limits take the
161
+ * smallest fully-published value, booleans require unanimous publication, and
162
+ * one explicit false defeats a true. Missing data never becomes a capability.
163
+ */
164
+ export function aggregateLiteLLMCapabilities(rows: ReadonlyArray<Partial<CapabilityFlags>>): Partial<CapabilityFlags> {
165
+ if (rows.length === 0) return {};
166
+ const aggregate: Partial<CapabilityFlags> = {};
167
+ for (const key of ["contextWindow", "maxTokens"] as const) {
168
+ const values = rows.map((row) => row[key]);
169
+ if (values.every((value): value is number => typeof value === "number")) {
170
+ aggregate[key] = Math.min(...values);
171
+ }
172
+ }
173
+ for (const key of BOOLEAN_CAPABILITIES) {
174
+ const values = rows.map((row) => row[key]);
175
+ if (values.some((value) => value === false)) aggregate[key] = false;
176
+ else if (values.every((value) => value === true)) aggregate[key] = true;
177
+ }
178
+ const controlRuntime = rows[0]?.thinkingControlRuntime;
179
+ if (controlRuntime !== undefined && rows.every((row) => row.thinkingControlRuntime === controlRuntime)) {
180
+ aggregate.thinkingControlRuntime = controlRuntime;
181
+ }
182
+ const structuredOutputs = rows.map((row) => row.structuredOutputs);
183
+ if (structuredOutputs.some((value) => value === "none")) aggregate.structuredOutputs = "none";
184
+ else if (structuredOutputs.every((value) => value === "json-schema")) aggregate.structuredOutputs = "json-schema";
185
+ return aggregate;
186
+ }
187
+
140
188
  interface LiteLLMCatalog {
141
189
  models: string[];
142
190
  modelCapabilities: Record<string, Partial<CapabilityFlags>>;
143
191
  modelStates: Record<string, ProbeModelStatus>;
144
192
  /** Physical deployment behind each alias, for display. */
145
- deployments: Record<string, { model: string; apiBase?: string }>;
193
+ deployments: Record<string, Array<{ model: string; apiBase?: string }>>;
194
+ /** Whether the empty catalog is specifically because the gateway rejected the key. */
195
+ authFailed: boolean;
146
196
  }
147
197
 
148
- const EMPTY_CATALOG: LiteLLMCatalog = { models: [], modelCapabilities: {}, modelStates: {}, deployments: {} };
198
+ const EMPTY_CATALOG: LiteLLMCatalog = {
199
+ models: [],
200
+ modelCapabilities: {},
201
+ modelStates: {},
202
+ deployments: {},
203
+ authFailed: false,
204
+ };
205
+
206
+ /** Whether a failed probe leg failed specifically on the credential, not on reachability. */
207
+ function isAuthError(leg: { ok: boolean; error?: string }): boolean {
208
+ return !leg.ok && /^HTTP 40[13]\b/u.test(leg.error ?? "");
209
+ }
149
210
 
150
211
  /**
151
212
  * Read the catalog from `/v1/model/info`, falling back to `/v1/models`.
@@ -163,37 +224,50 @@ async function fetchCatalog(base: string, ctx: ProbeContext, headers: Record<str
163
224
  : probeJson<LiteLLMModelInfoResponse>(detailOpts));
164
225
 
165
226
  if (detail.ok && Array.isArray(detail.data?.data)) {
166
- const catalog: LiteLLMCatalog = { models: [], modelCapabilities: {}, modelStates: {}, deployments: {} };
227
+ const catalog: LiteLLMCatalog = {
228
+ models: [],
229
+ modelCapabilities: {},
230
+ modelStates: {},
231
+ deployments: {},
232
+ authFailed: false,
233
+ };
234
+ const capabilityRows: Record<string, Array<Partial<CapabilityFlags>>> = {};
167
235
  for (const row of detail.data.data) {
168
236
  if (typeof row?.model_name !== "string" || row.model_name.length === 0) continue;
169
237
  const alias = row.model_name;
170
- // One alias can carry several deployments. They share a name and Clio
171
- // addresses them as one model, so the first row establishes the entry
172
- // and later rows for the same alias are the load-balancing pool behind
173
- // it rather than separate models.
174
- if (catalog.deployments[alias] !== undefined) continue;
175
- catalog.models.push(alias);
238
+ if (catalog.deployments[alias] === undefined) {
239
+ catalog.models.push(alias);
240
+ catalog.deployments[alias] = [];
241
+ capabilityRows[alias] = [];
242
+ }
176
243
  const caps = row.model_info ? capabilitiesFromLiteLLMModelInfo(row.model_info) : {};
177
- if (Object.keys(caps).length > 0) catalog.modelCapabilities[alias] = caps;
244
+ capabilityRows[alias]?.push(caps);
178
245
  const upstream = row.litellm_params?.model;
179
246
  const apiBase = row.litellm_params?.api_base;
180
- catalog.deployments[alias] = {
247
+ catalog.deployments[alias]?.push({
181
248
  model: typeof upstream === "string" ? upstream : alias,
182
249
  ...(typeof apiBase === "string" ? { apiBase } : {}),
183
- };
250
+ });
251
+ }
252
+ for (const alias of catalog.models) {
253
+ const caps = aggregateLiteLLMCapabilities(capabilityRows[alias] ?? []);
254
+ if (Object.keys(caps).length > 0) catalog.modelCapabilities[alias] = caps;
184
255
  }
185
256
  if (catalog.models.length > 0) return catalog;
186
257
  }
258
+ const detailAuthFailed = isAuthError(detail);
187
259
 
188
260
  const listOpts = { url: `${base}/v1/models`, timeoutMs: ctx.httpTimeoutMs, headers } as const;
189
261
  const list = await (ctx.signal
190
262
  ? probeJson<LiteLLMModelsResponse>({ ...listOpts, signal: ctx.signal })
191
263
  : probeJson<LiteLLMModelsResponse>(listOpts));
192
- if (!list.ok || !Array.isArray(list.data?.data)) return EMPTY_CATALOG;
264
+ if (!list.ok || !Array.isArray(list.data?.data)) {
265
+ return { ...EMPTY_CATALOG, authFailed: detailAuthFailed || isAuthError(list) };
266
+ }
193
267
  const models = list.data.data
194
268
  .map((row) => (typeof row?.id === "string" ? row.id : null))
195
269
  .filter((id): id is string => id !== null && id.length > 0);
196
- return { models, modelCapabilities: {}, modelStates: {}, deployments: {} };
270
+ return { models, modelCapabilities: {}, modelStates: {}, deployments: {}, authFailed: false };
197
271
  }
198
272
 
199
273
  const litellmRuntime: RuntimeDescriptor = {
@@ -226,8 +300,11 @@ const litellmRuntime: RuntimeDescriptor = {
226
300
  if (catalog.models.length === 0) {
227
301
  const result: ProbeResult = {
228
302
  ok: false,
229
- error: "gateway is live but served no model catalog; check the target's API key",
303
+ error: catalog.authFailed
304
+ ? "gateway rejected the key"
305
+ : "gateway is live but served no model catalog; check the target's API key",
230
306
  };
307
+ if (catalog.authFailed) result.authFailed = true;
231
308
  if (live.latencyMs !== undefined) result.latencyMs = live.latencyMs;
232
309
  return result;
233
310
  }
@@ -248,10 +325,23 @@ const litellmRuntime: RuntimeDescriptor = {
248
325
  if (configured && !catalog.models.includes(configured)) {
249
326
  notes.push(`configured model '${configured}' is not in the gateway catalog`);
250
327
  }
251
- // Naming the physical model behind each alias is the difference between a
252
- // catalog an operator can audit and a list of words.
253
- const routed = Object.entries(catalog.deployments)
254
- .map(([alias, deployment]) => `${alias}=${deployment.model}`)
328
+ // A node/model catalog already names placement. Summarize those one-to-one
329
+ // routes instead of flooding target diagnostics with dozens of tautologies;
330
+ // retain the explicit mapping for genuine aliases and multi-deployments.
331
+ const routeEntries = Object.entries(catalog.deployments);
332
+ const physical = routeEntries.filter(([alias, deployments]) => {
333
+ const slash = alias.indexOf("/");
334
+ if (slash <= 0 || deployments.length !== 1) return false;
335
+ const upstream = deployments[0]?.model.replace(/^openai\//u, "");
336
+ return upstream === alias.slice(slash + 1);
337
+ });
338
+ if (physical.length > 0) notes.push(`physical routes: ${physical.length} node/model names map one-to-one`);
339
+ const routed = routeEntries
340
+ .filter(([alias]) => !physical.some(([physicalAlias]) => physicalAlias === alias))
341
+ .map(([alias, deployments]) => {
342
+ const models = [...new Set(deployments.map((deployment) => deployment.model))];
343
+ return `${alias}=${models.join("|")}`;
344
+ })
255
345
  .sort();
256
346
  if (routed.length > 0) notes.push(`routes: ${routed.join(", ")}`);
257
347
  if (notes.length > 0) result.notes = notes;
@@ -5,7 +5,7 @@ import { getRuntimeRegistry } from "./registry.js";
5
5
  import type { RuntimeDescriptor } from "./types/runtime-descriptor.js";
6
6
  import type { TargetDescriptor } from "./types/target-descriptor.js";
7
7
 
8
- export type ProviderSupportGroup = "featured" | "cloud-api" | "subscription" | "local-http";
8
+ export type ProviderSupportGroup = "featured" | "external-worker" | "cloud-api" | "subscription" | "local-http";
9
9
 
10
10
  /**
11
11
  * Where a runtime's model ids come from, which decides whether their order
@@ -44,6 +44,7 @@ const SUMMARY_BY_RUNTIME_ID: Readonly<Record<string, string>> = {
44
44
  alcf: "ALCF inference gateway (Sophia/Metis) via Globus",
45
45
  anthropic: "Anthropic API",
46
46
  "anthropic-max": "Claude Pro/Max subscription via Anthropic OAuth",
47
+ "antigravity-code": "Experimental local delegation via the installed Antigravity CLI",
47
48
  bedrock: "Amazon Bedrock",
48
49
  "claude-code": "Claude Code subscription via installed claude CLI",
49
50
  "claude-sdk": "Claude Code subscription via Claude Agent SDK",
@@ -59,19 +60,21 @@ const SUMMARY_BY_RUNTIME_ID: Readonly<Record<string, string>> = {
59
60
  llamacpp: "llama.cpp server (auto-detect surface)",
60
61
  "anthropic-compat": "Generic Anthropic-compatible REST",
61
62
  "openai-compat": "Generic OpenAI-compatible REST",
62
- litellm: "LiteLLM gateway with per-alias capability discovery and routed-model attribution",
63
+ litellm: "LiteLLM gateway with per-route capability discovery and physical-model attribution",
63
64
  };
64
65
 
65
66
  function groupPriority(group: ProviderSupportGroup): number {
66
67
  switch (group) {
67
68
  case "featured":
68
69
  return 0;
69
- case "subscription":
70
+ case "external-worker":
70
71
  return 1;
71
- case "cloud-api":
72
+ case "subscription":
72
73
  return 2;
73
- case "local-http":
74
+ case "cloud-api":
74
75
  return 3;
76
+ case "local-http":
77
+ return 4;
75
78
  }
76
79
  }
77
80
 
@@ -79,6 +82,8 @@ export function supportGroupLabel(group: ProviderSupportGroup): string {
79
82
  switch (group) {
80
83
  case "featured":
81
84
  return "Featured";
85
+ case "external-worker":
86
+ return "External delegation";
82
87
  case "subscription":
83
88
  return "Subscriptions";
84
89
  case "cloud-api":
@@ -90,6 +95,7 @@ export function supportGroupLabel(group: ProviderSupportGroup): string {
90
95
 
91
96
  function classifyGroup(runtime: RuntimeDescriptor): ProviderSupportGroup {
92
97
  if (runtime.id === "openai-codex") return "featured";
98
+ if (runtime.externalAgentLoop !== undefined) return "external-worker";
93
99
  if (runtime.id === "alcf") return "cloud-api";
94
100
  if (runtime.auth === "oauth" || runtime.auth === "claude-cli") return "subscription";
95
101
  if (catalogProviderForRuntime(runtime.id) || (runtime.auth === "api-key" && !runtime.probe)) {
@@ -25,6 +25,7 @@ export interface TargetModelSnapshot {
25
25
  runtimeId: string;
26
26
  url: string | null;
27
27
  models: string[];
28
+ modelLabels?: Record<string, string>;
28
29
  observedAt: string;
29
30
  }
30
31
 
@@ -32,6 +33,7 @@ interface TargetModelCacheOptions {
32
33
  cacheDir?: string;
33
34
  nowMs?: number;
34
35
  ttlMs?: number;
36
+ modelLabels?: Readonly<Record<string, string>>;
35
37
  }
36
38
 
37
39
  function targetCacheKey(targetId: string): string {
@@ -55,6 +57,22 @@ function normalizedModels(models: ReadonlyArray<string>): string[] {
55
57
  return out;
56
58
  }
57
59
 
60
+ function normalizedLabels(models: ReadonlyArray<string>, labels: unknown): Record<string, string> | undefined {
61
+ if (typeof labels !== "object" || labels === null || Array.isArray(labels)) return undefined;
62
+ const source = labels as Record<string, unknown>;
63
+ const out: Record<string, string> = {};
64
+ for (const id of models) {
65
+ const label = source[id];
66
+ if (typeof label !== "string") continue;
67
+ const trimmed = label.trim();
68
+ if (trimmed.length === 0 || trimmed.length > TARGET_MODEL_CACHE_MAX_MODEL_ID_CHARS || /[\r\n\0]/u.test(trimmed)) {
69
+ continue;
70
+ }
71
+ out[id] = trimmed;
72
+ }
73
+ return Object.keys(out).length > 0 ? out : undefined;
74
+ }
75
+
58
76
  function parseSnapshot(value: unknown): TargetModelSnapshot | null {
59
77
  if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
60
78
  const row = value as Partial<TargetModelSnapshot>;
@@ -66,7 +84,7 @@ function parseSnapshot(value: unknown): TargetModelSnapshot | null {
66
84
  if (typeof row.observedAt !== "string" || !Number.isFinite(Date.parse(row.observedAt))) return null;
67
85
  const models = normalizedModels(row.models);
68
86
  if (models.length !== row.models.length) return null;
69
- return {
87
+ const snapshot: TargetModelSnapshot = {
70
88
  version: TARGET_MODEL_CACHE_VERSION,
71
89
  targetId: row.targetId,
72
90
  runtimeId: row.runtimeId,
@@ -74,6 +92,9 @@ function parseSnapshot(value: unknown): TargetModelSnapshot | null {
74
92
  models,
75
93
  observedAt: row.observedAt,
76
94
  };
95
+ const modelLabels = normalizedLabels(models, row.modelLabels);
96
+ if (modelLabels !== undefined) snapshot.modelLabels = modelLabels;
97
+ return snapshot;
77
98
  }
78
99
 
79
100
  /** Read a fresh snapshot only when it still describes this target identity. */
@@ -102,7 +123,7 @@ export function readTargetModelSnapshot(
102
123
  export function recordTargetModelSnapshot(
103
124
  target: Pick<TargetDescriptor, "id" | "runtime" | "url">,
104
125
  models: ReadonlyArray<string>,
105
- options: Pick<TargetModelCacheOptions, "cacheDir" | "nowMs"> = {},
126
+ options: Pick<TargetModelCacheOptions, "cacheDir" | "nowMs" | "modelLabels"> = {},
106
127
  ): boolean {
107
128
  if (target.id.length === 0 || target.runtime.length === 0) return false;
108
129
  const snapshot: TargetModelSnapshot = {
@@ -113,6 +134,8 @@ export function recordTargetModelSnapshot(
113
134
  models: normalizedModels(models),
114
135
  observedAt: new Date(options.nowMs ?? Date.now()).toISOString(),
115
136
  };
137
+ const modelLabels = normalizedLabels(snapshot.models, options.modelLabels);
138
+ if (modelLabels !== undefined) snapshot.modelLabels = modelLabels;
116
139
  try {
117
140
  safeResourceWrite(targetModelSnapshotPath(target.id, options.cacheDir), `${JSON.stringify(snapshot, null, 2)}\n`, {
118
141
  encoding: "utf8",
@@ -20,6 +20,8 @@ export interface CapabilityFlags {
20
20
  toolCallFormat?: ToolCallFormat;
21
21
  reasoning: boolean;
22
22
  thinkingFormat?: ThinkingFormat;
23
+ /** Probe-declared upstream control dialect only; never changes gateway routing or residency. */
24
+ thinkingControlRuntime?: "lmstudio" | "llamacpp";
23
25
  structuredOutputs?: StructuredOutputMode;
24
26
  vision: boolean;
25
27
  audio: boolean;
@@ -5,3 +5,22 @@ export type CostProvenance = "known" | "known_free" | "estimated" | "unknown";
5
5
  export function normalizeCostProvenance(value: CostProvenance | undefined): CostProvenance {
6
6
  return value ?? "unknown";
7
7
  }
8
+
9
+ const COST_PROVENANCE_VALUES: ReadonlySet<string> = new Set<CostProvenance>([
10
+ "known",
11
+ "known_free",
12
+ "estimated",
13
+ "unknown",
14
+ ]);
15
+
16
+ /**
17
+ * Validate an unvalidated wire value (a dispatch bus payload crossing a
18
+ * worker process boundary, never runtime-checked against this closed set
19
+ * before) against the four real provenance values. An unrecognized value
20
+ * keeps `fallback` rather than being accepted as-is, matching how the
21
+ * observability projection's run summary already treated this field; the
22
+ * interactive dispatch board previously accepted any truthy string here.
23
+ */
24
+ export function resolveCostProvenance(value: unknown, fallback: CostProvenance): CostProvenance {
25
+ return typeof value === "string" && COST_PROVENANCE_VALUES.has(value) ? (value as CostProvenance) : fallback;
26
+ }
@@ -2,7 +2,7 @@
2
2
  * Engine-visible quirks extracted from a knowledge-base entry. The catalog YAML
3
3
  * keeps free-form `quirks` (gpu tiers, runtime preferences, serving notes), so
4
4
  * `KnowledgeBaseEntry.quirks` stays `Record<string, unknown>`. This module
5
- * narrows the slice the engine consumes (KV cache layout, per-mode sampling)
5
+ * narrows the slice the engine consumes (per-mode sampling and thinking)
6
6
  * into a typed shape that flows through `model.clioCoder.quirks` at synth time.
7
7
  *
8
8
  * Field naming follows the Hugging Face / model-card terminology so the YAML
@@ -13,19 +13,7 @@
13
13
  */
14
14
 
15
15
  import type { ThinkingBudgetByLevel, ThinkingEffortByLevel } from "../thinking-control-policy.js";
16
-
17
- export const KV_CACHE_QUANTS = ["f32", "f16", "q8_0", "q4_0", "q4_1", "iq4_nl", "q5_0", "q5_1"] as const;
18
-
19
- export type KvCacheQuant = (typeof KV_CACHE_QUANTS)[number];
20
-
21
- export interface KvCacheQuirks {
22
- /** Quantization type for the key cache. `false` disables quantization (full precision). */
23
- kQuant?: KvCacheQuant | false;
24
- /** Quantization type for the value cache. Requires flash attention to take effect. */
25
- vQuant?: KvCacheQuant | false;
26
- /** Force fp16 KV cache regardless of K/V quant settings. */
27
- useFp16?: boolean;
28
- }
16
+ import { type ThinkingLevel, VALID_THINKING_LEVELS } from "./capability-flags.js";
29
17
 
30
18
  export interface SamplingProfile {
31
19
  temperature?: number;
@@ -36,7 +24,6 @@ export interface SamplingProfile {
36
24
  repeatPenalty?: number;
37
25
  presencePenalty?: number;
38
26
  frequencyPenalty?: number;
39
- maxTokens?: number;
40
27
  }
41
28
 
42
29
  export interface SamplingQuirks {
@@ -59,6 +46,20 @@ export interface SamplingQuirks {
59
46
  */
60
47
  export type ThinkingMechanism = "effort-levels" | "budget-tokens" | "on-off" | "always-on" | "none";
61
48
 
49
+ export type ChatTemplateKwargValue = string | number | boolean;
50
+
51
+ export interface ChatTemplateKwargsByLevel {
52
+ key: string;
53
+ values: Partial<Record<ThinkingLevel, string | number>>;
54
+ lmstudio?: "unsupported" | string;
55
+ }
56
+
57
+ export interface ChatTemplateKwargsQuirks {
58
+ static?: Record<string, ChatTemplateKwargValue>;
59
+ byLevel?: ChatTemplateKwargsByLevel;
60
+ lmstudio?: "unsupported" | string | Record<string, string>;
61
+ }
62
+
62
63
  export interface ThinkingQuirks {
63
64
  mechanism: ThinkingMechanism;
64
65
  /** Token budget for budget-tokens mechanism, keyed by Clio's thinking level. */
@@ -67,24 +68,19 @@ export interface ThinkingQuirks {
67
68
  effortByLevel?: ThinkingEffortByLevel;
68
69
  /** 2-5 line free-text guidance rendered into the Runtime prompt block. */
69
70
  guidance?: string;
71
+ chatTemplateKwargs?: ChatTemplateKwargsQuirks;
70
72
  }
71
73
 
72
74
  export interface LocalModelQuirks {
73
- kvCache?: KvCacheQuirks;
74
75
  sampling?: SamplingQuirks;
75
76
  thinking?: ThinkingQuirks;
77
+ chatTemplateKwargs?: ChatTemplateKwargsQuirks;
76
78
  }
77
79
 
78
80
  function isRecord(value: unknown): value is Record<string, unknown> {
79
81
  return value !== null && typeof value === "object" && !Array.isArray(value);
80
82
  }
81
83
 
82
- function asKvCacheQuant(value: unknown): KvCacheQuant | false | undefined {
83
- if (value === false) return false;
84
- if (typeof value !== "string") return undefined;
85
- return (KV_CACHE_QUANTS as ReadonlyArray<string>).includes(value) ? (value as KvCacheQuant) : undefined;
86
- }
87
-
88
84
  function asPositive(value: unknown): number | undefined {
89
85
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
90
86
  }
@@ -98,17 +94,6 @@ function asPenalty(value: unknown): number | undefined {
98
94
  return typeof value === "number" && Number.isFinite(value) ? value : undefined;
99
95
  }
100
96
 
101
- function extractKvCache(raw: unknown): KvCacheQuirks | undefined {
102
- if (!isRecord(raw)) return undefined;
103
- const out: KvCacheQuirks = {};
104
- const k = asKvCacheQuant(raw.kQuant);
105
- if (k !== undefined) out.kQuant = k;
106
- const v = asKvCacheQuant(raw.vQuant);
107
- if (v !== undefined) out.vQuant = v;
108
- if (typeof raw.useFp16 === "boolean") out.useFp16 = raw.useFp16;
109
- return Object.keys(out).length > 0 ? out : undefined;
110
- }
111
-
112
97
  function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
113
98
  if (!isRecord(raw)) return undefined;
114
99
  const out: SamplingProfile = {};
@@ -129,8 +114,6 @@ function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
129
114
  if (pp !== undefined) out.presencePenalty = pp;
130
115
  const fp = asPenalty(raw.frequencyPenalty);
131
116
  if (fp !== undefined) out.frequencyPenalty = fp;
132
- const maxTokens = asInteger(raw.maxTokens);
133
- if (maxTokens !== undefined) out.maxTokens = maxTokens;
134
117
  return Object.keys(out).length > 0 ? out : undefined;
135
118
  }
136
119
 
@@ -185,6 +168,66 @@ function extractEffortByLevel(raw: unknown): ThinkingQuirks["effortByLevel"] | u
185
168
  return Object.keys(out).length > 0 ? out : undefined;
186
169
  }
187
170
 
171
+ function extractChatTemplateKwargs(raw: unknown): ChatTemplateKwargsQuirks | undefined {
172
+ if (!isRecord(raw)) return undefined;
173
+ const out: ChatTemplateKwargsQuirks = {};
174
+
175
+ if (isRecord(raw.static)) {
176
+ const staticMap: Record<string, ChatTemplateKwargValue> = {};
177
+ for (const [k, v] of Object.entries(raw.static)) {
178
+ if (typeof v === "boolean") {
179
+ staticMap[k] = v;
180
+ } else if (typeof v === "number" && Number.isFinite(v)) {
181
+ staticMap[k] = v;
182
+ } else if (typeof v === "string" && v.length > 0) {
183
+ staticMap[k] = v;
184
+ }
185
+ }
186
+ if (Object.keys(staticMap).length > 0) out.static = staticMap;
187
+ }
188
+
189
+ if (isRecord(raw.byLevel)) {
190
+ const byLevelRaw = raw.byLevel;
191
+ if (typeof byLevelRaw.key === "string" && byLevelRaw.key.trim().length > 0 && isRecord(byLevelRaw.values)) {
192
+ const values: Partial<Record<ThinkingLevel, string | number>> = {};
193
+ for (const level of VALID_THINKING_LEVELS) {
194
+ const val = byLevelRaw.values[level];
195
+ if (typeof val === "string" && val.length > 0) {
196
+ values[level] = val;
197
+ } else if (typeof val === "number" && Number.isFinite(val)) {
198
+ values[level] = val;
199
+ }
200
+ }
201
+ if (Object.keys(values).length > 0) {
202
+ const byLevel: ChatTemplateKwargsByLevel = {
203
+ key: byLevelRaw.key.trim(),
204
+ values,
205
+ };
206
+ if (typeof byLevelRaw.lmstudio === "string" && byLevelRaw.lmstudio.trim().length > 0) {
207
+ byLevel.lmstudio = byLevelRaw.lmstudio.trim();
208
+ }
209
+ out.byLevel = byLevel;
210
+ }
211
+ }
212
+ }
213
+
214
+ if (typeof raw.lmstudio === "string" && raw.lmstudio.trim().length > 0) {
215
+ out.lmstudio = raw.lmstudio.trim();
216
+ } else if (isRecord(raw.lmstudio)) {
217
+ const lmstudioMap: Record<string, string> = {};
218
+ for (const [k, v] of Object.entries(raw.lmstudio)) {
219
+ if (typeof v === "string" && v.trim().length > 0) {
220
+ lmstudioMap[k] = v.trim();
221
+ }
222
+ }
223
+ if (Object.keys(lmstudioMap).length > 0) {
224
+ out.lmstudio = lmstudioMap;
225
+ }
226
+ }
227
+
228
+ return Object.keys(out).length > 0 ? out : undefined;
229
+ }
230
+
188
231
  function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
189
232
  if (!isRecord(raw)) return undefined;
190
233
  const mechanism = asThinkingMechanism(raw.mechanism);
@@ -195,6 +238,8 @@ function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
195
238
  const effortByLevel = extractEffortByLevel(raw.effortByLevel);
196
239
  if (effortByLevel) out.effortByLevel = effortByLevel;
197
240
  if (typeof raw.guidance === "string" && raw.guidance.length > 0) out.guidance = raw.guidance;
241
+ const chatTemplateKwargs = extractChatTemplateKwargs(raw.chatTemplateKwargs);
242
+ if (chatTemplateKwargs) out.chatTemplateKwargs = chatTemplateKwargs;
198
243
  return out;
199
244
  }
200
245
 
@@ -206,11 +251,14 @@ function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
206
251
  export function extractLocalModelQuirks(raw: unknown): LocalModelQuirks | undefined {
207
252
  if (!isRecord(raw)) return undefined;
208
253
  const out: LocalModelQuirks = {};
209
- const kvCache = extractKvCache(raw.kvCache);
210
- if (kvCache) out.kvCache = kvCache;
211
254
  const sampling = extractSampling(raw.sampling);
212
255
  if (sampling) out.sampling = sampling;
213
256
  const thinking = extractThinkingQuirks(raw.thinking);
214
257
  if (thinking) out.thinking = thinking;
258
+ const chatTemplateKwargs =
259
+ extractChatTemplateKwargs(raw.chatTemplateKwargs) ??
260
+ extractChatTemplateKwargs(isRecord(raw.thinking) ? raw.thinking.chatTemplateKwargs : undefined) ??
261
+ extractChatTemplateKwargs(isRecord(raw.request) ? raw.request.chatTemplateKwargs : undefined);
262
+ if (chatTemplateKwargs) out.chatTemplateKwargs = chatTemplateKwargs;
215
263
  return Object.keys(out).length > 0 ? out : undefined;
216
264
  }
@@ -22,7 +22,8 @@ export type RuntimeApiFamily =
22
22
  | "rerank-http"
23
23
  | "embeddings-http"
24
24
  | "claude-agent-sdk"
25
- | "claude-code-subprocess";
25
+ | "claude-code-subprocess"
26
+ | "external-agent-subprocess";
26
27
 
27
28
  export type RuntimeAuth = "api-key" | "oauth" | "aws-sdk" | "vertex-adc" | "claude-cli" | "none";
28
29
 
@@ -93,8 +94,14 @@ export interface ProbeResult {
93
94
  ok: boolean;
94
95
  latencyMs?: number;
95
96
  error?: string;
97
+ /** Set when `error` is specifically the server rejecting the credential, not a reachability failure. */
98
+ authFailed?: boolean;
96
99
  serverVersion?: string;
97
100
  models?: string[];
101
+ /** Human-readable labels keyed by the exact wire id returned in `models`. */
102
+ modelLabels?: Record<string, string>;
103
+ /** Stable cause class for setup UX; `error` remains the redacted human diagnostic. */
104
+ failureKind?: "missing" | "authentication" | "unsupported-feature" | "catalog-unavailable" | "cancelled" | "generic";
98
105
  /** Probe-only per-model load state when the runtime exposes it. */
99
106
  modelStates?: Record<string, ProbeModelStatus>;
100
107
  discoveredCapabilities?: Partial<CapabilityFlags>;
@@ -155,6 +162,18 @@ export interface RuntimeDescriptor {
155
162
  headlessCommand?: string;
156
163
  outputParser?: string;
157
164
  defaultCapabilities: CapabilityFlags;
165
+ /**
166
+ * Declares a black-box agent loop owned by an external executable. `tools`
167
+ * in CapabilityFlags stays false because Clio neither sends nor observes
168
+ * typed calls on this path; this field records the distinct external fact.
169
+ */
170
+ externalAgentLoop?: {
171
+ tools: "externally-governed-unobserved";
172
+ network: "externally-governed-unobserved";
173
+ budget: "external-one-shot";
174
+ generatingRetry: "forbidden";
175
+ modelCatalog: "live-authoritative" | "static";
176
+ };
158
177
  /**
159
178
  * When true, this id is a real, distinct runtime (e.g. `llamacpp-anthropic`,
160
179
  * the Anthropic Messages surface on llama.cpp, or the embed/rerank runtimes)