@adea-ai/ui 0.140.0 → 0.142.0

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 (455) hide show
  1. package/dist/components/composites/appearance-editor/appearance-editor.js +2 -2
  2. package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
  3. package/dist/components/composites/catalog-browser/catalog-browser-group.js +1 -1
  4. package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts +56 -0
  5. package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts.map +1 -0
  6. package/dist/components/composites/chain-of-thought/chain-of-thought.js +117 -0
  7. package/dist/components/composites/chain-of-thought/chain-of-thought.js.map +1 -0
  8. package/dist/components/composites/chain-of-thought/index.d.ts +2 -0
  9. package/dist/components/composites/chain-of-thought/index.d.ts.map +1 -0
  10. package/dist/components/composites/chain-of-thought/index.js +2 -0
  11. package/dist/components/composites/chat/chat.d.ts +67 -0
  12. package/dist/components/composites/chat/chat.d.ts.map +1 -0
  13. package/dist/components/composites/chat/chat.js +179 -0
  14. package/dist/components/composites/chat/chat.js.map +1 -0
  15. package/dist/components/composites/chat/index.d.ts +2 -0
  16. package/dist/components/composites/chat/index.d.ts.map +1 -0
  17. package/dist/components/composites/chat/index.js +2 -0
  18. package/dist/components/composites/checkpoint/checkpoint-model.d.ts +34 -0
  19. package/dist/components/composites/checkpoint/checkpoint-model.d.ts.map +1 -0
  20. package/dist/components/composites/checkpoint/checkpoint-model.js +48 -0
  21. package/dist/components/composites/checkpoint/checkpoint-model.js.map +1 -0
  22. package/dist/components/composites/checkpoint/checkpoint.d.ts +48 -0
  23. package/dist/components/composites/checkpoint/checkpoint.d.ts.map +1 -0
  24. package/dist/components/composites/checkpoint/checkpoint.js +160 -0
  25. package/dist/components/composites/checkpoint/checkpoint.js.map +1 -0
  26. package/dist/components/composites/checkpoint/index.d.ts +3 -0
  27. package/dist/components/composites/checkpoint/index.d.ts.map +1 -0
  28. package/dist/components/composites/checkpoint/index.js +3 -0
  29. package/dist/components/composites/confirmation/confirmation-model.d.ts +45 -0
  30. package/dist/components/composites/confirmation/confirmation-model.d.ts.map +1 -0
  31. package/dist/components/composites/confirmation/confirmation-model.js +51 -0
  32. package/dist/components/composites/confirmation/confirmation-model.js.map +1 -0
  33. package/dist/components/composites/confirmation/confirmation.d.ts +72 -0
  34. package/dist/components/composites/confirmation/confirmation.d.ts.map +1 -0
  35. package/dist/components/composites/confirmation/confirmation.js +300 -0
  36. package/dist/components/composites/confirmation/confirmation.js.map +1 -0
  37. package/dist/components/composites/confirmation/index.d.ts +3 -0
  38. package/dist/components/composites/confirmation/index.d.ts.map +1 -0
  39. package/dist/components/composites/confirmation/index.js +3 -0
  40. package/dist/components/composites/context/context-model.d.ts +69 -0
  41. package/dist/components/composites/context/context-model.d.ts.map +1 -0
  42. package/dist/components/composites/context/context-model.js +122 -0
  43. package/dist/components/composites/context/context-model.js.map +1 -0
  44. package/dist/components/composites/context/context.d.ts +38 -0
  45. package/dist/components/composites/context/context.d.ts.map +1 -0
  46. package/dist/components/composites/context/context.js +234 -0
  47. package/dist/components/composites/context/context.js.map +1 -0
  48. package/dist/components/composites/context/index.d.ts +3 -0
  49. package/dist/components/composites/context/index.d.ts.map +1 -0
  50. package/dist/components/composites/context/index.js +3 -0
  51. package/dist/components/composites/file-tree/build-file-tree.d.ts +138 -0
  52. package/dist/components/composites/file-tree/build-file-tree.d.ts.map +1 -0
  53. package/dist/components/composites/file-tree/build-file-tree.js +325 -0
  54. package/dist/components/composites/file-tree/build-file-tree.js.map +1 -0
  55. package/dist/components/composites/file-tree/file-tree.d.ts +74 -0
  56. package/dist/components/composites/file-tree/file-tree.d.ts.map +1 -0
  57. package/dist/components/composites/file-tree/file-tree.js +389 -0
  58. package/dist/components/composites/file-tree/file-tree.js.map +1 -0
  59. package/dist/components/composites/file-tree/index.d.ts +3 -0
  60. package/dist/components/composites/file-tree/index.d.ts.map +1 -0
  61. package/dist/components/composites/file-tree/index.js +3 -0
  62. package/dist/components/composites/inline-citation/citation.d.ts +37 -0
  63. package/dist/components/composites/inline-citation/citation.d.ts.map +1 -0
  64. package/dist/components/composites/inline-citation/citation.js +52 -0
  65. package/dist/components/composites/inline-citation/citation.js.map +1 -0
  66. package/dist/components/composites/inline-citation/index.d.ts +3 -0
  67. package/dist/components/composites/inline-citation/index.d.ts.map +1 -0
  68. package/dist/components/composites/inline-citation/index.js +3 -0
  69. package/dist/components/composites/inline-citation/inline-citation.d.ts +64 -0
  70. package/dist/components/composites/inline-citation/inline-citation.d.ts.map +1 -0
  71. package/dist/components/composites/inline-citation/inline-citation.js +272 -0
  72. package/dist/components/composites/inline-citation/inline-citation.js.map +1 -0
  73. package/dist/components/composites/message-scroller/index.d.ts +3 -0
  74. package/dist/components/composites/message-scroller/index.d.ts.map +1 -0
  75. package/dist/components/composites/message-scroller/index.js +3 -0
  76. package/dist/components/composites/message-scroller/message-scroller.d.ts +55 -0
  77. package/dist/components/composites/message-scroller/message-scroller.d.ts.map +1 -0
  78. package/dist/components/composites/message-scroller/message-scroller.js +201 -0
  79. package/dist/components/composites/message-scroller/message-scroller.js.map +1 -0
  80. package/dist/components/composites/message-scroller/scroll-anchor.d.ts +66 -0
  81. package/dist/components/composites/message-scroller/scroll-anchor.d.ts.map +1 -0
  82. package/dist/components/composites/message-scroller/scroll-anchor.js +122 -0
  83. package/dist/components/composites/message-scroller/scroll-anchor.js.map +1 -0
  84. package/dist/components/composites/model-selector/index.d.ts +3 -0
  85. package/dist/components/composites/model-selector/index.d.ts.map +1 -0
  86. package/dist/components/composites/model-selector/index.js +3 -0
  87. package/dist/components/composites/model-selector/model-selector.d.ts +55 -0
  88. package/dist/components/composites/model-selector/model-selector.d.ts.map +1 -0
  89. package/dist/components/composites/model-selector/model-selector.js +490 -0
  90. package/dist/components/composites/model-selector/model-selector.js.map +1 -0
  91. package/dist/components/composites/model-selector/models.d.ts +51 -0
  92. package/dist/components/composites/model-selector/models.d.ts.map +1 -0
  93. package/dist/components/composites/model-selector/models.js +71 -0
  94. package/dist/components/composites/model-selector/models.js.map +1 -0
  95. package/dist/components/composites/plan/index.d.ts +2 -0
  96. package/dist/components/composites/plan/index.d.ts.map +1 -0
  97. package/dist/components/composites/plan/index.js +2 -0
  98. package/dist/components/composites/plan/plan.d.ts +61 -0
  99. package/dist/components/composites/plan/plan.d.ts.map +1 -0
  100. package/dist/components/composites/plan/plan.js +130 -0
  101. package/dist/components/composites/plan/plan.js.map +1 -0
  102. package/dist/components/composites/queue/index.d.ts +2 -0
  103. package/dist/components/composites/queue/index.d.ts.map +1 -0
  104. package/dist/components/composites/queue/index.js +2 -0
  105. package/dist/components/composites/queue/queue.d.ts +77 -0
  106. package/dist/components/composites/queue/queue.d.ts.map +1 -0
  107. package/dist/components/composites/queue/queue.js +271 -0
  108. package/dist/components/composites/queue/queue.js.map +1 -0
  109. package/dist/components/composites/reasoning/index.d.ts +2 -0
  110. package/dist/components/composites/reasoning/index.d.ts.map +1 -0
  111. package/dist/components/composites/reasoning/index.js +2 -0
  112. package/dist/components/composites/reasoning/reasoning.d.ts +62 -0
  113. package/dist/components/composites/reasoning/reasoning.d.ts.map +1 -0
  114. package/dist/components/composites/reasoning/reasoning.js +156 -0
  115. package/dist/components/composites/reasoning/reasoning.js.map +1 -0
  116. package/dist/components/composites/sources/index.d.ts +3 -0
  117. package/dist/components/composites/sources/index.d.ts.map +1 -0
  118. package/dist/components/composites/sources/index.js +3 -0
  119. package/dist/components/composites/sources/source.d.ts +46 -0
  120. package/dist/components/composites/sources/source.d.ts.map +1 -0
  121. package/dist/components/composites/sources/source.js +74 -0
  122. package/dist/components/composites/sources/source.js.map +1 -0
  123. package/dist/components/composites/sources/sources.d.ts +45 -0
  124. package/dist/components/composites/sources/sources.d.ts.map +1 -0
  125. package/dist/components/composites/sources/sources.js +175 -0
  126. package/dist/components/composites/sources/sources.js.map +1 -0
  127. package/dist/components/composites/stack-trace/index.d.ts +3 -0
  128. package/dist/components/composites/stack-trace/index.d.ts.map +1 -0
  129. package/dist/components/composites/stack-trace/index.js +3 -0
  130. package/dist/components/composites/stack-trace/parse-stack-trace.d.ts +118 -0
  131. package/dist/components/composites/stack-trace/parse-stack-trace.d.ts.map +1 -0
  132. package/dist/components/composites/stack-trace/parse-stack-trace.js +376 -0
  133. package/dist/components/composites/stack-trace/parse-stack-trace.js.map +1 -0
  134. package/dist/components/composites/stack-trace/stack-trace.d.ts +63 -0
  135. package/dist/components/composites/stack-trace/stack-trace.d.ts.map +1 -0
  136. package/dist/components/composites/stack-trace/stack-trace.js +491 -0
  137. package/dist/components/composites/stack-trace/stack-trace.js.map +1 -0
  138. package/dist/components/composites/subagent/index.d.ts +2 -0
  139. package/dist/components/composites/subagent/index.d.ts.map +1 -0
  140. package/dist/components/composites/subagent/index.js +2 -0
  141. package/dist/components/composites/subagent/subagent.d.ts +55 -0
  142. package/dist/components/composites/subagent/subagent.d.ts.map +1 -0
  143. package/dist/components/composites/subagent/subagent.js +138 -0
  144. package/dist/components/composites/subagent/subagent.js.map +1 -0
  145. package/dist/components/composites/suggestion/index.d.ts +2 -0
  146. package/dist/components/composites/suggestion/index.d.ts.map +1 -0
  147. package/dist/components/composites/suggestion/index.js +2 -0
  148. package/dist/components/composites/suggestion/suggestion.d.ts +37 -0
  149. package/dist/components/composites/suggestion/suggestion.d.ts.map +1 -0
  150. package/dist/components/composites/suggestion/suggestion.js +100 -0
  151. package/dist/components/composites/suggestion/suggestion.js.map +1 -0
  152. package/dist/components/composites/task/index.d.ts +2 -0
  153. package/dist/components/composites/task/index.d.ts.map +1 -0
  154. package/dist/components/composites/task/index.js +2 -0
  155. package/dist/components/composites/task/task.d.ts +96 -0
  156. package/dist/components/composites/task/task.d.ts.map +1 -0
  157. package/dist/components/composites/task/task.js +311 -0
  158. package/dist/components/composites/task/task.js.map +1 -0
  159. package/dist/components/composites/terminal/ansi.d.ts +101 -0
  160. package/dist/components/composites/terminal/ansi.d.ts.map +1 -0
  161. package/dist/components/composites/terminal/ansi.js +544 -0
  162. package/dist/components/composites/terminal/ansi.js.map +1 -0
  163. package/dist/components/composites/terminal/index.d.ts +4 -0
  164. package/dist/components/composites/terminal/index.d.ts.map +1 -0
  165. package/dist/components/composites/terminal/index.js +4 -0
  166. package/dist/components/composites/terminal/terminal-model.d.ts +63 -0
  167. package/dist/components/composites/terminal/terminal-model.d.ts.map +1 -0
  168. package/dist/components/composites/terminal/terminal-model.js +69 -0
  169. package/dist/components/composites/terminal/terminal-model.js.map +1 -0
  170. package/dist/components/composites/terminal/terminal.d.ts +88 -0
  171. package/dist/components/composites/terminal/terminal.d.ts.map +1 -0
  172. package/dist/components/composites/terminal/terminal.js +500 -0
  173. package/dist/components/composites/terminal/terminal.js.map +1 -0
  174. package/dist/components/composites/test-results/index.d.ts +3 -0
  175. package/dist/components/composites/test-results/index.d.ts.map +1 -0
  176. package/dist/components/composites/test-results/index.js +3 -0
  177. package/dist/components/composites/test-results/test-results-model.d.ts +154 -0
  178. package/dist/components/composites/test-results/test-results-model.d.ts.map +1 -0
  179. package/dist/components/composites/test-results/test-results-model.js +252 -0
  180. package/dist/components/composites/test-results/test-results-model.js.map +1 -0
  181. package/dist/components/composites/test-results/test-results.d.ts +60 -0
  182. package/dist/components/composites/test-results/test-results.d.ts.map +1 -0
  183. package/dist/components/composites/test-results/test-results.js +631 -0
  184. package/dist/components/composites/test-results/test-results.js.map +1 -0
  185. package/dist/components/composites/tool/format-tool-value.d.ts +37 -0
  186. package/dist/components/composites/tool/format-tool-value.d.ts.map +1 -0
  187. package/dist/components/composites/tool/format-tool-value.js +135 -0
  188. package/dist/components/composites/tool/format-tool-value.js.map +1 -0
  189. package/dist/components/composites/tool/index.d.ts +3 -0
  190. package/dist/components/composites/tool/index.d.ts.map +1 -0
  191. package/dist/components/composites/tool/index.js +3 -0
  192. package/dist/components/composites/tool/tool.d.ts +69 -0
  193. package/dist/components/composites/tool/tool.d.ts.map +1 -0
  194. package/dist/components/composites/tool/tool.js +214 -0
  195. package/dist/components/composites/tool/tool.js.map +1 -0
  196. package/dist/components/composites/update-dialog/update-dialog.js +1 -1
  197. package/dist/components/conversation/conversation-surface.d.ts +7 -0
  198. package/dist/components/conversation/conversation-surface.d.ts.map +1 -1
  199. package/dist/components/conversation/conversation-surface.js +2 -0
  200. package/dist/components/conversation/conversation-surface.js.map +1 -1
  201. package/dist/components/conversation/scroll-follow-core.d.ts +24 -0
  202. package/dist/components/conversation/scroll-follow-core.d.ts.map +1 -1
  203. package/dist/components/conversation/scroll-follow-core.js +23 -1
  204. package/dist/components/conversation/scroll-follow-core.js.map +1 -1
  205. package/dist/components/conversation/scroll-follow.d.ts +3 -0
  206. package/dist/components/conversation/scroll-follow.d.ts.map +1 -1
  207. package/dist/components/conversation/scroll-follow.js +80 -1
  208. package/dist/components/conversation/scroll-follow.js.map +1 -1
  209. package/dist/components/ui/attachment/attachment.d.ts +58 -0
  210. package/dist/components/ui/attachment/attachment.d.ts.map +1 -0
  211. package/dist/components/ui/attachment/attachment.js +279 -0
  212. package/dist/components/ui/attachment/attachment.js.map +1 -0
  213. package/dist/components/ui/attachment/index.d.ts +2 -0
  214. package/dist/components/ui/attachment/index.d.ts.map +1 -0
  215. package/dist/components/ui/attachment/index.js +2 -0
  216. package/dist/components/ui/badge/badge.d.ts +1 -1
  217. package/dist/components/ui/bubble/bubble.d.ts +33 -0
  218. package/dist/components/ui/bubble/bubble.d.ts.map +1 -0
  219. package/dist/components/ui/bubble/bubble.js +95 -0
  220. package/dist/components/ui/bubble/bubble.js.map +1 -0
  221. package/dist/components/ui/bubble/index.d.ts +2 -0
  222. package/dist/components/ui/bubble/index.d.ts.map +1 -0
  223. package/dist/components/ui/bubble/index.js +2 -0
  224. package/dist/components/ui/button/button.d.ts +1 -1
  225. package/dist/components/ui/code-block/code-block.d.ts +56 -3
  226. package/dist/components/ui/code-block/code-block.d.ts.map +1 -1
  227. package/dist/components/ui/code-block/code-block.js +231 -50
  228. package/dist/components/ui/code-block/code-block.js.map +1 -1
  229. package/dist/components/ui/code-block/index.d.ts +1 -1
  230. package/dist/components/ui/code-block/index.d.ts.map +1 -1
  231. package/dist/components/ui/code-block/index.js +2 -2
  232. package/dist/components/ui/field/number-field.d.ts +21 -4
  233. package/dist/components/ui/field/number-field.d.ts.map +1 -1
  234. package/dist/components/ui/field/number-field.js +22 -11
  235. package/dist/components/ui/field/number-field.js.map +1 -1
  236. package/dist/components/ui/marker/index.d.ts +2 -0
  237. package/dist/components/ui/marker/index.d.ts.map +1 -0
  238. package/dist/components/ui/marker/index.js +2 -0
  239. package/dist/components/ui/marker/marker.d.ts +35 -0
  240. package/dist/components/ui/marker/marker.d.ts.map +1 -0
  241. package/dist/components/ui/marker/marker.js +123 -0
  242. package/dist/components/ui/marker/marker.js.map +1 -0
  243. package/dist/components/ui/message/cite-ranges.d.ts +42 -0
  244. package/dist/components/ui/message/cite-ranges.d.ts.map +1 -0
  245. package/dist/components/ui/message/cite-ranges.js +105 -0
  246. package/dist/components/ui/message/cite-ranges.js.map +1 -0
  247. package/dist/components/ui/message/index.d.ts +4 -0
  248. package/dist/components/ui/message/index.d.ts.map +1 -0
  249. package/dist/components/ui/message/index.js +4 -0
  250. package/dist/components/ui/message/message.d.ts +95 -0
  251. package/dist/components/ui/message/message.d.ts.map +1 -0
  252. package/dist/components/ui/message/message.js +443 -0
  253. package/dist/components/ui/message/message.js.map +1 -0
  254. package/dist/components/ui/message/parse-message-text.d.ts +93 -0
  255. package/dist/components/ui/message/parse-message-text.d.ts.map +1 -0
  256. package/dist/components/ui/message/parse-message-text.js +365 -0
  257. package/dist/components/ui/message/parse-message-text.js.map +1 -0
  258. package/dist/components/ui/questionnaire/index.d.ts +2 -0
  259. package/dist/components/ui/questionnaire/index.d.ts.map +1 -0
  260. package/dist/components/ui/questionnaire/index.js +2 -0
  261. package/dist/components/ui/questionnaire/questionnaire.d.ts +83 -0
  262. package/dist/components/ui/questionnaire/questionnaire.d.ts.map +1 -0
  263. package/dist/components/ui/questionnaire/questionnaire.js +470 -0
  264. package/dist/components/ui/questionnaire/questionnaire.js.map +1 -0
  265. package/dist/components/ui/status-chip/status-chip.d.ts +1 -1
  266. package/dist/components/ui/switch/switch.js +11 -11
  267. package/dist/components/ui/switch/switch.js.map +1 -1
  268. package/dist/components/ui/trace/index.d.ts +2 -0
  269. package/dist/components/ui/trace/index.d.ts.map +1 -0
  270. package/dist/components/ui/trace/index.js +2 -0
  271. package/dist/components/ui/trace/trace.d.ts +72 -0
  272. package/dist/components/ui/trace/trace.d.ts.map +1 -0
  273. package/dist/components/ui/trace/trace.js +340 -0
  274. package/dist/components/ui/trace/trace.js.map +1 -0
  275. package/dist/index.d.ts +26 -0
  276. package/dist/index.d.ts.map +1 -1
  277. package/dist/index.js +46 -5
  278. package/dist/r/attachment.json +25 -0
  279. package/dist/r/bubble.json +22 -0
  280. package/dist/r/chain-of-thought.json +26 -0
  281. package/dist/r/chat.json +24 -0
  282. package/dist/r/checkpoint.json +35 -0
  283. package/dist/r/confirmation.json +34 -0
  284. package/dist/r/context.json +33 -0
  285. package/dist/r/file-tree.json +32 -0
  286. package/dist/r/inline-citation.json +35 -0
  287. package/dist/r/marker.json +22 -0
  288. package/dist/r/message-scroller.json +31 -0
  289. package/dist/r/message.json +33 -0
  290. package/dist/r/model-selector.json +34 -0
  291. package/dist/r/plan.json +26 -0
  292. package/dist/r/questionnaire.json +28 -0
  293. package/dist/r/queue.json +26 -0
  294. package/dist/r/reasoning.json +26 -0
  295. package/dist/r/registry.json +811 -52
  296. package/dist/r/sources.json +32 -0
  297. package/dist/r/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
  298. package/dist/r/src/components/composites/chain-of-thought/index.ts +11 -0
  299. package/dist/r/src/components/composites/chat/chat.tsx +190 -0
  300. package/dist/r/src/components/composites/chat/index.ts +11 -0
  301. package/dist/r/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
  302. package/dist/r/src/components/composites/checkpoint/checkpoint.tsx +214 -0
  303. package/dist/r/src/components/composites/checkpoint/index.ts +8 -0
  304. package/dist/r/src/components/composites/confirmation/confirmation-model.ts +83 -0
  305. package/dist/r/src/components/composites/confirmation/confirmation.tsx +311 -0
  306. package/dist/r/src/components/composites/confirmation/index.ts +9 -0
  307. package/dist/r/src/components/composites/context/context-model.ts +168 -0
  308. package/dist/r/src/components/composites/context/context.tsx +187 -0
  309. package/dist/r/src/components/composites/context/index.ts +18 -0
  310. package/dist/r/src/components/composites/file-tree/build-file-tree.ts +456 -0
  311. package/dist/r/src/components/composites/file-tree/file-tree.tsx +405 -0
  312. package/dist/r/src/components/composites/file-tree/index.ts +25 -0
  313. package/dist/r/src/components/composites/inline-citation/citation.ts +78 -0
  314. package/dist/r/src/components/composites/inline-citation/index.ts +9 -0
  315. package/dist/r/src/components/composites/inline-citation/inline-citation.tsx +285 -0
  316. package/dist/r/src/components/composites/message-scroller/index.ts +2 -0
  317. package/dist/r/src/components/composites/message-scroller/message-scroller.tsx +301 -0
  318. package/dist/r/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
  319. package/dist/r/src/components/composites/model-selector/index.ts +14 -0
  320. package/dist/r/src/components/composites/model-selector/model-selector.tsx +420 -0
  321. package/dist/r/src/components/composites/model-selector/models.ts +103 -0
  322. package/dist/r/src/components/composites/plan/index.ts +1 -0
  323. package/dist/r/src/components/composites/plan/plan.tsx +155 -0
  324. package/dist/r/src/components/composites/queue/index.ts +10 -0
  325. package/dist/r/src/components/composites/queue/queue.tsx +264 -0
  326. package/dist/r/src/components/composites/reasoning/index.ts +1 -0
  327. package/dist/r/src/components/composites/reasoning/reasoning.tsx +176 -0
  328. package/dist/r/src/components/composites/sources/index.ts +11 -0
  329. package/dist/r/src/components/composites/sources/source.ts +116 -0
  330. package/dist/r/src/components/composites/sources/sources.tsx +163 -0
  331. package/dist/r/src/components/composites/stack-trace/index.ts +19 -0
  332. package/dist/r/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
  333. package/dist/r/src/components/composites/stack-trace/stack-trace.tsx +395 -0
  334. package/dist/r/src/components/composites/subagent/index.ts +1 -0
  335. package/dist/r/src/components/composites/subagent/subagent.tsx +159 -0
  336. package/dist/r/src/components/composites/suggestion/index.ts +1 -0
  337. package/dist/r/src/components/composites/suggestion/suggestion.tsx +140 -0
  338. package/dist/r/src/components/composites/task/index.ts +14 -0
  339. package/dist/r/src/components/composites/task/task.tsx +317 -0
  340. package/dist/r/src/components/composites/terminal/ansi.ts +674 -0
  341. package/dist/r/src/components/composites/terminal/index.ts +20 -0
  342. package/dist/r/src/components/composites/terminal/terminal-model.ts +111 -0
  343. package/dist/r/src/components/composites/terminal/terminal.tsx +574 -0
  344. package/dist/r/src/components/composites/test-results/index.ts +20 -0
  345. package/dist/r/src/components/composites/test-results/test-results-model.ts +368 -0
  346. package/dist/r/src/components/composites/test-results/test-results.tsx +586 -0
  347. package/dist/r/src/components/composites/tool/format-tool-value.ts +221 -0
  348. package/dist/r/src/components/composites/tool/index.ts +2 -0
  349. package/dist/r/src/components/composites/tool/tool.tsx +228 -0
  350. package/dist/r/src/components/conversation/conversation-surface.tsx +9 -0
  351. package/dist/r/src/components/conversation/scroll-follow-core.ts +31 -0
  352. package/dist/r/src/components/conversation/scroll-follow.ts +92 -0
  353. package/dist/r/src/components/ui/attachment/attachment.tsx +282 -0
  354. package/dist/r/src/components/ui/attachment/index.ts +10 -0
  355. package/dist/r/src/components/ui/bubble/bubble.tsx +86 -0
  356. package/dist/r/src/components/ui/bubble/index.ts +1 -0
  357. package/dist/r/src/components/ui/code-block/code-block.tsx +256 -26
  358. package/dist/r/src/components/ui/code-block/index.ts +9 -1
  359. package/dist/r/src/components/ui/field/number-field.tsx +51 -14
  360. package/dist/r/src/components/ui/marker/index.ts +1 -0
  361. package/dist/r/src/components/ui/marker/marker.tsx +90 -0
  362. package/dist/r/src/components/ui/message/cite-ranges.ts +144 -0
  363. package/dist/r/src/components/ui/message/index.ts +23 -0
  364. package/dist/r/src/components/ui/message/message.tsx +434 -0
  365. package/dist/r/src/components/ui/message/parse-message-text.ts +450 -0
  366. package/dist/r/src/components/ui/questionnaire/index.ts +10 -0
  367. package/dist/r/src/components/ui/questionnaire/questionnaire.tsx +446 -0
  368. package/dist/r/src/components/ui/trace/index.ts +9 -0
  369. package/dist/r/src/components/ui/trace/trace.tsx +334 -0
  370. package/dist/r/src/styles/base.css +34 -0
  371. package/dist/r/stack-trace.json +32 -0
  372. package/dist/r/subagent.json +27 -0
  373. package/dist/r/suggestion.json +24 -0
  374. package/dist/r/task.json +28 -0
  375. package/dist/r/terminal.json +35 -0
  376. package/dist/r/test-results.json +33 -0
  377. package/dist/r/tool.json +31 -0
  378. package/dist/r/trace.json +25 -0
  379. package/package.json +6 -3
  380. package/registry.json +811 -52
  381. package/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
  382. package/src/components/composites/chain-of-thought/index.ts +11 -0
  383. package/src/components/composites/chat/chat.tsx +190 -0
  384. package/src/components/composites/chat/index.ts +11 -0
  385. package/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
  386. package/src/components/composites/checkpoint/checkpoint.tsx +214 -0
  387. package/src/components/composites/checkpoint/index.ts +8 -0
  388. package/src/components/composites/confirmation/confirmation-model.ts +83 -0
  389. package/src/components/composites/confirmation/confirmation.tsx +311 -0
  390. package/src/components/composites/confirmation/index.ts +9 -0
  391. package/src/components/composites/context/context-model.ts +168 -0
  392. package/src/components/composites/context/context.tsx +187 -0
  393. package/src/components/composites/context/index.ts +18 -0
  394. package/src/components/composites/file-tree/build-file-tree.ts +456 -0
  395. package/src/components/composites/file-tree/file-tree.tsx +405 -0
  396. package/src/components/composites/file-tree/index.ts +25 -0
  397. package/src/components/composites/inline-citation/citation.ts +78 -0
  398. package/src/components/composites/inline-citation/index.ts +9 -0
  399. package/src/components/composites/inline-citation/inline-citation.tsx +285 -0
  400. package/src/components/composites/message-scroller/index.ts +2 -0
  401. package/src/components/composites/message-scroller/message-scroller.tsx +301 -0
  402. package/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
  403. package/src/components/composites/model-selector/index.ts +14 -0
  404. package/src/components/composites/model-selector/model-selector.tsx +420 -0
  405. package/src/components/composites/model-selector/models.ts +103 -0
  406. package/src/components/composites/plan/index.ts +1 -0
  407. package/src/components/composites/plan/plan.tsx +155 -0
  408. package/src/components/composites/queue/index.ts +10 -0
  409. package/src/components/composites/queue/queue.tsx +264 -0
  410. package/src/components/composites/reasoning/index.ts +1 -0
  411. package/src/components/composites/reasoning/reasoning.tsx +176 -0
  412. package/src/components/composites/sources/index.ts +11 -0
  413. package/src/components/composites/sources/source.ts +116 -0
  414. package/src/components/composites/sources/sources.tsx +163 -0
  415. package/src/components/composites/stack-trace/index.ts +19 -0
  416. package/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
  417. package/src/components/composites/stack-trace/stack-trace.tsx +395 -0
  418. package/src/components/composites/subagent/index.ts +1 -0
  419. package/src/components/composites/subagent/subagent.tsx +159 -0
  420. package/src/components/composites/suggestion/index.ts +1 -0
  421. package/src/components/composites/suggestion/suggestion.tsx +140 -0
  422. package/src/components/composites/task/index.ts +14 -0
  423. package/src/components/composites/task/task.tsx +317 -0
  424. package/src/components/composites/terminal/ansi.ts +674 -0
  425. package/src/components/composites/terminal/index.ts +20 -0
  426. package/src/components/composites/terminal/terminal-model.ts +111 -0
  427. package/src/components/composites/terminal/terminal.tsx +574 -0
  428. package/src/components/composites/test-results/index.ts +20 -0
  429. package/src/components/composites/test-results/test-results-model.ts +368 -0
  430. package/src/components/composites/test-results/test-results.tsx +586 -0
  431. package/src/components/composites/tool/format-tool-value.ts +221 -0
  432. package/src/components/composites/tool/index.ts +2 -0
  433. package/src/components/composites/tool/tool.tsx +228 -0
  434. package/src/components/conversation/conversation-surface.tsx +9 -0
  435. package/src/components/conversation/scroll-follow-core.ts +31 -0
  436. package/src/components/conversation/scroll-follow.ts +92 -0
  437. package/src/components/ui/attachment/attachment.tsx +282 -0
  438. package/src/components/ui/attachment/index.ts +10 -0
  439. package/src/components/ui/bubble/bubble.tsx +86 -0
  440. package/src/components/ui/bubble/index.ts +1 -0
  441. package/src/components/ui/code-block/code-block.tsx +256 -26
  442. package/src/components/ui/code-block/index.ts +9 -1
  443. package/src/components/ui/field/number-field.tsx +51 -14
  444. package/src/components/ui/marker/index.ts +1 -0
  445. package/src/components/ui/marker/marker.tsx +90 -0
  446. package/src/components/ui/message/cite-ranges.ts +144 -0
  447. package/src/components/ui/message/index.ts +23 -0
  448. package/src/components/ui/message/message.tsx +434 -0
  449. package/src/components/ui/message/parse-message-text.ts +450 -0
  450. package/src/components/ui/questionnaire/index.ts +10 -0
  451. package/src/components/ui/questionnaire/questionnaire.tsx +446 -0
  452. package/src/components/ui/trace/index.ts +9 -0
  453. package/src/components/ui/trace/trace.tsx +334 -0
  454. package/src/index.ts +26 -0
  455. package/src/styles/base.css +34 -0
@@ -0,0 +1,83 @@
1
+ import { boundText } from '../sources/source'
2
+
3
+ /**
4
+ * Where a request for approval stands.
5
+ *
6
+ * - `requested`: waiting on the reader. The only state with live buttons.
7
+ * - `approved` / `denied`: settled; the record of the answer.
8
+ * - `expired`: nobody can answer it any more (the run moved on, a timeout).
9
+ * - `unavailable`: it is still open, but this client cannot answer it right now
10
+ * (offline, no authority, another client holds it). The buttons stay visible and
11
+ * disabled so the reader can see what was asked and why they cannot answer.
12
+ */
13
+ export type ConfirmationState = 'requested' | 'approved' | 'denied' | 'expired' | 'unavailable'
14
+
15
+ /** Whether the choice is still open, which is exactly when the buttons are drawn. */
16
+ export function isAwaitingAnswer(state: ConfirmationState): boolean {
17
+ return state === 'requested' || state === 'unavailable'
18
+ }
19
+
20
+ /**
21
+ * The one line that replaces the buttons once the request settles. Who and when
22
+ * appear only if the host supplied them: "Approved" is a fact the state gives,
23
+ * "by Ana" is a fact only the host knows.
24
+ */
25
+ export function confirmationOutcome(
26
+ state: ConfirmationState,
27
+ by?: string,
28
+ at?: string
29
+ ): string | undefined {
30
+ const base =
31
+ state === 'approved'
32
+ ? 'Approved'
33
+ : state === 'denied'
34
+ ? 'Denied'
35
+ : state === 'expired'
36
+ ? 'Expired without an answer'
37
+ : undefined
38
+ if (base === undefined) return undefined
39
+ const who = by ? boundText(by, 60) : ''
40
+ const when = at ? boundText(at, 40) : ''
41
+ return `${base}${who ? ` by ${who}` : ''}${when ? ` at ${when}` : ''}`
42
+ }
43
+
44
+ export type DecisionResult = { ok: true } | { ok: false; message: string }
45
+
46
+ const DEFAULT_FAILURE = 'Your answer could not be sent. Try again.'
47
+
48
+ /**
49
+ * Run a host handler that may be synchronous, asynchronous, or throw, and report
50
+ * the outcome as data. A rejection's own message is shown (bounded) because the
51
+ * host usually knows why; a non-Error rejection gets a plain sentence instead of
52
+ * "[object Object]".
53
+ */
54
+ export async function settleDecision(
55
+ handler: (() => void | Promise<void>) | undefined
56
+ ): Promise<DecisionResult> {
57
+ try {
58
+ await handler?.()
59
+ return { ok: true }
60
+ } catch (error) {
61
+ const message = error instanceof Error ? boundText(error.message, 200) : ''
62
+ return { ok: false, message: message || DEFAULT_FAILURE }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Why a choice is not available, in words. A host `disabledReason` outranks the
68
+ * built-in sentence for a missing handler, and a request that is `unavailable`
69
+ * without a reason still says so rather than showing dead buttons.
70
+ */
71
+ export function decisionReason(options: {
72
+ state: ConfirmationState
73
+ disabledReason?: string
74
+ hasHandler: boolean
75
+ unavailableFallback: string
76
+ missingFallback: string
77
+ }): string | undefined {
78
+ const hostReason = options.disabledReason ? boundText(options.disabledReason, 240) : ''
79
+ if (hostReason) return hostReason
80
+ if (options.state === 'unavailable') return options.unavailableFallback
81
+ if (!options.hasHandler) return options.missingFallback
82
+ return undefined
83
+ }
@@ -0,0 +1,311 @@
1
+ import { Ban, Check, Clock, Lock, ShieldQuestion } from 'lucide-solid'
2
+ import {
3
+ createEffect,
4
+ createSignal,
5
+ createUniqueId,
6
+ Show,
7
+ splitProps,
8
+ type ComponentProps,
9
+ type JSX,
10
+ } from 'solid-js'
11
+ import { cn } from '../../../lib/utils'
12
+ import { Button } from '../../ui/button'
13
+ import { CodeBlock } from '../../ui/code-block'
14
+ import { DiffBlock } from '../../ui/diff-block'
15
+ import { Spinner } from '../../ui/spinner'
16
+ import { boundText } from '../sources/source'
17
+ import {
18
+ confirmationOutcome,
19
+ decisionReason,
20
+ isAwaitingAnswer,
21
+ settleDecision,
22
+ type ConfirmationState,
23
+ } from './confirmation-model'
24
+
25
+ /**
26
+ * Confirmation.
27
+ *
28
+ * The agent has stopped a tool and will not continue until the person approves or
29
+ * denies it. Like `Questionnaire`, this is one of the two elements in a transcript
30
+ * the reader *must* act on, so it is allowed a card surface — and the border is
31
+ * the focus ring's colour only while it is waiting. Once answered it drops to a
32
+ * hairline and a one-line record, because a settled decision should read as
33
+ * history, not as something still asking.
34
+ *
35
+ * ## It shows what is being approved, and nothing else
36
+ *
37
+ * `title` and `description` say what the tool wants to do; `details` is the
38
+ * evidence, rendered as `CodeBlock size="sm"` (a command, a request) or
39
+ * `DiffBlock` (a patch). Details are text: never interpreted, and a long one
40
+ * scrolls inside its block. Approve and Deny exist only while the request is
41
+ * open; afterwards they are replaced by the outcome, with *who* and *when* only if
42
+ * the host supplied them.
43
+ *
44
+ * ## The host owns authority
45
+ *
46
+ * Whether this client may answer is not decided here. No handler, or a host
47
+ * `disabledReason`, or the `unavailable` state, leaves the buttons visible and
48
+ * disabled with the reason beside them in words — never hidden, because a reader
49
+ * who cannot see the choice cannot tell whether the agent is waiting on them.
50
+ *
51
+ * ## Answering is a round trip
52
+ *
53
+ * `onApprove` / `onDeny` may return a promise. While one is pending both buttons
54
+ * refuse input (a synchronous guard as well as the signal, so a double click in
55
+ * one tick cannot submit twice) and the pressed one shows a spinner. A failure
56
+ * shows `error` (or the rejection's own message) and re-enables the buttons. The
57
+ * buttons use `aria-disabled` rather than `disabled`: a native disabled button
58
+ * drops focus, and the reader's place would be lost mid-decision. When the state
59
+ * settles, focus moves to the outcome line if it was in the card, so a keyboard
60
+ * user is not stranded on a control that no longer exists.
61
+ */
62
+ export type ConfirmationDetails =
63
+ | Readonly<{ kind: 'code'; code: string; language?: string; title?: string }>
64
+ | Readonly<{ kind: 'diff'; patch: string; title?: string }>
65
+
66
+ export type ConfirmationProps = Omit<ComponentProps<'section'>, 'title' | 'onError'> & {
67
+ state?: ConfirmationState
68
+ /** What the tool wants to do, as a short sentence. */
69
+ title: string
70
+ description?: string
71
+ details?: ConfirmationDetails
72
+ onApprove?: () => void | Promise<void>
73
+ onDeny?: () => void | Promise<void>
74
+ approveLabel?: string
75
+ denyLabel?: string
76
+ /** Why the choice cannot be made right now; shown in words beside the buttons. */
77
+ disabledReason?: string
78
+ /** A failed answer, in words. Overrides the rejection's own message. */
79
+ error?: string
80
+ /** Who answered, once settled. Omit if unknown; nothing is assumed. */
81
+ resolvedBy?: string
82
+ /** When it was answered, already formatted for the reader. Omit if unknown. */
83
+ resolvedAt?: string
84
+ /** Extra content between the details and the buttons. */
85
+ children?: JSX.Element
86
+ }
87
+
88
+ type Choice = 'approve' | 'deny'
89
+
90
+ export function Confirmation(props: ConfirmationProps) {
91
+ const [local, rest] = splitProps(props, [
92
+ 'class',
93
+ 'state',
94
+ 'title',
95
+ 'description',
96
+ 'details',
97
+ 'onApprove',
98
+ 'onDeny',
99
+ 'approveLabel',
100
+ 'denyLabel',
101
+ 'disabledReason',
102
+ 'error',
103
+ 'resolvedBy',
104
+ 'resolvedAt',
105
+ 'children',
106
+ ])
107
+ const uid = createUniqueId()
108
+ const titleId = `${uid}-title`
109
+ const reasonId = `${uid}-reason`
110
+ const state = (): ConfirmationState => local.state ?? 'requested'
111
+ const awaiting = () => isAwaitingAnswer(state())
112
+ const [pending, setPending] = createSignal<Choice | undefined>(undefined)
113
+ const [failure, setFailure] = createSignal<string | undefined>(undefined)
114
+ let inflight = false
115
+ let root: HTMLElement | undefined
116
+ let outcome: HTMLParagraphElement | undefined
117
+
118
+ const reasonFor = (handler: (() => void | Promise<void>) | undefined, missing: string) => {
119
+ if (pending() !== undefined) return 'Your answer is being sent.'
120
+ return decisionReason({
121
+ state: state(),
122
+ disabledReason: local.disabledReason,
123
+ hasHandler: handler !== undefined,
124
+ unavailableFallback: 'This request cannot be answered right now.',
125
+ missingFallback: missing,
126
+ })
127
+ }
128
+ const approveReason = () => reasonFor(local.onApprove, 'Approving is not available here.')
129
+ const denyReason = () => reasonFor(local.onDeny, 'Denying is not available here.')
130
+ // One sentence per distinct reason, so two identical reasons are not read twice.
131
+ const reasons = () => [...new Set([approveReason(), denyReason()].filter(Boolean))].join(' ')
132
+ const error = () => (local.error ? boundText(local.error, 240) : failure())
133
+
134
+ const choose = async (choice: Choice) => {
135
+ const handler = choice === 'approve' ? local.onApprove : local.onDeny
136
+ const blocked = choice === 'approve' ? approveReason() : denyReason()
137
+ if (inflight || blocked || !awaiting()) return
138
+ inflight = true
139
+ setPending(choice)
140
+ setFailure(undefined)
141
+ const result = await settleDecision(handler)
142
+ inflight = false
143
+ setPending(undefined)
144
+ if (!result.ok) setFailure(result.message)
145
+ }
146
+
147
+ // The buttons are replaced by the outcome line; keep a keyboard reader in the card.
148
+ // The previous value is kept by hand: `on(..., { defer: true })` does not record the
149
+ // input of its skipped first run, so its "previous" is undefined on the first change.
150
+ let wasAwaiting = awaiting()
151
+ createEffect(() => {
152
+ const now = awaiting()
153
+ if (wasAwaiting && !now) {
154
+ const active = document.activeElement
155
+ if (active === null || active === document.body || root?.contains(active)) {
156
+ outcome?.focus()
157
+ }
158
+ }
159
+ wasAwaiting = now
160
+ })
161
+
162
+ const buttonProps = (choice: Choice) => {
163
+ const blocked = () => (choice === 'approve' ? approveReason() : denyReason())
164
+ const disabled = () => pending() !== undefined || blocked() !== undefined
165
+ return {
166
+ 'aria-disabled': disabled() || undefined,
167
+ 'aria-describedby': blocked() ? reasonId : undefined,
168
+ onClick: () => void choose(choice),
169
+ }
170
+ }
171
+
172
+ return (
173
+ <section
174
+ ref={(element) => (root = element)}
175
+ data-slot="confirmation"
176
+ data-state={state()}
177
+ aria-labelledby={titleId}
178
+ class={cn('flex w-full max-w-xl min-w-0 flex-col gap-3 rounded-xl border bg-card p-4', {
179
+ 'border-ring': awaiting(),
180
+ 'border-border': !awaiting(),
181
+ })}
182
+ {...rest}
183
+ >
184
+ <header class="flex items-start gap-2.5">
185
+ <span aria-hidden="true" class="mt-0.5 text-muted-foreground [&_svg]:size-4">
186
+ <Show when={state() === 'approved'}>
187
+ <Check class="text-success" />
188
+ </Show>
189
+ <Show when={state() === 'denied'}>
190
+ <Ban />
191
+ </Show>
192
+ <Show when={state() === 'expired'}>
193
+ <Clock />
194
+ </Show>
195
+ <Show when={state() === 'unavailable'}>
196
+ <Lock />
197
+ </Show>
198
+ <Show when={state() === 'requested'}>
199
+ <ShieldQuestion />
200
+ </Show>
201
+ </span>
202
+ <div class="min-w-0 flex-1">
203
+ <h3 id={titleId} class="m-0 text-sm font-semibold [overflow-wrap:anywhere]">
204
+ {boundText(local.title, 200)}
205
+ </h3>
206
+ <Show when={local.description}>
207
+ <p class="m-0 mt-0.5 text-xs text-muted-foreground [overflow-wrap:anywhere]">
208
+ {boundText(local.description ?? '', 400)}
209
+ </p>
210
+ </Show>
211
+ </div>
212
+ <Show when={awaiting()}>
213
+ <span class="shrink-0 text-xs text-muted-foreground">
214
+ {state() === 'requested' ? 'Needs your answer' : 'Cannot be answered now'}
215
+ </span>
216
+ </Show>
217
+ </header>
218
+
219
+ <Show when={local.details}>{(details) => <Details details={details()} />}</Show>
220
+
221
+ {local.children}
222
+
223
+ <Show
224
+ when={awaiting()}
225
+ fallback={
226
+ <p
227
+ ref={(element) => (outcome = element)}
228
+ tabindex="-1"
229
+ role="status"
230
+ class="m-0 flex items-center gap-1.5 text-xs text-muted-foreground outline-none"
231
+ >
232
+ {confirmationOutcome(state(), local.resolvedBy, local.resolvedAt)}
233
+ </p>
234
+ }
235
+ >
236
+ <Show when={reasons()}>
237
+ <p id={reasonId} role="status" class="m-0 text-xs text-muted-foreground">
238
+ {reasons()}
239
+ </p>
240
+ </Show>
241
+ <Show when={error()}>
242
+ <p role="alert" class="m-0 text-xs text-destructive [overflow-wrap:anywhere]">
243
+ {error()}
244
+ </p>
245
+ </Show>
246
+ <footer class="flex flex-wrap items-center justify-end gap-2">
247
+ <Button type="button" variant="outline" size="sm" {...buttonProps('deny')}>
248
+ <Show when={pending() === 'deny'}>
249
+ <Spinner size="sm" label={false} />
250
+ </Show>
251
+ {local.denyLabel ?? 'Deny'}
252
+ </Button>
253
+ <Button type="button" size="sm" {...buttonProps('approve')}>
254
+ <Show when={pending() === 'approve'}>
255
+ <Spinner size="sm" label={false} />
256
+ </Show>
257
+ {local.approveLabel ?? 'Approve'}
258
+ </Button>
259
+ {/* Present from the start: a live region inserted with its text is not reliably announced. */}
260
+ <span role="status" class="visually-hidden">
261
+ {pending() !== undefined ? 'Sending your answer' : ''}
262
+ </span>
263
+ </footer>
264
+ </Show>
265
+ </section>
266
+ )
267
+ }
268
+
269
+ /** A name from the host or the model, cleaned and clipped before it reaches a header. */
270
+ function bounded(value: string | undefined, limit: number): string | undefined {
271
+ return value ? boundText(value, limit) || undefined : undefined
272
+ }
273
+
274
+ function Details(props: { details: ConfirmationDetails }) {
275
+ return (
276
+ <Show
277
+ when={props.details.kind === 'diff' && props.details}
278
+ fallback={
279
+ <CodeBlock
280
+ size="sm"
281
+ code={(props.details as Extract<ConfirmationDetails, { kind: 'code' }>).code}
282
+ language={bounded(
283
+ (props.details as Extract<ConfirmationDetails, { kind: 'code' }>).language,
284
+ 24
285
+ )}
286
+ title={bounded(props.details.title, 80)}
287
+ complete
288
+ wrap
289
+ maxHeight="14rem"
290
+ />
291
+ }
292
+ >
293
+ {(diff) => (
294
+ // The diff block has no height cap of its own, so the cap lives here; a
295
+ // scroller must be focusable, hence the labelled region and tab stop.
296
+ <div
297
+ role="region"
298
+ aria-label="Proposed changes"
299
+ tabindex="0"
300
+ class="max-h-64 overflow-auto rounded-xl outline-none focus-visible:ring-3 focus-visible:ring-primary-subtle"
301
+ >
302
+ <DiffBlock
303
+ patch={(diff() as Extract<ConfirmationDetails, { kind: 'diff' }>).patch}
304
+ title={bounded(diff().title, 80)}
305
+ complete
306
+ />
307
+ </div>
308
+ )}
309
+ </Show>
310
+ )
311
+ }
@@ -0,0 +1,9 @@
1
+ export { Confirmation, type ConfirmationDetails, type ConfirmationProps } from './confirmation'
2
+ export {
3
+ confirmationOutcome,
4
+ decisionReason,
5
+ isAwaitingAnswer,
6
+ settleDecision,
7
+ type ConfirmationState,
8
+ type DecisionResult,
9
+ } from './confirmation-model'
@@ -0,0 +1,168 @@
1
+ import { boundText } from '../sources/source'
2
+
3
+ /**
4
+ * The figures a host may know about a context window. Every one is optional and
5
+ * means "the host told us", so absence is never rendered as zero: `used: 0` is a
6
+ * fresh conversation, a missing `used` is an unknown.
7
+ */
8
+ export type ContextBreakdown = Readonly<{
9
+ input?: number
10
+ output?: number
11
+ cacheRead?: number
12
+ cacheWrite?: number
13
+ reasoning?: number
14
+ }>
15
+
16
+ export type ContextCost = Readonly<{
17
+ amount: number
18
+ /** An ISO 4217 code such as `USD`. Without one the amount is shown unlabelled. */
19
+ currency?: string
20
+ }>
21
+
22
+ export type ContextFigures = Readonly<{
23
+ /** Tokens in the window now. */
24
+ used?: number
25
+ /** The window's size. */
26
+ total?: number
27
+ breakdown?: ContextBreakdown
28
+ cost?: ContextCost
29
+ }>
30
+
31
+ /** A usable figure: a finite, non-negative number. NaN, Infinity and negatives are "unknown". */
32
+ export function isFigure(value: number | undefined): value is number {
33
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0
34
+ }
35
+
36
+ const BREAKDOWN_ROWS = [
37
+ ['input', 'Input'],
38
+ ['output', 'Output'],
39
+ ['cacheRead', 'Cache read'],
40
+ ['cacheWrite', 'Cache write'],
41
+ ['reasoning', 'Reasoning'],
42
+ ] as const
43
+
44
+ /** The breakdown entries the host actually supplied, in a fixed reading order. */
45
+ export function breakdownRows(
46
+ breakdown: ContextBreakdown | undefined
47
+ ): readonly { key: string; label: string; value: number }[] {
48
+ if (!breakdown) return []
49
+ const rows: { key: string; label: string; value: number }[] = []
50
+ for (const [key, label] of BREAKDOWN_ROWS) {
51
+ const value = breakdown[key]
52
+ if (isFigure(value)) rows.push({ key, label, value })
53
+ }
54
+ return rows
55
+ }
56
+
57
+ /**
58
+ * Whether there is anything to show. When there is not, the trigger is not
59
+ * rendered at all: an empty gauge or "0%" would assert an empty window.
60
+ */
61
+ export function hasContextFigures(figures: ContextFigures): boolean {
62
+ return (
63
+ isFigure(figures.used) ||
64
+ isFigure(figures.total) ||
65
+ breakdownRows(figures.breakdown).length > 0 ||
66
+ (figures.cost !== undefined && isFigure(figures.cost.amount))
67
+ )
68
+ }
69
+
70
+ /**
71
+ * Percentage of the window used, rounded. Needs both figures and a non-empty
72
+ * window; it is not clamped, because "112%" is the truth about an overrun and a
73
+ * clamp would hide it (the ring is what saturates, not the number).
74
+ */
75
+ export function contextPercent(
76
+ used: number | undefined,
77
+ total: number | undefined
78
+ ): number | undefined {
79
+ if (!isFigure(used) || !isFigure(total) || total <= 0) return undefined
80
+ return Math.round((used / total) * 100)
81
+ }
82
+
83
+ export type ContextLevel = 'normal' | 'high' | 'critical' | 'full'
84
+
85
+ /**
86
+ * How full, in steps. The step changes an icon and a word as well as a colour, so
87
+ * it reads without colour vision and in a screen reader.
88
+ */
89
+ export function contextLevel(percent: number | undefined): ContextLevel {
90
+ if (percent === undefined) return 'normal'
91
+ if (percent >= 100) return 'full'
92
+ if (percent >= 90) return 'critical'
93
+ if (percent >= 75) return 'high'
94
+ return 'normal'
95
+ }
96
+
97
+ export function contextLevelWord(level: ContextLevel): string | undefined {
98
+ switch (level) {
99
+ case 'high':
100
+ return 'Getting full'
101
+ case 'critical':
102
+ return 'Nearly full'
103
+ case 'full':
104
+ return 'Full'
105
+ case 'normal':
106
+ return undefined
107
+ }
108
+ }
109
+
110
+ /** Compact token count for the trigger: 950, 1.2K, 48.2K, 1.3M. */
111
+ export function formatTokens(value: number, locale = 'en-US'): string {
112
+ return new Intl.NumberFormat(locale, { notation: 'compact', maximumFractionDigits: 1 }).format(
113
+ value
114
+ )
115
+ }
116
+
117
+ /** The exact count for the popover. */
118
+ export function formatExact(value: number, locale = 'en-US'): string {
119
+ return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value)
120
+ }
121
+
122
+ /**
123
+ * Money, with its currency symbol when the code is valid. An unrecognised code
124
+ * (`Intl` throws a RangeError) is shown as written, bounded, rather than being
125
+ * swapped for a currency the host never named.
126
+ */
127
+ export function formatCost(cost: ContextCost, locale = 'en-US'): string {
128
+ const digits = { minimumFractionDigits: 2, maximumFractionDigits: cost.amount < 1 ? 4 : 2 }
129
+ if (!cost.currency) return new Intl.NumberFormat(locale, digits).format(cost.amount)
130
+ try {
131
+ return new Intl.NumberFormat(locale, {
132
+ ...digits,
133
+ style: 'currency',
134
+ currency: cost.currency,
135
+ }).format(cost.amount)
136
+ } catch {
137
+ return `${new Intl.NumberFormat(locale, digits).format(cost.amount)} ${boundText(cost.currency, 8)}`
138
+ }
139
+ }
140
+
141
+ /**
142
+ * The trigger's accessible name: the whole claim in words. Percent when both
143
+ * figures are known, else the most informative thing that is.
144
+ */
145
+ export function contextLabel(figures: ContextFigures, locale = 'en-US'): string | undefined {
146
+ const percent = contextPercent(figures.used, figures.total)
147
+ if (percent !== undefined) {
148
+ const word = contextLevelWord(contextLevel(percent))
149
+ return `${percent}% of context used${word ? `, ${word.toLowerCase()}` : ''}`
150
+ }
151
+ if (isFigure(figures.used)) return `${formatTokens(figures.used, locale)} tokens used`
152
+ if (isFigure(figures.total)) return `${formatTokens(figures.total, locale)} token context window`
153
+ if (breakdownRows(figures.breakdown).length > 0) return 'Token usage'
154
+ if (figures.cost && isFigure(figures.cost.amount))
155
+ return `Cost ${formatCost(figures.cost, locale)}`
156
+ return undefined
157
+ }
158
+
159
+ /** The short visible text inside the trigger. Always a prefix-compatible part of `contextLabel`. */
160
+ export function contextShort(figures: ContextFigures, locale = 'en-US'): string | undefined {
161
+ const percent = contextPercent(figures.used, figures.total)
162
+ if (percent !== undefined) return `${percent}%`
163
+ if (isFigure(figures.used)) return formatTokens(figures.used, locale)
164
+ if (isFigure(figures.total)) return formatTokens(figures.total, locale)
165
+ if (breakdownRows(figures.breakdown).length > 0) return 'Usage'
166
+ if (figures.cost && isFigure(figures.cost.amount)) return formatCost(figures.cost, locale)
167
+ return undefined
168
+ }