@iowarp/clio-coder 0.3.3 → 0.3.6

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 (370) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/CONTRIBUTING.md +7 -7
  3. package/README.md +3 -3
  4. package/dist/{acp-P2AQILE2.js → acp-2BEHC4DL.js} +9 -8
  5. package/dist/{agents-72W3BI7I.js → agents-LNNFTM53.js} +29 -24
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5TWEIYDN.js → auth-KXXFI2VS.js} +14 -10
  8. package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
  9. package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
  10. package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
  11. package/dist/chunk-3BPUFZDL.js +37 -0
  12. package/dist/chunk-43AOLP7E.js +375 -0
  13. package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
  14. package/dist/{chunk-6SGHMWE3.js → chunk-5JGRAMKL.js} +5 -5
  15. package/dist/{chunk-V6RTAOC2.js → chunk-6US73PDB.js} +572 -51
  16. package/dist/{chunk-5UFT4SUX.js → chunk-6XXKFVSN.js} +3 -3
  17. package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
  18. package/dist/chunk-AOCYTWAV.js +449 -0
  19. package/dist/chunk-CFGTUFWB.js +67 -0
  20. package/dist/chunk-CJUB2JJ2.js +1478 -0
  21. package/dist/{chunk-FNTMWMX5.js → chunk-CKXWIANG.js} +14 -12
  22. package/dist/{chunk-PIWWS5BL.js → chunk-CYQKWTG3.js} +63 -78
  23. package/dist/{chunk-LZSJBIVT.js → chunk-DJVECN66.js} +271 -762
  24. package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
  25. package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
  26. package/dist/{chunk-STBPMHSX.js → chunk-EKY57CSP.js} +51 -84
  27. package/dist/{chunk-DUYJ5IO6.js → chunk-EYPA3EGJ.js} +12 -4
  28. package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
  29. package/dist/chunk-FYYLNIL5.js +313 -0
  30. package/dist/{chunk-OQ33BKR3.js → chunk-G7MUEIGA.js} +3 -60
  31. package/dist/chunk-GEYXPTRF.js +613 -0
  32. package/dist/chunk-GOXNB3AO.js +261 -0
  33. package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
  34. package/dist/chunk-HWUFFB6L.js +83 -0
  35. package/dist/{chunk-4XUGQOHA.js → chunk-K7T3E2SR.js} +15 -8
  36. package/dist/chunk-K7VKOLQQ.js +15 -0
  37. package/dist/{chunk-UFIIWP2H.js → chunk-KHSFENX2.js} +8 -8
  38. package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
  39. package/dist/chunk-LCGCVYZ4.js +57 -0
  40. package/dist/chunk-LL4KHSZI.js +22 -0
  41. package/dist/{chunk-PAJK6MAQ.js → chunk-LYF7OHWH.js} +42 -15
  42. package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
  43. package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
  44. package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
  45. package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
  46. package/dist/chunk-ODFEOB4F.js +1082 -0
  47. package/dist/{chunk-AGYYIBLL.js → chunk-OH3TOQTB.js} +6 -2
  48. package/dist/chunk-OZNBF4L3.js +23 -0
  49. package/dist/{chunk-DSELYM6W.js → chunk-PBTHKCPN.js} +30 -10
  50. package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
  51. package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
  52. package/dist/{chunk-SRDMMSEP.js → chunk-QM3F2GKX.js} +1063 -1645
  53. package/dist/{chunk-X6IAEBZR.js → chunk-QNQHSOLF.js} +7 -7
  54. package/dist/{chunk-OC7FIQPC.js → chunk-R46L2BIR.js} +10 -7
  55. package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
  56. package/dist/{chunk-6N5PTWMY.js → chunk-RY3LY4J5.js} +50 -13
  57. package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
  58. package/dist/{chunk-OOJYHWRB.js → chunk-TSHXZTOQ.js} +6 -5
  59. package/dist/chunk-TZSKNMZG.js +434 -0
  60. package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
  61. package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
  62. package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
  63. package/dist/chunk-W6GROXXM.js +69 -0
  64. package/dist/{chunk-OAO4GE4M.js → chunk-WHGPSPT5.js} +2 -2
  65. package/dist/chunk-WHJYKASB.js +677 -0
  66. package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
  67. package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
  68. package/dist/{chunk-TZTZS7QK.js → chunk-XE2VEJHX.js} +5 -3
  69. package/dist/{chunk-LM5TQCJZ.js → chunk-XF5N4U5A.js} +8 -7
  70. package/dist/{chunk-LWLEKMDQ.js → chunk-XXQNGV4M.js} +1073 -552
  71. package/dist/{chunk-KZWTDYJF.js → chunk-XYDYPRZI.js} +7 -7
  72. package/dist/chunk-ZGVHUX3M.js +66 -0
  73. package/dist/{chunk-LW6DSM3M.js → chunk-ZRGEBJ4T.js} +1192 -1119
  74. package/dist/{chunk-2DJ2KNFG.js → chunk-ZXF4XRKW.js} +202 -40
  75. package/dist/chunk-ZZMN5OM4.js +122 -0
  76. package/dist/cli/index.js +34 -30
  77. package/dist/{clio-JOU4FXVA.js → clio-M2KGYUFZ.js} +7 -6
  78. package/dist/{code-nav-7AX6FYE6.js → code-nav-GQNL7XA6.js} +8 -6
  79. package/dist/codewiki/build-worker.js +4 -4
  80. package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
  81. package/dist/{config-XCDVKR23.js → config-XUUYQIWO.js} +47 -35
  82. package/dist/{configure-4GAP54ZW.js → configure-IHJ7YOMV.js} +18 -15
  83. package/dist/{context-77FM5DV5.js → context-74JLXAWD.js} +18 -10
  84. package/dist/{context-4UOGGLQ5.js → context-75MIWW3U.js} +41 -29
  85. package/dist/{context-5VKGUVJJ.js → context-ZQ7SIFJV.js} +85 -9
  86. package/dist/{context-clear-XXJRLCJJ.js → context-clear-GYKWNUML.js} +41 -29
  87. package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
  88. package/dist/context-working-set-UX5KEP4J.js +1553 -0
  89. package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-GIJBHNFL.js} +47 -32
  90. package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
  91. package/dist/{doctor-HR46URBJ.js → doctor-SVJ5BZCW.js} +12 -12
  92. package/dist/{eval-XSSNATB4.js → eval-CG6LLBLD.js} +54 -238
  93. package/dist/{evidence-6HG2PY2B.js → evidence-ZYFIEN42.js} +57 -28
  94. package/dist/{evolve-K7YU3NCY.js → evolve-QGEXEMDW.js} +36 -25
  95. package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
  96. package/dist/{fleet-VY3HHKN6.js → fleet-S5R4ZOQY.js} +73 -44
  97. package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-BHSNPBMH.js} +3 -3
  98. package/dist/{init-JYGXI3FK.js → init-5DRU55YR.js} +49 -37
  99. package/dist/memory-7YKKR6UC.js +467 -0
  100. package/dist/{models-I5QWSEOM.js → models-ZPOLRU2C.js} +24 -21
  101. package/dist/{monitor-GE4ID3IA.js → monitor-US5F5YGZ.js} +73 -46
  102. package/dist/{orchestrator-EM5MC3HM.js → orchestrator-E2AL4T5N.js} +1624 -1007
  103. package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
  104. package/dist/{reset-L2FQEE3E.js → reset-KZ652EK6.js} +6 -5
  105. package/dist/{run-ZU3QMZPZ.js → run-SRNBKDWD.js} +76 -54
  106. package/dist/{share-S5BZQC5I.js → share-CGZE33UP.js} +7 -6
  107. package/dist/{skills-X5VXCRNQ.js → skills-S2X4DLY5.js} +4 -4
  108. package/dist/{skills-eval-WKIHWTHR.js → skills-eval-W2GGIC4R.js} +40 -29
  109. package/dist/{targets-SNCPI2NR.js → targets-54SWINWB.js} +28 -23
  110. package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-SAIF2OGY.js} +6 -4
  111. package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
  112. package/dist/{upgrade-JQHHPQ4K.js → upgrade-JKAR27XC.js} +20 -19
  113. package/dist/{usage-OR4O5SMZ.js → usage-MSAWCLX4.js} +79 -36
  114. package/dist/verifiers-NCBTHHN2.js +1220 -0
  115. package/dist/verify-X5HDROLA.js +25 -0
  116. package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-GUSOQ6ZP.js} +50 -37
  117. package/dist/worker/entry.js +90 -70
  118. package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
  119. package/docs/README.md +8 -7
  120. package/docs/acp.md +1 -1
  121. package/docs/alcf-provider.md +1 -1
  122. package/docs/architecture.md +2 -2
  123. package/docs/artifact-placement.md +1 -2
  124. package/docs/artifact-versions.md +1 -1
  125. package/docs/built-in-agents.md +1 -1
  126. package/docs/capacity-and-scheduling.md +1 -1
  127. package/docs/commands-and-modes.md +60 -26
  128. package/docs/config-knobs-audit.md +1 -2
  129. package/docs/configuration-and-targets.md +26 -1
  130. package/docs/context-engine.md +67 -13
  131. package/docs/context-working-set.md +194 -0
  132. package/docs/development-pipeline.md +1 -1
  133. package/docs/documentation-coverage.md +6 -6
  134. package/docs/documentation-guide.md +7 -6
  135. package/docs/environment-variables.md +2 -1
  136. package/docs/eval-runner.md +1 -1
  137. package/docs/evals-internal.md +4 -32
  138. package/docs/evidence-and-memory.md +139 -7
  139. package/docs/evolution.md +1 -1
  140. package/docs/exit-codes-and-output.md +1 -1
  141. package/docs/extensions-and-sharing.md +2 -2
  142. package/docs/fleet-dispatch.md +49 -8
  143. package/docs/glossary.md +21 -1
  144. package/docs/installation-and-lifecycle.md +2 -2
  145. package/docs/middleware-and-components.md +19 -2
  146. package/docs/model-catalog.md +7 -9
  147. package/docs/observability.md +4 -4
  148. package/docs/proactive-memory.md +26 -16
  149. package/docs/prompt-envelope-and-tools.md +7 -5
  150. package/docs/provider-adapter-cookbook.md +1 -1
  151. package/docs/release-cut-checklist.md +43 -40
  152. package/docs/safety-model.md +49 -8
  153. package/docs/scientific-validation.md +21 -3
  154. package/docs/session-lifecycle.md +3 -3
  155. package/docs/skills-marketplace.md +1 -1
  156. package/docs/tool-usage.md +79 -12
  157. package/docs/trace-store.md +1 -1
  158. package/docs/troubleshooting.md +1 -1
  159. package/docs/tui-design.md +38 -4
  160. package/docs/worker-dispatch-mechanics.md +11 -1
  161. package/package.json +13 -13
  162. package/skills/meta/clio-test/SKILL.md +20 -17
  163. package/skills/meta/clio-test/evals.md +3 -3
  164. package/skills/meta/clio-test/references/harness.md +35 -6
  165. package/skills/meta/clio-test/references/test-map.md +20 -10
  166. package/skills/registry.yaml +2 -2
  167. package/skills/skill-marketplace.json +1 -1
  168. package/src/cli/agents.ts +2 -3
  169. package/src/cli/argv.ts +14 -1
  170. package/src/cli/context-working-set.ts +513 -0
  171. package/src/cli/context.ts +8 -0
  172. package/src/cli/evidence.ts +20 -2
  173. package/src/cli/fleet.ts +15 -0
  174. package/src/cli/index.ts +5 -1
  175. package/src/cli/memory.ts +272 -10
  176. package/src/cli/modes/json-stream.ts +2 -2
  177. package/src/cli/modes/print.ts +12 -1
  178. package/src/cli/run.ts +22 -2
  179. package/src/cli/targets.ts +12 -3
  180. package/src/cli/usage.ts +55 -7
  181. package/src/cli/verifiers.ts +325 -0
  182. package/src/core/bash-exec.ts +39 -14
  183. package/src/core/bus-events.ts +22 -4
  184. package/src/core/config.ts +54 -0
  185. package/src/core/defaults.ts +50 -3
  186. package/src/core/response-model-id.ts +134 -0
  187. package/src/core/toml.ts +62 -0
  188. package/src/core/verification-scripts.ts +6 -0
  189. package/src/core/workspace-files.ts +0 -1
  190. package/src/domains/agents/builtins/architect.md +1 -1
  191. package/src/domains/agents/builtins/verifier.md +3 -0
  192. package/src/domains/agents/catalog.ts +5 -4
  193. package/src/domains/agents/recipe.ts +54 -14
  194. package/src/domains/agents/result-contract.ts +7 -4
  195. package/src/domains/config/classify.ts +1 -0
  196. package/src/domains/context/bootstrap.ts +36 -27
  197. package/src/domains/context/project-metadata.ts +19 -63
  198. package/src/domains/context/prompt-context.ts +8 -0
  199. package/src/domains/context/working-set/contract.ts +161 -0
  200. package/src/domains/context/working-set/defaults.ts +28 -0
  201. package/src/domains/context/working-set/engine.ts +203 -0
  202. package/src/domains/context/working-set/fold.ts +62 -0
  203. package/src/domains/context/working-set/horizon.ts +38 -0
  204. package/src/domains/context/working-set/marker.ts +103 -0
  205. package/src/domains/context/working-set/path-index.ts +436 -0
  206. package/src/domains/context/working-set/payload.ts +152 -0
  207. package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
  208. package/src/domains/context/working-set/policies/index.ts +20 -0
  209. package/src/domains/context/working-set/policies/structural.ts +160 -0
  210. package/src/domains/context/working-set/project.ts +132 -0
  211. package/src/domains/context/working-set/protect.ts +109 -0
  212. package/src/domains/context/working-set/recall.ts +177 -0
  213. package/src/domains/context/working-set/replay/controls.ts +112 -0
  214. package/src/domains/context/working-set/replay/load-clio.ts +199 -0
  215. package/src/domains/context/working-set/replay/metrics.ts +185 -0
  216. package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
  217. package/src/domains/context/working-set/replay/report.ts +139 -0
  218. package/src/domains/context/working-set/replay/runner.ts +325 -0
  219. package/src/domains/context/working-set/replay/synthetic.ts +422 -0
  220. package/src/domains/context/working-set/replay/trace.ts +21 -0
  221. package/src/domains/context/working-set/visible.ts +54 -0
  222. package/src/domains/dispatch/budget-envelope.ts +396 -0
  223. package/src/domains/dispatch/contract.ts +2 -0
  224. package/src/domains/dispatch/extension.ts +81 -27
  225. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  226. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  227. package/src/domains/dispatch/state.ts +1 -0
  228. package/src/domains/dispatch/types.ts +10 -3
  229. package/src/domains/dispatch/validation.ts +14 -0
  230. package/src/domains/dispatch/worker-spawn.ts +14 -3
  231. package/src/domains/eval/metrics/evidence.ts +0 -116
  232. package/src/domains/eval/metrics/invariants.ts +1 -1
  233. package/src/domains/eval/runners/clio-run.ts +1 -10
  234. package/src/domains/eval/runners/external-command.ts +2 -29
  235. package/src/domains/eval/schema/suite.ts +0 -7
  236. package/src/domains/eval/suites/run.ts +1 -7
  237. package/src/domains/evidence/build.ts +112 -45
  238. package/src/domains/evidence/eval.ts +24 -7
  239. package/src/domains/evidence/index.ts +53 -0
  240. package/src/domains/evidence/ordering.ts +12 -0
  241. package/src/domains/evidence/run-trust.ts +221 -0
  242. package/src/domains/evidence/store.ts +46 -6
  243. package/src/domains/evidence/trust-status.ts +854 -0
  244. package/src/domains/evidence/types.ts +26 -0
  245. package/src/domains/memory/index.ts +22 -0
  246. package/src/domains/memory/operations.ts +58 -1
  247. package/src/domains/memory/promotion.ts +281 -0
  248. package/src/domains/memory/prompt-section.ts +25 -5
  249. package/src/domains/memory/proposal.ts +51 -7
  250. package/src/domains/memory/task-bank.ts +3 -2
  251. package/src/domains/memory/task-memory-handoff.ts +181 -24
  252. package/src/domains/memory/task-memory-policy.ts +3 -1
  253. package/src/domains/memory/types.ts +37 -0
  254. package/src/domains/memory/validate.ts +178 -0
  255. package/src/domains/middleware/memory-intervention.ts +38 -25
  256. package/src/domains/middleware/runtime.ts +6 -0
  257. package/src/domains/middleware/skills-reminder.ts +19 -4
  258. package/src/domains/middleware/stalled-turn.ts +208 -5
  259. package/src/domains/middleware/types.ts +10 -0
  260. package/src/domains/observability/contract.ts +6 -1
  261. package/src/domains/observability/cost.ts +20 -4
  262. package/src/domains/observability/extension.ts +2 -2
  263. package/src/domains/providers/index.ts +3 -0
  264. package/src/domains/providers/model-discovery.ts +9 -0
  265. package/src/domains/providers/runtime-resolution.ts +38 -1
  266. package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
  267. package/src/domains/providers/types/context-window-slots.ts +18 -0
  268. package/src/domains/providers/types/runtime-descriptor.ts +3 -1
  269. package/src/domains/safety/autonomy.ts +1 -1
  270. package/src/domains/safety/call-target.ts +211 -14
  271. package/src/domains/safety/decision-presentation.ts +268 -0
  272. package/src/domains/safety/default-path-policy.ts +8 -0
  273. package/src/domains/safety/finish-contract.ts +4 -3
  274. package/src/domains/safety/policy-engine.ts +48 -6
  275. package/src/domains/safety/redaction.ts +73 -0
  276. package/src/domains/session/compaction/compact.ts +23 -1
  277. package/src/domains/session/compaction/cut-point.ts +2 -0
  278. package/src/domains/session/compaction/tokens.ts +16 -1
  279. package/src/domains/session/context-ledger.ts +12 -1
  280. package/src/domains/session/decision-board.ts +4 -0
  281. package/src/domains/session/entries.ts +110 -1
  282. package/src/domains/session/history.ts +68 -19
  283. package/src/domains/session/manager.ts +9 -2
  284. package/src/domains/session/migrations/index.ts +22 -3
  285. package/src/domains/session/usage.ts +24 -7
  286. package/src/engine/acp/event-mapper.ts +7 -0
  287. package/src/engine/acp/server.ts +32 -2
  288. package/src/engine/agent.ts +18 -1
  289. package/src/engine/apis/lmstudio.ts +25 -4
  290. package/src/engine/apis/openai-completions.ts +147 -22
  291. package/src/engine/claude/sdk-runtime.ts +8 -2
  292. package/src/engine/claude/tool-safety.ts +13 -0
  293. package/src/engine/loop-guard.ts +27 -3
  294. package/src/engine/session.ts +9 -3
  295. package/src/engine/worker-events.ts +4 -3
  296. package/src/engine/worker-runtime.ts +59 -54
  297. package/src/entry/orchestrator.ts +34 -5
  298. package/src/interactive/chat-loop-messages.ts +40 -6
  299. package/src/interactive/chat-loop.ts +13 -0
  300. package/src/interactive/chat-panel.ts +17 -1
  301. package/src/interactive/chat-renderer.ts +49 -24
  302. package/src/interactive/clio-editor.ts +44 -7
  303. package/src/interactive/context-meter.ts +10 -0
  304. package/src/interactive/context-overlay.ts +120 -7
  305. package/src/interactive/context-recall-command.ts +110 -0
  306. package/src/interactive/cost-overlay.ts +39 -8
  307. package/src/interactive/dispatch-board.ts +212 -35
  308. package/src/interactive/footer/widgets.ts +13 -0
  309. package/src/interactive/interactive-application.ts +6 -1
  310. package/src/interactive/interactive-input-runtime.ts +11 -1
  311. package/src/interactive/interactive-presentation.ts +11 -1
  312. package/src/interactive/interactive-slash-runtime.ts +37 -1
  313. package/src/interactive/memory-overlay.ts +89 -4
  314. package/src/interactive/model-session-replay.ts +21 -0
  315. package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
  316. package/src/interactive/overlay-frame.ts +5 -2
  317. package/src/interactive/overlay-general-openers.ts +46 -1
  318. package/src/interactive/overlay-key-routing.ts +41 -1
  319. package/src/interactive/overlay-lifecycle.ts +11 -4
  320. package/src/interactive/overlay-permission-lifecycle.ts +23 -8
  321. package/src/interactive/overlay-session-lifecycle.ts +8 -4
  322. package/src/interactive/overlay-transitions.ts +11 -0
  323. package/src/interactive/overlays/ask-user.ts +74 -30
  324. package/src/interactive/overlays/decisions.ts +3 -1
  325. package/src/interactive/permission-hint.ts +35 -0
  326. package/src/interactive/permission-overlay.ts +95 -45
  327. package/src/interactive/renderers/tool-execution.ts +37 -51
  328. package/src/interactive/session-last-turn.ts +8 -1
  329. package/src/interactive/session-transcript.ts +2 -2
  330. package/src/interactive/session-usage-reseed.ts +36 -10
  331. package/src/interactive/slash-commands.ts +31 -4
  332. package/src/interactive/status/summary.ts +5 -0
  333. package/src/interactive/status/types.ts +5 -0
  334. package/src/interactive/terminal-lease.ts +1 -0
  335. package/src/interactive/turn-context.ts +333 -110
  336. package/src/interactive/turn-middleware.ts +7 -6
  337. package/src/interactive/turn-runtime.ts +37 -8
  338. package/src/interactive/turn-state.ts +3 -0
  339. package/src/interactive/worker-progress.ts +440 -0
  340. package/src/interactive/worker-stream.ts +51 -110
  341. package/src/tools/agent-tools.ts +39 -7
  342. package/src/tools/ask-user.ts +21 -1
  343. package/src/tools/bash.ts +144 -82
  344. package/src/tools/builtin-tool-catalog.ts +11 -5
  345. package/src/tools/context/index.ts +107 -5
  346. package/src/tools/context/surface.ts +3 -2
  347. package/src/tools/core-bootstrap.ts +21 -0
  348. package/src/tools/dispatch-arguments.ts +8 -0
  349. package/src/tools/dispatch-event-text.ts +19 -0
  350. package/src/tools/dispatch-runner.ts +9 -7
  351. package/src/tools/dispatch.ts +24 -1
  352. package/src/tools/monitor.ts +43 -20
  353. package/src/tools/registry.ts +72 -10
  354. package/src/tools/result-disposition.ts +706 -0
  355. package/src/tools/result-shaping.ts +321 -20
  356. package/src/tools/safe-exec.ts +2 -0
  357. package/src/tools/verify/authoring.ts +1120 -0
  358. package/src/tools/verify/catalog.ts +346 -0
  359. package/src/tools/verify/index.ts +13 -3
  360. package/src/tools/verify/scripts.ts +135 -37
  361. package/src/tools/verify/surface.ts +9 -5
  362. package/src/tools/worker-evidence.ts +54 -12
  363. package/src/worker/spec-contract.ts +43 -3
  364. package/dist/chunk-J7CWMCQD.js +0 -255
  365. package/dist/chunk-T6YILFSB.js +0 -80
  366. package/dist/chunk-VAKQQHWR.js +0 -434
  367. package/dist/chunk-VPAYEGVX.js +0 -184
  368. package/dist/chunk-XBXAASKX.js +0 -18
  369. package/dist/memory-WFZMGYHX.js +0 -236
  370. package/src/domains/eval/metrics/chaos-stream.ts +0 -93
@@ -1,10 +1,14 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
+ import {
3
+ createSentinelStripper,
4
+ stripTokenizerSentinels
5
+ } from "./chunk-CFGTUFWB.js";
2
6
  import {
3
7
  readSettings
4
- } from "./chunk-A3CYT5EX.js";
8
+ } from "./chunk-AD2SYQYC.js";
5
9
  import {
6
10
  THINKING_LEVELS
7
- } from "./chunk-ZDOOVTXZ.js";
11
+ } from "./chunk-4OC57DA6.js";
8
12
  import {
9
13
  authNotRequiredStatus,
10
14
  openAuthStorage,
@@ -13,10 +17,6 @@ import {
13
17
  resolveRuntimeAuthTarget,
14
18
  targetRequiresAuth
15
19
  } from "./chunk-4VP4KH3K.js";
16
- import {
17
- cwdHash,
18
- sessionPaths
19
- } from "./chunk-M6SHUN7Q.js";
20
20
  import {
21
21
  sleep
22
22
  } from "./chunk-FQ4SKYE4.js";
@@ -24,8 +24,10 @@ import {
24
24
  withStateFileLock
25
25
  } from "./chunk-IKCO5N3L.js";
26
26
  import {
27
- require_dist
28
- } from "./chunk-APJ265NV.js";
27
+ ceilChars,
28
+ estimateAgentMessageTokens,
29
+ toolSchemaChars
30
+ } from "./chunk-GEYXPTRF.js";
29
31
  import {
30
32
  activateExternalPluginApiBridge,
31
33
  calculateEngineCost,
@@ -34,15 +36,20 @@ import {
34
36
  getEngineSupportedThinkingLevels,
35
37
  registerEngineApiProvider
36
38
  } from "./chunk-FCSXB6T2.js";
39
+ import {
40
+ require_dist
41
+ } from "./chunk-APJ265NV.js";
37
42
  import {
38
43
  clioConfigDir,
39
44
  clioStatePath,
40
45
  resolveClioDirs
41
46
  } from "./chunk-BNAZZHFG.js";
42
47
  import {
43
- BusChannels,
44
48
  getSharedBus
45
- } from "./chunk-OQ33BKR3.js";
49
+ } from "./chunk-ZGVHUX3M.js";
50
+ import {
51
+ BusChannels
52
+ } from "./chunk-G7MUEIGA.js";
46
53
  import {
47
54
  __toESM,
48
55
  init_esm_shims
@@ -363,597 +370,15 @@ function credentialsPresent() {
363
370
  return present;
364
371
  }
365
372
 
366
- // src/domains/session/context-accounting.ts
367
- init_esm_shims();
368
- import { appendFileSync, existsSync, readFileSync } from "node:fs";
369
- import { dirname, join as join2 } from "node:path";
370
-
371
- // src/domains/session/compaction/auto.ts
372
- init_esm_shims();
373
- var DEFAULT_COMPACTION_THRESHOLD = 0.8;
374
- function shouldCompact(contextTokens, threshold, contextWindow) {
375
- const base = {
376
- shouldCompact: false,
377
- pressure: null,
378
- contextTokens,
379
- contextWindow,
380
- threshold
381
- };
382
- if (!Number.isFinite(threshold) || threshold <= 0 || threshold > 1) return base;
383
- if (!Number.isFinite(contextTokens) || contextTokens <= 0) return base;
384
- if (!Number.isFinite(contextWindow) || contextWindow <= 0) return base;
385
- const pressure = contextTokens / contextWindow;
386
- return {
387
- shouldCompact: pressure >= threshold,
388
- pressure,
389
- contextTokens,
390
- contextWindow,
391
- threshold
392
- };
393
- }
394
- var AutoCompactionTrigger = class {
395
- inFlight = null;
396
- /** True while a task is in flight. Callers can short-circuit on this. */
397
- isBusy() {
398
- return this.inFlight !== null;
399
- }
400
- /**
401
- * Run `task` unless one is already in flight. Returns the Promise the
402
- * task is running under. Callers always get the eventual result of the
403
- * first task, never a second call. Rejections clear the slot so a later
404
- * fire can start fresh.
405
- */
406
- fire(task) {
407
- if (this.inFlight) return this.inFlight;
408
- const run = task().finally(() => {
409
- this.inFlight = null;
410
- });
411
- this.inFlight = run;
412
- return run;
413
- }
414
- };
415
-
416
- // src/domains/session/context-ledger.ts
417
- init_esm_shims();
418
- var SEGMENT_CATEGORY = {
419
- identity: "system",
420
- "operating-contract": "system",
421
- delegation: "agents",
422
- skills: "skills",
423
- safety: "system",
424
- runtime: "system",
425
- "tool-contract": "system",
426
- "retrieval-hints": "system",
427
- "tool-catalog": "tools",
428
- "tools-and-agents": "agents",
429
- "agent-fleet-deltas": "agents",
430
- "skills-catalog": "skills",
431
- memory: "memory",
432
- "project-context": "project",
433
- "context.project-rules": "project",
434
- "context.operator-profile": "memory",
435
- "context.clio-repo-awareness": "system",
436
- "history-summary": "messages"
437
- };
438
- var CONTEXT_CATEGORY_LABEL = {
439
- system: "System prompt",
440
- tools: "Tool definitions",
441
- agents: "Agent fleet",
442
- skills: "Skills",
443
- memory: "Memory",
444
- project: "Project context",
445
- messages: "Messages",
446
- pending: "Pending input",
447
- reserve: "Autocompact reserve",
448
- free: "Free space",
449
- streaming: "Streaming output"
450
- };
451
- var CONTENT_ORDER = [
452
- "system",
453
- "tools",
454
- "agents",
455
- "skills",
456
- "memory",
457
- "project",
458
- "messages",
459
- "pending",
460
- "streaming"
461
- ];
462
- function categoryForSegment(id) {
463
- return SEGMENT_CATEGORY[id] ?? "system";
464
- }
465
- function finiteNonNegative(value) {
466
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
467
- }
468
- function percentOf(tokens, window) {
469
- if (window <= 0) return null;
470
- return Math.min(100, tokens / window * 100);
471
- }
472
- function buildContextLedger(input) {
473
- const window = finiteNonNegative(input.contextWindow);
474
- const raw = {
475
- system: 0,
476
- tools: 0,
477
- agents: 0,
478
- skills: 0,
479
- memory: 0,
480
- project: 0,
481
- messages: 0,
482
- pending: 0,
483
- reserve: 0,
484
- free: 0,
485
- streaming: 0
486
- };
487
- const segments = input.promptSegments ?? [];
488
- if (segments.length > 0) {
489
- for (const segment of segments) {
490
- raw[categoryForSegment(segment.id)] += finiteNonNegative(segment.tokenEstimate);
491
- }
492
- } else {
493
- raw.system += finiteNonNegative(input.systemPromptTokens);
494
- }
495
- raw.tools += finiteNonNegative(input.toolSchemaTokens);
496
- raw.messages += finiteNonNegative(input.messageTokens);
497
- raw.pending += finiteNonNegative(input.pendingTokens);
498
- raw.streaming += finiteNonNegative(input.streamingTokens);
499
- raw.agents += finiteNonNegative(input.agentsTokens);
500
- raw.skills += finiteNonNegative(input.skillsTokens);
501
- raw.memory += finiteNonNegative(input.memoryTokens);
502
- raw.project += finiteNonNegative(input.projectTokens);
503
- const decomposed = CONTENT_ORDER.reduce((sum, category) => sum + raw[category], 0);
504
- const liveTotal = finiteNonNegative(input.liveTotalTokens);
505
- if (liveTotal > decomposed) {
506
- raw.messages += liveTotal - decomposed;
507
- }
508
- const usedTokens = Math.max(decomposed, liveTotal);
509
- const effectiveThreshold = typeof input.compactionThreshold === "number" && input.compactionThreshold > 0 && input.compactionThreshold < 1 ? input.compactionThreshold : input.compactionAuto ? DEFAULT_COMPACTION_THRESHOLD : null;
510
- let reserveTokens = 0;
511
- let freeTokens = 0;
512
- if (window > 0) {
513
- const remaining = Math.max(0, window - usedTokens);
514
- reserveTokens = effectiveThreshold !== null ? Math.min(Math.round(window * (1 - effectiveThreshold)), remaining) : 0;
515
- freeTokens = Math.max(0, window - usedTokens - reserveTokens);
516
- }
517
- const groups = [];
518
- for (const category of CONTENT_ORDER) {
519
- const tokens = raw[category];
520
- if (tokens <= 0) continue;
521
- groups.push({
522
- category,
523
- label: CONTEXT_CATEGORY_LABEL[category],
524
- tokens,
525
- percent: percentOf(tokens, window)
526
- });
527
- }
528
- const meter = [...groups];
529
- if (reserveTokens > 0) {
530
- meter.push({
531
- category: "reserve",
532
- label: CONTEXT_CATEGORY_LABEL.reserve,
533
- tokens: reserveTokens,
534
- percent: percentOf(reserveTokens, window)
535
- });
536
- }
537
- if (window > 0) {
538
- meter.push({
539
- category: "free",
540
- label: CONTEXT_CATEGORY_LABEL.free,
541
- tokens: freeTokens,
542
- percent: percentOf(freeTokens, window)
543
- });
544
- }
545
- return {
546
- provider: input.provider ?? null,
547
- model: input.model ?? null,
548
- contextWindow: window,
549
- contextWindowSource: input.contextWindowSource ?? null,
550
- usedTokens,
551
- reserveTokens,
552
- freeTokens,
553
- percent: percentOf(usedTokens, window),
554
- measured: input.measured === true && liveTotal > 0,
555
- compactionThreshold: effectiveThreshold,
556
- compactionAuto: input.compactionAuto === true,
557
- projectPreload: input.projectPreload ?? null,
558
- projectHandbookFiles: input.projectHandbookFiles ?? null,
559
- toolCount: Math.max(0, Math.floor(input.toolCount ?? 0)),
560
- groups,
561
- meter,
562
- lastCompaction: input.lastCompaction ?? null,
563
- promptCache: input.promptCache ?? null
564
- };
565
- }
566
-
567
- // src/domains/session/context-accounting.ts
568
- var IMAGE_CHAR_ESTIMATE = 4800;
569
- var TOKEN_CHARS = 4;
570
- var MESSAGE_OVERHEAD_TOKENS = 16;
571
- function ceilChars(chars) {
572
- return Math.ceil(Math.max(0, chars) / TOKEN_CHARS);
573
- }
574
- function isRecord(value) {
575
- return !!value && typeof value === "object" && !Array.isArray(value);
576
- }
577
- function jsonLength(value) {
578
- if (value === void 0 || value === null) return 0;
579
- if (typeof value === "string") return value.length;
580
- if (typeof value === "number" || typeof value === "boolean") return String(value).length;
581
- try {
582
- return JSON.stringify(value).length;
583
- } catch {
584
- return String(value).length;
585
- }
586
- }
587
- function argsLength(value) {
588
- if (value === void 0 || value === null) return 0;
589
- return typeof value === "string" ? value.length : jsonLength(value);
590
- }
591
- function blockChars(block) {
592
- if (typeof block === "string") return block.length;
593
- if (!isRecord(block)) return jsonLength(block);
594
- if (block.type === "text" && typeof block.text === "string") return block.text.length;
595
- if (block.type === "thinking" && typeof block.thinking === "string") return block.thinking.length;
596
- if (block.type === "image") return IMAGE_CHAR_ESTIMATE;
597
- if (block.type === "toolCall") {
598
- const name = typeof block.name === "string" ? block.name : "";
599
- const id = typeof block.id === "string" ? block.id : "";
600
- return id.length + name.length + argsLength(block.arguments ?? block.args ?? block.input);
601
- }
602
- if (Array.isArray(block.content)) return contentChars(block.content);
603
- if (typeof block.text === "string") return block.text.length;
604
- if (typeof block.thinking === "string") return block.thinking.length;
605
- return jsonLength(block);
606
- }
607
- function contentChars(content) {
608
- if (typeof content === "string") return content.length;
609
- if (!Array.isArray(content)) return jsonLength(content);
610
- return content.reduce((sum, block) => sum + blockChars(block), 0);
611
- }
612
- function messageChars(message) {
613
- if (!isRecord(message)) return jsonLength(message);
614
- let chars = 0;
615
- chars += typeof message.role === "string" ? message.role.length : 0;
616
- const payload = message.payload !== void 0 ? message.payload : message.content;
617
- chars += contentChars(payload);
618
- chars += typeof message.toolCallId === "string" ? message.toolCallId.length : 0;
619
- chars += typeof message.toolName === "string" ? message.toolName.length : 0;
620
- chars += typeof message.errorMessage === "string" ? message.errorMessage.length : 0;
621
- return chars;
622
- }
623
- function toolSchemaChars(tool) {
624
- if (!isRecord(tool)) return jsonLength(tool);
625
- const name = typeof tool.name === "string" ? tool.name.length : 0;
626
- const description = typeof tool.description === "string" ? tool.description.length : 0;
627
- const parameters = jsonLength(tool.parameters);
628
- return name + description + parameters;
629
- }
630
- function usageTotalTokens(usage) {
631
- if (!isRecord(usage)) return null;
632
- const total = usage.totalTokens;
633
- if (typeof total === "number" && Number.isFinite(total) && total > 0) return total;
634
- const input = typeof usage.input === "number" && Number.isFinite(usage.input) ? usage.input : 0;
635
- const output = typeof usage.output === "number" && Number.isFinite(usage.output) ? usage.output : 0;
636
- const cacheRead = typeof usage.cacheRead === "number" && Number.isFinite(usage.cacheRead) ? usage.cacheRead : 0;
637
- const cacheWrite = typeof usage.cacheWrite === "number" && Number.isFinite(usage.cacheWrite) ? usage.cacheWrite : 0;
638
- const sum = input + output + cacheRead + cacheWrite;
639
- return sum > 0 ? sum : null;
640
- }
641
- function usageInvalidated(message) {
642
- return message.contextUsageInvalidated === true;
643
- }
644
- function latestUsableAssistantUsage(messages) {
645
- for (let i = messages.length - 1; i >= 0; i -= 1) {
646
- const message = messages[i];
647
- if (message?.role !== "assistant") continue;
648
- if (usageInvalidated(message)) continue;
649
- const stopReason = message.stopReason;
650
- if (stopReason === "error" || stopReason === "aborted") continue;
651
- const tokens = usageTotalTokens(message.usage);
652
- if (tokens !== null) return { index: i, tokens };
653
- }
654
- return null;
655
- }
656
- function finiteNonNegative2(value) {
657
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
658
- }
659
- function nestedNumber(root, path) {
660
- let current = root;
661
- for (const key of path) {
662
- if (!isRecord(current)) return null;
663
- current = current[key];
664
- }
665
- return finiteNonNegative2(current);
666
- }
667
- function estimateReasoningTextTokens(text) {
668
- if (typeof text !== "string" || text.trim().length === 0) return null;
669
- return Math.max(1, Math.round(text.length / TOKEN_CHARS));
670
- }
671
- function extractReasoningTokens(usage) {
672
- if (!isRecord(usage)) return null;
673
- const direct = finiteNonNegative2(usage.reasoningTokens) ?? finiteNonNegative2(usage.reasoning_tokens) ?? finiteNonNegative2(usage.reasoning);
674
- if (direct !== null) return direct;
675
- const paths = [
676
- ["outputDetails", "reasoningTokens"],
677
- ["output_details", "reasoning_tokens"],
678
- ["output_tokens_details", "reasoning_tokens"],
679
- ["completion_tokens_details", "reasoning_tokens"],
680
- ["completionTokensDetails", "reasoningTokens"],
681
- ["details", "reasoningTokens"]
682
- ];
683
- for (const path of paths) {
684
- const value = nestedNumber(usage, path);
685
- if (value !== null) return value;
686
- }
687
- return null;
688
- }
689
- function estimateAgentMessageTokens(message) {
690
- return ceilChars(messageChars(message)) + MESSAGE_OVERHEAD_TOKENS;
691
- }
692
- function estimateAgentContextBreakdown(input) {
693
- return {
694
- systemPromptTokens: input.systemPrompt ? ceilChars(input.systemPrompt.length) : 0,
695
- messageTokens: input.messages.reduce((sum, message) => sum + estimateAgentMessageTokens(message), 0),
696
- pendingUserTokens: input.pendingUserText ? ceilChars(input.pendingUserText.length) : 0,
697
- toolSchemaTokens: (input.tools ?? []).reduce((sum, tool) => sum + ceilChars(toolSchemaChars(tool)), 0)
698
- };
699
- }
700
- function estimateAgentContextTokens(input) {
701
- const breakdown = estimateAgentContextBreakdown(input);
702
- const projection = breakdown.systemPromptTokens + breakdown.messageTokens + breakdown.pendingUserTokens + breakdown.toolSchemaTokens;
703
- const usage = latestUsableAssistantUsage(input.messages);
704
- if (!usage) return projection;
705
- const trailingTokens = input.messages.slice(usage.index + 1).reduce((sum, message) => sum + estimateAgentMessageTokens(message), 0);
706
- const anchored = usage.tokens + trailingTokens + breakdown.pendingUserTokens + breakdown.toolSchemaTokens;
707
- return Math.max(projection, anchored);
708
- }
709
- function contextUsageSnapshot(tokens, contextWindow, breakdown) {
710
- const window = typeof contextWindow === "number" && Number.isFinite(contextWindow) ? Math.max(0, contextWindow) : 0;
711
- const base = tokens === null || tokens <= 0 || window <= 0 ? { tokens, contextWindow: window, percent: null } : { tokens, contextWindow: window, percent: Math.min(100, tokens / window * 100) };
712
- return breakdown ? { ...base, breakdown } : base;
713
- }
714
- function getSnapshotsFilePath(meta) {
715
- const safeMeta = {
716
- ...meta,
717
- cwdHash: meta.cwdHash || cwdHash(meta.cwd || process.cwd())
718
- };
719
- const paths = sessionPaths(safeMeta);
720
- return join2(dirname(paths.current), "context-snapshots.jsonl");
721
- }
722
- function persistableSnapshot(snapshot) {
723
- const {
724
- systemPrompt: _systemPrompt,
725
- conversationMessages: _messages,
726
- activeToolSchemas: _tools,
727
- pendingUserInput: _pending,
728
- images: _images,
729
- ...slim
730
- } = snapshot;
731
- return slim;
732
- }
733
- function appendContextSnapshot(meta, snapshot) {
734
- try {
735
- const file = getSnapshotsFilePath(meta);
736
- appendFileSync(file, `${JSON.stringify(persistableSnapshot(snapshot))}
737
- `, "utf8");
738
- } catch {
739
- }
740
- }
741
- function getContextSnapshots(meta) {
742
- try {
743
- const file = getSnapshotsFilePath(meta);
744
- if (!existsSync(file)) return [];
745
- const content = readFileSync(file, "utf8");
746
- const snapshots = [];
747
- for (const line of content.split("\n")) {
748
- if (line.trim().length === 0) continue;
749
- try {
750
- snapshots.push(JSON.parse(line));
751
- } catch {
752
- }
753
- }
754
- return snapshots;
755
- } catch {
756
- return [];
757
- }
758
- }
759
- function getLatestContextSnapshot(meta) {
760
- const list = getContextSnapshots(meta);
761
- return list.at(-1) ?? null;
762
- }
763
- function buildSnapshotCategories(inputs) {
764
- const raw = {
765
- system: 0,
766
- tools: 0,
767
- agents: 0,
768
- skills: 0,
769
- memory: 0,
770
- project: 0,
771
- messages: 0
772
- };
773
- if (inputs.promptSegments && inputs.promptSegments.length > 0) {
774
- for (const segment of inputs.promptSegments) {
775
- const cat = categoryForSegment(segment.id);
776
- raw[cat] = (raw[cat] ?? 0) + segment.tokenEstimate;
777
- }
778
- } else if (inputs.systemPrompt) {
779
- raw.system += ceilChars(inputs.systemPrompt.length);
780
- }
781
- if (inputs.tools) {
782
- for (const tool of inputs.tools) {
783
- raw.tools += ceilChars(toolSchemaChars(tool));
784
- }
785
- }
786
- if (inputs.messages) {
787
- for (const msg of inputs.messages) {
788
- raw.messages += estimateAgentMessageTokens(msg);
789
- }
790
- }
791
- const decomposed = Object.keys(raw).reduce((sum, k) => sum + (raw[k] ?? 0), 0);
792
- const window = inputs.effectiveContextWindow;
793
- const threshold = inputs.compactionThreshold ?? DEFAULT_COMPACTION_THRESHOLD;
794
- let reserve = 0;
795
- let free = 0;
796
- if (window > 0) {
797
- const remaining = Math.max(0, window - decomposed);
798
- reserve = Math.min(Math.round(window * (1 - threshold)), remaining);
799
- free = Math.max(0, window - decomposed - reserve);
800
- }
801
- return {
802
- system: raw.system,
803
- tools: raw.tools,
804
- agents: raw.agents,
805
- skills: raw.skills,
806
- memory: raw.memory,
807
- project: raw.project,
808
- messages: raw.messages,
809
- reserve,
810
- free,
811
- streaming: 0
812
- };
813
- }
814
- var SNAPSHOT_SPLIT_KEYS = ["system", "tools", "agents", "skills", "memory", "project", "messages"];
815
- function estimatedSplitSources() {
816
- const splits = {};
817
- for (const key of SNAPSHOT_SPLIT_KEYS) splits[key] = "estimated";
818
- return splits;
819
- }
820
- var snapshotCounter = 0;
821
- function nextSnapshotId() {
822
- snapshotCounter += 1;
823
- return `snap-${Date.now()}-${snapshotCounter.toString(36)}-${Math.random().toString(36).slice(2, 7)}`;
824
- }
825
- function captureContextSnapshot(input) {
826
- const categories = buildSnapshotCategories({
827
- systemPrompt: input.systemPrompt,
828
- promptSegments: input.promptSegments,
829
- tools: input.activeToolSchemas,
830
- messages: input.conversationMessages,
831
- effectiveContextWindow: input.effectiveContextWindow,
832
- compactionThreshold: input.compactionThreshold
833
- });
834
- return {
835
- snapshotId: nextSnapshotId(),
836
- sessionId: input.sessionId,
837
- turnId: input.turnId,
838
- providerId: input.providerId,
839
- runtimeId: input.runtimeId,
840
- modelId: input.modelId,
841
- systemPrompt: input.systemPrompt,
842
- promptSegments: input.promptSegments ? [...input.promptSegments] : void 0,
843
- conversationMessages: [...input.conversationMessages],
844
- activeToolSchemas: [...input.activeToolSchemas],
845
- pendingUserInput: input.pendingUserInput,
846
- images: input.images ? [...input.images] : void 0,
847
- desiredContextWindow: input.desiredContextWindow,
848
- effectiveContextWindow: input.effectiveContextWindow,
849
- contextWindowSource: input.contextWindowSource,
850
- categories,
851
- sources: { total: "estimated", splits: estimatedSplitSources() },
852
- promptHash: input.promptHash,
853
- toolSignature: input.toolSignature,
854
- messageRange: input.conversationMessages.length > 0 ? { start: 0, end: input.conversationMessages.length - 1 } : void 0
855
- };
856
- }
857
- function snapshotInputTokens(snapshot) {
858
- return SNAPSHOT_SPLIT_KEYS.reduce((sum, key) => sum + (snapshot.categories[key] ?? 0), 0);
859
- }
860
- function reconcileSnapshot(snapshot, usage) {
861
- const exactInput = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
862
- const exactOutput = usage.output || 0;
863
- if (exactInput <= 0) {
864
- const updatedCategories2 = {
865
- ...snapshot.categories,
866
- streaming: exactOutput
867
- };
868
- const window2 = snapshot.effectiveContextWindow;
869
- const used2 = snapshotInputTokens(snapshot) + exactOutput;
870
- let reserve2 = snapshot.categories.reserve;
871
- let free2 = 0;
872
- if (window2 > 0) {
873
- const remaining = Math.max(0, window2 - used2);
874
- reserve2 = Math.min(reserve2, remaining);
875
- free2 = Math.max(0, window2 - used2 - reserve2);
876
- }
877
- updatedCategories2.reserve = reserve2;
878
- updatedCategories2.free = free2;
879
- return {
880
- ...snapshot,
881
- categories: updatedCategories2,
882
- sources: {
883
- total: "estimated",
884
- splits: snapshot.sources.splits
885
- }
886
- };
887
- }
888
- const keys = SNAPSHOT_SPLIT_KEYS;
889
- const currentCategories = { ...snapshot.categories };
890
- const sum = keys.reduce((s, k) => s + (currentCategories[k] ?? 0), 0);
891
- let normalized;
892
- if (sum === 0) {
893
- normalized = keys.reduce(
894
- (acc, k) => {
895
- acc[k] = k === "messages" ? exactInput : 0;
896
- return acc;
897
- },
898
- {}
899
- );
900
- } else {
901
- normalized = {};
902
- let newSum = 0;
903
- for (const key of keys) {
904
- const val = currentCategories[key] ?? 0;
905
- const norm = Math.round(val / sum * exactInput);
906
- normalized[key] = norm;
907
- newSum += norm;
908
- }
909
- const diff = exactInput - newSum;
910
- if (diff !== 0) {
911
- const largestKey = keys.reduce((a, b) => (normalized[a] ?? 0) >= (normalized[b] ?? 0) ? a : b);
912
- normalized[largestKey] = (normalized[largestKey] ?? 0) + diff;
913
- }
914
- }
915
- const updatedCategories = {
916
- ...snapshot.categories,
917
- ...normalized,
918
- streaming: exactOutput
919
- };
920
- const window = snapshot.effectiveContextWindow;
921
- const used = exactInput + exactOutput;
922
- let reserve = snapshot.categories.reserve;
923
- let free = 0;
924
- if (window > 0) {
925
- const remaining = Math.max(0, window - used);
926
- reserve = Math.min(reserve, remaining);
927
- free = Math.max(0, window - used - reserve);
928
- }
929
- updatedCategories.reserve = reserve;
930
- updatedCategories.free = free;
931
- const splitsSources = keys.reduce(
932
- (acc, k) => {
933
- acc[k] = "reconciled";
934
- return acc;
935
- },
936
- {}
937
- );
938
- return {
939
- ...snapshot,
940
- categories: updatedCategories,
941
- sources: {
942
- total: "reconciled",
943
- splits: splitsSources
944
- }
945
- };
946
- }
947
-
948
373
  // src/engine/apis/residency.ts
949
374
  init_esm_shims();
950
375
 
951
376
  // src/engine/apis/residency-lock.ts
952
377
  init_esm_shims();
953
- import { join as join3 } from "node:path";
378
+ import { join as join2 } from "node:path";
954
379
  var LOCK_WAIT_MS = 12e4;
955
380
  function lockTargetFor(targetKey) {
956
- return join3(clioStatePath(), "residency-locks", targetKey.replace(/[^a-zA-Z0-9._-]+/g, "_"));
381
+ return join2(clioStatePath(), "residency-locks", targetKey.replace(/[^a-zA-Z0-9._-]+/g, "_"));
957
382
  }
958
383
  async function withResidencyLock(targetKey, fn) {
959
384
  return withStateFileLock(lockTargetFor(targetKey), fn, {
@@ -1506,7 +931,7 @@ init_esm_shims();
1506
931
  // src/domains/providers/types/local-model-quirks.ts
1507
932
  init_esm_shims();
1508
933
  var KV_CACHE_QUANTS = ["f32", "f16", "q8_0", "q4_0", "q4_1", "iq4_nl", "q5_0", "q5_1"];
1509
- function isRecord2(value) {
934
+ function isRecord(value) {
1510
935
  return value !== null && typeof value === "object" && !Array.isArray(value);
1511
936
  }
1512
937
  function asKvCacheQuant(value) {
@@ -1525,7 +950,7 @@ function asPenalty(value) {
1525
950
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1526
951
  }
1527
952
  function extractKvCache(raw) {
1528
- if (!isRecord2(raw)) return void 0;
953
+ if (!isRecord(raw)) return void 0;
1529
954
  const out = {};
1530
955
  const k = asKvCacheQuant(raw.kQuant);
1531
956
  if (k !== void 0) out.kQuant = k;
@@ -1535,7 +960,7 @@ function extractKvCache(raw) {
1535
960
  return Object.keys(out).length > 0 ? out : void 0;
1536
961
  }
1537
962
  function extractSamplingProfile(raw) {
1538
- if (!isRecord2(raw)) return void 0;
963
+ if (!isRecord(raw)) return void 0;
1539
964
  const out = {};
1540
965
  const temperature = asPositive(raw.temperature);
1541
966
  if (temperature !== void 0) out.temperature = temperature;
@@ -1556,7 +981,7 @@ function extractSamplingProfile(raw) {
1556
981
  return Object.keys(out).length > 0 ? out : void 0;
1557
982
  }
1558
983
  function extractSampling(raw) {
1559
- if (!isRecord2(raw)) return void 0;
984
+ if (!isRecord(raw)) return void 0;
1560
985
  const out = {};
1561
986
  const thinking = extractSamplingProfile(raw.thinking);
1562
987
  if (thinking) out.thinking = thinking;
@@ -1576,7 +1001,7 @@ function asThinkingMechanism(value) {
1576
1001
  return THINKING_MECHANISMS.includes(value) ? value : void 0;
1577
1002
  }
1578
1003
  function extractBudgetByLevel(raw) {
1579
- if (!isRecord2(raw)) return void 0;
1004
+ if (!isRecord(raw)) return void 0;
1580
1005
  const out = {};
1581
1006
  const minimal = asInteger(raw.minimal);
1582
1007
  if (minimal !== void 0) out.minimal = minimal;
@@ -1591,7 +1016,7 @@ function extractBudgetByLevel(raw) {
1591
1016
  return Object.keys(out).length > 0 ? out : void 0;
1592
1017
  }
1593
1018
  function extractEffortByLevel(raw) {
1594
- if (!isRecord2(raw)) return void 0;
1019
+ if (!isRecord(raw)) return void 0;
1595
1020
  const out = {};
1596
1021
  if (typeof raw.off === "string" && raw.off.length > 0) out.off = raw.off;
1597
1022
  if (typeof raw.minimal === "string" && raw.minimal.length > 0) out.minimal = raw.minimal;
@@ -1602,7 +1027,7 @@ function extractEffortByLevel(raw) {
1602
1027
  return Object.keys(out).length > 0 ? out : void 0;
1603
1028
  }
1604
1029
  function extractThinkingQuirks(raw) {
1605
- if (!isRecord2(raw)) return void 0;
1030
+ if (!isRecord(raw)) return void 0;
1606
1031
  const mechanism = asThinkingMechanism(raw.mechanism);
1607
1032
  if (!mechanism) return void 0;
1608
1033
  const out = { mechanism };
@@ -1614,7 +1039,7 @@ function extractThinkingQuirks(raw) {
1614
1039
  return out;
1615
1040
  }
1616
1041
  function extractLocalModelQuirks(raw) {
1617
- if (!isRecord2(raw)) return void 0;
1042
+ if (!isRecord(raw)) return void 0;
1618
1043
  const out = {};
1619
1044
  const kvCache = extractKvCache(raw.kvCache);
1620
1045
  if (kvCache) out.kvCache = kvCache;
@@ -2279,7 +1704,7 @@ function targetRootUrl(target) {
2279
1704
 
2280
1705
  // src/domains/providers/runtimes/common/lmstudio-http.ts
2281
1706
  var catalogsByHost = /* @__PURE__ */ new Map();
2282
- function isRecord3(value) {
1707
+ function isRecord2(value) {
2283
1708
  return value !== null && typeof value === "object" && !Array.isArray(value);
2284
1709
  }
2285
1710
  function positiveNumber(value) {
@@ -2339,7 +1764,7 @@ async function requestLmStudioJson(url2, init, timeoutMs, signal) {
2339
1764
  };
2340
1765
  if (data !== void 0) result.data = data;
2341
1766
  if (!response.ok) {
2342
- const message = isRecord3(data) ? nonEmptyString(data.error) : void 0;
1767
+ const message = isRecord2(data) ? nonEmptyString(data.error) : void 0;
2343
1768
  result.error = message ?? `HTTP ${response.status}`;
2344
1769
  }
2345
1770
  return result;
@@ -2358,28 +1783,28 @@ function loadedInstances(value) {
2358
1783
  if (!Array.isArray(value)) return [];
2359
1784
  const instances = [];
2360
1785
  for (const raw of value) {
2361
- if (!isRecord3(raw)) continue;
1786
+ if (!isRecord2(raw)) continue;
2362
1787
  const id = nonEmptyString(raw.id);
2363
1788
  if (!id) continue;
2364
- instances.push({ id, config: isRecord3(raw.config) ? { ...raw.config } : {} });
1789
+ instances.push({ id, config: isRecord2(raw.config) ? { ...raw.config } : {} });
2365
1790
  }
2366
1791
  return instances;
2367
1792
  }
2368
1793
  function reasoningOptions(capabilities2) {
2369
- if (!isRecord3(capabilities2) || !isRecord3(capabilities2.reasoning)) return void 0;
1794
+ if (!isRecord2(capabilities2) || !isRecord2(capabilities2.reasoning)) return void 0;
2370
1795
  const allowed = capabilities2.reasoning.allowed_options;
2371
1796
  if (!Array.isArray(allowed)) return void 0;
2372
1797
  const options = allowed.filter((entry) => typeof entry === "string");
2373
1798
  return options.length > 0 ? options : void 0;
2374
1799
  }
2375
1800
  function parseLmStudioV1Models(data) {
2376
- if (!isRecord3(data) || !Array.isArray(data.models)) return null;
1801
+ if (!isRecord2(data) || !Array.isArray(data.models)) return null;
2377
1802
  const models = [];
2378
1803
  for (const raw of data.models) {
2379
- if (!isRecord3(raw)) continue;
1804
+ if (!isRecord2(raw)) continue;
2380
1805
  const key = nonEmptyString(raw.key);
2381
1806
  if (!key) continue;
2382
- const capabilities2 = isRecord3(raw.capabilities) ? raw.capabilities : void 0;
1807
+ const capabilities2 = isRecord2(raw.capabilities) ? raw.capabilities : void 0;
2383
1808
  const info = {
2384
1809
  key,
2385
1810
  loadedInstances: loadedInstances(raw.loaded_instances),
@@ -2397,7 +1822,7 @@ function parseLmStudioV1Models(data) {
2397
1822
  const options = reasoningOptions(capabilities2);
2398
1823
  if (options) info.reasoningOptions = options;
2399
1824
  if (capabilities2 && "reasoning" in capabilities2) {
2400
- info.reasoning = capabilities2.reasoning === true || isRecord3(capabilities2.reasoning);
1825
+ info.reasoning = capabilities2.reasoning === true || isRecord2(capabilities2.reasoning);
2401
1826
  }
2402
1827
  models.push(info);
2403
1828
  }
@@ -2495,10 +1920,10 @@ function lmStudioReasoningEffort(level, options) {
2495
1920
  return "low";
2496
1921
  }
2497
1922
  function v0Models(data) {
2498
- if (!isRecord3(data) || !Array.isArray(data.data)) return null;
1923
+ if (!isRecord2(data) || !Array.isArray(data.data)) return null;
2499
1924
  const models = [];
2500
1925
  for (const raw of data.data) {
2501
- if (!isRecord3(raw)) continue;
1926
+ if (!isRecord2(raw)) continue;
2502
1927
  const key = nonEmptyString(raw.id);
2503
1928
  if (!key) continue;
2504
1929
  const state = nonEmptyString(raw.state);
@@ -2522,10 +1947,10 @@ function v0Models(data) {
2522
1947
  return models;
2523
1948
  }
2524
1949
  function openAIModels(data) {
2525
- if (!isRecord3(data) || !Array.isArray(data.data)) return null;
1950
+ if (!isRecord2(data) || !Array.isArray(data.data)) return null;
2526
1951
  const models = [];
2527
1952
  for (const raw of data.data) {
2528
- if (!isRecord3(raw)) continue;
1953
+ if (!isRecord2(raw)) continue;
2529
1954
  const key = nonEmptyString(raw.id);
2530
1955
  if (key) models.push({ key, loadedInstances: [], metadata: { ...raw } });
2531
1956
  }
@@ -2585,7 +2010,7 @@ async function greetLmStudio(target, ctx) {
2585
2010
  ctx.httpTimeoutMs,
2586
2011
  ctx.signal
2587
2012
  );
2588
- if (result.ok && isRecord3(result.data) && result.data.lmstudio === true) {
2013
+ if (result.ok && isRecord2(result.data) && result.data.lmstudio === true) {
2589
2014
  return { ok: true, latencyMs: result.latencyMs };
2590
2015
  }
2591
2016
  return { ok: false, latencyMs: result.latencyMs, error: result.error ?? "endpoint did not return {lmstudio:true}" };
@@ -2914,6 +2339,15 @@ async function probeOpenAICompatReasoning(opts) {
2914
2339
 
2915
2340
  // src/domains/providers/runtimes/common/probe-helpers.ts
2916
2341
  init_esm_shims();
2342
+
2343
+ // src/domains/providers/types/context-window-slots.ts
2344
+ init_esm_shims();
2345
+ function formatContextWindowSlots(contextWindow, slots) {
2346
+ const format = (n) => Math.round(n).toLocaleString("en-US");
2347
+ return `${format(contextWindow)} (${format(slots.totalContextSize)} / ${slots.slots} slots)`;
2348
+ }
2349
+
2350
+ // src/domains/providers/runtimes/common/probe-helpers.ts
2917
2351
  async function probeUrl(url2, ctx, method = "GET") {
2918
2352
  const base = { url: url2, timeoutMs: ctx.httpTimeoutMs, method };
2919
2353
  return ctx.signal ? probeHttp({ ...base, signal: ctx.signal }) : probeHttp(base);
@@ -2958,11 +2392,15 @@ async function probeOpenAIModelCatalog(base, ctx, modelsPath = "/v1/models") {
2958
2392
  const state = modelStateFromOpenAIModelEntry(row) ?? (detailRow ? modelStateFromOpenAIModelEntry(detailRow) : void 0) ?? // A reported loaded context is itself the residency answer: nothing
2959
2393
  // serves a window for a model it has not loaded.
2960
2394
  (loadedContext !== void 0 ? { state: "loaded" } : void 0);
2961
- if (state) modelStates[row.id] = loadedContext === void 0 ? state : { ...state, contextLength: loadedContext };
2395
+ const contextSlots = contextSlotsFromEntry(row) ?? (detailRow ? contextSlotsFromEntry(detailRow) : void 0);
2396
+ const withSlots = contextSlots ? { ...state ?? { state: "unknown" }, contextSlots } : state;
2397
+ if (withSlots) {
2398
+ modelStates[row.id] = loadedContext === void 0 ? withSlots : { ...withSlots, contextLength: loadedContext };
2399
+ }
2962
2400
  }
2963
2401
  return { models, modelCapabilities, modelStates };
2964
2402
  }
2965
- function isRecord4(value) {
2403
+ function isRecord3(value) {
2966
2404
  return value !== null && typeof value === "object" && !Array.isArray(value);
2967
2405
  }
2968
2406
  function positiveNumber2(value) {
@@ -2989,7 +2427,7 @@ function booleanFromAny(record, keys) {
2989
2427
  }
2990
2428
  function nestedRecord(record, key) {
2991
2429
  const value = record[key];
2992
- return isRecord4(value) ? value : null;
2430
+ return isRecord3(value) ? value : null;
2993
2431
  }
2994
2432
  function firstString(record, keys) {
2995
2433
  if (!record) return void 0;
@@ -3012,7 +2450,9 @@ function normalizeModelState(raw) {
3012
2450
  if (!value) return void 0;
3013
2451
  if (value === "loaded" || value === "ready" || value === "running" || value === "active") return "loaded";
3014
2452
  if (value === "loading" || value === "pending" || value === "queued" || value === "starting") return "loading";
3015
- if (value === "unloaded" || value === "not-loaded" || value === "idle" || value === "stopped") return "unloaded";
2453
+ if (value === "unloaded" || value === "not-loaded" || value === "idle" || value === "sleeping" || value === "stopped") {
2454
+ return "unloaded";
2455
+ }
3016
2456
  if (value === "failed" || value === "error" || value === "errored") return "failed";
3017
2457
  if (value === "unknown") return "unknown";
3018
2458
  return void 0;
@@ -3043,11 +2483,14 @@ function statusArgsFromEntry(row) {
3043
2483
  const status = nestedRecord(row, "status");
3044
2484
  return argsFromStatus(status);
3045
2485
  }
2486
+ function contextSlotsFromEntry(row) {
2487
+ return llamaCppRequestContextWindow(parseLlamaCppServerFlags(statusArgsFromEntry(row)))?.slots;
2488
+ }
3046
2489
  function capabilitiesFromOpenAIModelEntry(row) {
3047
2490
  const caps = {};
3048
2491
  const meta = nestedRecord(row, "meta");
3049
2492
  const flags = parseLlamaCppServerFlags(statusArgsFromEntry(row));
3050
- const contextWindow = positiveNumber2(flags.contextSize) ?? firstPositiveNumber(row, [
2493
+ const contextWindow = llamaCppRequestContextWindow(flags)?.contextWindow ?? firstPositiveNumber(row, [
3051
2494
  // What is actually loaded outranks what the model could support: a
3052
2495
  // model served at 8k out of a possible 262k has an 8k window today,
3053
2496
  // and the run has to be planned against the real one.
@@ -3100,27 +2543,45 @@ async function probeOpenAIModelEntries(base, ctx) {
3100
2543
  if (!result.ok) return [];
3101
2544
  return modelEntries(result.data);
3102
2545
  }
2546
+ function llamaCppRequestContextWindow(flags) {
2547
+ const total = positiveNumber2(flags.contextSize);
2548
+ if (total === void 0) return void 0;
2549
+ const parallel = positiveNumber2(flags.parallel);
2550
+ if (parallel === void 0 || parallel <= 1 || flags.kvUnified === true) return { contextWindow: Math.floor(total) };
2551
+ const slots = Math.floor(parallel);
2552
+ return {
2553
+ contextWindow: Math.floor(total / slots),
2554
+ slots: { totalContextSize: Math.floor(total), slots }
2555
+ };
2556
+ }
3103
2557
  function argsFromStatus(status) {
3104
- if (!isRecord4(status)) return [];
2558
+ if (!isRecord3(status)) return [];
3105
2559
  const args = status.args;
3106
2560
  if (Array.isArray(args)) return args.filter((entry) => typeof entry === "string");
3107
2561
  if (typeof args === "string") return args.trim().split(/\s+/).filter(Boolean);
3108
2562
  return [];
3109
2563
  }
3110
- function valueAfter(args, flag) {
3111
- const index = args.indexOf(flag);
3112
- if (index < 0) return void 0;
3113
- const value = args[index + 1];
3114
- return value && !value.startsWith("--") ? value : void 0;
2564
+ function looksLikeFlag(token) {
2565
+ return token.startsWith("-") && Number.isNaN(Number(token));
3115
2566
  }
3116
- function numberFlag(args, flag) {
3117
- const value = valueAfter(args, flag);
2567
+ function valueAfter(args, ...flags) {
2568
+ for (const flag of flags) {
2569
+ const index = args.indexOf(flag);
2570
+ if (index < 0) continue;
2571
+ const value = args[index + 1];
2572
+ return value && !looksLikeFlag(value) ? value : void 0;
2573
+ }
2574
+ return void 0;
2575
+ }
2576
+ function numberFlag(args, ...flags) {
2577
+ const value = valueAfter(args, ...flags);
3118
2578
  if (value === void 0) return void 0;
3119
2579
  const parsed = Number(value);
3120
2580
  return Number.isFinite(parsed) ? parsed : void 0;
3121
2581
  }
3122
- function booleanFlag(args, flag) {
3123
- if (!args.includes(flag)) return void 0;
2582
+ function booleanFlag(args, ...flags) {
2583
+ const flag = flags.find((candidate) => args.includes(candidate));
2584
+ if (flag === void 0) return void 0;
3124
2585
  const value = valueAfter(args, flag);
3125
2586
  if (value === void 0) return true;
3126
2587
  const normalized = value.toLowerCase();
@@ -3130,7 +2591,7 @@ function booleanFlag(args, flag) {
3130
2591
  }
3131
2592
  function parseLlamaCppServerFlags(args) {
3132
2593
  const flags = {};
3133
- const ctxSize = numberFlag(args, "--ctx-size");
2594
+ const ctxSize = numberFlag(args, "--ctx-size", "-c");
3134
2595
  if (ctxSize !== void 0) flags.contextSize = ctxSize;
3135
2596
  const maxTokens = numberFlag(args, "--n-predict");
3136
2597
  if (maxTokens !== void 0) flags.maxTokens = maxTokens;
@@ -3150,8 +2611,12 @@ function parseLlamaCppServerFlags(args) {
3150
2611
  if (topK !== void 0) flags.topK = topK;
3151
2612
  const nGpuLayers = numberFlag(args, "--n-gpu-layers");
3152
2613
  if (nGpuLayers !== void 0) flags.nGpuLayers = nGpuLayers;
3153
- const parallel = numberFlag(args, "--parallel");
2614
+ const parallel = numberFlag(args, "--parallel", "-np");
3154
2615
  if (parallel !== void 0) flags.parallel = parallel;
2616
+ const kvUnifiedAt = Math.max(args.lastIndexOf("--kv-unified"), args.lastIndexOf("-kvu"));
2617
+ const noKvUnifiedAt = args.lastIndexOf("--no-kv-unified");
2618
+ if (noKvUnifiedAt > kvUnifiedAt) flags.kvUnified = false;
2619
+ else if (kvUnifiedAt >= 0) flags.kvUnified = booleanFlag(args, "--kv-unified", "-kvu") ?? true;
3155
2620
  const cacheTypeK = valueAfter(args, "--cache-type-k");
3156
2621
  if (cacheTypeK) flags.cacheTypeK = cacheTypeK;
3157
2622
  const cacheTypeV = valueAfter(args, "--cache-type-v");
@@ -3168,7 +2633,7 @@ function selectedModelEntry(entries, target) {
3168
2633
  return entries[0] ?? null;
3169
2634
  }
3170
2635
  function statusNotes(id, status) {
3171
- if (!isRecord4(status)) return [];
2636
+ if (!isRecord3(status)) return [];
3172
2637
  const notes = [];
3173
2638
  if (status.failed === true) notes.push(`llama.cpp router marks ${id} as failed`);
3174
2639
  const state = typeof status.state === "string" ? status.state : void 0;
@@ -3183,7 +2648,8 @@ async function probeLlamaCppModelStatus(base, target, ctx) {
3183
2648
  if (args.length === 0) return { notes: statusNotes(selected.id, selected.status) };
3184
2649
  const flags = parseLlamaCppServerFlags(args);
3185
2650
  const caps = {};
3186
- if (flags.contextSize !== void 0 && flags.contextSize > 0) caps.contextWindow = flags.contextSize;
2651
+ const window = llamaCppRequestContextWindow(flags);
2652
+ if (window !== void 0) caps.contextWindow = window.contextWindow;
3187
2653
  if (flags.maxTokens !== void 0 && flags.maxTokens > 0) caps.maxTokens = flags.maxTokens;
3188
2654
  if (flags.reasoning === true || flags.reasoningBudget !== void 0) caps.reasoning = true;
3189
2655
  if (flags.mmproj) caps.vision = true;
@@ -3191,6 +2657,11 @@ async function probeLlamaCppModelStatus(base, target, ctx) {
3191
2657
  const enrichment = { modelId: selected.id, serverFlags: flags };
3192
2658
  if (Object.keys(caps).length > 0) enrichment.discoveredCapabilities = caps;
3193
2659
  const notes = statusNotes(selected.id, selected.status);
2660
+ if (window?.slots) {
2661
+ notes.push(
2662
+ `${selected.id} context window ${formatContextWindowSlots(window.contextWindow, window.slots)}: --ctx-size is split across --parallel slots without --kv-unified`
2663
+ );
2664
+ }
3194
2665
  if (notes.length > 0) enrichment.notes = notes;
3195
2666
  return enrichment;
3196
2667
  }
@@ -5148,6 +4619,9 @@ function loadedContextWindowForModel(status, modelId) {
5148
4619
  const reported = status?.discoveredModelStates?.[modelId]?.contextLength;
5149
4620
  return typeof reported === "number" && Number.isFinite(reported) && reported > 0 ? reported : null;
5150
4621
  }
4622
+ function contextSlotsForModel(status, modelId) {
4623
+ return status?.discoveredModelStates?.[modelId]?.contextSlots ?? null;
4624
+ }
5151
4625
  function modelResidencyForStatus(status, modelId) {
5152
4626
  if (loadedContextWindowForModel(status, modelId) !== null) return "resident";
5153
4627
  switch (status?.discoveredModelStates?.[modelId]?.state) {
@@ -5414,7 +4888,9 @@ function resolveRuntimeTarget(providers, input) {
5414
4888
  wireModelId,
5415
4889
  providers.knowledgeBase,
5416
4890
  probedContextWindow,
5417
- loadedContextWindow
4891
+ loadedContextWindow,
4892
+ void 0,
4893
+ contextSlotsForModel(status, wireModelId)
5418
4894
  );
5419
4895
  capabilities2.contextWindow = contextWindowDetails.effectiveContextWindow;
5420
4896
  if (contextWindowDetails.warning) {
@@ -5495,7 +4971,8 @@ function refineRuntimeTargetWithModelHints(target, model, knowledgeBase) {
5495
4971
  // one the backend has open. Re-resolving without the loaded number would
5496
4972
  // hand the planner the declared window back on the first refinement.
5497
4973
  target.contextWindowDetails.loadedContextWindow,
5498
- modelHintContextWindow
4974
+ modelHintContextWindow,
4975
+ target.contextWindowDetails.contextWindowSlots
5499
4976
  );
5500
4977
  capabilities2.contextWindow = contextWindowDetails.effectiveContextWindow;
5501
4978
  const modelRuntime = resolveModelRuntimeCapabilities({
@@ -5554,12 +5031,16 @@ function firstRuntimeResolutionError(diagnostics) {
5554
5031
  function runtimeResolutionWarnings(diagnostics) {
5555
5032
  return diagnostics.filter((entry) => entry.severity === "warning").map((entry) => entry.message);
5556
5033
  }
5034
+ function runtimeResolutionWarningsBesideThinkingNotice(diagnostics, thinkingNotice) {
5035
+ if (thinkingNotice.trim().length === 0) return runtimeResolutionWarnings(diagnostics);
5036
+ return runtimeResolutionWarnings(diagnostics.filter((entry) => !entry.code.startsWith("thinking-")));
5037
+ }
5557
5038
  var DESIRED_CONTEXT_WINDOW = CLIO_MIN_CONTEXT_WINDOW;
5558
5039
  var FALLBACK_CONTEXT_WINDOW = CLIO_MIN_CONTEXT_WINDOW;
5559
5040
  function positiveWindow(value) {
5560
5041
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
5561
5042
  }
5562
- function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase, probedContextWindow, loadedContextWindow = null, modelHintContextWindow) {
5043
+ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase, probedContextWindow, loadedContextWindow = null, modelHintContextWindow, probedContextSlots = null) {
5563
5044
  const catalogModel = getCatalogModelForRuntime(runtime.id, wireModelId);
5564
5045
  const kbHit = knowledgeBase?.lookup(wireModelId) ?? null;
5565
5046
  let modelDeclared;
@@ -5614,6 +5095,7 @@ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase
5614
5095
  if (source === "descriptor-default" || source === "unknown") {
5615
5096
  provenanceNotice = `Context window ${effective} is Clio's assumed minimum, not a figure this target reported. Run 'clio-coder targets --probe' to read the real one.`;
5616
5097
  }
5098
+ const contextWindowSlots = source === "probe" && probedContextSlots !== null && Math.floor(probedContextSlots.totalContextSize / probedContextSlots.slots) === effective ? probedContextSlots : null;
5617
5099
  return {
5618
5100
  declaredContextWindow,
5619
5101
  probedContextWindow,
@@ -5621,6 +5103,7 @@ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase
5621
5103
  desiredContextWindow: desired,
5622
5104
  effectiveContextWindow: effective,
5623
5105
  contextWindowSource: source,
5106
+ contextWindowSlots,
5624
5107
  warning,
5625
5108
  provenanceNotice
5626
5109
  };
@@ -5837,63 +5320,6 @@ function filterGemmaChannelStream(source, enabled) {
5837
5320
  return filtered;
5838
5321
  }
5839
5322
 
5840
- // src/engine/strip-tokenizer-sentinels.ts
5841
- init_esm_shims();
5842
- var KNOWN_SENTINELS = [
5843
- "<|endoftext|>",
5844
- "<|im_start|>",
5845
- "<|im_end|>",
5846
- "<|eot_id|>",
5847
- "<|end_of_turn|>",
5848
- "<|fim_prefix|>",
5849
- "<|fim_middle|>",
5850
- "<|fim_suffix|>",
5851
- "<|file_separator|>",
5852
- "<s>",
5853
- "</s>"
5854
- ];
5855
- var SENTINEL_RE = new RegExp(KNOWN_SENTINELS.map((s) => s.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&")).join("|"), "g");
5856
- var MAX_SENTINEL_LEN = KNOWN_SENTINELS.reduce((max, s) => s.length > max ? s.length : max, 0);
5857
- function stripTokenizerSentinels(text) {
5858
- if (text.length === 0) return text;
5859
- return text.replace(SENTINEL_RE, "");
5860
- }
5861
- function isSentinelPrefix(tail) {
5862
- if (tail.length === 0) return false;
5863
- for (const sentinel of KNOWN_SENTINELS) {
5864
- if (sentinel.length > tail.length && sentinel.startsWith(tail)) return true;
5865
- }
5866
- return false;
5867
- }
5868
- function createSentinelStripper() {
5869
- let buffer = "";
5870
- return {
5871
- push(chunk) {
5872
- if (chunk.length === 0) return "";
5873
- buffer += chunk;
5874
- const stripped = buffer.replace(SENTINEL_RE, "");
5875
- const holdMax = Math.min(stripped.length, MAX_SENTINEL_LEN - 1);
5876
- let hold = 0;
5877
- for (let take = holdMax; take > 0; take--) {
5878
- const tail = stripped.slice(stripped.length - take);
5879
- if (isSentinelPrefix(tail)) {
5880
- hold = take;
5881
- break;
5882
- }
5883
- }
5884
- const safe = hold === 0 ? stripped : stripped.slice(0, stripped.length - hold);
5885
- buffer = hold === 0 ? "" : stripped.slice(stripped.length - hold);
5886
- return safe;
5887
- },
5888
- flush() {
5889
- if (buffer.length === 0) return "";
5890
- const remainder = buffer.replace(SENTINEL_RE, "");
5891
- buffer = "";
5892
- return remainder;
5893
- }
5894
- };
5895
- }
5896
-
5897
5323
  // src/engine/apis/output-budget.ts
5898
5324
  init_esm_shims();
5899
5325
  var CONTEXT_BUDGET_SAFETY_TOKENS = 1024;
@@ -6340,6 +5766,7 @@ var ollamaNativeApiProvider = {
6340
5766
 
6341
5767
  // src/engine/apis/openai-completions.ts
6342
5768
  init_esm_shims();
5769
+ import { TextDecoder as TextDecoder2 } from "node:util";
6343
5770
  import {
6344
5771
  createAssistantMessageEventStream as createAssistantMessageEventStream3
6345
5772
  } from "@earendil-works/pi-ai";
@@ -6472,24 +5899,24 @@ var POLL_INTERVAL_MS = 500;
6472
5899
  function isResidentState(state) {
6473
5900
  return state === "loaded" || state === "loading" || state === "sleeping";
6474
5901
  }
6475
- function isRecord5(value) {
5902
+ function isRecord4(value) {
6476
5903
  return value !== null && typeof value === "object" && !Array.isArray(value);
6477
5904
  }
6478
5905
  function routerModelState(entry) {
6479
5906
  const status = entry.status;
6480
- const state = isRecord5(status) ? status.value : status;
5907
+ const state = isRecord4(status) ? status.value : status;
6481
5908
  if (state === "loaded" || state === "loading" || state === "sleeping" || state === "unloaded" || state === "failed") {
6482
5909
  return state;
6483
5910
  }
6484
5911
  return "unknown";
6485
5912
  }
6486
5913
  function parseRouterModels(payload) {
6487
- if (!isRecord5(payload)) return [];
5914
+ if (!isRecord4(payload)) return [];
6488
5915
  const data = payload.data;
6489
5916
  if (!Array.isArray(data)) return [];
6490
5917
  const models = [];
6491
5918
  for (const entry of data) {
6492
- if (!isRecord5(entry) || typeof entry.id !== "string") continue;
5919
+ if (!isRecord4(entry) || typeof entry.id !== "string") continue;
6493
5920
  const tags = Array.isArray(entry.tags) ? entry.tags.filter((tag) => typeof tag === "string") : [];
6494
5921
  models.push({ id: entry.id, state: routerModelState(entry), tags });
6495
5922
  }
@@ -6499,7 +5926,7 @@ function residentModel(model) {
6499
5926
  return isResidentState(model.state);
6500
5927
  }
6501
5928
  function parseLlamaCppRouterProps(payload) {
6502
- if (!isRecord5(payload)) return {};
5929
+ if (!isRecord4(payload)) return {};
6503
5930
  const maxInstances = payload.max_instances;
6504
5931
  return typeof maxInstances === "number" && Number.isFinite(maxInstances) && maxInstances > 0 ? { maxInstances: Math.floor(maxInstances) } : {};
6505
5932
  }
@@ -6727,6 +6154,12 @@ async function loadOwnedInstance(target, targetKey, body, apiKey, signal) {
6727
6154
  if (instanceId) ownedInstances(targetKey).add(instanceId);
6728
6155
  return instanceId;
6729
6156
  }
6157
+ var announcedResidencyFacts = /* @__PURE__ */ new Set();
6158
+ function emitResidencyNoticeOnce(key, notice) {
6159
+ if (announcedResidencyFacts.has(key)) return;
6160
+ announcedResidencyFacts.add(key);
6161
+ emitResidencyNotice(notice);
6162
+ }
6730
6163
  async function ensureLmStudioResidency(model, options = {}) {
6731
6164
  const target = targetForModel(model);
6732
6165
  if (!target) return model.id;
@@ -6749,7 +6182,7 @@ async function ensureLmStudioResidency(model, options = {}) {
6749
6182
  );
6750
6183
  }
6751
6184
  if (resolution.wireModelId !== model.id) {
6752
- emitResidencyNotice({
6185
+ emitResidencyNoticeOnce(`resolved|${info.targetId}|${model.id}|${resolution.wireModelId}`, {
6753
6186
  kind: "co-resident",
6754
6187
  level: "info",
6755
6188
  targetId: info.targetId,
@@ -6760,14 +6193,16 @@ async function ensureLmStudioResidency(model, options = {}) {
6760
6193
  });
6761
6194
  }
6762
6195
  if (resolution.peerTargets.length > 0) {
6763
- emitResidencyNotice({
6196
+ const peers = resolution.peerTargets.join(", ");
6197
+ const requested = resolution.wireModelId === model.id ? "" : ` (requested '${model.id}')`;
6198
+ emitResidencyNoticeOnce(`peer|${info.targetId}|${model.id}|${resolution.wireModelId}|${peers}`, {
6764
6199
  kind: "co-resident",
6765
6200
  level: "warning",
6766
6201
  targetId: info.targetId,
6767
6202
  runtimeId: "lmstudio",
6768
6203
  model: resolution.wireModelId,
6769
- message: `LM Studio instance '${resolution.wireModelId}' is also loaded on ${resolution.peerTargets.join(", ")}; this request may be served by that LM Link peer.`,
6770
- detail: { peerTargets: resolution.peerTargets.join(", ") }
6204
+ message: `LM Studio instance '${resolution.wireModelId}'${requested} is also loaded on ${peers}; a request may be served by that LM Link peer, and the footer and usage ledger name the id that answered when it differs.`,
6205
+ detail: { requestedModel: model.id, wireModel: resolution.wireModelId, peerTargets: peers }
6771
6206
  });
6772
6207
  }
6773
6208
  if (!load || Object.keys(load).length === 0 || resolution.instance) return resolution.wireModelId;
@@ -6853,6 +6288,98 @@ function pickSamplingProfile2(quirks, thinkingActive) {
6853
6288
  function isPlainRecord(value) {
6854
6289
  return value !== null && typeof value === "object" && !Array.isArray(value);
6855
6290
  }
6291
+ function observeResponseModelIdLine(line, capture) {
6292
+ if (capture.done) return;
6293
+ const normalized = line.endsWith("\r") ? line.slice(0, -1) : line;
6294
+ if (!normalized.startsWith("data:")) return;
6295
+ const data = normalized.slice("data:".length).trimStart();
6296
+ if (data.length === 0 || data === "[DONE]") return;
6297
+ try {
6298
+ const payload = JSON.parse(data);
6299
+ if (!isPlainRecord(payload)) return;
6300
+ const model = payload.model;
6301
+ if (typeof model === "string" && model.trim().length > 0) {
6302
+ capture.reportedModelId = model.trim();
6303
+ capture.done = true;
6304
+ }
6305
+ } catch {
6306
+ }
6307
+ }
6308
+ function observeResponseModelIdBytes(chunk, capture, flush = false) {
6309
+ if (capture.done || !capture.decoder) return;
6310
+ capture.buffer += chunk ? capture.decoder.decode(chunk, { stream: !flush }) : capture.decoder.decode();
6311
+ let newline = capture.buffer.indexOf("\n");
6312
+ while (newline >= 0) {
6313
+ const line = capture.buffer.slice(0, newline);
6314
+ capture.buffer = capture.buffer.slice(newline + 1);
6315
+ observeResponseModelIdLine(line, capture);
6316
+ if (capture.done) {
6317
+ capture.buffer = "";
6318
+ capture.decoder = null;
6319
+ return;
6320
+ }
6321
+ newline = capture.buffer.indexOf("\n");
6322
+ }
6323
+ if (flush && capture.buffer.length > 0) {
6324
+ observeResponseModelIdLine(capture.buffer, capture);
6325
+ capture.buffer = "";
6326
+ }
6327
+ if (capture.done || flush) capture.decoder = null;
6328
+ }
6329
+ function captureResponseModelId(response, capture) {
6330
+ if (!response.body || !response.headers.get("content-type")?.toLowerCase().includes("text/event-stream")) {
6331
+ return response;
6332
+ }
6333
+ const body = response.body.pipeThrough(
6334
+ new TransformStream({
6335
+ transform(chunk, controller) {
6336
+ capture.observed = true;
6337
+ if (!capture.done) observeResponseModelIdBytes(chunk, capture);
6338
+ controller.enqueue(chunk);
6339
+ },
6340
+ flush() {
6341
+ capture.observed = true;
6342
+ if (!capture.done) observeResponseModelIdBytes(void 0, capture, true);
6343
+ }
6344
+ })
6345
+ );
6346
+ return new Response(body, {
6347
+ status: response.status,
6348
+ statusText: response.statusText,
6349
+ headers: response.headers
6350
+ });
6351
+ }
6352
+ function withResponseModelIdCapture(options, sourceFactory) {
6353
+ const capture = {
6354
+ reportedModelId: null,
6355
+ observed: false,
6356
+ done: false,
6357
+ buffer: "",
6358
+ decoder: new TextDecoder2()
6359
+ };
6360
+ const fetchImpl = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
6361
+ const capturedOptions = {
6362
+ ...options,
6363
+ fetch: async (input, init) => captureResponseModelId(await fetchImpl(input, init), capture)
6364
+ };
6365
+ const source = sourceFactory(capturedOptions);
6366
+ const annotated = createAssistantMessageEventStream3();
6367
+ (async () => {
6368
+ try {
6369
+ for await (const event of source) {
6370
+ const observation = capture.observed ? capture.reportedModelId === null ? { state: "not-reported" } : { state: "reported", reportedModelId: capture.reportedModelId } : { state: "not-observed" };
6371
+ if (event.type === "done") event.message.responseModelIdObservation = observation;
6372
+ else if (event.type === "error") event.error.responseModelIdObservation = observation;
6373
+ annotated.push(event);
6374
+ }
6375
+ annotated.end();
6376
+ } catch (err) {
6377
+ const message = err instanceof Error ? err.message : String(err);
6378
+ throw new Error(message);
6379
+ }
6380
+ })();
6381
+ return annotated;
6382
+ }
6856
6383
  function samplingParamsFromProfile(profile) {
6857
6384
  return {
6858
6385
  ...profile.topP !== void 0 ? { top_p: profile.topP } : {},
@@ -7336,16 +6863,15 @@ var openAICompletionsApiProvider = {
7336
6863
  stripSentinelsFromStream(
7337
6864
  stripNeverReasoningFromStream(
7338
6865
  filterGemmaChannelStream(
7339
- withLocalResidency(
7340
- model,
7341
- {
7342
- ...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
7343
- ...options?.signal !== void 0 ? { signal: options.signal } : {}
7344
- },
7345
- (requestModel) => piOpenAICompletions.stream(
7346
- requestModel,
7347
- effectiveContext,
7348
- withRemainingContextBudget(model, effectiveContext, withSamplers)
6866
+ withResponseModelIdCapture(
6867
+ withRemainingContextBudget(model, effectiveContext, withSamplers),
6868
+ (capturedOptions) => withLocalResidency(
6869
+ model,
6870
+ {
6871
+ ...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
6872
+ ...options?.signal !== void 0 ? { signal: options.signal } : {}
6873
+ },
6874
+ (requestModel) => piOpenAICompletions.stream(requestModel, effectiveContext, capturedOptions)
7349
6875
  )
7350
6876
  ),
7351
6877
  resolved.family === "gemma-4"
@@ -7368,16 +6894,15 @@ var openAICompletionsApiProvider = {
7368
6894
  stripSentinelsFromStream(
7369
6895
  stripNeverReasoningFromStream(
7370
6896
  filterGemmaChannelStream(
7371
- withLocalResidency(
7372
- model,
7373
- {
7374
- ...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
7375
- ...options?.signal !== void 0 ? { signal: options.signal } : {}
7376
- },
7377
- (requestModel) => piOpenAICompletions.streamSimple(
7378
- requestModel,
7379
- effectiveContext,
7380
- withRemainingContextBudget(model, effectiveContext, withSamplers)
6897
+ withResponseModelIdCapture(
6898
+ withRemainingContextBudget(model, effectiveContext, withSamplers),
6899
+ (capturedOptions) => withLocalResidency(
6900
+ model,
6901
+ {
6902
+ ...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
6903
+ ...options?.signal !== void 0 ? { signal: options.signal } : {}
6904
+ },
6905
+ (requestModel) => piOpenAICompletions.streamSimple(requestModel, effectiveContext, capturedOptions)
7381
6906
  )
7382
6907
  ),
7383
6908
  resolved.family === "gemma-4"
@@ -7404,8 +6929,8 @@ function registerClioApiProviders() {
7404
6929
 
7405
6930
  // src/domains/providers/knowledge-base-path.ts
7406
6931
  init_esm_shims();
7407
- import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
7408
- import { delimiter, dirname as dirname2, join as join4 } from "node:path";
6932
+ import { existsSync, statSync as statSync2 } from "node:fs";
6933
+ import { delimiter, dirname, join as join3 } from "node:path";
7409
6934
  import { fileURLToPath } from "node:url";
7410
6935
  var MODEL_CATALOG_OVERLAY_DIR = "model-catalog.d";
7411
6936
  var MODEL_CATALOG_DIRS_ENV = "CLIO_CODER_MODEL_CATALOG_DIRS";
@@ -7417,25 +6942,25 @@ function isDirectory(path) {
7417
6942
  }
7418
6943
  }
7419
6944
  function resolveProvidersModelsDir(importMetaUrl) {
7420
- const start = dirname2(fileURLToPath(importMetaUrl));
6945
+ const start = dirname(fileURLToPath(importMetaUrl));
7421
6946
  const directCandidates = [
7422
- join4(start, "models"),
7423
- join4(start, "..", "domains", "providers", "models"),
7424
- join4(start, "..", "providers-models")
6947
+ join3(start, "models"),
6948
+ join3(start, "..", "domains", "providers", "models"),
6949
+ join3(start, "..", "providers-models")
7425
6950
  ];
7426
6951
  for (const candidate of directCandidates) {
7427
6952
  if (isDirectory(candidate)) return candidate;
7428
6953
  }
7429
6954
  let cursor = start;
7430
6955
  for (let i = 0; i < 8; i++) {
7431
- const packageJson = join4(cursor, "package.json");
7432
- const sourceModels = join4(cursor, "src", "domains", "providers", "models");
7433
- const distModels = join4(cursor, "dist", "providers-models");
7434
- if (existsSync2(packageJson)) {
6956
+ const packageJson = join3(cursor, "package.json");
6957
+ const sourceModels = join3(cursor, "src", "domains", "providers", "models");
6958
+ const distModels = join3(cursor, "dist", "providers-models");
6959
+ if (existsSync(packageJson)) {
7435
6960
  if (isDirectory(sourceModels)) return sourceModels;
7436
6961
  if (isDirectory(distModels)) return distModels;
7437
6962
  }
7438
- const parent = dirname2(cursor);
6963
+ const parent = dirname(cursor);
7439
6964
  if (parent === cursor) break;
7440
6965
  cursor = parent;
7441
6966
  }
@@ -7461,8 +6986,8 @@ function resolveProviderModelCatalogDirs(importMetaUrl, options = {}) {
7461
6986
  const bundled = resolveProvidersModelsDir(importMetaUrl);
7462
6987
  const cwd = options.cwd ?? process.cwd();
7463
6988
  const overlays = uniqueExistingDirs([
7464
- join4(resolveClioDirs().config, MODEL_CATALOG_OVERLAY_DIR),
7465
- join4(cwd, ".clio-coder", MODEL_CATALOG_OVERLAY_DIR),
6989
+ join3(resolveClioDirs().config, MODEL_CATALOG_OVERLAY_DIR),
6990
+ join3(cwd, ".clio-coder", MODEL_CATALOG_OVERLAY_DIR),
7466
6991
  ...envOverlayDirs()
7467
6992
  ]);
7468
6993
  return {
@@ -7481,7 +7006,7 @@ function resolveProviderKnowledgeBaseRoots(importMetaUrl, options = {}) {
7481
7006
 
7482
7007
  // src/domains/providers/plugins.ts
7483
7008
  init_esm_shims();
7484
- import { join as join5 } from "node:path";
7009
+ import { join as join4 } from "node:path";
7485
7010
  function extractPluginPackages(settings) {
7486
7011
  if (!settings || typeof settings !== "object") return [];
7487
7012
  const raw = settings.runtimePlugins;
@@ -7490,7 +7015,7 @@ function extractPluginPackages(settings) {
7490
7015
  }
7491
7016
  async function loadPluginRuntimes(registry, settings) {
7492
7017
  const loaded = [];
7493
- const pluginDir = join5(clioConfigDir(), "runtimes");
7018
+ const pluginDir = join4(clioConfigDir(), "runtimes");
7494
7019
  const packages = extractPluginPackages(settings);
7495
7020
  try {
7496
7021
  const ids = await registry.loadFromDir(pluginDir, activateExternalPluginApiBridge);
@@ -7518,8 +7043,8 @@ async function loadPluginRuntimes(registry, settings) {
7518
7043
  // src/domains/providers/types/knowledge-base.ts
7519
7044
  init_esm_shims();
7520
7045
  var import_yaml = __toESM(require_dist(), 1);
7521
- import { readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync3 } from "node:fs";
7522
- import { join as join6 } from "node:path";
7046
+ import { readdirSync as readdirSync2, readFileSync, statSync as statSync3 } from "node:fs";
7047
+ import { join as join5 } from "node:path";
7523
7048
  var FileKnowledgeBase = class {
7524
7049
  roots;
7525
7050
  loaded = [];
@@ -7533,7 +7058,7 @@ var FileKnowledgeBase = class {
7533
7058
  const files = collectYamlFiles(root.dir);
7534
7059
  for (const file of files) {
7535
7060
  const name = root.label ? `${root.label}:${file.name}` : file.name;
7536
- const raw = readFileSync2(file.path, "utf8");
7061
+ const raw = readFileSync(file.path, "utf8");
7537
7062
  const parsed = (0, import_yaml.parse)(raw);
7538
7063
  if (!Array.isArray(parsed)) {
7539
7064
  throw new Error(`knowledge base file ${name} must be a YAML list of KnowledgeBaseEntry`);
@@ -7591,7 +7116,7 @@ function collectYamlFiles(dir, prefix = "") {
7591
7116
  const out = [];
7592
7117
  const entries = readdirSync2(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
7593
7118
  for (const entry of entries) {
7594
- const path = join6(dir, entry.name);
7119
+ const path = join5(dir, entry.name);
7595
7120
  const name = prefix ? `${prefix}/${entry.name}` : entry.name;
7596
7121
  if (entry.isDirectory()) {
7597
7122
  out.push(...collectYamlFiles(path, name));
@@ -8171,24 +7696,6 @@ export {
8171
7696
  getCatalogModelForRuntime,
8172
7697
  getRuntimeRegistry,
8173
7698
  credentialsPresent,
8174
- stripTokenizerSentinels,
8175
- DEFAULT_COMPACTION_THRESHOLD,
8176
- shouldCompact,
8177
- AutoCompactionTrigger,
8178
- buildContextLedger,
8179
- ceilChars,
8180
- contentChars,
8181
- estimateReasoningTextTokens,
8182
- extractReasoningTokens,
8183
- estimateAgentMessageTokens,
8184
- estimateAgentContextBreakdown,
8185
- estimateAgentContextTokens,
8186
- contextUsageSnapshot,
8187
- appendContextSnapshot,
8188
- getLatestContextSnapshot,
8189
- captureContextSnapshot,
8190
- snapshotInputTokens,
8191
- reconcileSnapshot,
8192
7699
  setGlobalDefaultMaxOutputTokens,
8193
7700
  resolveReservedOutputTokens,
8194
7701
  setResidencyNoticeSink,
@@ -8207,6 +7714,7 @@ export {
8207
7714
  registerClioApiProviders,
8208
7715
  resolveProviderKnowledgeBaseRoots,
8209
7716
  loadPluginRuntimes,
7717
+ formatContextWindowSlots,
8210
7718
  registerBuiltinRuntimes,
8211
7719
  FileKnowledgeBase,
8212
7720
  isOrchestratorEligibleRuntime,
@@ -8228,7 +7736,8 @@ export {
8228
7736
  runtimeTargetSnapshot,
8229
7737
  firstRuntimeResolutionError,
8230
7738
  runtimeResolutionWarnings,
7739
+ runtimeResolutionWarningsBesideThinkingNotice,
8231
7740
  normalizeCostProvenance,
8232
7741
  ProvidersDomainModule
8233
7742
  };
8234
- //# sourceMappingURL=chunk-LZSJBIVT.js.map
7743
+ //# sourceMappingURL=chunk-DJVECN66.js.map