@iowarp/clio-coder 0.3.1 → 0.3.2

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 (595) hide show
  1. package/CHANGELOG.md +90 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +284 -613
  4. package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
  5. package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.js} +43 -26
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
  8. package/dist/{chunk-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
  9. package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
  10. package/dist/chunk-2SFS6XQE.js +122 -0
  11. package/dist/chunk-2VTFPG5O.js +48 -0
  12. package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
  13. package/dist/chunk-4BJ5BYCE.js +61 -0
  14. package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
  15. package/dist/chunk-4KLWL3UC.js +18 -0
  16. package/dist/chunk-4VP4KH3K.js +962 -0
  17. package/dist/chunk-4ZG3XFUR.js +77 -0
  18. package/dist/chunk-5B2AEOW5.js +5407 -0
  19. package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
  20. package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
  21. package/dist/chunk-65DEGPJ6.js +52 -0
  22. package/dist/chunk-6EJMN2Y3.js +17 -0
  23. package/dist/chunk-6EJV5X2W.js +16405 -0
  24. package/dist/chunk-6N5PTWMY.js +136 -0
  25. package/dist/chunk-6XLNIQDB.js +27 -0
  26. package/dist/{chunk-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
  27. package/dist/chunk-7CR24IG7.js +242 -0
  28. package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
  29. package/dist/chunk-7MNJORFF.js +22 -0
  30. package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
  31. package/dist/chunk-AGYYIBLL.js +1069 -0
  32. package/dist/chunk-AO4RKG4M.js +277 -0
  33. package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
  34. package/dist/chunk-ARBGF5F7.js +174 -0
  35. package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
  36. package/dist/chunk-CBCAPZAA.js +229 -0
  37. package/dist/chunk-CMZWFGD2.js +352 -0
  38. package/dist/chunk-ECH6PKUQ.js +39 -0
  39. package/dist/chunk-ED4KHGC3.js +143 -0
  40. package/dist/chunk-EKMEHE4H.js +340 -0
  41. package/dist/{chunk-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
  42. package/dist/chunk-FCSXB6T2.js +338 -0
  43. package/dist/chunk-FJ3H4MN5.js +48 -0
  44. package/dist/chunk-FQ4SKYE4.js +29 -0
  45. package/dist/chunk-G2DE3C7R.js +644 -0
  46. package/dist/chunk-G4BMMOKF.js +182 -0
  47. package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
  48. package/dist/chunk-HC4CLZ2Y.js +68 -0
  49. package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
  50. package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
  51. package/dist/chunk-I4HZDVNP.js +73 -0
  52. package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
  53. package/dist/chunk-IKCO5N3L.js +162 -0
  54. package/dist/chunk-IR4CFBFN.js +56 -0
  55. package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
  56. package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
  57. package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
  58. package/dist/chunk-KJ5LWLOE.js +1077 -0
  59. package/dist/chunk-LBMZMYH2.js +285 -0
  60. package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
  61. package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
  62. package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
  63. package/dist/chunk-MAW544W2.js +1882 -0
  64. package/dist/chunk-MBS4V7ZP.js +217 -0
  65. package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
  66. package/dist/chunk-MNA4JGU4.js +255 -0
  67. package/dist/chunk-MQSRRFWA.js +3428 -0
  68. package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
  69. package/dist/chunk-OAO4GE4M.js +619 -0
  70. package/dist/chunk-OHHN2SO4.js +5135 -0
  71. package/dist/chunk-OKGUZO2U.js +34 -0
  72. package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
  73. package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
  74. package/dist/chunk-OQE5J4C6.js +73 -0
  75. package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
  76. package/dist/chunk-POHLU5DW.js +1186 -0
  77. package/dist/chunk-QKMUKYO7.js +4961 -0
  78. package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
  79. package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
  80. package/dist/chunk-SST6Z5JA.js +80 -0
  81. package/dist/chunk-STBPMHSX.js +2456 -0
  82. package/dist/chunk-T6YILFSB.js +80 -0
  83. package/dist/chunk-TZTZS7QK.js +227 -0
  84. package/dist/chunk-UOV2BYIW.js +107 -0
  85. package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
  86. package/dist/chunk-VAKQQHWR.js +434 -0
  87. package/dist/chunk-VG7TBQIY.js +128 -0
  88. package/dist/chunk-VJWL6YS5.js +244 -0
  89. package/dist/chunk-WEH5XRJQ.js +32 -0
  90. package/dist/chunk-WMSVI4G2.js +2095 -0
  91. package/dist/chunk-WVO7V2QY.js +797 -0
  92. package/dist/chunk-X4RCMKVQ.js +641 -0
  93. package/dist/chunk-X75S7HFS.js +374 -0
  94. package/dist/chunk-XN3L4EYL.js +46 -0
  95. package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
  96. package/dist/chunk-YHZX5GEU.js +193 -0
  97. package/dist/chunk-YXLYO42X.js +91 -0
  98. package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
  99. package/dist/chunk-ZI647VB5.js +37 -0
  100. package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
  101. package/dist/cli/index.js +62 -54
  102. package/dist/clio-4LY5K2AC.js +25 -0
  103. package/dist/code-nav-7AX6FYE6.js +600 -0
  104. package/dist/codewiki/build-worker.js +66 -0
  105. package/dist/compile-cache-CVJMMODC.js +18 -0
  106. package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
  107. package/dist/{config-IRUQ7SE4.js → config-GTLUW2PR.js} +92 -55
  108. package/dist/configure-R6A64DHX.js +42 -0
  109. package/dist/context-5VKGUVJJ.js +866 -0
  110. package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
  111. package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
  112. package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
  113. package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
  114. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  115. package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
  116. package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
  117. package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
  118. package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
  119. package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
  120. package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
  121. package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
  122. package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
  123. package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
  124. package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
  125. package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
  126. package/dist/monitor-MEQA5C3I.js +661 -0
  127. package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
  128. package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
  129. package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
  130. package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
  131. package/dist/{run-YTPEYQOH.js → run-IV4Q6RLN.js} +101 -61
  132. package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
  133. package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
  134. package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
  135. package/dist/steer-GGWFUJUD.js +77 -0
  136. package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
  137. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  138. package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
  139. package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
  140. package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
  141. package/dist/{upgrade-33G2LMM5.js → upgrade-7TT7SQ3G.js} +45 -25
  142. package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
  143. package/dist/verify-G6V4D2G7.js +716 -0
  144. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  145. package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.js} +74 -34
  146. package/dist/worker/entry.js +221 -36
  147. package/dist/workspace-G4ZWUIPR.js +22 -0
  148. package/docs/README.md +22 -17
  149. package/docs/acp.md +168 -16
  150. package/docs/alcf-provider.md +1 -1
  151. package/docs/architecture.md +136 -7
  152. package/docs/artifact-versions.md +1 -1
  153. package/docs/built-in-agents.md +1 -1
  154. package/docs/capacity-and-scheduling.md +1 -1
  155. package/docs/commands-and-modes.md +114 -71
  156. package/docs/config-knobs-audit.md +1 -3
  157. package/docs/configuration-and-targets.md +174 -46
  158. package/docs/context-engine.md +29 -6
  159. package/docs/development-pipeline.md +26 -1
  160. package/docs/dispatch-architecture-rationale.md +1 -1
  161. package/docs/documentation-coverage.md +2 -2
  162. package/docs/documentation-guide.md +1 -1
  163. package/docs/environment-variables.md +13 -5
  164. package/docs/eval-runner.md +1 -1
  165. package/docs/evals-internal.md +1 -1
  166. package/docs/evidence-and-memory.md +6 -2
  167. package/docs/evolution.md +2 -2
  168. package/docs/exit-codes-and-output.md +15 -9
  169. package/docs/extensions-and-sharing.md +9 -9
  170. package/docs/fleet-dispatch.md +7 -5
  171. package/docs/git-commit-provenance.md +120 -0
  172. package/docs/glossary.md +1 -1
  173. package/docs/installation-and-lifecycle.md +34 -27
  174. package/docs/middleware-and-components.md +1 -1
  175. package/docs/model-catalog.md +45 -14
  176. package/docs/observability.md +8 -5
  177. package/docs/performance-methodology.md +491 -0
  178. package/docs/pi-boundary.md +72 -0
  179. package/docs/proactive-memory.md +3 -3
  180. package/docs/prompt-envelope-and-tools.md +24 -3
  181. package/docs/provider-adapter-cookbook.md +57 -4
  182. package/docs/release-cut-checklist.md +129 -115
  183. package/docs/safety-model.md +9 -5
  184. package/docs/scientific-validation.md +3 -3
  185. package/docs/session-lifecycle.md +55 -12
  186. package/docs/skills-marketplace.md +12 -8
  187. package/docs/time-conventions.md +1 -1
  188. package/docs/tool-usage.md +3 -3
  189. package/docs/trace-store.md +1 -1
  190. package/docs/troubleshooting.md +10 -7
  191. package/docs/tui-design.md +47 -10
  192. package/docs/worker-dispatch-mechanics.md +1 -1
  193. package/package.json +19 -22
  194. package/skills/coding/ast-grep/SKILL.md +136 -0
  195. package/skills/coding/ast-grep/evals.md +56 -0
  196. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  197. package/skills/coding/coding-standards/SKILL.md +113 -0
  198. package/skills/coding/coding-standards/evals.md +34 -0
  199. package/skills/coding/prototype/SKILL.md +86 -0
  200. package/skills/coding/prototype/evals.md +42 -0
  201. package/skills/coding/prototype/references/LOGIC.md +67 -0
  202. package/skills/coding/prototype/references/UI.md +112 -0
  203. package/skills/coding/tdd/SKILL.md +101 -0
  204. package/skills/coding/tdd/evals.md +41 -0
  205. package/skills/coding/tdd/references/mocking.md +59 -0
  206. package/skills/coding/tdd/references/tests.md +77 -0
  207. package/skills/context/context-handoff/SKILL.md +126 -0
  208. package/skills/context/context-handoff/evals.md +57 -0
  209. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  210. package/skills/context/context-prime/SKILL.md +95 -0
  211. package/skills/context/context-prime/evals.md +54 -0
  212. package/skills/meta/clio-dev/SKILL.md +91 -0
  213. package/skills/meta/clio-dev/evals.md +45 -0
  214. package/skills/meta/clio-test/SKILL.md +130 -0
  215. package/skills/meta/clio-test/evals.md +43 -0
  216. package/skills/meta/clio-test/references/harness.md +97 -0
  217. package/skills/meta/clio-test/references/test-map.md +59 -0
  218. package/skills/meta/credentials/SKILL.md +125 -0
  219. package/skills/meta/credentials/evals.md +104 -0
  220. package/skills/meta/find-skills/SKILL.md +72 -0
  221. package/skills/meta/find-skills/evals.md +47 -0
  222. package/skills/meta/herdr/SKILL.md +127 -0
  223. package/skills/meta/herdr/evals.md +38 -0
  224. package/skills/meta/skill-craft/SKILL.md +102 -0
  225. package/skills/meta/skill-craft/evals.md +41 -0
  226. package/skills/planning/architecture/SKILL.md +129 -0
  227. package/skills/planning/architecture/evals.md +36 -0
  228. package/skills/planning/backlog/SKILL.md +90 -0
  229. package/skills/planning/backlog/evals.md +43 -0
  230. package/skills/planning/prd/SKILL.md +82 -0
  231. package/skills/planning/prd/evals.md +49 -0
  232. package/skills/planning/product-intent/SKILL.md +112 -0
  233. package/skills/planning/product-intent/evals.md +36 -0
  234. package/skills/planning/tech-spec/SKILL.md +115 -0
  235. package/skills/planning/tech-spec/evals.md +47 -0
  236. package/skills/registry.yaml +136 -0
  237. package/skills/research/arxiv-literature/SKILL.md +104 -0
  238. package/skills/research/arxiv-literature/evals.md +58 -0
  239. package/skills/research/experiment-protocol/SKILL.md +122 -0
  240. package/skills/research/experiment-protocol/evals.md +91 -0
  241. package/skills/research/scientific-debugging/SKILL.md +119 -0
  242. package/skills/research/scientific-debugging/evals.md +138 -0
  243. package/skills/research/scientific-modernization/SKILL.md +138 -0
  244. package/skills/research/scientific-modernization/evals.md +84 -0
  245. package/skills/workflow/design-council/SKILL.md +139 -0
  246. package/skills/workflow/design-council/evals.md +97 -0
  247. package/skills/workflow/grill-me/SKILL.md +186 -0
  248. package/skills/workflow/grill-me/evals.md +78 -0
  249. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  250. package/skills/workflow/workflow-distiller/evals.md +107 -0
  251. package/src/cli/acp.ts +31 -4
  252. package/src/cli/clio.ts +68 -6
  253. package/src/cli/config-inspect.ts +28 -22
  254. package/src/cli/configure.ts +47 -9
  255. package/src/cli/context-clear.ts +2 -2
  256. package/src/cli/context-index.ts +21 -23
  257. package/src/cli/context.ts +13 -8
  258. package/src/cli/default-target.ts +9 -17
  259. package/src/cli/docs.ts +11 -5
  260. package/src/cli/evidence.ts +4 -1
  261. package/src/cli/extensions.ts +10 -1
  262. package/src/cli/fleet.ts +47 -6
  263. package/src/cli/index.ts +55 -26
  264. package/src/cli/memory.ts +3 -1
  265. package/src/cli/models.ts +1 -1
  266. package/src/cli/modes/json-stream.ts +37 -1
  267. package/src/cli/modes/print.ts +24 -9
  268. package/src/cli/run.ts +2 -2
  269. package/src/cli/skills-eval.ts +23 -8
  270. package/src/cli/skills.ts +19 -4
  271. package/src/cli/targets.ts +4 -0
  272. package/src/cli/text-layout.ts +15 -5
  273. package/src/cli/trace.ts +62 -14
  274. package/src/cli/upgrade.ts +18 -2
  275. package/src/cli/usage.ts +10 -3
  276. package/src/cli/wiki-generate.ts +2 -1
  277. package/src/core/agent-environment.ts +7 -0
  278. package/src/core/bash-exec.ts +72 -1
  279. package/src/core/boot-trace.ts +9 -4
  280. package/src/core/bus-events.ts +20 -4
  281. package/src/core/commit-attribution.ts +157 -0
  282. package/src/core/compile-cache.ts +159 -0
  283. package/src/core/config.ts +131 -2
  284. package/src/core/defaults.ts +39 -5
  285. package/src/core/domain-loader.ts +12 -5
  286. package/src/core/git-commit-attribution.ts +362 -0
  287. package/src/core/incomplete-installation.ts +45 -0
  288. package/src/core/response-schema.ts +1 -1
  289. package/src/core/safe-exec.ts +13 -1
  290. package/src/core/settings-layers.ts +155 -21
  291. package/src/core/skill-activation.ts +1 -1
  292. package/src/core/startup-timer.ts +3 -3
  293. package/src/core/state-file-lock.ts +13 -1
  294. package/src/core/termination.ts +78 -5
  295. package/src/domains/config/classify.ts +15 -3
  296. package/src/domains/config/extension.ts +19 -13
  297. package/src/domains/config/index.ts +10 -0
  298. package/src/domains/config/keybindings.ts +42 -6
  299. package/src/domains/context/bootstrap-prompt.ts +1 -1
  300. package/src/domains/context/bootstrap.ts +111 -18
  301. package/src/domains/context/clear.ts +16 -11
  302. package/src/domains/context/clio-md.ts +111 -9
  303. package/src/domains/context/codewiki/artifact.ts +400 -0
  304. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  305. package/src/domains/context/codewiki/build-worker.ts +54 -0
  306. package/src/domains/context/codewiki/coordinator.ts +182 -0
  307. package/src/domains/context/codewiki/indexer.ts +59 -144
  308. package/src/domains/context/codewiki/paths.ts +67 -0
  309. package/src/domains/context/codewiki/schema.ts +80 -0
  310. package/src/domains/context/codewiki/tree-sitter.ts +1 -1
  311. package/src/domains/context/contract.ts +11 -5
  312. package/src/domains/context/extension.ts +94 -143
  313. package/src/domains/context/fingerprint.ts +3 -1
  314. package/src/domains/context/index.ts +12 -22
  315. package/src/domains/context/project-metadata.ts +19 -0
  316. package/src/domains/context/prompt-context.ts +9 -10
  317. package/src/domains/context/refresh.ts +29 -21
  318. package/src/domains/context/runtime.ts +17 -0
  319. package/src/domains/context/wiki/generate.ts +39 -34
  320. package/src/domains/context/wiki/plan.ts +1 -1
  321. package/src/domains/context/wiki/prompts.ts +21 -8
  322. package/src/domains/dispatch/code-step.ts +20 -1
  323. package/src/domains/dispatch/extension.ts +158 -21
  324. package/src/domains/dispatch/failure-classification.ts +6 -0
  325. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  326. package/src/domains/dispatch/orphan-recovery.ts +50 -8
  327. package/src/domains/dispatch/receipt-integrity.ts +5 -0
  328. package/src/domains/dispatch/state.ts +31 -6
  329. package/src/domains/dispatch/transport.ts +2 -1
  330. package/src/domains/dispatch/types.ts +14 -0
  331. package/src/domains/dispatch/worker-spawn.ts +21 -2
  332. package/src/domains/eval/metrics/context.ts +1 -1
  333. package/src/domains/eval/types.ts +0 -1
  334. package/src/domains/evidence/build.ts +41 -1
  335. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  336. package/src/domains/lifecycle/migrations/index.ts +24 -4
  337. package/src/domains/middleware/hooks-io.ts +12 -0
  338. package/src/domains/middleware/skills-reminder.ts +30 -15
  339. package/src/domains/prompts/compiler.ts +142 -84
  340. package/src/domains/prompts/contract.ts +18 -2
  341. package/src/domains/prompts/extension.ts +39 -7
  342. package/src/domains/prompts/fragment-loader.ts +0 -1
  343. package/src/domains/prompts/fragments/identity/clio.md +2 -4
  344. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  345. package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
  346. package/src/domains/prompts/fragments/operating/contract.md +4 -50
  347. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  348. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  349. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  350. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  351. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  352. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  353. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  354. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  355. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  356. package/src/domains/prompts/preload.ts +3 -3
  357. package/src/domains/providers/auth/api-key.ts +1 -1
  358. package/src/domains/providers/auth/backend-file.ts +20 -10
  359. package/src/domains/providers/auth/backend-memory.ts +59 -4
  360. package/src/domains/providers/auth/boot-status.ts +65 -0
  361. package/src/domains/providers/auth/oauth.ts +2 -1
  362. package/src/domains/providers/auth/storage.ts +97 -38
  363. package/src/domains/providers/capabilities.ts +12 -4
  364. package/src/domains/providers/contract.ts +15 -4
  365. package/src/domains/providers/extension.ts +18 -6
  366. package/src/domains/providers/model-runtime-capabilities.ts +15 -4
  367. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
  368. package/src/domains/providers/plugins.ts +5 -3
  369. package/src/domains/providers/probe/fingerprint.ts +25 -5
  370. package/src/domains/providers/registry.ts +31 -10
  371. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  372. package/src/domains/providers/runtimes/builtins.ts +2 -2
  373. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  374. package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
  375. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  376. package/src/domains/providers/support.ts +6 -3
  377. package/src/domains/providers/types/local-model-quirks.ts +7 -9
  378. package/src/domains/providers/types/runtime-descriptor.ts +12 -1
  379. package/src/domains/providers/types/target-descriptor.ts +22 -0
  380. package/src/domains/resources/contract.ts +0 -1
  381. package/src/domains/resources/extension.ts +1 -3
  382. package/src/domains/resources/loader.ts +3 -4
  383. package/src/domains/resources/prompts/loader.ts +16 -2
  384. package/src/domains/resources/prompts/substitute.ts +1 -65
  385. package/src/domains/resources/skills/content-hash.ts +2 -0
  386. package/src/domains/resources/skills/install.ts +17 -0
  387. package/src/domains/resources/skills/loader.ts +17 -10
  388. package/src/domains/resources/skills/marketplace.ts +55 -9
  389. package/src/domains/safety/action-classifier.ts +4 -2
  390. package/src/domains/safety/audit.ts +8 -2
  391. package/src/domains/safety/extension.ts +1 -1
  392. package/src/domains/session/compaction/branch-summary.ts +3 -2
  393. package/src/domains/session/compaction/cut-point.ts +2 -1
  394. package/src/domains/session/compaction/tokens.ts +2 -1
  395. package/src/domains/session/context-ledger.ts +14 -0
  396. package/src/domains/session/contract.ts +15 -0
  397. package/src/domains/session/decision-board.ts +190 -0
  398. package/src/domains/session/entries.ts +66 -3
  399. package/src/domains/session/extension.ts +93 -12
  400. package/src/domains/session/retry.ts +10 -18
  401. package/src/domains/session/session-artifacts.ts +107 -0
  402. package/src/domains/session/task-board.ts +207 -13
  403. package/src/domains/session/tree/active-path.ts +44 -5
  404. package/src/domains/session/tree/fork.ts +26 -27
  405. package/src/domains/session/tree/preview.ts +2 -2
  406. package/src/domains/session/workspace/git-probe.ts +17 -11
  407. package/src/domains/user-tasks/store.ts +297 -0
  408. package/src/engine/acp/errors.ts +96 -0
  409. package/src/engine/acp/server.ts +1728 -146
  410. package/src/engine/acp/transport.ts +135 -14
  411. package/src/engine/acp/types.ts +26 -0
  412. package/src/engine/agent.ts +3 -3
  413. package/src/engine/ai.ts +32 -27
  414. package/src/engine/alcf-oauth.ts +26 -19
  415. package/src/engine/api-registry.ts +223 -0
  416. package/src/engine/apis/index.ts +3 -7
  417. package/src/engine/apis/llamacpp-residency.ts +49 -9
  418. package/src/engine/apis/lmstudio-residency.ts +5 -21
  419. package/src/engine/apis/lmstudio.ts +243 -0
  420. package/src/engine/apis/ollama-native.ts +24 -3
  421. package/src/engine/apis/openai-completions.ts +170 -91
  422. package/src/engine/apis/residency.ts +139 -3
  423. package/src/engine/apis/types.ts +16 -0
  424. package/src/engine/env-api-keys.ts +98 -0
  425. package/src/engine/gemma-channel-filter.ts +223 -0
  426. package/src/engine/instrumented-tui.ts +192 -0
  427. package/src/engine/messages.ts +14 -0
  428. package/src/engine/models.ts +42 -0
  429. package/src/engine/oauth.ts +16 -12
  430. package/src/engine/prompt-templates.ts +1 -0
  431. package/src/engine/provider-payload.ts +16 -59
  432. package/src/engine/strip-tokenizer-sentinels.ts +1 -1
  433. package/src/engine/truncate.ts +9 -0
  434. package/src/engine/tui.ts +17 -9
  435. package/src/engine/types.ts +3 -6
  436. package/src/engine/worker-runtime-capabilities.ts +5 -0
  437. package/src/engine/worker-runtime.ts +1 -1
  438. package/src/engine/worker-tools.ts +9 -4
  439. package/src/entry/boot-options.ts +50 -0
  440. package/src/entry/orchestrator.ts +288 -150
  441. package/src/interactive/application-controller.ts +89 -2
  442. package/src/interactive/chat-loop.ts +266 -41
  443. package/src/interactive/chat-panel.ts +173 -47
  444. package/src/interactive/chat-renderer.ts +262 -72
  445. package/src/interactive/clio-editor.ts +3 -8
  446. package/src/interactive/command-fallbacks.ts +2 -2
  447. package/src/interactive/context-overlay.ts +27 -1
  448. package/src/interactive/editor-submit.ts +228 -24
  449. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  450. package/src/interactive/export-html/index.ts +51 -0
  451. package/src/interactive/export-html/template.ts +45 -0
  452. package/src/interactive/export-html/tool-renderer.ts +54 -0
  453. package/src/interactive/footer/dashboard.ts +4 -0
  454. package/src/interactive/footer/notifications.ts +1 -1
  455. package/src/interactive/footer/widgets.ts +20 -2
  456. package/src/interactive/footer-panel.ts +2 -2
  457. package/src/interactive/format-time.ts +14 -2
  458. package/src/interactive/interactive-application.ts +201 -17
  459. package/src/interactive/interactive-event-projection.ts +6 -1
  460. package/src/interactive/interactive-input-runtime.ts +50 -4
  461. package/src/interactive/interactive-presentation.ts +151 -19
  462. package/src/interactive/interactive-shell.ts +268 -14
  463. package/src/interactive/interactive-slash-runtime.ts +176 -114
  464. package/src/interactive/interactive-tickers.ts +38 -7
  465. package/src/interactive/keybinding-manager.ts +1 -1
  466. package/src/interactive/layout.ts +40 -3
  467. package/src/interactive/overlay-frame.ts +1 -1
  468. package/src/interactive/overlay-general-openers.ts +58 -1
  469. package/src/interactive/overlay-key-routing.ts +3 -0
  470. package/src/interactive/overlay-lifecycle.ts +13 -0
  471. package/src/interactive/overlay-permission-lifecycle.ts +2 -1
  472. package/src/interactive/overlay-session-lifecycle.ts +69 -12
  473. package/src/interactive/overlays/decisions.ts +300 -0
  474. package/src/interactive/overlays/help-reference.ts +15 -10
  475. package/src/interactive/overlays/model-selector.ts +34 -16
  476. package/src/interactive/overlays/session-selector.ts +18 -0
  477. package/src/interactive/overlays/settings.ts +105 -17
  478. package/src/interactive/overlays/skills-hub.ts +4 -4
  479. package/src/interactive/overlays/tree-selector.ts +41 -6
  480. package/src/interactive/render-trace.ts +499 -90
  481. package/src/interactive/renderers/compaction-summary.ts +2 -2
  482. package/src/interactive/renderers/diff.ts +115 -104
  483. package/src/interactive/renderers/mermaid.ts +53 -0
  484. package/src/interactive/renderers/tool-execution.ts +386 -133
  485. package/src/interactive/renderers/worker-entry.ts +20 -4
  486. package/src/interactive/session-switch-settlement.ts +10 -0
  487. package/src/interactive/slash-autocomplete.ts +6 -114
  488. package/src/interactive/slash-commands.ts +135 -47
  489. package/src/interactive/slash-spec.ts +9 -38
  490. package/src/interactive/status/controller.ts +5 -1
  491. package/src/interactive/stdout-backpressure.ts +99 -0
  492. package/src/interactive/stream-pacer.ts +530 -0
  493. package/src/interactive/stream-pacing-policy.ts +66 -0
  494. package/src/interactive/tasks-overlay.ts +368 -14
  495. package/src/interactive/terminal-lease.ts +485 -0
  496. package/src/interactive/theme/tokens.ts +1 -1
  497. package/src/interactive/turn-context.ts +4 -3
  498. package/src/interactive/turn-persistence.ts +30 -13
  499. package/src/interactive/turn-queues.ts +12 -0
  500. package/src/interactive/turn-recovery.ts +25 -8
  501. package/src/interactive/turn-runtime.ts +79 -12
  502. package/src/interactive/turn-state.ts +10 -0
  503. package/src/interactive/view/artifacts.ts +114 -4
  504. package/src/interactive/view/view-overlay.ts +3 -0
  505. package/src/interactive/welcome-dashboard.ts +17 -16
  506. package/src/interactive/worker-receipts.ts +52 -3
  507. package/src/interactive/worker-stream.ts +5 -1
  508. package/src/tools/agent-tools.ts +23 -3
  509. package/src/tools/artifact.ts +2 -2
  510. package/src/tools/ask-user.ts +23 -13
  511. package/src/tools/bash.ts +30 -2
  512. package/src/tools/bootstrap.ts +34 -431
  513. package/src/tools/builtin-tool-catalog.ts +265 -0
  514. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  515. package/src/tools/codewiki/code-nav.ts +8 -22
  516. package/src/tools/codewiki/shared.ts +41 -38
  517. package/src/tools/context/docs-engine.ts +14 -3
  518. package/src/tools/context/index.ts +107 -28
  519. package/src/tools/context/surface.ts +19 -0
  520. package/src/tools/core-bootstrap.ts +168 -0
  521. package/src/tools/credential-present.ts +5 -5
  522. package/src/tools/dispatch-admission.ts +533 -0
  523. package/src/tools/dispatch-background.ts +54 -0
  524. package/src/tools/dispatch-event-text.ts +6 -0
  525. package/src/tools/dispatch-plan.ts +9 -4
  526. package/src/tools/dispatch-run-events.ts +238 -0
  527. package/src/tools/dispatch-runner.ts +2370 -0
  528. package/src/tools/dispatch-scout-admission.ts +295 -0
  529. package/src/tools/dispatch-types.ts +77 -0
  530. package/src/tools/dispatch.ts +67 -3161
  531. package/src/tools/find.ts +4 -2
  532. package/src/tools/grep.ts +2 -2
  533. package/src/tools/lazy-tool.ts +60 -0
  534. package/src/tools/ledger.ts +3 -3
  535. package/src/tools/monitor-surface.ts +36 -0
  536. package/src/tools/monitor.ts +2 -32
  537. package/src/tools/observers.ts +2 -2
  538. package/src/tools/registry.ts +39 -27
  539. package/src/tools/safe-exec.ts +2 -2
  540. package/src/tools/steer-surface.ts +17 -0
  541. package/src/tools/steer.ts +2 -13
  542. package/src/tools/tasks.ts +108 -11
  543. package/src/tools/truncate.ts +25 -184
  544. package/src/tools/verify/frontend.ts +3 -1
  545. package/src/tools/verify/index.ts +3 -38
  546. package/src/tools/verify/surface.ts +46 -0
  547. package/src/tools/web-fetch-surface.ts +23 -0
  548. package/src/tools/web-fetch.ts +2 -20
  549. package/src/tools/write.ts +7 -2
  550. package/src/worker/entry.ts +39 -2
  551. package/src/worker/spec-contract.ts +26 -5
  552. package/dist/chunk-7SS2CTV2.js +0 -61361
  553. package/dist/chunk-DKGKUHFA.js +0 -924
  554. package/dist/chunk-GEP36Y4X.js +0 -12796
  555. package/dist/chunk-XYWBQRDM.js +0 -137
  556. package/dist/clio-BZVGEUFJ.js +0 -58
  557. package/dist/configure-S7S6F6CL.js +0 -32
  558. package/docs/html/agents_blueprint.html +0 -936
  559. package/docs/html/alcf_blueprint.html +0 -324
  560. package/docs/html/architecture_blueprint.html +0 -850
  561. package/docs/html/commands_blueprint.html +0 -939
  562. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  563. package/docs/html/configuration_blueprint.html +0 -1080
  564. package/docs/html/context_blueprint.html +0 -603
  565. package/docs/html/documentation_blueprint.html +0 -832
  566. package/docs/html/environment_blueprint.html +0 -404
  567. package/docs/html/eval_blueprint.html +0 -743
  568. package/docs/html/evals_internal_blueprint.html +0 -190
  569. package/docs/html/evolution_blueprint.html +0 -674
  570. package/docs/html/extensions_blueprint.html +0 -2065
  571. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  572. package/docs/html/index.html +0 -919
  573. package/docs/html/lifecycle_blueprint.html +0 -723
  574. package/docs/html/memory_blueprint.html +0 -699
  575. package/docs/html/middleware_blueprint.html +0 -664
  576. package/docs/html/models_blueprint.html +0 -2366
  577. package/docs/html/observability_blueprint.html +0 -683
  578. package/docs/html/provider_adapter_blueprint.html +0 -245
  579. package/docs/html/safety_blueprint.html +0 -1386
  580. package/docs/html/shared.css +0 -571
  581. package/docs/html/shared.js +0 -143
  582. package/docs/html/skills_blueprint.html +0 -671
  583. package/docs/html/soak_blueprint.html +0 -182
  584. package/docs/html/tool_usage_blueprint.html +0 -350
  585. package/docs/html/tools_blueprint.html +0 -2249
  586. package/docs/html/trace_blueprint.html +0 -235
  587. package/docs/html/tui_design_blueprint.html +0 -374
  588. package/docs/html/validation_blueprint.html +0 -961
  589. package/docs/html/worker_dispatch_blueprint.html +0 -231
  590. package/src/core/release.ts +0 -2
  591. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
  592. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
  593. package/src/engine/apis/lmstudio-native.ts +0 -1438
  594. package/src/engine/apis/thinking-replay.ts +0 -11
  595. package/src/tools/string-enum.ts +0 -15
@@ -15,7 +15,6 @@ import type {
15
15
  Usage,
16
16
  } from "@earendil-works/pi-ai";
17
17
  import { createAssistantMessageEventStream } from "@earendil-works/pi-ai";
18
- import type { ApiProvider } from "@earendil-works/pi-ai/compat";
19
18
  import {
20
19
  type ChatRequest,
21
20
  type ChatResponse,
@@ -32,11 +31,13 @@ import {
32
31
  } from "../../domains/providers/index.js";
33
32
  import type { LocalModelQuirks, SamplingProfile } from "../../domains/providers/types/local-model-quirks.js";
34
33
  import { calculateEngineCost } from "../ai.js";
34
+ import { createGemmaChannelFilter } from "../gemma-channel-filter.js";
35
35
  import { createSentinelStripper } from "../strip-tokenizer-sentinels.js";
36
36
  import { remainingContextMaxTokens } from "./output-budget.js";
37
37
  import { type ResidencyAdapter, reconcileResidency, residencyManagedFor } from "./residency.js";
38
38
  import type { ResidentModelInfo } from "./resident-models.js";
39
39
  import { mergeSamplingOverride } from "./sampling-overrides.js";
40
+ import type { EngineApiProvider } from "./types.js";
40
41
 
41
42
  const REASONING_CHARS_PER_TOKEN = 4;
42
43
 
@@ -381,6 +382,8 @@ function runStream(
381
382
  let hadToolCall = false;
382
383
  let doneReason: string | undefined;
383
384
  const sentinelStripper = createSentinelStripper();
385
+ const resolved = resolveModelRuntimeCapabilitiesForModel(model, thinkingLevel);
386
+ const channelFilter = resolved.family === "gemma-4" ? createGemmaChannelFilter() : null;
384
387
  const closeActiveThinking = () => {
385
388
  if (!activeThinking) return;
386
389
  stream.push({
@@ -446,6 +449,22 @@ function runStream(
446
449
  partial: output,
447
450
  });
448
451
  };
452
+ const routeText = (content: string) => {
453
+ if (!channelFilter) {
454
+ emitText(content);
455
+ return;
456
+ }
457
+ for (const segment of channelFilter.push(content)) {
458
+ if (segment.kind === "thinking") emitThinking(segment.content);
459
+ else emitText(segment.content);
460
+ }
461
+ };
462
+ const flushChannel = () => {
463
+ for (const segment of channelFilter?.flush() ?? []) {
464
+ if (segment.kind === "thinking") emitThinking(segment.content);
465
+ else emitText(segment.content);
466
+ }
467
+ };
449
468
  for await (const chunk of iterator) {
450
469
  const response = chunk as ChatResponse;
451
470
  const msg = response.message;
@@ -453,15 +472,17 @@ function runStream(
453
472
  emitThinking(msg.thinking);
454
473
  }
455
474
  if (msg?.content && msg.content.length > 0) {
456
- emitText(msg.content);
475
+ routeText(msg.content);
457
476
  }
458
477
  if (msg?.tool_calls && msg.tool_calls.length > 0) {
478
+ flushChannel();
459
479
  closeActiveText();
460
480
  closeActiveThinking();
461
481
  for (const raw of msg.tool_calls) emitToolCall(raw, output, stream);
462
482
  hadToolCall = true;
463
483
  }
464
484
  if (response.done) {
485
+ flushChannel();
465
486
  closeActiveText();
466
487
  closeActiveThinking();
467
488
  output.usage.input = response.prompt_eval_count ?? 0;
@@ -499,7 +520,7 @@ function stripReasoning(options: SimpleStreamOptions | undefined): StreamOptions
499
520
  return rest;
500
521
  }
501
522
 
502
- export const ollamaNativeApiProvider: ApiProvider<"ollama-native"> = {
523
+ export const ollamaNativeApiProvider: EngineApiProvider<"ollama-native"> = {
503
524
  api: "ollama-native",
504
525
  stream: (model, context, options) => runStream(model, context, options, fallbackThinkingLevel(model)),
505
526
  streamSimple: (model, context, options?: SimpleStreamOptions) =>
@@ -2,31 +2,40 @@ import {
2
2
  type Api,
3
3
  type AssistantMessage,
4
4
  type AssistantMessageEvent,
5
+ type AssistantMessageEventStream,
5
6
  type Context,
6
7
  createAssistantMessageEventStream,
7
8
  type Model,
8
9
  type OpenAICompletionsOptions,
9
10
  type SimpleStreamOptions,
10
11
  type StreamOptions,
12
+ type ThinkingBudgets,
11
13
  type ThinkingContent,
12
14
  type Tool,
13
15
  type Usage,
14
16
  } from "@earendil-works/pi-ai";
15
- import { type ApiProvider, streamOpenAICompletions, streamSimpleOpenAICompletions } from "@earendil-works/pi-ai/compat";
17
+ import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
16
18
  import {
17
19
  type AppliedThinking,
18
20
  type ResolvedModelRuntimeCapabilities,
19
21
  reasoningClassForMechanism,
20
22
  resolveModelRuntimeCapabilitiesForModel,
21
23
  } from "../../domains/providers/model-runtime-capabilities.js";
24
+ import { lmStudioReasoningEffort } from "../../domains/providers/runtimes/common/lmstudio-http.js";
22
25
  import type { ThinkingLevel } from "../../domains/providers/types/capability-flags.js";
23
26
  import type { LocalModelQuirks, SamplingProfile } from "../../domains/providers/types/local-model-quirks.js";
27
+ import type { LmStudioTargetSettings } from "../../domains/providers/types/target-descriptor.js";
28
+ import { filterGemmaChannelStream } from "../gemma-channel-filter.js";
24
29
  import { HarmonyResponseParser } from "../harmony-response.js";
25
30
  import { createSentinelStripper, stripTokenizerSentinels } from "../strip-tokenizer-sentinels.js";
26
31
  import { ensureLlamaCppResidency } from "./llamacpp-residency.js";
32
+ import { ensureLmStudioResidency } from "./lmstudio.js";
27
33
  import { LOCAL_TOOL_TURN_MAX_OUTPUT_TOKENS, remainingContextMaxTokens } from "./output-budget.js";
28
34
  import { residencyManagedFor } from "./residency.js";
29
35
  import { mergeSamplingOverride } from "./sampling-overrides.js";
36
+ import type { EngineApiProvider } from "./types.js";
37
+
38
+ const piOpenAICompletions = openAICompletionsApi();
30
39
 
31
40
  /**
32
41
  * Average characters-per-token for the English/code reasoning streams pi-ai
@@ -47,6 +56,9 @@ interface ClioRuntimeMetadata {
47
56
  gateway?: boolean;
48
57
  quirks?: LocalModelQuirks;
49
58
  chatTemplateKwargsUnsupported?: boolean;
59
+ lmstudio?: LmStudioTargetSettings;
60
+ lmstudioReasoningOptions?: ReadonlyArray<string>;
61
+ lmstudioDefaultModel?: string;
50
62
  };
51
63
  }
52
64
 
@@ -71,33 +83,30 @@ function isPlainRecord(value: unknown): value is Record<string, unknown> {
71
83
  return value !== null && typeof value === "object" && !Array.isArray(value);
72
84
  }
73
85
 
74
- /**
75
- * Install catalog sampling quirks on the OpenAI-compat request body. Standard
76
- * OpenAI fields (`temperature`, `top_p`, `presence_penalty`,
77
- * `frequency_penalty`) and LM Studio's extra fields (`top_k`, `min_p`,
78
- * `repeat_penalty`) are added only when the request body does not already
79
- * carry them. This keeps explicit StreamOptions and any user-supplied
80
- * `onPayload` overrides authoritative.
81
- */
82
- function applyOpenAISamplingProfile(
83
- payload: Record<string, unknown>,
84
- profile: SamplingProfile,
85
- ): Record<string, unknown> {
86
- const next: Record<string, unknown> = { ...payload };
87
- if (profile.temperature !== undefined && next.temperature === undefined) next.temperature = profile.temperature;
88
- if (profile.topP !== undefined && next.top_p === undefined) next.top_p = profile.topP;
89
- if (profile.topK !== undefined && next.top_k === undefined) next.top_k = profile.topK;
90
- if (profile.minP !== undefined && next.min_p === undefined) next.min_p = profile.minP;
91
- if (profile.repeatPenalty !== undefined && next.repeat_penalty === undefined)
92
- next.repeat_penalty = profile.repeatPenalty;
93
- if (profile.presencePenalty !== undefined && next.presence_penalty === undefined)
94
- next.presence_penalty = profile.presencePenalty;
95
- if (profile.frequencyPenalty !== undefined && next.frequency_penalty === undefined)
96
- next.frequency_penalty = profile.frequencyPenalty;
97
- return next;
86
+ function samplingParamsFromProfile(profile: SamplingProfile): Record<string, unknown> {
87
+ return {
88
+ ...(profile.topP !== undefined ? { top_p: profile.topP } : {}),
89
+ ...(profile.topK !== undefined ? { top_k: profile.topK } : {}),
90
+ ...(profile.minP !== undefined ? { min_p: profile.minP } : {}),
91
+ ...(profile.repeatPenalty !== undefined ? { repeat_penalty: profile.repeatPenalty } : {}),
92
+ ...(profile.presencePenalty !== undefined ? { presence_penalty: profile.presencePenalty } : {}),
93
+ ...(profile.frequencyPenalty !== undefined ? { frequency_penalty: profile.frequencyPenalty } : {}),
94
+ };
95
+ }
96
+
97
+ function piThinkingBudgets(quirks: LocalModelQuirks | undefined): ThinkingBudgets | undefined {
98
+ const budgets = quirks?.thinking?.budgetByLevel;
99
+ if (!budgets) return undefined;
100
+ return {
101
+ ...(budgets.minimal !== undefined ? { minimal: budgets.minimal } : {}),
102
+ ...(budgets.low !== undefined ? { low: budgets.low } : {}),
103
+ ...(budgets.medium !== undefined ? { medium: budgets.medium } : {}),
104
+ ...(budgets.high !== undefined ? { high: budgets.high } : {}),
105
+ };
98
106
  }
99
107
 
100
108
  type AnyOnPayload = (payload: unknown, model: Model<Api>) => unknown | undefined | Promise<unknown | undefined>;
109
+ type StreamOptionsWithThinkingBudgets = StreamOptions & { thinkingBudgets?: ThinkingBudgets };
101
110
 
102
111
  const THINKING_CHAT_TEMPLATE_KWARGS = new Set([
103
112
  "enable_thinking",
@@ -156,7 +165,9 @@ function withStrippedPartial<TEvent extends AssistantMessageEvent>(event: TEvent
156
165
  * Apply thinking-mechanism payload mutations to an openai-compat request body
157
166
  * after the catalog sampler is in place. Each mechanism owns the wire fields
158
167
  * it touches:
159
- * - `effort-levels` writes `reasoning_effort` when the family resolved one.
168
+ * - `effort-levels` writes `reasoning_effort` when the family resolved one;
169
+ * off also carries `chat_template_kwargs.enable_thinking=false` for strict
170
+ * templates whose effort vocabulary has no off value.
160
171
  * - `budget-tokens` writes a vendor-specific budget object when the family
161
172
  * declares a `thinkingFormat` of `anthropic-extended`; otherwise the
162
173
  * budget remains informational and surfaces through the prompt only.
@@ -189,7 +200,8 @@ function applyThinkingPayload(
189
200
  applied.mechanism === "budget-tokens" &&
190
201
  resolved.request.budgetTokens !== undefined &&
191
202
  next.thinking === undefined &&
192
- resolved.request.budgetEnforcement === "enforced"
203
+ resolved.request.budgetEnforcement === "enforced" &&
204
+ resolved.runtimeId !== "vllm"
193
205
  ) {
194
206
  // Only vendors whose openai-compat surface advertises a structured
195
207
  // thinking budget (e.g. anthropic-extended on routed providers) get
@@ -201,6 +213,44 @@ function applyThinkingPayload(
201
213
  return next;
202
214
  }
203
215
 
216
+ function isLmStudioModel(model: Model<Api>): boolean {
217
+ const metadata = runtimeMetadata(model);
218
+ return model.provider === "lmstudio" && metadata?.runtimeId === "lmstudio";
219
+ }
220
+
221
+ function applyLmStudioPayload(
222
+ payload: Record<string, unknown>,
223
+ model: Model<Api>,
224
+ resolved: ResolvedModelRuntimeCapabilities,
225
+ ): Record<string, unknown> {
226
+ if (!isLmStudioModel(model)) return payload;
227
+ const request = runtimeMetadata(model)?.lmstudio?.request;
228
+ const next: Record<string, unknown> = { ...payload };
229
+ delete next.chat_template_kwargs;
230
+ if (request?.ttlSeconds !== undefined) next.ttl = request.ttlSeconds;
231
+ if (request?.draftModel !== undefined) next.draft_model = request.draftModel;
232
+ if (resolved.thinking.mechanism === "none" || resolved.thinking.mechanism === "always-on") return next;
233
+ const resolvedEffort =
234
+ resolved.request.reasoningEffort ??
235
+ lmStudioReasoningEffort(resolved.thinking.effectiveLevel, runtimeMetadata(model)?.lmstudioReasoningOptions);
236
+ switch (request?.reasoning) {
237
+ case "off":
238
+ next.reasoning_effort = "none";
239
+ break;
240
+ case "on":
241
+ next.reasoning_effort = "low";
242
+ break;
243
+ case "low":
244
+ case "medium":
245
+ case "high":
246
+ next.reasoning_effort = lmStudioReasoningEffort(request.reasoning, runtimeMetadata(model)?.lmstudioReasoningOptions);
247
+ break;
248
+ default:
249
+ next.reasoning_effort = resolvedEffort;
250
+ }
251
+ return next;
252
+ }
253
+
204
254
  function applyLlamaCppPromptCachePayload(payload: Record<string, unknown>, model: Model<Api>): Record<string, unknown> {
205
255
  const metadata = runtimeMetadata(model);
206
256
  if (model.provider !== "llamacpp" || metadata?.runtimeId !== "llamacpp") return payload;
@@ -213,35 +263,7 @@ function shouldApplyLlamaCppPromptCache(model: Model<"openai-completions">): boo
213
263
  return model.provider === "llamacpp" && metadata?.runtimeId === "llamacpp";
214
264
  }
215
265
 
216
- /**
217
- * Compose an `onPayload` hook over any caller-supplied one. Catalog overrides
218
- * apply first so the caller's hook sees the mutated body and can override or
219
- * inspect it. The result is returned only when the body actually changed
220
- * (pi-ai treats `undefined` as "use the original").
221
- */
222
- function composeSamplingOnPayload(
223
- profile: SamplingProfile,
224
- resolved: ResolvedModelRuntimeCapabilities | undefined,
225
- base: AnyOnPayload | undefined,
226
- ): AnyOnPayload {
227
- return async (payload, model) => {
228
- if (!isPlainRecord(payload)) {
229
- return base ? await base(payload, model) : undefined;
230
- }
231
- let next = applyLlamaCppPromptCachePayload(applyOpenAISamplingProfile(payload, profile), model);
232
- if (resolved) next = applyThinkingPayload(next, resolved.thinking, resolved, model);
233
- if (base) {
234
- const fromBase = await base(next, model);
235
- if (fromBase !== undefined) return fromBase;
236
- }
237
- return next;
238
- };
239
- }
240
-
241
- /**
242
- * Variant of `composeSamplingOnPayload` for cases where there is no catalog
243
- * sampler but we still need to inject thinking-mechanism fields.
244
- */
266
+ /** Compose Clio-only payload deltas over the caller hook after pi applies sampling. */
245
267
  function composeThinkingOnPayload(
246
268
  resolved: ResolvedModelRuntimeCapabilities,
247
269
  base: AnyOnPayload | undefined,
@@ -250,11 +272,10 @@ function composeThinkingOnPayload(
250
272
  if (!isPlainRecord(payload)) {
251
273
  return base ? await base(payload, model) : undefined;
252
274
  }
253
- const next = applyThinkingPayload(
254
- applyLlamaCppPromptCachePayload(payload, model),
255
- resolved.thinking,
256
- resolved,
275
+ const next = applyLmStudioPayload(
276
+ applyThinkingPayload(applyLlamaCppPromptCachePayload(payload, model), resolved.thinking, resolved, model),
257
277
  model,
278
+ resolved,
258
279
  );
259
280
  if (base) {
260
281
  const fromBase = await base(next, model);
@@ -270,11 +291,16 @@ function withSamplingOverrides<TOptions extends StreamOptions>(
270
291
  resolved: ResolvedModelRuntimeCapabilities,
271
292
  ): TOptions | undefined {
272
293
  const applied = resolved.thinking;
273
- const profile = pickSamplingProfile(clioQuirks(model), applied.thinkingActive);
294
+ const quirks = clioQuirks(model);
295
+ const profile = pickSamplingProfile(quirks, applied.thinkingActive);
274
296
  const promptCache = shouldApplyLlamaCppPromptCache(model);
297
+ const lmstudio = isLmStudioModel(model);
298
+ const vllmThinkingBudgets = resolved.runtimeId === "vllm" ? piThinkingBudgets(quirks) : undefined;
275
299
  if (
276
300
  !promptCache &&
301
+ !lmstudio &&
277
302
  !profile &&
303
+ !vllmThinkingBudgets &&
278
304
  applied.mechanism !== "effort-levels" &&
279
305
  applied.mechanism !== "budget-tokens" &&
280
306
  applied.mechanism !== "on-off" &&
@@ -285,17 +311,34 @@ function withSamplingOverrides<TOptions extends StreamOptions>(
285
311
  const merged: Record<string, unknown> = { ...(options ?? {}) };
286
312
  if (profile?.temperature !== undefined && merged.temperature === undefined) merged.temperature = profile.temperature;
287
313
  if (profile) {
288
- merged.onPayload = composeSamplingOnPayload(profile, resolved, options?.onPayload);
289
- } else {
314
+ merged.samplingParams = {
315
+ ...samplingParamsFromProfile(profile),
316
+ ...options?.samplingParams,
317
+ };
318
+ }
319
+ if (vllmThinkingBudgets) {
320
+ merged.thinkingBudgets = {
321
+ ...vllmThinkingBudgets,
322
+ ...(options as StreamOptionsWithThinkingBudgets | undefined)?.thinkingBudgets,
323
+ };
324
+ }
325
+ if (
326
+ promptCache ||
327
+ lmstudio ||
328
+ applied.mechanism === "effort-levels" ||
329
+ applied.mechanism === "budget-tokens" ||
330
+ applied.mechanism === "on-off" ||
331
+ applied.mechanism === "none"
332
+ ) {
290
333
  merged.onPayload = composeThinkingOnPayload(resolved, options?.onPayload);
291
334
  }
292
335
  return merged as TOptions;
293
336
  }
294
337
 
295
338
  function stripNeverReasoningFromStream(
296
- source: ReturnType<typeof streamOpenAICompletions>,
339
+ source: AssistantMessageEventStream,
297
340
  resolved: ResolvedModelRuntimeCapabilities,
298
- ): ReturnType<typeof streamOpenAICompletions> {
341
+ ): AssistantMessageEventStream {
299
342
  if (!stripsThinking(resolved)) return source;
300
343
  const stripped = createAssistantMessageEventStream();
301
344
  (async () => {
@@ -399,7 +442,7 @@ function malformedToolArgsMessage(
399
442
  const workaround =
400
443
  model.provider === "llamacpp" || runtime === "llamacpp"
401
444
  ? "For llama.cpp, verify --jinja, the model chat template, reasoning flags, and tool parser support for this model."
402
- : "For LM Studio, use the verified openai-compat gateway fallback when native SDK tool extraction is unreliable.";
445
+ : "For LM Studio, verify the model's tool-use capability and active chat template in LM Studio.";
403
446
  return `OpenAI-compatible runtime returned empty tool-call arguments for target '${target}' model '${model.id}' tool '${toolName}'.${required} ${workaround}`;
404
447
  }
405
448
 
@@ -450,15 +493,18 @@ function hasReportedReasoningUsage(usage: Usage): boolean {
450
493
  */
451
494
  export function applyOpenAICompatReasoningEstimate(message: AssistantMessage): void {
452
495
  if (hasReportedReasoningUsage(message.usage)) return;
453
- const reasoningTokens = estimateReasoningTokens(message.content);
496
+ const estimated = estimateReasoningTokens(message.content);
497
+ const reportedOutput = message.usage.output;
498
+ const reasoningTokens =
499
+ typeof reportedOutput === "number" && Number.isFinite(reportedOutput)
500
+ ? Math.min(estimated, Math.max(0, reportedOutput))
501
+ : estimated;
454
502
  if (reasoningTokens > 0) {
455
503
  (message.usage as UsageWithReasoningAliases).reasoningTokens = reasoningTokens;
456
504
  }
457
505
  }
458
506
 
459
- function withReasoningTokenEstimate(
460
- source: ReturnType<typeof streamOpenAICompletions>,
461
- ): ReturnType<typeof streamOpenAICompletions> {
507
+ function withReasoningTokenEstimate(source: AssistantMessageEventStream): AssistantMessageEventStream {
462
508
  const annotated = createAssistantMessageEventStream();
463
509
  (async () => {
464
510
  try {
@@ -488,9 +534,9 @@ function withReasoningTokenEstimate(
488
534
  * tool-call events pass through unchanged.
489
535
  */
490
536
  function stripSentinelsFromStream(
491
- source: ReturnType<typeof streamOpenAICompletions>,
537
+ source: AssistantMessageEventStream,
492
538
  resolved: ResolvedModelRuntimeCapabilities,
493
- ): ReturnType<typeof streamOpenAICompletions> {
539
+ ): AssistantMessageEventStream {
494
540
  const sanitized = createAssistantMessageEventStream();
495
541
  (async () => {
496
542
  try {
@@ -576,10 +622,10 @@ function stripSentinelsFromStream(
576
622
  }
577
623
 
578
624
  function guardMalformedToolCalls(
579
- source: ReturnType<typeof streamOpenAICompletions>,
625
+ source: AssistantMessageEventStream,
580
626
  model: Model<"openai-completions">,
581
627
  context: Context,
582
- ): ReturnType<typeof streamOpenAICompletions> {
628
+ ): AssistantMessageEventStream {
583
629
  const requiredByTool = new Map<string, ReadonlyArray<string>>();
584
630
  for (const tool of context.tools ?? []) {
585
631
  const required = requiredToolArguments(tool);
@@ -638,16 +684,29 @@ async function ensureResidencyForModel(model: Model<"openai-completions">): Prom
638
684
  });
639
685
  }
640
686
 
641
- function withLlamaCppResidency(
687
+ async function ensureLocalResidency(
688
+ model: Model<"openai-completions">,
689
+ options: { apiKey?: string; signal?: AbortSignal },
690
+ ): Promise<Model<"openai-completions">> {
691
+ if (isLmStudioModel(model)) {
692
+ const wireModelId = await ensureLmStudioResidency(model, options);
693
+ return wireModelId === model.id ? model : { ...model, id: wireModelId };
694
+ }
695
+ await ensureResidencyForModel(model);
696
+ return model;
697
+ }
698
+
699
+ function withLocalResidency(
642
700
  model: Model<"openai-completions">,
643
- sourceFactory: () => ReturnType<typeof streamOpenAICompletions>,
644
- ): ReturnType<typeof streamOpenAICompletions> {
645
- if (!isManagedLlamaCppModel(model)) return sourceFactory();
701
+ options: { apiKey?: string; signal?: AbortSignal },
702
+ sourceFactory: (requestModel: Model<"openai-completions">) => AssistantMessageEventStream,
703
+ ): AssistantMessageEventStream {
704
+ if (!isManagedLlamaCppModel(model) && !isLmStudioModel(model)) return sourceFactory(model);
646
705
  const stream = createAssistantMessageEventStream();
647
706
  (async () => {
648
707
  try {
649
- await ensureResidencyForModel(model);
650
- for await (const event of sourceFactory()) {
708
+ const requestModel = await ensureLocalResidency(model, options);
709
+ for await (const event of sourceFactory(requestModel)) {
651
710
  stream.push(event as AssistantMessageEvent);
652
711
  }
653
712
  stream.end();
@@ -661,24 +720,35 @@ function withLlamaCppResidency(
661
720
  return stream;
662
721
  }
663
722
 
664
- export const openAICompletionsApiProvider: ApiProvider<"openai-completions", OpenAICompletionsOptions> = {
723
+ export const openAICompletionsApiProvider: EngineApiProvider<"openai-completions", OpenAICompletionsOptions> = {
665
724
  api: "openai-completions",
666
725
  stream: (model, context, options) => {
667
726
  // Bare `stream` callers don't communicate thinking state; fall back to
668
- // the model's reasoning capability so the catalog still applies.
669
- const resolved = resolvedCapabilitiesForModel(model, model.reasoning === true ? "medium" : "off");
727
+ // the model's reasoning capability so the catalog still applies. LM Studio
728
+ // is the exception because its HTTP server defaults to thinking off.
729
+ const defaultLevel = isLmStudioModel(model) ? "off" : model.reasoning === true ? "medium" : "off";
730
+ const resolved = resolvedCapabilitiesForModel(model, defaultLevel);
670
731
  const effectiveContext = stripsThinking(resolved) ? stripThinkingFromContext(context) : context;
671
732
  const withSamplers = withSamplingOverrides(model, options, resolved);
672
733
  return guardMalformedToolCalls(
673
734
  withReasoningTokenEstimate(
674
735
  stripSentinelsFromStream(
675
736
  stripNeverReasoningFromStream(
676
- withLlamaCppResidency(model, () =>
677
- streamOpenAICompletions(
737
+ filterGemmaChannelStream(
738
+ withLocalResidency(
678
739
  model,
679
- effectiveContext,
680
- withRemainingContextBudget(model, effectiveContext, withSamplers),
740
+ {
741
+ ...(options?.apiKey !== undefined ? { apiKey: options.apiKey } : {}),
742
+ ...(options?.signal !== undefined ? { signal: options.signal } : {}),
743
+ },
744
+ (requestModel) =>
745
+ piOpenAICompletions.stream(
746
+ requestModel,
747
+ effectiveContext,
748
+ withRemainingContextBudget(model, effectiveContext, withSamplers),
749
+ ),
681
750
  ),
751
+ resolved.family === "gemma-4",
682
752
  ),
683
753
  resolved,
684
754
  ),
@@ -697,12 +767,21 @@ export const openAICompletionsApiProvider: ApiProvider<"openai-completions", Ope
697
767
  withReasoningTokenEstimate(
698
768
  stripSentinelsFromStream(
699
769
  stripNeverReasoningFromStream(
700
- withLlamaCppResidency(model, () =>
701
- streamSimpleOpenAICompletions(
770
+ filterGemmaChannelStream(
771
+ withLocalResidency(
702
772
  model,
703
- effectiveContext,
704
- withRemainingContextBudget(model, effectiveContext, withSamplers),
773
+ {
774
+ ...(options?.apiKey !== undefined ? { apiKey: options.apiKey } : {}),
775
+ ...(options?.signal !== undefined ? { signal: options.signal } : {}),
776
+ },
777
+ (requestModel) =>
778
+ piOpenAICompletions.streamSimple(
779
+ requestModel,
780
+ effectiveContext,
781
+ withRemainingContextBudget(model, effectiveContext, withSamplers),
782
+ ),
705
783
  ),
784
+ resolved.family === "gemma-4",
706
785
  ),
707
786
  resolved,
708
787
  ),