@calliopelabs/cli 3.1.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (856) hide show
  1. package/README.md +68 -7
  2. package/dist/acp.d.ts +1 -4
  3. package/dist/acp.d.ts.map +1 -1
  4. package/dist/acp.js +118 -217
  5. package/dist/acp.js.map +1 -1
  6. package/dist/approvals/commands.d.ts +35 -0
  7. package/dist/approvals/commands.d.ts.map +1 -0
  8. package/dist/approvals/commands.js +51 -0
  9. package/dist/approvals/commands.js.map +1 -0
  10. package/dist/approvals/index.d.ts +6 -0
  11. package/dist/approvals/index.d.ts.map +1 -0
  12. package/dist/approvals/index.js +6 -0
  13. package/dist/approvals/index.js.map +1 -0
  14. package/dist/approvals/queue.d.ts +18 -0
  15. package/dist/approvals/queue.d.ts.map +1 -0
  16. package/dist/approvals/queue.js +46 -0
  17. package/dist/approvals/queue.js.map +1 -0
  18. package/dist/approvals/request.d.ts +13 -0
  19. package/dist/approvals/request.d.ts.map +1 -0
  20. package/dist/approvals/request.js +102 -0
  21. package/dist/approvals/request.js.map +1 -0
  22. package/dist/approvals/store.d.ts +24 -0
  23. package/dist/approvals/store.d.ts.map +1 -0
  24. package/dist/approvals/store.js +229 -0
  25. package/dist/approvals/store.js.map +1 -0
  26. package/dist/approvals/types.d.ts +27 -0
  27. package/dist/approvals/types.d.ts.map +1 -0
  28. package/dist/approvals/types.js +4 -0
  29. package/dist/approvals/types.js.map +1 -0
  30. package/dist/auto-compressor.d.ts +3 -2
  31. package/dist/auto-compressor.d.ts.map +1 -1
  32. package/dist/auto-compressor.js +9 -9
  33. package/dist/auto-compressor.js.map +1 -1
  34. package/dist/bin.d.ts.map +1 -1
  35. package/dist/bin.js +125 -22
  36. package/dist/bin.js.map +1 -1
  37. package/dist/brain/access.d.ts +65 -0
  38. package/dist/brain/access.d.ts.map +1 -0
  39. package/dist/brain/access.js +216 -0
  40. package/dist/brain/access.js.map +1 -0
  41. package/dist/brain/actions.d.ts +120 -0
  42. package/dist/brain/actions.d.ts.map +1 -0
  43. package/dist/brain/actions.js +270 -0
  44. package/dist/brain/actions.js.map +1 -0
  45. package/dist/brain/cli.d.ts +17 -0
  46. package/dist/brain/cli.d.ts.map +1 -0
  47. package/dist/brain/cli.js +206 -0
  48. package/dist/brain/cli.js.map +1 -0
  49. package/dist/brain/index.d.ts +16 -0
  50. package/dist/brain/index.d.ts.map +1 -0
  51. package/dist/brain/index.js +16 -0
  52. package/dist/brain/index.js.map +1 -0
  53. package/dist/brain/journal.d.ts +17 -0
  54. package/dist/brain/journal.d.ts.map +1 -0
  55. package/dist/brain/journal.js +189 -0
  56. package/dist/brain/journal.js.map +1 -0
  57. package/dist/brain/kg.d.ts +23 -0
  58. package/dist/brain/kg.d.ts.map +1 -0
  59. package/dist/brain/kg.js +36 -0
  60. package/dist/brain/kg.js.map +1 -0
  61. package/dist/brain/presentation.d.ts +3 -0
  62. package/dist/brain/presentation.d.ts.map +1 -0
  63. package/dist/brain/presentation.js +48 -0
  64. package/dist/brain/presentation.js.map +1 -0
  65. package/dist/brain/queries.d.ts +179 -0
  66. package/dist/brain/queries.d.ts.map +1 -0
  67. package/dist/brain/queries.js +210 -0
  68. package/dist/brain/queries.js.map +1 -0
  69. package/dist/brain/run-ingest.d.ts +29 -0
  70. package/dist/brain/run-ingest.d.ts.map +1 -0
  71. package/dist/brain/run-ingest.js +200 -0
  72. package/dist/brain/run-ingest.js.map +1 -0
  73. package/dist/brain/sqlite.d.ts +19 -0
  74. package/dist/brain/sqlite.d.ts.map +1 -0
  75. package/dist/brain/sqlite.js +252 -0
  76. package/dist/brain/sqlite.js.map +1 -0
  77. package/dist/brain/store.d.ts +31 -0
  78. package/dist/brain/store.d.ts.map +1 -0
  79. package/dist/brain/store.js +324 -0
  80. package/dist/brain/store.js.map +1 -0
  81. package/dist/brain/tool-query.d.ts +6 -0
  82. package/dist/brain/tool-query.d.ts.map +1 -0
  83. package/dist/brain/tool-query.js +42 -0
  84. package/dist/brain/tool-query.js.map +1 -0
  85. package/dist/brain/tools.d.ts +13 -0
  86. package/dist/brain/tools.d.ts.map +1 -0
  87. package/dist/brain/tools.js +20 -0
  88. package/dist/brain/tools.js.map +1 -0
  89. package/dist/brain/transfer.d.ts +57 -0
  90. package/dist/brain/transfer.d.ts.map +1 -0
  91. package/dist/brain/transfer.js +266 -0
  92. package/dist/brain/transfer.js.map +1 -0
  93. package/dist/brain/types.d.ts +145 -0
  94. package/dist/brain/types.d.ts.map +1 -0
  95. package/dist/brain/types.js +38 -0
  96. package/dist/brain/types.js.map +1 -0
  97. package/dist/brain/validation.d.ts +15 -0
  98. package/dist/brain/validation.d.ts.map +1 -0
  99. package/dist/brain/validation.js +163 -0
  100. package/dist/brain/validation.js.map +1 -0
  101. package/dist/budget.d.ts +5 -4
  102. package/dist/budget.d.ts.map +1 -1
  103. package/dist/budget.js +16 -38
  104. package/dist/budget.js.map +1 -1
  105. package/dist/cancellation.d.ts +8 -0
  106. package/dist/cancellation.d.ts.map +1 -0
  107. package/dist/cancellation.js +42 -0
  108. package/dist/cancellation.js.map +1 -0
  109. package/dist/checkpoint.d.ts +2 -2
  110. package/dist/checkpoint.d.ts.map +1 -1
  111. package/dist/checkpoint.js +5 -5
  112. package/dist/checkpoint.js.map +1 -1
  113. package/dist/config.d.ts +13 -0
  114. package/dist/config.d.ts.map +1 -1
  115. package/dist/config.js +32 -8
  116. package/dist/config.js.map +1 -1
  117. package/dist/doctor.d.ts +30 -0
  118. package/dist/doctor.d.ts.map +1 -0
  119. package/dist/doctor.js +124 -0
  120. package/dist/doctor.js.map +1 -0
  121. package/dist/errors.d.ts +15 -0
  122. package/dist/errors.d.ts.map +1 -1
  123. package/dist/errors.js +33 -9
  124. package/dist/errors.js.map +1 -1
  125. package/dist/execution/attribution.d.ts +17 -0
  126. package/dist/execution/attribution.d.ts.map +1 -0
  127. package/dist/execution/attribution.js +21 -0
  128. package/dist/execution/attribution.js.map +1 -0
  129. package/dist/execution/authority.d.ts +22 -0
  130. package/dist/execution/authority.d.ts.map +1 -0
  131. package/dist/execution/authority.js +134 -0
  132. package/dist/execution/authority.js.map +1 -0
  133. package/dist/execution/billing.d.ts +100 -0
  134. package/dist/execution/billing.d.ts.map +1 -0
  135. package/dist/execution/billing.js +166 -0
  136. package/dist/execution/billing.js.map +1 -0
  137. package/dist/execution/child-grants.d.ts +9 -0
  138. package/dist/execution/child-grants.d.ts.map +1 -0
  139. package/dist/execution/child-grants.js +55 -0
  140. package/dist/execution/child-grants.js.map +1 -0
  141. package/dist/execution/files.d.ts +6 -0
  142. package/dist/execution/files.d.ts.map +1 -0
  143. package/dist/execution/files.js +159 -0
  144. package/dist/execution/files.js.map +1 -0
  145. package/dist/execution/guard.d.ts +50 -0
  146. package/dist/execution/guard.d.ts.map +1 -0
  147. package/dist/execution/guard.js +158 -0
  148. package/dist/execution/guard.js.map +1 -0
  149. package/dist/execution/index.d.ts +12 -0
  150. package/dist/execution/index.d.ts.map +1 -0
  151. package/dist/execution/index.js +12 -0
  152. package/dist/execution/index.js.map +1 -0
  153. package/dist/execution/ledger.d.ts +23 -0
  154. package/dist/execution/ledger.d.ts.map +1 -0
  155. package/dist/execution/ledger.js +379 -0
  156. package/dist/execution/ledger.js.map +1 -0
  157. package/dist/execution/project-spend.d.ts +45 -0
  158. package/dist/execution/project-spend.d.ts.map +1 -0
  159. package/dist/execution/project-spend.js +274 -0
  160. package/dist/execution/project-spend.js.map +1 -0
  161. package/dist/execution/quote.d.ts +19 -0
  162. package/dist/execution/quote.d.ts.map +1 -0
  163. package/dist/execution/quote.js +116 -0
  164. package/dist/execution/quote.js.map +1 -0
  165. package/dist/execution/types.d.ts +113 -0
  166. package/dist/execution/types.d.ts.map +1 -0
  167. package/dist/execution/types.js +9 -0
  168. package/dist/execution/types.js.map +1 -0
  169. package/dist/execution/writer-recovery.d.ts +3 -0
  170. package/dist/execution/writer-recovery.d.ts.map +1 -0
  171. package/dist/execution/writer-recovery.js +85 -0
  172. package/dist/execution/writer-recovery.js.map +1 -0
  173. package/dist/goals/accounting.d.ts +69 -0
  174. package/dist/goals/accounting.d.ts.map +1 -0
  175. package/dist/goals/accounting.js +100 -0
  176. package/dist/goals/accounting.js.map +1 -0
  177. package/dist/goals/actions.d.ts +33 -0
  178. package/dist/goals/actions.d.ts.map +1 -0
  179. package/dist/goals/actions.js +261 -0
  180. package/dist/goals/actions.js.map +1 -0
  181. package/dist/goals/authority.d.ts +9 -0
  182. package/dist/goals/authority.d.ts.map +1 -0
  183. package/dist/goals/authority.js +47 -0
  184. package/dist/goals/authority.js.map +1 -0
  185. package/dist/goals/cli.d.ts +10 -0
  186. package/dist/goals/cli.d.ts.map +1 -0
  187. package/dist/goals/cli.js +169 -0
  188. package/dist/goals/cli.js.map +1 -0
  189. package/dist/goals/contracts.d.ts +18 -0
  190. package/dist/goals/contracts.d.ts.map +1 -0
  191. package/dist/goals/contracts.js +127 -0
  192. package/dist/goals/contracts.js.map +1 -0
  193. package/dist/goals/index.d.ts +17 -0
  194. package/dist/goals/index.d.ts.map +1 -0
  195. package/dist/goals/index.js +16 -0
  196. package/dist/goals/index.js.map +1 -0
  197. package/dist/goals/journal.d.ts +5 -0
  198. package/dist/goals/journal.d.ts.map +1 -0
  199. package/dist/goals/journal.js +142 -0
  200. package/dist/goals/journal.js.map +1 -0
  201. package/dist/goals/metrics.d.ts +53 -0
  202. package/dist/goals/metrics.d.ts.map +1 -0
  203. package/dist/goals/metrics.js +141 -0
  204. package/dist/goals/metrics.js.map +1 -0
  205. package/dist/goals/repair.d.ts +10 -0
  206. package/dist/goals/repair.d.ts.map +1 -0
  207. package/dist/goals/repair.js +50 -0
  208. package/dist/goals/repair.js.map +1 -0
  209. package/dist/goals/routing.d.ts +18 -0
  210. package/dist/goals/routing.d.ts.map +1 -0
  211. package/dist/goals/routing.js +60 -0
  212. package/dist/goals/routing.js.map +1 -0
  213. package/dist/goals/store.d.ts +30 -0
  214. package/dist/goals/store.d.ts.map +1 -0
  215. package/dist/goals/store.js +314 -0
  216. package/dist/goals/store.js.map +1 -0
  217. package/dist/goals/supervised-cli.d.ts +5 -0
  218. package/dist/goals/supervised-cli.d.ts.map +1 -0
  219. package/dist/goals/supervised-cli.js +44 -0
  220. package/dist/goals/supervised-cli.js.map +1 -0
  221. package/dist/goals/supervised.d.ts +8 -0
  222. package/dist/goals/supervised.d.ts.map +1 -0
  223. package/dist/goals/supervised.js +65 -0
  224. package/dist/goals/supervised.js.map +1 -0
  225. package/dist/goals/team.d.ts +8 -0
  226. package/dist/goals/team.d.ts.map +1 -0
  227. package/dist/goals/team.js +64 -0
  228. package/dist/goals/team.js.map +1 -0
  229. package/dist/goals/types.d.ts +174 -0
  230. package/dist/goals/types.d.ts.map +1 -0
  231. package/dist/goals/types.js +2 -0
  232. package/dist/goals/types.js.map +1 -0
  233. package/dist/goals/validation.d.ts +17 -0
  234. package/dist/goals/validation.d.ts.map +1 -0
  235. package/dist/goals/validation.js +172 -0
  236. package/dist/goals/validation.js.map +1 -0
  237. package/dist/headless.d.ts +1 -0
  238. package/dist/headless.d.ts.map +1 -1
  239. package/dist/headless.js +98 -275
  240. package/dist/headless.js.map +1 -1
  241. package/dist/health/index.d.ts +5 -0
  242. package/dist/health/index.d.ts.map +1 -0
  243. package/dist/health/index.js +5 -0
  244. package/dist/health/index.js.map +1 -0
  245. package/dist/health/store.d.ts +24 -0
  246. package/dist/health/store.d.ts.map +1 -0
  247. package/dist/health/store.js +190 -0
  248. package/dist/health/store.js.map +1 -0
  249. package/dist/health/summary.d.ts +10 -0
  250. package/dist/health/summary.d.ts.map +1 -0
  251. package/dist/health/summary.js +95 -0
  252. package/dist/health/summary.js.map +1 -0
  253. package/dist/health/target.d.ts +3 -0
  254. package/dist/health/target.d.ts.map +1 -0
  255. package/dist/health/target.js +53 -0
  256. package/dist/health/target.js.map +1 -0
  257. package/dist/health/types.d.ts +72 -0
  258. package/dist/health/types.d.ts.map +1 -0
  259. package/dist/health/types.js +2 -0
  260. package/dist/health/types.js.map +1 -0
  261. package/dist/hooks.d.ts +7 -2
  262. package/dist/hooks.d.ts.map +1 -1
  263. package/dist/hooks.js +35 -17
  264. package/dist/hooks.js.map +1 -1
  265. package/dist/improvement/actions.d.ts +27 -0
  266. package/dist/improvement/actions.d.ts.map +1 -0
  267. package/dist/improvement/actions.js +116 -0
  268. package/dist/improvement/actions.js.map +1 -0
  269. package/dist/improvement/cli.d.ts +9 -0
  270. package/dist/improvement/cli.d.ts.map +1 -0
  271. package/dist/improvement/cli.js +58 -0
  272. package/dist/improvement/cli.js.map +1 -0
  273. package/dist/improvement/feedback.d.ts +30 -0
  274. package/dist/improvement/feedback.d.ts.map +1 -0
  275. package/dist/improvement/feedback.js +7 -0
  276. package/dist/improvement/feedback.js.map +1 -0
  277. package/dist/improvement/index.d.ts +7 -0
  278. package/dist/improvement/index.d.ts.map +1 -0
  279. package/dist/improvement/index.js +7 -0
  280. package/dist/improvement/index.js.map +1 -0
  281. package/dist/improvement/metrics.d.ts +4 -0
  282. package/dist/improvement/metrics.d.ts.map +1 -0
  283. package/dist/improvement/metrics.js +38 -0
  284. package/dist/improvement/metrics.js.map +1 -0
  285. package/dist/improvement/projection.d.ts +7 -0
  286. package/dist/improvement/projection.d.ts.map +1 -0
  287. package/dist/improvement/projection.js +135 -0
  288. package/dist/improvement/projection.js.map +1 -0
  289. package/dist/improvement/types.d.ts +115 -0
  290. package/dist/improvement/types.d.ts.map +1 -0
  291. package/dist/improvement/types.js +2 -0
  292. package/dist/improvement/types.js.map +1 -0
  293. package/dist/index.d.ts +3 -0
  294. package/dist/index.d.ts.map +1 -1
  295. package/dist/index.js +3 -0
  296. package/dist/index.js.map +1 -1
  297. package/dist/instructions.d.ts +10 -0
  298. package/dist/instructions.d.ts.map +1 -0
  299. package/dist/instructions.js +93 -0
  300. package/dist/instructions.js.map +1 -0
  301. package/dist/isolation/contracts.d.ts +42 -0
  302. package/dist/isolation/contracts.d.ts.map +1 -0
  303. package/dist/isolation/contracts.js +33 -0
  304. package/dist/isolation/contracts.js.map +1 -0
  305. package/dist/isolation/coordinator.d.ts +10 -0
  306. package/dist/isolation/coordinator.d.ts.map +1 -0
  307. package/dist/isolation/coordinator.js +79 -0
  308. package/dist/isolation/coordinator.js.map +1 -0
  309. package/dist/isolation/index.d.ts +5 -0
  310. package/dist/isolation/index.d.ts.map +1 -0
  311. package/dist/isolation/index.js +5 -0
  312. package/dist/isolation/index.js.map +1 -0
  313. package/dist/isolation/process.d.ts +11 -0
  314. package/dist/isolation/process.d.ts.map +1 -0
  315. package/dist/isolation/process.js +131 -0
  316. package/dist/isolation/process.js.map +1 -0
  317. package/dist/isolation/worktree.d.ts +25 -0
  318. package/dist/isolation/worktree.d.ts.map +1 -0
  319. package/dist/isolation/worktree.js +282 -0
  320. package/dist/isolation/worktree.js.map +1 -0
  321. package/dist/memory.d.ts.map +1 -1
  322. package/dist/memory.js +5 -1
  323. package/dist/memory.js.map +1 -1
  324. package/dist/model-detection.d.ts +14 -18
  325. package/dist/model-detection.d.ts.map +1 -1
  326. package/dist/model-detection.js +287 -149
  327. package/dist/model-detection.js.map +1 -1
  328. package/dist/models/index.d.ts +3 -0
  329. package/dist/models/index.d.ts.map +1 -0
  330. package/dist/models/index.js +3 -0
  331. package/dist/models/index.js.map +1 -0
  332. package/dist/models/metadata.d.ts +43 -0
  333. package/dist/models/metadata.d.ts.map +1 -0
  334. package/dist/models/metadata.js +72 -0
  335. package/dist/models/metadata.js.map +1 -0
  336. package/dist/models/openrouter.d.ts +6 -0
  337. package/dist/models/openrouter.d.ts.map +1 -0
  338. package/dist/models/openrouter.js +38 -0
  339. package/dist/models/openrouter.js.map +1 -0
  340. package/dist/orchestration/accounting.d.ts +35 -0
  341. package/dist/orchestration/accounting.d.ts.map +1 -0
  342. package/dist/orchestration/accounting.js +27 -0
  343. package/dist/orchestration/accounting.js.map +1 -0
  344. package/dist/orchestration/actions.d.ts +23 -0
  345. package/dist/orchestration/actions.d.ts.map +1 -0
  346. package/dist/orchestration/actions.js +65 -0
  347. package/dist/orchestration/actions.js.map +1 -0
  348. package/dist/orchestration/cli.d.ts +28 -0
  349. package/dist/orchestration/cli.d.ts.map +1 -0
  350. package/dist/orchestration/cli.js +178 -0
  351. package/dist/orchestration/cli.js.map +1 -0
  352. package/dist/orchestration/coordinator-actions.d.ts +15 -0
  353. package/dist/orchestration/coordinator-actions.d.ts.map +1 -0
  354. package/dist/orchestration/coordinator-actions.js +79 -0
  355. package/dist/orchestration/coordinator-actions.js.map +1 -0
  356. package/dist/orchestration/coordinator-types.d.ts +193 -0
  357. package/dist/orchestration/coordinator-types.d.ts.map +1 -0
  358. package/dist/orchestration/coordinator-types.js +2 -0
  359. package/dist/orchestration/coordinator-types.js.map +1 -0
  360. package/dist/orchestration/coordinator.d.ts +32 -0
  361. package/dist/orchestration/coordinator.d.ts.map +1 -0
  362. package/dist/orchestration/coordinator.js +405 -0
  363. package/dist/orchestration/coordinator.js.map +1 -0
  364. package/dist/orchestration/execution-cli.d.ts +11 -0
  365. package/dist/orchestration/execution-cli.d.ts.map +1 -0
  366. package/dist/orchestration/execution-cli.js +183 -0
  367. package/dist/orchestration/execution-cli.js.map +1 -0
  368. package/dist/orchestration/execution-journal.d.ts +15 -0
  369. package/dist/orchestration/execution-journal.d.ts.map +1 -0
  370. package/dist/orchestration/execution-journal.js +477 -0
  371. package/dist/orchestration/execution-journal.js.map +1 -0
  372. package/dist/orchestration/execution-store.d.ts +39 -0
  373. package/dist/orchestration/execution-store.d.ts.map +1 -0
  374. package/dist/orchestration/execution-store.js +325 -0
  375. package/dist/orchestration/execution-store.js.map +1 -0
  376. package/dist/orchestration/execution.d.ts +8 -0
  377. package/dist/orchestration/execution.d.ts.map +1 -0
  378. package/dist/orchestration/execution.js +47 -0
  379. package/dist/orchestration/execution.js.map +1 -0
  380. package/dist/orchestration/index.d.ts +20 -0
  381. package/dist/orchestration/index.d.ts.map +1 -0
  382. package/dist/orchestration/index.js +17 -0
  383. package/dist/orchestration/index.js.map +1 -0
  384. package/dist/orchestration/progress.d.ts +19 -0
  385. package/dist/orchestration/progress.d.ts.map +1 -0
  386. package/dist/orchestration/progress.js +20 -0
  387. package/dist/orchestration/progress.js.map +1 -0
  388. package/dist/orchestration/recovery.d.ts +4 -0
  389. package/dist/orchestration/recovery.d.ts.map +1 -0
  390. package/dist/orchestration/recovery.js +121 -0
  391. package/dist/orchestration/recovery.js.map +1 -0
  392. package/dist/orchestration/request-accounting.d.ts +35 -0
  393. package/dist/orchestration/request-accounting.d.ts.map +1 -0
  394. package/dist/orchestration/request-accounting.js +71 -0
  395. package/dist/orchestration/request-accounting.js.map +1 -0
  396. package/dist/orchestration/routing.d.ts +20 -0
  397. package/dist/orchestration/routing.d.ts.map +1 -0
  398. package/dist/orchestration/routing.js +38 -0
  399. package/dist/orchestration/routing.js.map +1 -0
  400. package/dist/orchestration/store.d.ts +26 -0
  401. package/dist/orchestration/store.d.ts.map +1 -0
  402. package/dist/orchestration/store.js +381 -0
  403. package/dist/orchestration/store.js.map +1 -0
  404. package/dist/orchestration/types.d.ts +201 -0
  405. package/dist/orchestration/types.d.ts.map +1 -0
  406. package/dist/orchestration/types.js +11 -0
  407. package/dist/orchestration/types.js.map +1 -0
  408. package/dist/orchestration/validation.d.ts +29 -0
  409. package/dist/orchestration/validation.d.ts.map +1 -0
  410. package/dist/orchestration/validation.js +440 -0
  411. package/dist/orchestration/validation.js.map +1 -0
  412. package/dist/orchestration/verification.d.ts +30 -0
  413. package/dist/orchestration/verification.d.ts.map +1 -0
  414. package/dist/orchestration/verification.js +204 -0
  415. package/dist/orchestration/verification.js.map +1 -0
  416. package/dist/orchestration/worker-context.d.ts +33 -0
  417. package/dist/orchestration/worker-context.d.ts.map +1 -0
  418. package/dist/orchestration/worker-context.js +31 -0
  419. package/dist/orchestration/worker-context.js.map +1 -0
  420. package/dist/policy.d.ts +1 -0
  421. package/dist/policy.d.ts.map +1 -1
  422. package/dist/policy.js +25 -5
  423. package/dist/policy.js.map +1 -1
  424. package/dist/preferences/controls.d.ts +21 -0
  425. package/dist/preferences/controls.d.ts.map +1 -0
  426. package/dist/preferences/controls.js +36 -0
  427. package/dist/preferences/controls.js.map +1 -0
  428. package/dist/preferences/flags.d.ts +8 -0
  429. package/dist/preferences/flags.d.ts.map +1 -0
  430. package/dist/preferences/flags.js +27 -0
  431. package/dist/preferences/flags.js.map +1 -0
  432. package/dist/preferences/index.d.ts +9 -0
  433. package/dist/preferences/index.d.ts.map +1 -0
  434. package/dist/preferences/index.js +9 -0
  435. package/dist/preferences/index.js.map +1 -0
  436. package/dist/preferences/once.d.ts +8 -0
  437. package/dist/preferences/once.d.ts.map +1 -0
  438. package/dist/preferences/once.js +28 -0
  439. package/dist/preferences/once.js.map +1 -0
  440. package/dist/preferences/resolve.d.ts +14 -0
  441. package/dist/preferences/resolve.d.ts.map +1 -0
  442. package/dist/preferences/resolve.js +58 -0
  443. package/dist/preferences/resolve.js.map +1 -0
  444. package/dist/preferences/store.d.ts +19 -0
  445. package/dist/preferences/store.d.ts.map +1 -0
  446. package/dist/preferences/store.js +147 -0
  447. package/dist/preferences/store.js.map +1 -0
  448. package/dist/preferences/submission.d.ts +16 -0
  449. package/dist/preferences/submission.d.ts.map +1 -0
  450. package/dist/preferences/submission.js +29 -0
  451. package/dist/preferences/submission.js.map +1 -0
  452. package/dist/preferences/types.d.ts +23 -0
  453. package/dist/preferences/types.d.ts.map +1 -0
  454. package/dist/preferences/types.js +2 -0
  455. package/dist/preferences/types.js.map +1 -0
  456. package/dist/preferences/validate.d.ts +3 -0
  457. package/dist/preferences/validate.d.ts.map +1 -0
  458. package/dist/preferences/validate.js +15 -0
  459. package/dist/preferences/validate.js.map +1 -0
  460. package/dist/process-cancellation.d.ts +6 -0
  461. package/dist/process-cancellation.d.ts.map +1 -0
  462. package/dist/process-cancellation.js +39 -0
  463. package/dist/process-cancellation.js.map +1 -0
  464. package/dist/providers/anthropic.d.ts +7 -2
  465. package/dist/providers/anthropic.d.ts.map +1 -1
  466. package/dist/providers/anthropic.js +72 -41
  467. package/dist/providers/anthropic.js.map +1 -1
  468. package/dist/providers/bedrock.d.ts +1 -1
  469. package/dist/providers/bedrock.d.ts.map +1 -1
  470. package/dist/providers/bedrock.js +39 -23
  471. package/dist/providers/bedrock.js.map +1 -1
  472. package/dist/providers/compat.d.ts +4 -3
  473. package/dist/providers/compat.d.ts.map +1 -1
  474. package/dist/providers/compat.js +49 -31
  475. package/dist/providers/compat.js.map +1 -1
  476. package/dist/providers/deepseek-reasoning.d.ts +64 -0
  477. package/dist/providers/deepseek-reasoning.d.ts.map +1 -0
  478. package/dist/providers/deepseek-reasoning.js +28 -0
  479. package/dist/providers/deepseek-reasoning.js.map +1 -0
  480. package/dist/providers/google.d.ts +4 -3
  481. package/dist/providers/google.d.ts.map +1 -1
  482. package/dist/providers/google.js +128 -19
  483. package/dist/providers/google.js.map +1 -1
  484. package/dist/providers/index.d.ts +2 -0
  485. package/dist/providers/index.d.ts.map +1 -1
  486. package/dist/providers/index.js +216 -36
  487. package/dist/providers/index.js.map +1 -1
  488. package/dist/providers/ollama.d.ts.map +1 -1
  489. package/dist/providers/ollama.js +79 -43
  490. package/dist/providers/ollama.js.map +1 -1
  491. package/dist/providers/openai.d.ts +2 -2
  492. package/dist/providers/openai.d.ts.map +1 -1
  493. package/dist/providers/openai.js +50 -46
  494. package/dist/providers/openai.js.map +1 -1
  495. package/dist/providers/openrouter-bounds.d.ts +22 -0
  496. package/dist/providers/openrouter-bounds.d.ts.map +1 -0
  497. package/dist/providers/openrouter-bounds.js +16 -0
  498. package/dist/providers/openrouter-bounds.js.map +1 -0
  499. package/dist/providers/stream-attempt.d.ts +29 -0
  500. package/dist/providers/stream-attempt.d.ts.map +1 -0
  501. package/dist/providers/stream-attempt.js +63 -0
  502. package/dist/providers/stream-attempt.js.map +1 -0
  503. package/dist/providers/types.d.ts +40 -4
  504. package/dist/providers/types.d.ts.map +1 -1
  505. package/dist/providers/types.js +19 -0
  506. package/dist/providers/types.js.map +1 -1
  507. package/dist/replay.d.ts.map +1 -1
  508. package/dist/replay.js +16 -0
  509. package/dist/replay.js.map +1 -1
  510. package/dist/risk.d.ts.map +1 -1
  511. package/dist/risk.js +5 -0
  512. package/dist/risk.js.map +1 -1
  513. package/dist/router.d.ts +7 -110
  514. package/dist/router.d.ts.map +1 -1
  515. package/dist/router.js +0 -451
  516. package/dist/router.js.map +1 -1
  517. package/dist/routing/index.d.ts +6 -0
  518. package/dist/routing/index.d.ts.map +1 -0
  519. package/dist/routing/index.js +5 -0
  520. package/dist/routing/index.js.map +1 -0
  521. package/dist/routing/prompt.d.ts +4 -0
  522. package/dist/routing/prompt.d.ts.map +1 -0
  523. package/dist/routing/prompt.js +14 -0
  524. package/dist/routing/prompt.js.map +1 -0
  525. package/dist/routing/select.d.ts +9 -0
  526. package/dist/routing/select.d.ts.map +1 -0
  527. package/dist/routing/select.js +279 -0
  528. package/dist/routing/select.js.map +1 -0
  529. package/dist/routing/smart.d.ts +31 -0
  530. package/dist/routing/smart.d.ts.map +1 -0
  531. package/dist/routing/smart.js +46 -0
  532. package/dist/routing/smart.js.map +1 -0
  533. package/dist/routing/types.d.ts +79 -0
  534. package/dist/routing/types.d.ts.map +1 -0
  535. package/dist/routing/types.js +2 -0
  536. package/dist/routing/types.js.map +1 -0
  537. package/dist/runlog.d.ts +32 -4
  538. package/dist/runlog.d.ts.map +1 -1
  539. package/dist/runlog.js +22 -6
  540. package/dist/runlog.js.map +1 -1
  541. package/dist/runtime/index.d.ts +6 -0
  542. package/dist/runtime/index.d.ts.map +1 -0
  543. package/dist/runtime/index.js +6 -0
  544. package/dist/runtime/index.js.map +1 -0
  545. package/dist/runtime/permissions.d.ts +21 -0
  546. package/dist/runtime/permissions.d.ts.map +1 -0
  547. package/dist/runtime/permissions.js +110 -0
  548. package/dist/runtime/permissions.js.map +1 -0
  549. package/dist/runtime/repair.d.ts +20 -0
  550. package/dist/runtime/repair.d.ts.map +1 -0
  551. package/dist/runtime/repair.js +50 -0
  552. package/dist/runtime/repair.js.map +1 -0
  553. package/dist/runtime/tool-retry.d.ts +3 -0
  554. package/dist/runtime/tool-retry.d.ts.map +1 -0
  555. package/dist/runtime/tool-retry.js +12 -0
  556. package/dist/runtime/tool-retry.js.map +1 -0
  557. package/dist/runtime/turn.d.ts +97 -0
  558. package/dist/runtime/turn.d.ts.map +1 -0
  559. package/dist/runtime/turn.js +437 -0
  560. package/dist/runtime/turn.js.map +1 -0
  561. package/dist/runtime/types.d.ts +11 -0
  562. package/dist/runtime/types.d.ts.map +1 -0
  563. package/dist/runtime/types.js +5 -0
  564. package/dist/runtime/types.js.map +1 -0
  565. package/dist/sandbox/docker.d.ts +4 -4
  566. package/dist/sandbox/docker.d.ts.map +1 -1
  567. package/dist/sandbox/docker.js +55 -16
  568. package/dist/sandbox/docker.js.map +1 -1
  569. package/dist/sandbox/native.d.ts +1 -0
  570. package/dist/sandbox/native.d.ts.map +1 -1
  571. package/dist/sandbox/native.js +11 -2
  572. package/dist/sandbox/native.js.map +1 -1
  573. package/dist/scope.d.ts +5 -9
  574. package/dist/scope.d.ts.map +1 -1
  575. package/dist/scope.js +43 -20
  576. package/dist/scope.js.map +1 -1
  577. package/dist/session-management/actions.d.ts +28 -0
  578. package/dist/session-management/actions.d.ts.map +1 -0
  579. package/dist/session-management/actions.js +78 -0
  580. package/dist/session-management/actions.js.map +1 -0
  581. package/dist/session-management/cli.d.ts +24 -0
  582. package/dist/session-management/cli.d.ts.map +1 -0
  583. package/dist/session-management/cli.js +92 -0
  584. package/dist/session-management/cli.js.map +1 -0
  585. package/dist/session-management/files.d.ts +5 -0
  586. package/dist/session-management/files.d.ts.map +1 -0
  587. package/dist/session-management/files.js +92 -0
  588. package/dist/session-management/files.js.map +1 -0
  589. package/dist/session-management/index.d.ts +7 -0
  590. package/dist/session-management/index.d.ts.map +1 -0
  591. package/dist/session-management/index.js +7 -0
  592. package/dist/session-management/index.js.map +1 -0
  593. package/dist/session-management/permissions.d.ts +12 -0
  594. package/dist/session-management/permissions.d.ts.map +1 -0
  595. package/dist/session-management/permissions.js +33 -0
  596. package/dist/session-management/permissions.js.map +1 -0
  597. package/dist/session-management/presentation.d.ts +5 -0
  598. package/dist/session-management/presentation.d.ts.map +1 -0
  599. package/dist/session-management/presentation.js +10 -0
  600. package/dist/session-management/presentation.js.map +1 -0
  601. package/dist/session-management/transfer.d.ts +9 -0
  602. package/dist/session-management/transfer.d.ts.map +1 -0
  603. package/dist/session-management/transfer.js +39 -0
  604. package/dist/session-management/transfer.js.map +1 -0
  605. package/dist/sessions/context.d.ts +4 -0
  606. package/dist/sessions/context.d.ts.map +1 -0
  607. package/dist/sessions/context.js +6 -0
  608. package/dist/sessions/context.js.map +1 -0
  609. package/dist/sessions/format.d.ts +38 -0
  610. package/dist/sessions/format.d.ts.map +1 -0
  611. package/dist/sessions/format.js +116 -0
  612. package/dist/sessions/format.js.map +1 -0
  613. package/dist/sessions/history.d.ts +37 -0
  614. package/dist/sessions/history.d.ts.map +1 -0
  615. package/dist/sessions/history.js +197 -0
  616. package/dist/sessions/history.js.map +1 -0
  617. package/dist/sessions/index.d.ts +8 -0
  618. package/dist/sessions/index.d.ts.map +1 -0
  619. package/dist/sessions/index.js +8 -0
  620. package/dist/sessions/index.js.map +1 -0
  621. package/dist/sessions/output.d.ts +31 -0
  622. package/dist/sessions/output.d.ts.map +1 -0
  623. package/dist/sessions/output.js +115 -0
  624. package/dist/sessions/output.js.map +1 -0
  625. package/dist/sessions/portable.d.ts +26 -0
  626. package/dist/sessions/portable.d.ts.map +1 -0
  627. package/dist/sessions/portable.js +105 -0
  628. package/dist/sessions/portable.js.map +1 -0
  629. package/dist/sessions/snapshot.d.ts +11 -0
  630. package/dist/sessions/snapshot.d.ts.map +1 -0
  631. package/dist/sessions/snapshot.js +118 -0
  632. package/dist/sessions/snapshot.js.map +1 -0
  633. package/dist/sessions/tool-state.d.ts +11 -0
  634. package/dist/sessions/tool-state.d.ts.map +1 -0
  635. package/dist/sessions/tool-state.js +152 -0
  636. package/dist/sessions/tool-state.js.map +1 -0
  637. package/dist/setup.d.ts.map +1 -1
  638. package/dist/setup.js +13 -5
  639. package/dist/setup.js.map +1 -1
  640. package/dist/spawning/actions.d.ts +23 -0
  641. package/dist/spawning/actions.d.ts.map +1 -0
  642. package/dist/spawning/actions.js +120 -0
  643. package/dist/spawning/actions.js.map +1 -0
  644. package/dist/spawning/authority.d.ts +15 -0
  645. package/dist/spawning/authority.d.ts.map +1 -0
  646. package/dist/spawning/authority.js +16 -0
  647. package/dist/spawning/authority.js.map +1 -0
  648. package/dist/spawning/cli.d.ts +4 -0
  649. package/dist/spawning/cli.d.ts.map +1 -0
  650. package/dist/spawning/cli.js +46 -0
  651. package/dist/spawning/cli.js.map +1 -0
  652. package/dist/spawning/execution.d.ts +13 -0
  653. package/dist/spawning/execution.d.ts.map +1 -0
  654. package/dist/spawning/execution.js +59 -0
  655. package/dist/spawning/execution.js.map +1 -0
  656. package/dist/spawning/index.d.ts +8 -0
  657. package/dist/spawning/index.d.ts.map +1 -0
  658. package/dist/spawning/index.js +8 -0
  659. package/dist/spawning/index.js.map +1 -0
  660. package/dist/spawning/store.d.ts +12 -0
  661. package/dist/spawning/store.d.ts.map +1 -0
  662. package/dist/spawning/store.js +93 -0
  663. package/dist/spawning/store.js.map +1 -0
  664. package/dist/spawning/types.d.ts +34 -0
  665. package/dist/spawning/types.d.ts.map +1 -0
  666. package/dist/spawning/types.js +2 -0
  667. package/dist/spawning/types.js.map +1 -0
  668. package/dist/spawning/validation.d.ts +14 -0
  669. package/dist/spawning/validation.d.ts.map +1 -0
  670. package/dist/spawning/validation.js +95 -0
  671. package/dist/spawning/validation.js.map +1 -0
  672. package/dist/storage.d.ts +29 -1
  673. package/dist/storage.d.ts.map +1 -1
  674. package/dist/storage.js +112 -40
  675. package/dist/storage.js.map +1 -1
  676. package/dist/supervision/approval.d.ts +4 -0
  677. package/dist/supervision/approval.d.ts.map +1 -0
  678. package/dist/supervision/approval.js +7 -0
  679. package/dist/supervision/approval.js.map +1 -0
  680. package/dist/supervision/availability.d.ts +34 -0
  681. package/dist/supervision/availability.d.ts.map +1 -0
  682. package/dist/supervision/availability.js +44 -0
  683. package/dist/supervision/availability.js.map +1 -0
  684. package/dist/supervision/context.d.ts +36 -0
  685. package/dist/supervision/context.d.ts.map +1 -0
  686. package/dist/supervision/context.js +52 -0
  687. package/dist/supervision/context.js.map +1 -0
  688. package/dist/supervision/contracts.d.ts +7 -0
  689. package/dist/supervision/contracts.d.ts.map +1 -0
  690. package/dist/supervision/contracts.js +86 -0
  691. package/dist/supervision/contracts.js.map +1 -0
  692. package/dist/supervision/effects.d.ts +15 -0
  693. package/dist/supervision/effects.d.ts.map +1 -0
  694. package/dist/supervision/effects.js +19 -0
  695. package/dist/supervision/effects.js.map +1 -0
  696. package/dist/supervision/evidence.d.ts +32 -0
  697. package/dist/supervision/evidence.d.ts.map +1 -0
  698. package/dist/supervision/evidence.js +68 -0
  699. package/dist/supervision/evidence.js.map +1 -0
  700. package/dist/supervision/health.d.ts +16 -0
  701. package/dist/supervision/health.d.ts.map +1 -0
  702. package/dist/supervision/health.js +86 -0
  703. package/dist/supervision/health.js.map +1 -0
  704. package/dist/supervision/index.d.ts +13 -0
  705. package/dist/supervision/index.d.ts.map +1 -0
  706. package/dist/supervision/index.js +13 -0
  707. package/dist/supervision/index.js.map +1 -0
  708. package/dist/supervision/journal.d.ts +16 -0
  709. package/dist/supervision/journal.d.ts.map +1 -0
  710. package/dist/supervision/journal.js +311 -0
  711. package/dist/supervision/journal.js.map +1 -0
  712. package/dist/supervision/receipts.d.ts +4 -0
  713. package/dist/supervision/receipts.d.ts.map +1 -0
  714. package/dist/supervision/receipts.js +21 -0
  715. package/dist/supervision/receipts.js.map +1 -0
  716. package/dist/supervision/reply.d.ts +12 -0
  717. package/dist/supervision/reply.d.ts.map +1 -0
  718. package/dist/supervision/reply.js +50 -0
  719. package/dist/supervision/reply.js.map +1 -0
  720. package/dist/supervision/runtime.d.ts +8 -0
  721. package/dist/supervision/runtime.d.ts.map +1 -0
  722. package/dist/supervision/runtime.js +188 -0
  723. package/dist/supervision/runtime.js.map +1 -0
  724. package/dist/supervision/types.d.ts +174 -0
  725. package/dist/supervision/types.d.ts.map +1 -0
  726. package/dist/supervision/types.js +2 -0
  727. package/dist/supervision/types.js.map +1 -0
  728. package/dist/tools.d.ts +12 -0
  729. package/dist/tools.d.ts.map +1 -1
  730. package/dist/tools.js +131 -23
  731. package/dist/tools.js.map +1 -1
  732. package/dist/turn-controller.d.ts +12 -0
  733. package/dist/turn-controller.d.ts.map +1 -0
  734. package/dist/turn-controller.js +51 -0
  735. package/dist/turn-controller.js.map +1 -0
  736. package/dist/types.d.ts +7 -1
  737. package/dist/types.d.ts.map +1 -1
  738. package/dist/types.js +3 -0
  739. package/dist/types.js.map +1 -1
  740. package/dist/ui/agent.d.ts +11 -10
  741. package/dist/ui/agent.d.ts.map +1 -1
  742. package/dist/ui/agent.js +293 -897
  743. package/dist/ui/agent.js.map +1 -1
  744. package/dist/ui/commands.d.ts +20 -2
  745. package/dist/ui/commands.d.ts.map +1 -1
  746. package/dist/ui/commands.js +208 -155
  747. package/dist/ui/commands.js.map +1 -1
  748. package/dist/ui/completions.d.ts.map +1 -1
  749. package/dist/ui/completions.js +16 -5
  750. package/dist/ui/completions.js.map +1 -1
  751. package/dist/ui/index.d.ts +6 -2
  752. package/dist/ui/index.d.ts.map +1 -1
  753. package/dist/ui/index.js +13 -11
  754. package/dist/ui/index.js.map +1 -1
  755. package/dist/ui/messages.d.ts.map +1 -1
  756. package/dist/ui/messages.js +5 -0
  757. package/dist/ui/messages.js.map +1 -1
  758. package/dist/ui/modals/index.d.ts +1 -0
  759. package/dist/ui/modals/index.d.ts.map +1 -1
  760. package/dist/ui/modals/index.js +1 -0
  761. package/dist/ui/modals/index.js.map +1 -1
  762. package/dist/ui/modals/prompts.d.ts +4 -7
  763. package/dist/ui/modals/prompts.d.ts.map +1 -1
  764. package/dist/ui/modals/prompts.js +14 -10
  765. package/dist/ui/modals/prompts.js.map +1 -1
  766. package/dist/ui/modals/selectors.d.ts +1 -0
  767. package/dist/ui/modals/selectors.d.ts.map +1 -1
  768. package/dist/ui/modals/selectors.js +3 -2
  769. package/dist/ui/modals/selectors.js.map +1 -1
  770. package/dist/ui/modals/tool-output.d.ts +8 -0
  771. package/dist/ui/modals/tool-output.d.ts.map +1 -0
  772. package/dist/ui/modals/tool-output.js +26 -0
  773. package/dist/ui/modals/tool-output.js.map +1 -0
  774. package/dist/ui/model-commands.d.ts +4 -0
  775. package/dist/ui/model-commands.d.ts.map +1 -0
  776. package/dist/ui/model-commands.js +69 -0
  777. package/dist/ui/model-commands.js.map +1 -0
  778. package/dist/ui/regions/modal-host.d.ts +3 -0
  779. package/dist/ui/regions/modal-host.d.ts.map +1 -1
  780. package/dist/ui/regions/modal-host.js +7 -1
  781. package/dist/ui/regions/modal-host.js.map +1 -1
  782. package/dist/ui/regions/status-region.d.ts +2 -1
  783. package/dist/ui/regions/status-region.d.ts.map +1 -1
  784. package/dist/ui/regions/status-region.js +2 -2
  785. package/dist/ui/regions/status-region.js.map +1 -1
  786. package/dist/ui/regions/tool-activity.d.ts +6 -0
  787. package/dist/ui/regions/tool-activity.d.ts.map +1 -0
  788. package/dist/ui/regions/tool-activity.js +9 -0
  789. package/dist/ui/regions/tool-activity.js.map +1 -0
  790. package/dist/ui/regions/transcript-region.d.ts.map +1 -1
  791. package/dist/ui/regions/transcript-region.js +2 -1
  792. package/dist/ui/regions/transcript-region.js.map +1 -1
  793. package/dist/ui/regions/workflow-region.d.ts +9 -0
  794. package/dist/ui/regions/workflow-region.d.ts.map +1 -0
  795. package/dist/ui/regions/workflow-region.js +11 -0
  796. package/dist/ui/regions/workflow-region.js.map +1 -0
  797. package/dist/ui/session-commands.d.ts +3 -0
  798. package/dist/ui/session-commands.d.ts.map +1 -0
  799. package/dist/ui/session-commands.js +141 -0
  800. package/dist/ui/session-commands.js.map +1 -0
  801. package/dist/ui/state/use-approval-state.d.ts +9 -0
  802. package/dist/ui/state/use-approval-state.d.ts.map +1 -0
  803. package/dist/ui/state/use-approval-state.js +18 -0
  804. package/dist/ui/state/use-approval-state.js.map +1 -0
  805. package/dist/ui/state/use-chat-controller.d.ts +4 -1
  806. package/dist/ui/state/use-chat-controller.d.ts.map +1 -1
  807. package/dist/ui/state/use-chat-controller.js +256 -180
  808. package/dist/ui/state/use-chat-controller.js.map +1 -1
  809. package/dist/ui/state/use-modal-state.d.ts +6 -8
  810. package/dist/ui/state/use-modal-state.d.ts.map +1 -1
  811. package/dist/ui/state/use-modal-state.js +3 -4
  812. package/dist/ui/state/use-modal-state.js.map +1 -1
  813. package/dist/ui/state/use-model-state.d.ts +7 -3
  814. package/dist/ui/state/use-model-state.d.ts.map +1 -1
  815. package/dist/ui/state/use-model-state.js +24 -17
  816. package/dist/ui/state/use-model-state.js.map +1 -1
  817. package/dist/ui/state/use-queue-state.d.ts +4 -3
  818. package/dist/ui/state/use-queue-state.d.ts.map +1 -1
  819. package/dist/ui/state/use-queue-state.js +11 -8
  820. package/dist/ui/state/use-queue-state.js.map +1 -1
  821. package/dist/ui/state/use-session-init.d.ts +4 -0
  822. package/dist/ui/state/use-session-init.d.ts.map +1 -1
  823. package/dist/ui/state/use-session-init.js +19 -3
  824. package/dist/ui/state/use-session-init.js.map +1 -1
  825. package/dist/ui/state/use-transcript-state.d.ts +6 -3
  826. package/dist/ui/state/use-transcript-state.d.ts.map +1 -1
  827. package/dist/ui/state/use-transcript-state.js +27 -15
  828. package/dist/ui/state/use-transcript-state.js.map +1 -1
  829. package/dist/ui/status-bar.d.ts +2 -1
  830. package/dist/ui/status-bar.d.ts.map +1 -1
  831. package/dist/ui/status-bar.js +2 -2
  832. package/dist/ui/status-bar.js.map +1 -1
  833. package/dist/ui/tool-output-cache.d.ts +12 -0
  834. package/dist/ui/tool-output-cache.d.ts.map +1 -0
  835. package/dist/ui/tool-output-cache.js +27 -0
  836. package/dist/ui/tool-output-cache.js.map +1 -0
  837. package/dist/ui/tool-output-commands.d.ts +3 -0
  838. package/dist/ui/tool-output-commands.d.ts.map +1 -0
  839. package/dist/ui/tool-output-commands.js +37 -0
  840. package/dist/ui/tool-output-commands.js.map +1 -0
  841. package/dist/ui/tool-output-wrap.d.ts +3 -0
  842. package/dist/ui/tool-output-wrap.d.ts.map +1 -0
  843. package/dist/ui/tool-output-wrap.js +24 -0
  844. package/dist/ui/tool-output-wrap.js.map +1 -0
  845. package/dist/ui/tool-progress.d.ts +23 -0
  846. package/dist/ui/tool-progress.d.ts.map +1 -0
  847. package/dist/ui/tool-progress.js +42 -0
  848. package/dist/ui/tool-progress.js.map +1 -0
  849. package/dist/ui/types.d.ts +8 -0
  850. package/dist/ui/types.d.ts.map +1 -1
  851. package/dist/ui/workflow-progress.d.ts +21 -0
  852. package/dist/ui/workflow-progress.d.ts.map +1 -0
  853. package/dist/ui/workflow-progress.js +107 -0
  854. package/dist/ui/workflow-progress.js.map +1 -0
  855. package/package.json +13 -4
  856. package/scripts/verify-runlog.mjs +208 -0
@@ -6,7 +6,65 @@
6
6
  import OpenAI from 'openai';
7
7
  import { select } from '@inquirer/prompts';
8
8
  import * as config from './config.js';
9
+ import { AsyncLocalStorage } from 'node:async_hooks';
10
+ import { cancellable, throwIfCancelled } from './cancellation.js';
11
+ import { bindProcessCancellation, detachedProcess } from './process-cancellation.js';
12
+ import { createHash } from 'node:crypto';
13
+ import { ModelDiscoveryError, compatibleMetadata, anthropicMetadata, openRouterPricing, capability, positiveLimit, price, stringList, validateModels } from './models/index.js';
9
14
  const DEBUG = process.env.CALLIOPE_DEBUG === '1';
15
+ const discoveryContext = new AsyncLocalStorage();
16
+ function fetchModelMetadata(input, init) {
17
+ const signal = discoveryContext.getStore()?.signal;
18
+ throwIfCancelled(signal);
19
+ if (!signal)
20
+ return init === undefined ? fetch(input) : fetch(input, init);
21
+ return fetch(input, { ...init, signal: init?.signal ? AbortSignal.any([signal, init.signal]) : signal });
22
+ }
23
+ function discoveryTransportOptions() {
24
+ return discoveryContext.getStore()?.signal ? { fetch: fetchModelMetadata, maxRetries: 0 } : {};
25
+ }
26
+ /** Follow provider cursors only on the original endpoint, with fixed page/item caps. */
27
+ async function modelPages(endpoint, kind, headers) {
28
+ const models = [], seen = new Set();
29
+ let cursor = '';
30
+ for (let page = 0; page < 20; page++) {
31
+ const url = new URL(endpoint);
32
+ if (cursor)
33
+ url.searchParams.set(kind === 'anthropic' ? 'after_id' : 'pageToken', cursor);
34
+ const response = await fetchModelMetadata(url.toString(), headers ? { headers } : undefined);
35
+ if (!response.ok)
36
+ throw new Error(`Model discovery HTTP ${response.status}`);
37
+ const data = await response.json();
38
+ const items = data[kind === 'anthropic' ? 'data' : 'models'];
39
+ if (!Array.isArray(items) || models.length + items.length > 10000)
40
+ throw new ModelDiscoveryError('Invalid model discovery page');
41
+ models.push(...items);
42
+ if (kind === 'anthropic' && data.has_more !== undefined && typeof data.has_more !== 'boolean')
43
+ throw new ModelDiscoveryError('Invalid discovery pagination');
44
+ if (kind === 'anthropic' && data.has_more && (typeof data.last_id !== 'string' || !data.last_id))
45
+ throw new ModelDiscoveryError('Missing discovery cursor');
46
+ const next = kind === 'anthropic' ? (data.has_more ? data.last_id : undefined) : data.nextPageToken;
47
+ if (next === undefined || next === null || next === '')
48
+ return models;
49
+ if (typeof next !== 'string' || next.length > 4096 || seen.has(next))
50
+ throw new ModelDiscoveryError('Invalid model discovery cursor');
51
+ seen.add(next);
52
+ cursor = next;
53
+ }
54
+ throw new ModelDiscoveryError('Model discovery page budget exceeded');
55
+ }
56
+ /** Scope transport cancellation to this discovery call, including concurrent probes. */
57
+ export async function getAvailableModels(provider, options = {}) {
58
+ throwIfCancelled(options.signal);
59
+ return discoveryContext.run({ ...options, cleanups: [] }, async () => {
60
+ try {
61
+ return await cancellable(loadAvailableModels(provider, options), options.signal);
62
+ }
63
+ finally {
64
+ await Promise.allSettled(discoveryContext.getStore().cleanups);
65
+ }
66
+ });
67
+ }
10
68
  function logModelDetectionWarning(message, error, options = {}) {
11
69
  if (options.quiet || !DEBUG) {
12
70
  return;
@@ -25,7 +83,10 @@ const PROVIDER_BASE_URLS = {
25
83
  fireworks: 'https://api.fireworks.ai/inference/v1',
26
84
  mistral: 'https://api.mistral.ai/v1',
27
85
  ai21: 'https://api.ai21.com/studio/v1',
28
- huggingface: 'https://api-inference.huggingface.co/v1',
86
+ huggingface: 'https://router.huggingface.co/v1',
87
+ deepseek: 'https://api.deepseek.com',
88
+ xai: 'https://api.x.ai/v1',
89
+ cerebras: 'https://api.cerebras.ai/v1',
29
90
  // Bedrock uses a configurable gateway URL, not a fixed URL
30
91
  };
31
92
  /**
@@ -57,6 +118,7 @@ const INCOMPATIBLE_MODEL_PATTERNS = {
57
118
  /^text-embedding/, // Text embedding
58
119
  /^aqa/, // Attributed QA (not chat)
59
120
  /embedding$/, // Any model ending in embedding
121
+ /computer-use/i, // Requires the dedicated Computer Use tool contract
60
122
  ],
61
123
  groq: [
62
124
  /^whisper/, // Speech-to-text
@@ -114,6 +176,48 @@ function isCompatibleModel(modelId, provider) {
114
176
  // Model cache to avoid repeated API calls
115
177
  const modelCache = new Map();
116
178
  const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
179
+ const previousDiscovery = new Map();
180
+ /** Stale negative capability evidence still blocks an unverified fallback. */
181
+ export function getPreviousDiscoveredModels(provider) {
182
+ const previous = previousDiscovery.get(provider);
183
+ return previous?.target === modelCacheTarget(provider) ? structuredClone(previous.models) : undefined;
184
+ }
185
+ function modelCacheTarget(provider) {
186
+ const profile = provider === 'bedrock' ? config.getProviderCred(provider) : { profile: undefined, region: undefined };
187
+ return createHash('sha256').update(JSON.stringify([provider, config.getBaseUrl(provider), config.getApiKey(provider), profile.profile, profile.region])).digest('hex');
188
+ }
189
+ export function getDiscoveredModels(provider) {
190
+ const cached = modelCache.get(provider);
191
+ if (!cached || cached.target !== modelCacheTarget(provider) || Date.now() - cached.timestamp >= CACHE_DURATION || cached.models.some(model => model.evidence?.source !== 'live'))
192
+ return undefined;
193
+ return structuredClone(cached.models);
194
+ }
195
+ /** Anthropic explicitly supports resolving aliases through Models.retrieve. */
196
+ export async function resolveModelAlias(provider, alias, signal) {
197
+ if (provider !== 'anthropic')
198
+ return undefined;
199
+ throwIfCancelled(signal);
200
+ const key = config.getApiKey(provider);
201
+ if (!key)
202
+ return undefined;
203
+ const target = modelCacheTarget(provider);
204
+ const response = await cancellable(fetch(`${(config.getBaseUrl('anthropic') || 'https://api.anthropic.com').replace(/\/v1\/?$/, '').replace(/\/$/, '')}/v1/models/${encodeURIComponent(alias)}`, {
205
+ headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01' }, signal,
206
+ }), signal);
207
+ if (!response.ok)
208
+ return undefined;
209
+ const body = await cancellable(response.json(), signal);
210
+ const model = { id: body.id, name: body.display_name, aliases: [alias], ...anthropicMetadata(body), evidence: { source: 'live', at: new Date().toISOString() } };
211
+ validateModels([model]);
212
+ throwIfCancelled(signal);
213
+ const cached = modelCache.get(provider);
214
+ if (cached?.target === target && modelCacheTarget(provider) === target) {
215
+ model.aliases = [...new Set([...(cached.models.find(item => item.id === model.id)?.aliases ?? []), alias])];
216
+ cached.models = [...cached.models.filter(item => item.id !== model.id), model];
217
+ previousDiscovery.set(provider, { models: structuredClone(cached.models), target });
218
+ }
219
+ return model;
220
+ }
117
221
  /**
118
222
  * Get available models for a provider with interactive selection
119
223
  */
@@ -158,8 +262,8 @@ function formatModelChoice(model) {
158
262
  display += ` (${formatContextLength(model.contextLength)})`;
159
263
  }
160
264
  if (model.pricing) {
161
- const inputPrice = model.pricing.input ? `$${model.pricing.input.toFixed(2)}/1M` : '';
162
- const outputPrice = model.pricing.output ? `$${model.pricing.output.toFixed(2)}/1M` : '';
265
+ const inputPrice = model.pricing.input !== undefined ? `$${model.pricing.input.toFixed(2)}/1M` : '';
266
+ const outputPrice = model.pricing.output !== undefined ? `$${model.pricing.output.toFixed(2)}/1M` : '';
163
267
  if (inputPrice || outputPrice) {
164
268
  display += ` - ${inputPrice}${inputPrice && outputPrice ? '/' : ''}${outputPrice}`;
165
269
  }
@@ -183,11 +287,15 @@ function formatContextLength(tokens) {
183
287
  /**
184
288
  * Get available models for a provider
185
289
  */
186
- export async function getAvailableModels(provider, options = {}) {
290
+ async function loadAvailableModels(provider, options) {
187
291
  // Check cache first
188
292
  const cached = modelCache.get(provider);
189
- if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
190
- return cached.models;
293
+ const target = modelCacheTarget(provider);
294
+ // Strict callers require current wire evidence; a cached emergency fallback
295
+ // must never masquerade as successful live discovery.
296
+ if (cached?.target === target && Date.now() - cached.timestamp < CACHE_DURATION &&
297
+ (!options.throwOnError || (options.cache === 'live' && cached.models.every(model => model.evidence?.source === 'live')))) {
298
+ return structuredClone(cached.models);
191
299
  }
192
300
  let models = [];
193
301
  try {
@@ -222,6 +330,9 @@ export async function getAvailableModels(provider, options = {}) {
222
330
  case 'ai21':
223
331
  case 'huggingface':
224
332
  case 'fireworks':
333
+ case 'deepseek':
334
+ case 'xai':
335
+ case 'cerebras':
225
336
  models = await getOpenAICompatibleModels(provider);
226
337
  break;
227
338
  case 'bedrock':
@@ -233,8 +344,16 @@ export async function getAvailableModels(provider, options = {}) {
233
344
  default:
234
345
  throw new Error(`Model detection not implemented for ${provider}`);
235
346
  }
347
+ throwIfCancelled(options.signal);
236
348
  // Cache the results
237
- modelCache.set(provider, { models, timestamp: Date.now() });
349
+ const timestamp = Date.now();
350
+ models = validateModels(models).map(model => ({ ...model, evidence: model.evidence ?? { source: 'live', at: new Date(timestamp).toISOString() } }));
351
+ // Endpoint/credential changes during discovery cannot populate a new target's cache.
352
+ if (modelCacheTarget(provider) === target) {
353
+ modelCache.set(provider, { models: structuredClone(models), timestamp, target });
354
+ if (models.every(model => model.evidence?.source === 'live'))
355
+ previousDiscovery.set(provider, { models: structuredClone(models), target });
356
+ }
238
357
  }
239
358
  catch (error) {
240
359
  logModelDetectionWarning(`Failed to fetch models for ${provider}:`, error, options);
@@ -251,37 +370,28 @@ async function getAnthropicModels(options = {}) {
251
370
  if (!apiKey)
252
371
  throw new Error('Anthropic API key not configured');
253
372
  try {
254
- const response = await fetch('https://api.anthropic.com/v1/models', {
255
- headers: {
256
- 'x-api-key': apiKey,
257
- 'anthropic-version': '2023-06-01'
258
- }
259
- });
260
- if (!response.ok) {
261
- throw new Error(`Anthropic API error: ${response.status}`);
262
- }
263
- const data = await response.json();
264
- return data.data
373
+ const models = await modelPages(`${(config.getBaseUrl('anthropic') || 'https://api.anthropic.com').replace(/\/v1\/?$/, '').replace(/\/$/, '')}/v1/models`, 'anthropic', { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' });
374
+ return models
265
375
  .filter(model => model.id.startsWith('claude'))
266
376
  .map(model => ({
267
377
  id: model.id,
268
378
  name: model.display_name || formatModelName(model.id),
269
379
  description: getAnthropicModelDescription(model.id),
270
- // The /v1/models list endpoint does not return the context window;
271
- // derive it per model family rather than hardcoding a single value.
272
- contextLength: getModelContextLimit('anthropic', model.id),
380
+ ...anthropicMetadata(model),
273
381
  }))
274
382
  .sort((a, b) => b.id.localeCompare(a.id)); // Newest first
275
383
  }
276
384
  catch (error) {
277
385
  // Emergency fallback when the API is unreachable. Keep these as the current
278
386
  // shipping models — discovery is the source of truth; this is the offline net.
387
+ if (options.throwOnError)
388
+ throw error;
279
389
  logModelDetectionWarning('Failed to fetch Anthropic models, using fallback list', error, options);
280
390
  return [
281
391
  { id: 'claude-opus-4-8', name: 'Claude Opus 4.8', description: 'Most capable model', contextLength: 1000000 },
282
392
  { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', description: 'Balanced intelligence and speed', contextLength: 1000000 },
283
393
  { id: 'claude-haiku-4-5', name: 'Claude Haiku 4.5', description: 'Fast and affordable', contextLength: 200000 },
284
- ];
394
+ ].map(model => ({ ...model, evidence: { source: 'emergency', at: new Date().toISOString() } }));
285
395
  }
286
396
  }
287
397
  function formatModelName(modelId) {
@@ -311,12 +421,8 @@ async function getGoogleModels(options = {}) {
311
421
  throw new Error('Google API key not configured');
312
422
  try {
313
423
  // Use REST API directly for model listing
314
- const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`);
315
- if (!response.ok) {
316
- throw new Error(`Google API error: ${response.status}`);
317
- }
318
- const data = await response.json();
319
- return data.models
424
+ const models = await modelPages(`${(config.getBaseUrl('google') || 'https://generativelanguage.googleapis.com').replace(/\/v1beta\/?$/, '').replace(/\/$/, '')}/v1beta/models?key=${encodeURIComponent(apiKey)}`, 'google');
425
+ return models
320
426
  .filter(model => {
321
427
  const modelId = model.name.replace('models/', '');
322
428
  return model.name.includes('gemini') && isCompatibleModel(modelId, 'google');
@@ -325,12 +431,16 @@ async function getGoogleModels(options = {}) {
325
431
  id: model.name.replace('models/', ''),
326
432
  name: model.displayName || model.name.replace('models/', ''),
327
433
  description: model.description || 'Google Gemini model',
328
- contextLength: model.inputTokenLimit || 1048576,
434
+ contextLength: positiveLimit(model.inputTokenLimit),
435
+ maxOutputTokens: positiveLimit(model.outputTokenLimit),
436
+ capabilities: { chat: stringList(model.supportedGenerationMethods)?.includes('generateContent'), thinking: capability(model.thinking) },
329
437
  }))
330
438
  .sort((a, b) => b.id.localeCompare(a.id)); // Newest first
331
439
  }
332
440
  catch (error) {
333
441
  // Fallback to known models if API fails
442
+ if (options.throwOnError)
443
+ throw error;
334
444
  logModelDetectionWarning('Failed to fetch Google models, using fallback list', error, options);
335
445
  return [
336
446
  { id: 'gemini-2.5-pro-preview-06-05', name: 'Gemini 2.5 Pro', description: 'Most capable', contextLength: 1048576 },
@@ -338,7 +448,7 @@ async function getGoogleModels(options = {}) {
338
448
  { id: 'gemini-2.0-flash', name: 'Gemini 2.0 Flash', description: 'Multimodal', contextLength: 1048576 },
339
449
  { id: 'gemini-1.5-pro-latest', name: 'Gemini 1.5 Pro', description: 'Complex reasoning', contextLength: 2097152 },
340
450
  { id: 'gemini-1.5-flash-latest', name: 'Gemini 1.5 Flash', description: 'Fast and versatile', contextLength: 1048576 },
341
- ];
451
+ ].map(model => ({ ...model, evidence: { source: 'emergency', at: new Date().toISOString() } }));
342
452
  }
343
453
  }
344
454
  /**
@@ -348,7 +458,7 @@ async function getOpenAIModels() {
348
458
  const apiKey = config.getApiKey('openai');
349
459
  if (!apiKey)
350
460
  throw new Error('OpenAI API key not configured');
351
- const client = new OpenAI({ apiKey });
461
+ const client = new OpenAI({ apiKey, baseURL: config.getBaseUrl('openai'), ...discoveryTransportOptions() });
352
462
  const response = await client.models.list();
353
463
  // Filter for chat-compatible models (GPT and reasoning models)
354
464
  return response.data
@@ -361,6 +471,7 @@ async function getOpenAIModels() {
361
471
  id: model.id,
362
472
  name: model.id,
363
473
  description: getOpenAIModelDescription(model.id),
474
+ ...compatibleMetadata(model),
364
475
  }))
365
476
  .sort((a, b) => a.name.localeCompare(b.name));
366
477
  }
@@ -371,7 +482,7 @@ async function getOpenRouterModels() {
371
482
  const apiKey = config.getApiKey('openrouter');
372
483
  if (!apiKey)
373
484
  throw new Error('OpenRouter API key not configured');
374
- const response = await fetch('https://openrouter.ai/api/v1/models', {
485
+ const response = await fetchModelMetadata(`${(config.getBaseUrl('openrouter') || 'https://openrouter.ai/api/v1').replace(/\/+$/, '')}/models`, {
375
486
  headers: {
376
487
  'Authorization': `Bearer ${apiKey}`,
377
488
  'HTTP-Referer': 'https://calliope.ai',
@@ -409,11 +520,11 @@ async function getOpenRouterModels() {
409
520
  id: model.id,
410
521
  name: model.name,
411
522
  description: model.description,
412
- contextLength: model.context_length,
413
- pricing: {
414
- input: parseFloat(model.pricing?.prompt || '0') * 1000000, // Convert to per 1M tokens
415
- output: parseFloat(model.pricing?.completion || '0') * 1000000
416
- }
523
+ contextLength: positiveLimit(model.context_length),
524
+ maxOutputTokens: positiveLimit(model.top_provider?.max_completion_tokens),
525
+ capabilities: { chat: true, tools: model.supported_parameters ? model.supported_parameters.includes('tools') : undefined,
526
+ vision: model.architecture?.input_modalities ? model.architecture.input_modalities.includes('image') : undefined },
527
+ pricing: openRouterPricing(model.pricing)
417
528
  }));
418
529
  }
419
530
  /**
@@ -424,7 +535,7 @@ async function getTogetherModels() {
424
535
  if (!apiKey)
425
536
  throw new Error('Together API key not configured');
426
537
  // Together's API returns a raw array, not wrapped in { data: [...] } like OpenAI
427
- const response = await fetch('https://api.together.xyz/v1/models', {
538
+ const response = await fetchModelMetadata(`${(config.getBaseUrl('together') || 'https://api.together.xyz/v1').replace(/\/+$/, '')}/models`, {
428
539
  headers: {
429
540
  'Authorization': `Bearer ${apiKey}`,
430
541
  }
@@ -440,10 +551,11 @@ async function getTogetherModels() {
440
551
  id: model.id,
441
552
  name: model.display_name || model.id,
442
553
  description: getTogetherModelDescription(model.id),
443
- contextLength: model.context_length,
554
+ ...compatibleMetadata(model),
555
+ contextLength: positiveLimit(model.context_length),
444
556
  pricing: model.pricing ? {
445
- input: model.pricing.input,
446
- output: model.pricing.output,
557
+ input: price(model.pricing.input),
558
+ output: price(model.pricing.output),
447
559
  } : undefined,
448
560
  }))
449
561
  .sort((a, b) => a.name.localeCompare(b.name));
@@ -456,8 +568,9 @@ async function getGroqModels() {
456
568
  if (!apiKey)
457
569
  throw new Error('Groq API key not configured');
458
570
  const client = new OpenAI({
571
+ ...discoveryTransportOptions(),
459
572
  apiKey,
460
- baseURL: 'https://api.groq.com/openai/v1'
573
+ baseURL: config.getBaseUrl('groq') || 'https://api.groq.com/openai/v1'
461
574
  });
462
575
  const response = await client.models.list();
463
576
  return response.data
@@ -466,6 +579,7 @@ async function getGroqModels() {
466
579
  id: model.id,
467
580
  name: model.id,
468
581
  description: 'High-speed inference model',
582
+ ...compatibleMetadata(model),
469
583
  }));
470
584
  }
471
585
  /**
@@ -476,8 +590,9 @@ async function getMistralModels() {
476
590
  if (!apiKey)
477
591
  throw new Error('Mistral API key not configured');
478
592
  const client = new OpenAI({
593
+ ...discoveryTransportOptions(),
479
594
  apiKey,
480
- baseURL: 'https://api.mistral.ai/v1'
595
+ baseURL: config.getBaseUrl('mistral') || 'https://api.mistral.ai/v1'
481
596
  });
482
597
  const response = await client.models.list();
483
598
  return response.data
@@ -486,6 +601,7 @@ async function getMistralModels() {
486
601
  id: model.id,
487
602
  name: model.id,
488
603
  description: getMistralModelDescription(model.id),
604
+ ...compatibleMetadata(model),
489
605
  }));
490
606
  }
491
607
  /**
@@ -498,7 +614,7 @@ async function getOllamaModels() {
498
614
  baseUrl = baseUrl.slice(0, -3);
499
615
  }
500
616
  try {
501
- const response = await fetch(`${baseUrl}/api/tags`);
617
+ const response = await fetchModelMetadata(`${baseUrl}/api/tags`);
502
618
  if (!response.ok) {
503
619
  throw new Error(`Ollama API error: ${response.status}`);
504
620
  }
@@ -508,26 +624,30 @@ async function getOllamaModels() {
508
624
  const results = [];
509
625
  for (const model of models) {
510
626
  let contextLength;
627
+ let capabilities;
511
628
  try {
512
- const showResp = await fetch(`${baseUrl}/api/show`, {
629
+ const showResp = await fetchModelMetadata(`${baseUrl}/api/show`, {
513
630
  method: 'POST',
514
631
  headers: { 'Content-Type': 'application/json' },
515
632
  body: JSON.stringify({ name: model.name }),
516
633
  });
517
634
  if (showResp.ok) {
518
635
  const showData = await showResp.json();
636
+ const supported = stringList(showData.capabilities);
637
+ if (supported)
638
+ capabilities = { chat: supported.includes('completion'), tools: supported.includes('tools'), vision: supported.includes('vision'), thinking: supported.includes('thinking') };
519
639
  // Check model_info for context length keys
520
640
  if (showData.model_info) {
521
641
  const ctxKey = Object.keys(showData.model_info).find(k => k.includes('context_length') || k.includes('context_window'));
522
642
  if (ctxKey && typeof showData.model_info[ctxKey] === 'number') {
523
- contextLength = showData.model_info[ctxKey];
643
+ contextLength = positiveLimit(showData.model_info[ctxKey]);
524
644
  }
525
645
  }
526
646
  // Also check Modelfile parameters for num_ctx override
527
647
  if (showData.parameters) {
528
648
  const numCtxMatch = showData.parameters.match(/num_ctx\s+(\d+)/);
529
649
  if (numCtxMatch) {
530
- contextLength = parseInt(numCtxMatch[1], 10);
650
+ contextLength = positiveLimit(parseInt(numCtxMatch[1], 10));
531
651
  }
532
652
  }
533
653
  }
@@ -537,14 +657,20 @@ async function getOllamaModels() {
537
657
  }
538
658
  results.push({
539
659
  id: model.name,
660
+ capabilities,
540
661
  name: model.name,
541
662
  description: `Size: ${formatSize(model.size)}${model.details?.parameter_size ? ` (${model.details.parameter_size})` : ''}`,
542
663
  contextLength,
664
+ // Ollama does not expose a separate output limit. Bound generation by
665
+ // the live context window so execution admission can remain fail-closed.
666
+ maxOutputTokens: contextLength === undefined ? undefined : Math.min(contextLength, 8192),
543
667
  });
544
668
  }
545
669
  return results;
546
670
  }
547
671
  catch (error) {
672
+ if (error instanceof ModelDiscoveryError || error instanceof SyntaxError || error instanceof TypeError)
673
+ throw error;
548
674
  throw new Error(`Failed to connect to Ollama at ${baseUrl}. Is Ollama running? Try: ollama serve`);
549
675
  }
550
676
  }
@@ -584,7 +710,7 @@ async function getLiteLLMModels() {
584
710
  baseUrl = baseUrl.slice(0, -3);
585
711
  }
586
712
  try {
587
- const response = await fetch(`${baseUrl}/v1/models`);
713
+ const response = await fetchModelMetadata(`${baseUrl}/v1/models`);
588
714
  if (!response.ok) {
589
715
  throw new Error(`LiteLLM API error: ${response.status}`);
590
716
  }
@@ -595,9 +721,12 @@ async function getLiteLLMModels() {
595
721
  id: model.id,
596
722
  name: model.id,
597
723
  description: 'Proxied via LiteLLM',
724
+ ...compatibleMetadata(model),
598
725
  }));
599
726
  }
600
727
  catch (error) {
728
+ if (error instanceof ModelDiscoveryError || error instanceof SyntaxError || error instanceof TypeError)
729
+ throw error;
601
730
  throw new Error(`Failed to connect to LiteLLM at ${baseUrl}`);
602
731
  }
603
732
  }
@@ -614,7 +743,7 @@ async function getBedrockModels() {
614
743
  if (apiKey) {
615
744
  headers['Authorization'] = `Bearer ${apiKey}`;
616
745
  }
617
- const response = await fetch(modelsUrl, { headers });
746
+ const response = await fetchModelMetadata(modelsUrl, { headers });
618
747
  if (response.ok) {
619
748
  const data = await response.json();
620
749
  return data.data
@@ -623,7 +752,7 @@ async function getBedrockModels() {
623
752
  id: model.id,
624
753
  name: model.id,
625
754
  description: getBedrockModelDescription(model.id),
626
- contextLength: getBedrockContextLength(model.id),
755
+ ...compatibleMetadata(model),
627
756
  }));
628
757
  }
629
758
  throw new Error(`Bedrock gateway ${baseUrl} returned ${response.status}. Check BEDROCK_BASE_URL / BEDROCK_API_KEY.`);
@@ -639,12 +768,44 @@ async function getBedrockModels() {
639
768
  async function resolveAwsCredentialsViaCli(profile) {
640
769
  try {
641
770
  const { execFileSync } = await import('child_process');
771
+ const signal = discoveryContext.getStore()?.signal;
772
+ const read = async (format) => {
773
+ const args = ['configure', 'export-credentials', '--profile', profile, '--format', format];
774
+ if (!signal)
775
+ return execFileSync('aws', args, { encoding: 'utf-8', timeout: 10000, stdio: ['ignore', 'pipe', 'pipe'] });
776
+ throwIfCancelled(signal);
777
+ const { spawn } = await import('node:child_process');
778
+ throwIfCancelled(signal);
779
+ return new Promise((resolve, reject) => {
780
+ const capacity = new AbortController();
781
+ const combined = AbortSignal.any([signal, AbortSignal.timeout(10000), capacity.signal]);
782
+ const child = spawn('aws', args, { stdio: ['ignore', 'pipe', 'pipe'], detached: detachedProcess });
783
+ const cleanup = bindProcessCancellation(child, combined);
784
+ discoveryContext.getStore()?.cleanups.push(cleanup);
785
+ const chunks = [];
786
+ let size = 0;
787
+ child.stdout.on('data', (chunk) => {
788
+ size += chunk.length;
789
+ if (size > 1024 * 1024)
790
+ capacity.abort();
791
+ else
792
+ chunks.push(chunk);
793
+ });
794
+ child.stderr.resume();
795
+ child.once('error', () => { void cleanup.then(() => reject(new Error('AWS profile credential resolution failed'))); });
796
+ child.once('close', code => {
797
+ void cleanup.then(() => code === 0 && !combined.aborted
798
+ ? resolve(Buffer.concat(chunks).toString('utf8')) : reject(new Error('AWS profile credential resolution failed')));
799
+ });
800
+ });
801
+ };
642
802
  let output = '';
643
803
  try {
644
- output = execFileSync('aws', ['configure', 'export-credentials', '--profile', profile, '--format', 'env-no-export'], { encoding: 'utf-8', timeout: 10_000, stdio: ['ignore', 'pipe', 'pipe'] });
804
+ output = await read('env-no-export');
645
805
  }
646
806
  catch {
647
- output = execFileSync('aws', ['configure', 'export-credentials', '--profile', profile, '--format', 'env'], { encoding: 'utf-8', timeout: 10_000, stdio: ['ignore', 'pipe', 'pipe'] });
807
+ throwIfCancelled(signal);
808
+ output = await read('env');
648
809
  }
649
810
  const envs = {};
650
811
  for (const rawLine of output.split(/\r?\n/)) {
@@ -764,7 +925,7 @@ async function discoverBedrockModelsNative() {
764
925
  const signingKey = hmacFn(kService, 'aws4_request');
765
926
  const signature = createHmac('sha256', signingKey).update(stringToSign).digest('hex');
766
927
  headers['Authorization'] = `AWS4-HMAC-SHA256 Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
767
- return fetch(url, { headers });
928
+ return fetchModelMetadata(url, { headers });
768
929
  };
769
930
  // 1. ListFoundationModels (direct on-demand access).
770
931
  // Dropped the byInferenceType=ON_DEMAND filter — newer Claude models are only
@@ -781,49 +942,55 @@ async function discoverBedrockModelsNative() {
781
942
  '(2) IAM role missing bedrock:ListFoundationModels; (3) SSO token expired — run `aws sso login`.'));
782
943
  }
783
944
  const foundationData = await foundationResp.json();
784
- const foundationModels = (foundationData.modelSummaries || [])
945
+ if (!Array.isArray(foundationData.modelSummaries))
946
+ throw new ModelDiscoveryError('Invalid Bedrock foundation discovery');
947
+ const foundationModels = foundationData.modelSummaries
785
948
  .filter(m => m.inputModalities?.includes('TEXT') && m.outputModalities?.includes('TEXT'))
786
- .filter(m => bedrockSupportsConverseTools(m.modelId))
787
949
  .map(m => ({
788
950
  id: m.modelId,
789
951
  name: m.modelName || m.modelId,
790
952
  description: `${m.providerName || 'Unknown'} — ${getBedrockModelDescription(m.modelId)}`,
791
- contextLength: getBedrockContextLength(m.modelId),
953
+ capabilities: { streaming: capability(m.responseStreamingSupported), vision: stringList(m.inputModalities)?.includes('IMAGE') },
792
954
  }));
793
955
  // 2. ListInferenceProfiles — cross-region profile IDs (e.g. us.anthropic.claude-sonnet-4-5-*).
794
956
  // Many modern models are ONLY reachable via these, not direct foundation-model IDs.
795
957
  // Failures here are non-fatal (older accounts / regions may not support it).
796
- let profileModels = [];
797
- try {
798
- const profileResp = await signedGet('/inference-profiles', '');
799
- if (profileResp.ok) {
800
- const profileData = await profileResp.json();
801
- profileModels = (profileData.inferenceProfileSummaries || [])
802
- .filter(p => p.status !== 'INACTIVE')
803
- .filter(p => bedrockSupportsConverseTools(p.inferenceProfileId))
804
- .map(p => ({
805
- id: p.inferenceProfileId,
806
- name: p.inferenceProfileName || p.inferenceProfileId,
807
- description: `Inference profile — ${getBedrockModelDescription(p.inferenceProfileId)}`,
808
- contextLength: getBedrockContextLength(p.inferenceProfileId),
809
- }));
958
+ const profileModels = [], coveredBaseIds = new Set();
959
+ const seen = new Set();
960
+ let nextToken = '';
961
+ for (let page = 0; page < 20; page++) {
962
+ const profileResp = await signedGet('/inference-profiles', nextToken ? `nextToken=${encodeURIComponent(nextToken)}` : '');
963
+ if (!profileResp.ok)
964
+ break; // Profiles are optional; foundation evidence remains usable.
965
+ const data = await profileResp.json();
966
+ if (!Array.isArray(data.inferenceProfileSummaries) || profileModels.length + data.inferenceProfileSummaries.length > 10000)
967
+ throw new ModelDiscoveryError('Invalid Bedrock profile discovery');
968
+ for (const profile of data.inferenceProfileSummaries) {
969
+ if (profile.status === 'INACTIVE')
970
+ continue;
971
+ const baseIds = profile.models?.map(model => model.modelArn.split(':foundation-model/')[1]).filter((id) => !!id) ?? [];
972
+ const bases = baseIds.map(id => foundationModels.find(model => model.id === id));
973
+ // Only profile-provided ARNs establish a relationship to foundation models.
974
+ // Inherit a capability only when every regional model reports the same value.
975
+ const shared = (key) => {
976
+ const values = bases.map(model => model?.capabilities?.[key]);
977
+ return values.length && values.every(value => value === values[0]) ? values[0] : undefined;
978
+ };
979
+ for (const id of baseIds)
980
+ coveredBaseIds.add(id);
981
+ profileModels.push({ id: profile.inferenceProfileId, name: profile.inferenceProfileName || profile.inferenceProfileId,
982
+ description: 'Bedrock inference profile', capabilities: { streaming: shared('streaming'), vision: shared('vision') } });
810
983
  }
984
+ if (data.nextToken == null || data.nextToken === '')
985
+ break;
986
+ if (typeof data.nextToken !== 'string' || data.nextToken.length > 2048 || seen.has(data.nextToken))
987
+ throw new ModelDiscoveryError('Invalid Bedrock discovery cursor');
988
+ seen.add(data.nextToken);
989
+ nextToken = data.nextToken;
990
+ if (page === 19)
991
+ throw new ModelDiscoveryError('Bedrock discovery page budget exceeded');
811
992
  }
812
- catch {
813
- // Non-fatal — foundation models alone is still useful.
814
- }
815
- // Merge. For every inference profile, strip the region prefix (e.g. `us.`,
816
- // `eu.`, `apac.`, `jp.`) to get the base foundation-model ID it wraps, and
817
- // drop that base from the foundation list — because newer Claude 4.x / Haiku
818
- // 4.5 models can ONLY be invoked via their inference profile on on-demand
819
- // throughput. Showing both would let users pick the invokable-broken raw ID.
820
- const coveredBaseIds = new Set();
821
- for (const p of profileModels) {
822
- const base = p.id.replace(/^[a-z]{2,5}\./, '');
823
- if (base !== p.id)
824
- coveredBaseIds.add(base);
825
- }
826
- const filteredFoundation = foundationModels.filter(m => !coveredBaseIds.has(m.id));
993
+ const filteredFoundation = foundationModels.filter(model => !coveredBaseIds.has(model.id));
827
994
  const merged = new Map();
828
995
  for (const m of filteredFoundation)
829
996
  merged.set(m.id, m);
@@ -831,38 +998,6 @@ async function discoverBedrockModelsNative() {
831
998
  merged.set(m.id, m);
832
999
  return Array.from(merged.values()).sort((a, b) => a.id.localeCompare(b.id));
833
1000
  }
834
- /**
835
- * Bedrock Converse API tool-calling support. Maintained as a local allowlist
836
- * because AWS doesn't expose per-model tool capability via the list APIs.
837
- * See: https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html
838
- * Matches both raw foundation model IDs (e.g. anthropic.claude-3-5-sonnet-*)
839
- * and cross-region inference profile IDs (e.g. us.anthropic.claude-sonnet-4-5-*).
840
- */
841
- function bedrockSupportsConverseTools(modelId) {
842
- const id = modelId.toLowerCase();
843
- // Anthropic Claude 3, 3.5, 3.7, 4, 4.5 (all support tools). Excludes Claude 2.x / Instant.
844
- if (/anthropic\.claude-(3|opus-4|sonnet-4|haiku-4|3-5|3-7)/.test(id))
845
- return true;
846
- // Amazon Nova (Pro / Lite / Micro support Converse tools; Nova Canvas/Reel are image models — excluded)
847
- if (/amazon\.nova-(pro|lite|micro|premier)/.test(id))
848
- return true;
849
- // Cohere Command R / R+ support tools (older Command models do not)
850
- if (/cohere\.command-r/.test(id))
851
- return true;
852
- // Mistral Large (2402, 2407), Pixtral Large, Mistral Small, Nemo
853
- if (/mistral\.(mistral-large|pixtral|mistral-small|mistral-nemo)/.test(id))
854
- return true;
855
- // Meta Llama 3.1+ supports tools via Converse (3.0 and earlier do not)
856
- if (/meta\.llama(3-1|3-2|3-3|4)/.test(id))
857
- return true;
858
- // AI21 Jamba 1.5 supports tools
859
- if (/ai21\.jamba-1-5/.test(id))
860
- return true;
861
- // DeepSeek R1 supports tools
862
- if (/deepseek\.r1/.test(id))
863
- return true;
864
- return false;
865
- }
866
1001
  function getBedrockModelDescription(modelId) {
867
1002
  if (modelId.includes('claude') && modelId.includes('opus'))
868
1003
  return 'Most capable Claude model on Bedrock';
@@ -880,21 +1015,6 @@ function getBedrockModelDescription(modelId) {
880
1015
  return 'Cohere model on Bedrock';
881
1016
  return 'AWS Bedrock model';
882
1017
  }
883
- function getBedrockContextLength(modelId) {
884
- if (modelId.includes('claude'))
885
- return 200000;
886
- if (modelId.includes('llama3-1') || modelId.includes('llama3.1'))
887
- return 128000;
888
- if (modelId.includes('mistral-large'))
889
- return 128000;
890
- if (modelId.includes('command-r'))
891
- return 128000;
892
- if (modelId.includes('titan-text-premier'))
893
- return 32000;
894
- if (modelId.includes('titan-text-express'))
895
- return 8192;
896
- return 32000;
897
- }
898
1018
  /**
899
1019
  * Get models from a generic OpenAI-compatible server (e.g. LM Studio, Jan, LocalAI, vLLM)
900
1020
  */
@@ -903,15 +1023,17 @@ async function getOpenAICompatModels() {
903
1023
  if (!baseUrl.endsWith('/v1'))
904
1024
  baseUrl = `${baseUrl}/v1`;
905
1025
  const apiKey = config.getApiKey('openai-compat') || 'openai-compat';
906
- const response = await fetch(`${baseUrl}/models`, {
1026
+ const response = await fetchModelMetadata(`${baseUrl}/models`, {
907
1027
  headers: { 'Authorization': `Bearer ${apiKey}` },
908
1028
  });
909
1029
  if (!response.ok) {
910
1030
  throw new Error(`OpenAI-compat server error: ${response.status}`);
911
1031
  }
912
1032
  const data = await response.json();
913
- const models = data.data ?? [];
914
- return models.map(m => ({ id: m.id, name: m.id, description: 'OpenAI-compatible server' }));
1033
+ if (!Array.isArray(data.data))
1034
+ throw new ModelDiscoveryError('Invalid model discovery response');
1035
+ const models = data.data;
1036
+ return models.map(m => ({ id: m.id, name: m.id, description: 'OpenAI-compatible server', ...compatibleMetadata(m) }));
915
1037
  }
916
1038
  /**
917
1039
  * Get models for OpenAI-compatible providers
@@ -920,17 +1042,27 @@ async function getOpenAICompatibleModels(provider) {
920
1042
  const apiKey = config.getApiKey(provider);
921
1043
  if (!apiKey)
922
1044
  throw new Error(`${provider} API key not configured`);
923
- const baseURL = PROVIDER_BASE_URLS[provider];
1045
+ const baseURL = config.getBaseUrl(provider) || PROVIDER_BASE_URLS[provider];
924
1046
  if (!baseURL)
925
1047
  throw new Error(`Unknown provider: ${provider}`);
926
- const client = new OpenAI({ apiKey, baseURL });
1048
+ // Cerebras exposes richer limits, pricing and capability metadata on its
1049
+ // public catalog; the OpenAI-compatible /v1/models endpoint only returns
1050
+ // identifiers, which makes bounded tool execution impossible to quote.
1051
+ if (provider === 'cerebras') {
1052
+ const publicUrl = `${new URL(baseURL).origin}/public/v1/models`;
1053
+ const metadataResponse = await fetchModelMetadata(publicUrl, { headers: { Authorization: `Bearer ${apiKey}` } });
1054
+ if (metadataResponse.ok) {
1055
+ const payload = await metadataResponse.json();
1056
+ if (!Array.isArray(payload.data))
1057
+ throw new ModelDiscoveryError('Invalid Cerebras model discovery response');
1058
+ return payload.data
1059
+ .filter(model => { const id = typeof model === 'object' && model !== null ? model.id : undefined; return typeof id === 'string' && isCompatibleModel(id, provider); })
1060
+ .map(model => { const id = model.id; return { id, name: id, ...compatibleMetadata(model) }; });
1061
+ }
1062
+ }
1063
+ const client = new OpenAI({ apiKey, baseURL, ...discoveryTransportOptions() });
927
1064
  const response = await client.models.list();
928
- return response.data
929
- .filter(model => isCompatibleModel(model.id, provider))
930
- .map(model => ({
931
- id: model.id,
932
- name: model.id,
933
- }));
1065
+ return response.data.filter(model => isCompatibleModel(model.id, provider)).map(model => ({ id: model.id, name: model.id, ...compatibleMetadata(model) }));
934
1066
  }
935
1067
  /**
936
1068
  * Helper functions for model descriptions
@@ -989,36 +1121,42 @@ function formatSize(bytes) {
989
1121
  export function clearModelCache(provider) {
990
1122
  if (provider) {
991
1123
  modelCache.delete(provider);
1124
+ previousDiscovery.delete(provider);
992
1125
  }
993
1126
  else {
994
1127
  modelCache.clear();
1128
+ previousDiscovery.clear();
995
1129
  }
996
1130
  }
997
1131
  /**
998
1132
  * Pre-warm model cache for configured providers
999
1133
  * Runs in background, doesn't block startup
1000
1134
  */
1001
- export async function preWarmModelCache() {
1135
+ export async function preWarmModelCache(parentSignal) {
1002
1136
  const configuredProviders = config.getConfiguredProviders();
1137
+ const deadline = AbortSignal.timeout(30000);
1138
+ const signal = parentSignal ? AbortSignal.any([parentSignal, deadline]) : deadline;
1003
1139
  // Fetch models for all configured providers in parallel
1004
- await Promise.allSettled(configuredProviders.map(provider => getAvailableModels(provider, { quiet: true })));
1140
+ await Promise.allSettled(configuredProviders.map(provider => getAvailableModels(provider, { quiet: true, signal })));
1005
1141
  }
1006
1142
  /**
1007
1143
  * Get model info from cache by ID
1008
1144
  */
1009
1145
  export function getModelInfo(provider, modelId) {
1010
1146
  const cached = modelCache.get(provider);
1011
- if (!cached)
1147
+ if (!cached || cached.target !== modelCacheTarget(provider) || Date.now() - cached.timestamp >= CACHE_DURATION)
1012
1148
  return undefined;
1013
1149
  // Exact match first.
1014
- const exact = cached.models.find(m => m.id === modelId);
1150
+ const exact = cached.models.find(m => m.id === modelId || m.aliases?.includes(modelId));
1015
1151
  if (exact)
1016
- return exact;
1152
+ return structuredClone(exact);
1153
+ if (cached.models.every(model => model.evidence?.source === 'live'))
1154
+ return undefined;
1017
1155
  // Otherwise only accept an UNAMBIGUOUS prefix relationship. Loose substring
1018
1156
  // matching wrongly resolved e.g. `gpt-4` -> `gpt-4o` or `claude-opus-4` ->
1019
1157
  // `claude-opus-4-8`, returning a different model's context/pricing.
1020
1158
  const related = cached.models.filter(m => m.id.startsWith(modelId) || modelId.startsWith(m.id));
1021
- return related.length === 1 ? related[0] : undefined;
1159
+ return related.length === 1 ? structuredClone(related[0]) : undefined;
1022
1160
  }
1023
1161
  /**
1024
1162
  * Default context limits by model family (fallback when API doesn't provide it)