@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 @@
1
+ {"version":3,"file":"test-results.js","names":["Check","CircleCheck","CircleMinus","CircleX","Copy","FlaskConical","LoaderCircle","createComputed","createMemo","createEffect","createSignal","For","Show","splitProps","Accessor","ComponentProps","JSX","writeClipboardText","cn","Button","DiffBlock","Trace","TraceDetail","TraceLine","TraceStatus","StackTrace","StackTraceProps","boundedEntries","describeCount","firstFailureRenderPath","formatDuration","listedCounts","reconcileCounts","sameFailure","siblingKey","suiteState","CountLine","TestCase","TestCaseStatus","TestOutcome","TestSuite","TestSummary","FirstFailureRenderPath","TestResultsProps","Omit","suites","summary","running","listLimit","onOpenFrame","label","TEST_RESULTS_LIST_LIMIT","OUTCOME_ICON","Readonly","Record","Element","failed","_$createComponent","passed","skipped","CountReadout","props","line","_el$","_tmpl$","_$insert","outcome","_$effect","_$setAttribute","SEGMENT_CLASS","SummaryBar","lines","visible","filter","count","when","length","children","_el$2","_tmpl$2","each","_el$3","_tmpl$3","_p$","_v$","_v$2","e","_$className","t","_$setStyleProperty","undefined","TRACE_STATUS","status","pending","keepFocusThroughReorder","keys","noted","HTMLElement","active","document","activeElement","closest","element","isConnected","body","focus","preventScroll","Bounded","items","T","itemKey","item","index","limit","noun","key","shown","setShown","page","entries","visibleKeys","map","entry","hidden","byKey","get","_el$4","_tmpl$4","variant","size","onClick","_$memo","Math","min","toLocaleString","TEST_RESULTS_MESSAGE_LIMIT","FailureMessage","text","onCopy","ok","all","setAll","copied","setCopied","copyFailed","setCopyFailed","clipped","cut","last","charCodeAt","slice","copy","setTimeout","_el$5","_tmpl$5","_el$6","_tmpl$6","_el$7","firstChild","fallback","title","TestLine","test","keyed","failure","state","hasDetail","Boolean","message","diff","stack","failureKey","equals","open","setOpen","previousFailure","collapsedFailure","currentFailure","handleOpenChange","next","name","statusLabel","meta","durationMs","onOpenChange","patch","complete","SuiteLine","suite","depth","counts","tests","holdsFailure","description","parts","file","join","icon","_el$8","_tmpl$7","aria-label","_index","nested","TestResults","local","rest","listed","max","floor","duration","nothing","reportedTotal","_el$9","_tmpl$11","_$spread","_$mergeProps","aria-busy","class","_tmpl$12","_el$0","_tmpl$10","_el$1","_el$10","_tmpl$8","_el$11","totalNote","_el$12","_tmpl$9","_el$13","note","_el$18","_tmpl$13","_el$19","_el$21","nextSibling","_el$20","reported","_el$14","_tmpl$0","_el$15","basis","_tmpl$1","_$createComponent","_$setAttribute","_$className","_$setStyleProperty","_$memo","_$mergeProps"],"sources":["../../../../src/components/composites/test-results/test-results.tsx"],"sourcesContent":["import {\n Check,\n CircleCheck,\n CircleMinus,\n CircleX,\n Copy,\n FlaskConical,\n LoaderCircle,\n} from 'lucide-solid'\nimport {\n createComputed,\n createMemo,\n createEffect,\n createSignal,\n For,\n Show,\n splitProps,\n type Accessor,\n type ComponentProps,\n type JSX,\n} from 'solid-js'\nimport { writeClipboardText } from '#lib/clipboard'\nimport { cn } from '#lib/utils'\nimport { Button } from '../../ui/button'\nimport { DiffBlock } from '../../ui/diff-block'\nimport { Trace, TraceDetail, TraceLine, type TraceStatus } from '../../ui/trace'\nimport { StackTrace, type StackTraceProps } from '../stack-trace'\nimport {\n boundedEntries,\n describeCount,\n firstFailureRenderPath,\n formatDuration,\n listedCounts,\n reconcileCounts,\n sameFailure,\n siblingKey,\n suiteState,\n type CountLine,\n type TestCase,\n type TestCaseStatus,\n type TestOutcome,\n type TestSuite,\n type TestSummary,\n type FirstFailureRenderPath,\n} from './test-results-model'\n\n/**\n * TestResults.\n *\n * A test run: how it went in words and in a segmented bar, then the suites it\n * ran as `Trace` lines, each opening onto its tests, and a failing test opening\n * onto its message, diff and stack. It is for a run the host can structure; reach\n * for `Terminal` when all there is to show is the command's output, and for\n * `StackTrace` alone when one call failed outside a test.\n *\n * ## Counts are claims\n *\n * Nothing is computed that the host did not supply data for, and nothing the host\n * supplied is quietly recomputed. `summary` is the host's own tally and is shown\n * as given. If tests are listed and their number for an outcome does not match, the\n * listed number is shown beside it — \"40 passed (2 listed)\" — which is also how a\n * host that lists only its failures reads. Without a `summary` the counts shown are\n * those of the tests listed, and the component says so; it does not present them as\n * the run's totals. A suite is marked failed or passed only from the tests listed in\n * it, and its spoken label says \"listed\" so it claims no more than that.\n *\n * ## Not colour-only\n *\n * The bar is decoration: every segment has a counterpart in the words beside it,\n * each with its own shape (a cross, a tick, a dash). Segments are separated by a\n * gap and never narrower than a visible sliver, so one failure in five thousand\n * tests is still on the bar.\n *\n * ## Bounded\n *\n * Suites and tests are listed `listLimit` at a time with \"show more\", and a suite's\n * tests are not rendered until it is open. The first failure in reading order opens\n * when its row is visible; a failure beyond a \"show more\" boundary stays unmounted\n * until its page is revealed. When a running result first reports a failure, its\n * suite and test open once. Later updates preserve the user's disclosure choices.\n *\n * Failure details are text: the message is a `pre`, the diff goes to `DiffBlock`\n * and the stack to `StackTrace`. If a stack already begins with the message, pass\n * only the stack; nothing here de-duplicates what the host sends.\n */\nexport type TestResultsProps = Omit<ComponentProps<'section'>, 'children'> & {\n suites: readonly TestSuite[]\n /** The host's own counts. Shown as given; see the component comment. */\n summary?: TestSummary\n /** The run is still going. */\n running?: boolean\n /** Suites, or tests within a suite, listed before \"show more\". Default 50. */\n listLimit?: number\n /** Passed to each failure's `StackTrace`. */\n onOpenFrame?: StackTraceProps['onOpenFrame']\n /** The section's accessible name. Default \"Test results\". */\n label?: string\n}\n\nexport const TEST_RESULTS_LIST_LIMIT = 50\n\nconst OUTCOME_ICON: Readonly<Record<TestOutcome, () => JSX.Element>> = {\n failed: () => <CircleX aria-hidden=\"true\" class=\"size-3.5 text-destructive\" />,\n passed: () => <CircleCheck aria-hidden=\"true\" class=\"size-3.5 text-success\" />,\n skipped: () => <CircleMinus aria-hidden=\"true\" class=\"size-3.5 text-muted-foreground\" />,\n}\n\nfunction CountReadout(props: { line: CountLine }) {\n return (\n <span class=\"flex items-center gap-1 whitespace-nowrap\" data-outcome={props.line.outcome}>\n {OUTCOME_ICON[props.line.outcome]()}\n {describeCount(props.line)}\n </span>\n )\n}\n\n// Segments are drawn in this order so the bar reads the same in every run.\nconst SEGMENT_CLASS: Readonly<Record<TestOutcome, string>> = {\n failed: 'bg-destructive',\n passed: 'bg-success',\n skipped: 'bg-muted-foreground/40',\n}\n\nfunction SummaryBar(props: { lines: readonly CountLine[] }) {\n const visible = () => props.lines.filter((line) => line.count > 0)\n return (\n <Show when={visible().length > 0}>\n <div\n aria-hidden=\"true\"\n data-slot=\"test-results-bar\"\n class=\"flex h-1.5 w-full gap-px overflow-hidden rounded-full bg-muted\"\n >\n <For each={visible()}>\n {(line) => (\n <span\n class={cn('min-w-1', SEGMENT_CLASS[line.outcome])}\n style={{ flex: `${line.count} 1 0` }}\n />\n )}\n </For>\n </div>\n </Show>\n )\n}\n\nconst TRACE_STATUS: Readonly<Record<TestCaseStatus, { status: TraceStatus; label: string }>> = {\n passed: { status: 'success', label: 'Passed' },\n failed: { status: 'error', label: 'Failed' },\n skipped: { status: 'cancelled', label: 'Skipped' },\n running: { status: 'running', label: 'Running' },\n pending: { status: 'pending', label: 'Not run yet' },\n}\n\n/**\n * Keep keyboard focus through a reorder. Solid moves a keyed row's node instead\n * of replacing it, and a browser blurs a focused element that is moved, so an\n * immutable reorder would drop the reader's place onto the body even though the\n * node and its open state survive. The focused element is noted just before the\n * rows move and given focus back just after, but only when nothing else has taken\n * focus meanwhile, and only inside a test run, so a reader who has moved on is\n * never pulled back and an unrelated element is never refocused.\n */\nfunction keepFocusThroughReorder(keys: Accessor<readonly string[]>) {\n let noted: HTMLElement | undefined\n createComputed(() => {\n keys()\n const active = typeof document === 'undefined' ? null : document.activeElement\n noted =\n active instanceof HTMLElement && active.closest('[data-slot=\"test-results\"]')\n ? active\n : undefined\n })\n createEffect(() => {\n keys()\n const element = noted\n noted = undefined\n if (!element || !element.isConnected) return\n const active = document.activeElement\n if (active === null || active === document.body) element.focus({ preventScroll: true })\n })\n}\n\n/** A list that shows its first `limit` items and offers the rest. */\nfunction Bounded<T>(props: {\n items: readonly T[]\n itemKey: (item: T, index: number) => string\n limit: number\n noun: string\n children: (item: Accessor<T>, index: Accessor<number>, key: string) => JSX.Element\n}) {\n const [shown, setShown] = createSignal(props.limit)\n const page = createMemo(() => boundedEntries(props.items, shown(), props.itemKey))\n const visible = () => page().entries\n const visibleKeys = createMemo(() => visible().map((entry) => entry.key))\n keepFocusThroughReorder(visibleKeys)\n const hidden = () => props.items.length - visible().length\n return (\n <>\n <For each={visibleKeys()}>\n {(key) => {\n const entry = createMemo(() => page().byKey.get(key)!)\n return props.children(\n () => entry().item,\n () => entry().index,\n key\n )\n }}\n </For>\n <Show when={hidden() > 0}>\n <li class=\"px-1.5 py-0.5\">\n <Button variant=\"ghost\" size=\"2xs\" onClick={() => setShown(shown() + props.limit)}>\n Show {Math.min(hidden(), props.limit).toLocaleString()} more {props.noun} (\n {hidden().toLocaleString()} hidden)\n </Button>\n </li>\n </Show>\n </>\n )\n}\n\n/** Characters of a failure message drawn before the rest is offered. */\nexport const TEST_RESULTS_MESSAGE_LIMIT = 4_000\n\n/**\n * A failed test's message, which a runner may print at any length: a captured\n * log, a serialized object, a long assertion. It opens on its own for the first\n * failure, so it is bounded where the diff and stack are already bounded: the\n * body scrolls past a fixed height, only the first characters are drawn until the\n * reader asks for the rest, and Copy writes all of it.\n */\nfunction FailureMessage(props: { text: string; onCopy?: (ok: boolean) => void }) {\n const [all, setAll] = createSignal(false)\n const [copied, setCopied] = createSignal(false)\n const [copyFailed, setCopyFailed] = createSignal(false)\n const clipped = () => props.text.length > TEST_RESULTS_MESSAGE_LIMIT\n const cut = () => {\n // Never inside a surrogate pair, which would draw a replacement character.\n const last = props.text.charCodeAt(TEST_RESULTS_MESSAGE_LIMIT - 1)\n return last >= 0xd800 && last <= 0xdbff\n ? TEST_RESULTS_MESSAGE_LIMIT - 1\n : TEST_RESULTS_MESSAGE_LIMIT\n }\n const shown = () => (clipped() && !all() ? props.text.slice(0, cut()) : props.text)\n const copy = async () => {\n let ok = true\n try {\n await writeClipboardText(props.text)\n } catch {\n ok = false\n }\n setCopied(ok)\n setCopyFailed(!ok)\n props.onCopy?.(ok)\n if (ok) setTimeout(() => setCopied(false), 1500)\n }\n return (\n <>\n {/* A region that scrolls is a tab stop and needs a name. */}\n <pre\n data-slot=\"test-results-message\"\n tabindex=\"0\"\n role=\"group\"\n aria-label=\"Failure message\"\n class=\"m-0 max-h-64 overflow-auto font-code text-code whitespace-pre-wrap text-foreground [overflow-wrap:anywhere]\"\n >\n {shown()}\n </pre>\n <Show when={clipped()}>\n <div class=\"flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground\">\n <span class=\"italic\">\n <Show\n when={!all()}\n fallback={`All ${props.text.length.toLocaleString()} characters shown.`}\n >\n Showing the first {cut().toLocaleString()} of {props.text.length.toLocaleString()}{' '}\n characters (copy has all of it).\n </Show>\n </span>\n <Show when={!all()}>\n <Button variant=\"ghost\" size=\"2xs\" onClick={() => setAll(true)}>\n Show all {props.text.length.toLocaleString()} characters\n </Button>\n </Show>\n <Button\n variant=\"ghost\"\n size=\"2xs\"\n title={copyFailed() ? 'Copying is unavailable in this context' : undefined}\n onClick={() => void copy()}\n >\n <Show when={copied()} fallback={<Copy aria-hidden=\"true\" />}>\n <Check aria-hidden=\"true\" />\n </Show>\n {copied() ? 'Copied' : 'Copy message'}\n </Button>\n </div>\n </Show>\n </>\n )\n}\n\nfunction TestLine(props: {\n test: Accessor<TestCase>\n keyed: string\n failure?: FirstFailureRenderPath\n onOpenFrame?: TestResultsProps['onOpenFrame']\n}) {\n const test = () => props.test()\n const state = () => (test().status ? TRACE_STATUS[test().status as TestCaseStatus] : undefined)\n // Whether there is anything to disclose. Read once per change, so the disclosure\n // exists while closed without anything below it being built.\n const hasDetail = createMemo(() => Boolean(test().message || test().diff || test().stack))\n // Only the last suite on the failure's path is given it, so a key among\n // this suite's tests is enough to know the failure is this test.\n const failureKey = createMemo(\n () => (props.failure?.test === props.keyed ? props.failure : undefined),\n undefined,\n { equals: sameFailure }\n )\n const [open, setOpen] = createSignal(failureKey() !== undefined)\n let previousFailure = failureKey()\n let collapsedFailure: FirstFailureRenderPath | undefined\n\n createEffect(() => {\n const currentFailure = failureKey()\n if (\n currentFailure &&\n !sameFailure(currentFailure, previousFailure) &&\n !sameFailure(currentFailure, collapsedFailure)\n ) {\n setOpen(true)\n }\n previousFailure = currentFailure\n })\n\n const handleOpenChange = (next: boolean) => {\n if (!next && failureKey()) collapsedFailure = failureKey()\n else if (next) collapsedFailure = undefined\n setOpen(next)\n }\n\n return (\n <TraceLine\n title={test().name}\n status={state()?.status}\n statusLabel={state()?.label}\n meta={formatDuration(test().durationMs)}\n open={open()}\n onOpenChange={handleOpenChange}\n >\n {hasDetail() ? (\n // A closed test builds nothing: the body is made when it is opened, so a diff or\n // stack is not parsed for every test of an open suite.\n <Show when={open()}>\n <TraceDetail class=\"flex flex-col gap-2\">\n <Show when={test().message}>\n <FailureMessage text={test().message!} />\n </Show>\n <Show when={test().diff}>\n <DiffBlock patch={test().diff!} complete title=\"Expected and received\" />\n </Show>\n <Show when={test().stack}>\n <StackTrace text={test().stack!} onOpenFrame={props.onOpenFrame} />\n </Show>\n </TraceDetail>\n </Show>\n ) : undefined}\n </TraceLine>\n )\n}\n\nfunction SuiteLine(props: {\n suite: Accessor<TestSuite>\n /** This suite's key among its siblings. */\n keyed: string\n /** How many suites enclose this one. */\n depth: number\n limit: number\n /** The first failure, given only to suites on the way to it. */\n failure?: FirstFailureRenderPath\n onOpenFrame?: TestResultsProps['onOpenFrame']\n}) {\n const suite = () => props.suite()\n const counts = createMemo(() => listedCounts([suite()]))\n const state = createMemo(() => suiteState(counts()))\n const children = () => (suite().tests?.length ?? 0) + (suite().suites?.length ?? 0) > 0\n const [open, setOpen] = createSignal(state() === 'failed')\n // The parent passes the failure down only while it is on the way to it, so\n // one comparison at this suite's own depth settles whether it is on the path.\n // Memoised: each level reads its parent's, so a bare function would re-run the\n // whole chain above it on every read and cost exponential time in the depth.\n const failure = createMemo(\n () => (props.failure?.suites[props.depth] === props.keyed ? props.failure : undefined),\n undefined,\n { equals: sameFailure }\n )\n const holdsFailure = createMemo(() => failure()?.suites.length === props.depth + 1)\n let previousFailure = failure()\n let collapsedFailure: FirstFailureRenderPath | undefined\n\n createEffect(() => {\n const currentFailure = failure()\n if (\n currentFailure &&\n !sameFailure(currentFailure, previousFailure) &&\n !sameFailure(currentFailure, collapsedFailure)\n ) {\n setOpen(true)\n }\n previousFailure = currentFailure\n })\n\n const handleOpenChange = (next: boolean) => {\n if (!next && failure()) collapsedFailure = failure()\n else if (next) collapsedFailure = undefined\n setOpen(next)\n }\n\n const description = () => {\n const parts = [\n suite().file,\n counts().failed > 0 ? `${counts().failed.toLocaleString()} failed` : undefined,\n ]\n return parts.filter(Boolean).join(' · ') || undefined\n }\n return (\n <TraceLine\n icon={<FlaskConical />}\n title={suite().name}\n description={description()}\n status={\n state() === 'failed'\n ? 'error'\n : state() === 'running'\n ? 'running'\n : state() === 'passed'\n ? 'success'\n : undefined\n }\n statusLabel={\n state() === 'failed'\n ? 'Has failing tests'\n : state() === 'passed'\n ? 'All listed tests passed'\n : undefined\n }\n meta={formatDuration(suite().durationMs)}\n open={open()}\n onOpenChange={handleOpenChange}\n >\n {children() ? (\n <div>\n <Show when={open()}>\n <Trace size=\"sm\" aria-label={`${suite().name} tests`}>\n <Bounded\n items={suite().tests ?? []}\n itemKey={siblingKey}\n limit={props.limit}\n noun=\"tests\"\n >\n {(test, _index, key) => (\n <TestLine\n test={test}\n keyed={key}\n failure={holdsFailure() ? failure() : undefined}\n onOpenFrame={props.onOpenFrame}\n />\n )}\n </Bounded>\n <Bounded\n items={suite().suites ?? []}\n itemKey={siblingKey}\n limit={props.limit}\n noun=\"suites\"\n >\n {(nested, _index, key) => (\n <SuiteLine\n suite={nested}\n keyed={key}\n depth={props.depth + 1}\n limit={props.limit}\n failure={failure()}\n onOpenFrame={props.onOpenFrame}\n />\n )}\n </Bounded>\n </Trace>\n </Show>\n </div>\n ) : undefined}\n </TraceLine>\n )\n}\n\nexport function TestResults(props: TestResultsProps) {\n const [local, rest] = splitProps(props, [\n 'suites',\n 'summary',\n 'running',\n 'listLimit',\n 'onOpenFrame',\n 'label',\n 'class',\n ])\n\n const listed = createMemo(() => listedCounts(local.suites))\n const counts = createMemo(() => reconcileCounts(local.summary, listed()))\n const limit = () => Math.max(1, Math.floor(local.listLimit ?? TEST_RESULTS_LIST_LIMIT))\n const failure = createMemo(() => firstFailureRenderPath(local.suites), undefined, {\n equals: sameFailure,\n })\n const duration = () => formatDuration(local.summary?.durationMs, 'long')\n const nothing = () =>\n counts().lines.length === 0 &&\n counts().reportedTotal === undefined &&\n local.suites.length === 0 &&\n !local.running\n\n return (\n <section\n data-slot=\"test-results\"\n aria-label={local.label ?? 'Test results'}\n aria-busy={local.running || undefined}\n class={cn('flex min-w-0 flex-col gap-2', local.class)}\n {...rest}\n >\n <Show\n when={!nothing()}\n fallback={<p class=\"m-0 text-sm text-muted-foreground\">No test results</p>}\n >\n <div class=\"flex flex-col gap-1.5\">\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-sm\">\n <Show when={local.running}>\n <span class=\"flex items-center gap-1 text-info\">\n <LoaderCircle aria-hidden=\"true\" class=\"size-3.5 motion-safe:animate-spin\" />\n Running\n </span>\n </Show>\n <For each={counts().lines}>{(line) => <CountReadout line={line} />}</For>\n <Show\n when={\n counts().lines.length === 0 &&\n !counts().totalNote &&\n counts().reportedTotal !== undefined\n }\n >\n <span class=\"text-muted-foreground\">\n {counts().reportedTotal?.toLocaleString()} tests reported\n </span>\n </Show>\n <Show when={counts().totalNote}>\n {(note) => (\n <span class=\"text-muted-foreground\">\n {note().reported.toLocaleString()} tests reported (\n {note().listed.toLocaleString()} listed)\n </span>\n )}\n </Show>\n <Show when={duration()}>\n <span class=\"text-muted-foreground\">in {duration()}</span>\n </Show>\n </div>\n <SummaryBar lines={counts().lines} />\n <Show when={counts().basis === 'listed' && counts().lines.length > 0}>\n <p class=\"m-0 text-xs text-muted-foreground\">Counts are from the tests listed below.</p>\n </Show>\n </div>\n <Show when={local.suites.length > 0}>\n <Trace aria-label=\"Test suites\">\n <Bounded items={local.suites} itemKey={siblingKey} limit={limit()} noun=\"suites\">\n {(suite, _index, key) => (\n <SuiteLine\n suite={suite}\n keyed={key}\n depth={0}\n limit={limit()}\n failure={failure()}\n onOpenFrame={local.onOpenFrame}\n />\n )}\n </Bounded>\n </Trace>\n </Show>\n </Show>\n </section>\n )\n}\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Turning a tool's input or output into text, safely.
3
+ *
4
+ * A tool call's payload is whatever the model sent and whatever the tool
5
+ * returned: it can be a megabyte of log, an object that refers to itself, a
6
+ * `BigInt` (which `JSON.stringify` throws on), or a getter that throws. A
7
+ * transcript component that calls `JSON.stringify` on that and renders the result
8
+ * is one hostile payload away from a frozen tab or a blank page, so this is a
9
+ * small serializer of our own rather than a call to the built-in one:
10
+ *
11
+ * - **It never throws.** Anything it cannot read becomes a marker string.
12
+ * - **It stops early.** Output is written into a budget of `maxChars`; the moment
13
+ * the budget is spent it stops walking, so the cost is bounded by the budget and
14
+ * not by the size of the value.
15
+ * - **It says when it stopped.** `truncated` is true whenever text was cut, so the
16
+ * caller can tell the reader the view is partial instead of passing off a cut
17
+ * JSON document as the whole thing.
18
+ * - **It does not lie about types.** Values JSON cannot carry are written as what
19
+ * they are (`12n`, `undefined`, `NaN`) rather than coerced to `null`, which
20
+ * would read as the tool having returned null.
21
+ *
22
+ * Strings are returned as given, not quoted and not re-parsed: re-serializing a
23
+ * JSON string would silently round numbers beyond double precision.
24
+ */
25
+ export type ToolValueText = Readonly<{
26
+ text: string;
27
+ /** `json` for structured values, `text` for strings and anything that is not JSON. */
28
+ language: 'json' | 'text';
29
+ /** True when `text` is only the start of the value. */
30
+ truncated: boolean;
31
+ }>;
32
+ /** Characters shown per section unless the caller says otherwise. */
33
+ export declare const TOOL_VALUE_MAX_CHARS = 20000;
34
+ export declare function formatToolValue(value: unknown, options?: {
35
+ maxChars?: number;
36
+ }): ToolValueText;
37
+ //# sourceMappingURL=format-tool-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-tool-value.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/tool/format-tool-value.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,sFAAsF;IACtF,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,QAAS,CAAA;AAoJ1C,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,aAAa,CAoCf"}
@@ -0,0 +1,135 @@
1
+ //#region src/components/composites/tool/format-tool-value.ts
2
+ /** Characters shown per section unless the caller says otherwise. */
3
+ var TOOL_VALUE_MAX_CHARS = 2e4;
4
+ /** Nesting deeper than this is written as a marker. */
5
+ var MAX_DEPTH = 12;
6
+ var BudgetSpent = class extends Error {};
7
+ function write(writer, chunk) {
8
+ writer.out.push(chunk);
9
+ writer.length += chunk.length;
10
+ if (writer.length > writer.max) throw new BudgetSpent();
11
+ }
12
+ /** A JSON string literal, without stringifying more than the budget could hold. */
13
+ function quote(writer, value) {
14
+ const room = Math.max(0, writer.max - writer.length);
15
+ return value.length > room + 1 ? JSON.stringify(value.slice(0, room + 1)).slice(0, -1) : JSON.stringify(value);
16
+ }
17
+ function describeNonJson(value) {
18
+ switch (typeof value) {
19
+ case "undefined": return "undefined";
20
+ case "bigint": return `${value}n`;
21
+ case "symbol": return value.toString();
22
+ case "function": return `[Function${value.name ? ` ${value.name}` : ""}]`;
23
+ default: return String(value);
24
+ }
25
+ }
26
+ /** At most `limit` items: each costs at least a character, so more could never be shown. */
27
+ function take(source, limit) {
28
+ const taken = [];
29
+ for (const item of source) {
30
+ if (taken.length > limit) break;
31
+ taken.push(item);
32
+ }
33
+ return taken;
34
+ }
35
+ function readEntries(value, limit) {
36
+ const entries = [];
37
+ for (const key of Object.keys(value).slice(0, limit + 1)) try {
38
+ entries.push([key, value[key]]);
39
+ } catch {
40
+ entries.push([key, "[Unreadable]"]);
41
+ }
42
+ return entries;
43
+ }
44
+ function writeValue(writer, value, depth, ancestors) {
45
+ if (value === null) return write(writer, "null");
46
+ if (typeof value === "string") return write(writer, quote(writer, value));
47
+ if (typeof value === "number") return write(writer, Number.isFinite(value) ? JSON.stringify(value) : String(value));
48
+ if (typeof value === "boolean") return write(writer, String(value));
49
+ if (typeof value !== "object") {
50
+ const text = describeNonJson(value);
51
+ return write(writer, typeof value === "bigint" || typeof value === "undefined" ? text : quote(writer, text));
52
+ }
53
+ if (ancestors.includes(value)) return write(writer, "\"[Circular]\"");
54
+ let subject = value;
55
+ if (!Array.isArray(value) && typeof value.toJSON === "function") {
56
+ try {
57
+ subject = value.toJSON();
58
+ } catch {
59
+ return write(writer, "\"[Unreadable]\"");
60
+ }
61
+ if (typeof subject !== "object" || subject === null) return writeValue(writer, subject, depth, ancestors);
62
+ }
63
+ const node = subject;
64
+ if (ArrayBuffer.isView(node) || node instanceof ArrayBuffer) return write(writer, quote(writer, `[${node.constructor.name}: ${node.byteLength.toLocaleString("en")} bytes]`));
65
+ let items;
66
+ let fields;
67
+ if (Array.isArray(node)) items = node;
68
+ else if (node instanceof Set) items = take(node, writer.max);
69
+ else if (node instanceof Map) items = take(node, writer.max).map(([key, entry]) => [key, entry]);
70
+ else if (node instanceof Error) fields = [["name", node.name], ["message", node.message]];
71
+ else fields = readEntries(node, writer.max);
72
+ if (depth >= MAX_DEPTH) return write(writer, quote(writer, items ? `[Array(${items.length})]` : "[Object]"));
73
+ const nested = [...ancestors, value];
74
+ const indent = " ".repeat(depth + 1);
75
+ const closing = " ".repeat(depth);
76
+ if (items) {
77
+ if (items.length === 0) return write(writer, "[]");
78
+ write(writer, "[\n");
79
+ for (let index = 0; index < items.length; index += 1) {
80
+ write(writer, indent);
81
+ writeValue(writer, items[index], depth + 1, nested);
82
+ write(writer, index < items.length - 1 ? ",\n" : "\n");
83
+ }
84
+ return write(writer, `${closing}]`);
85
+ }
86
+ const present = fields ?? [];
87
+ if (present.length === 0) return write(writer, "{}");
88
+ write(writer, "{\n");
89
+ present.forEach(([key, entry], index) => {
90
+ write(writer, `${indent}${quote(writer, key)}: `);
91
+ writeValue(writer, entry, depth + 1, nested);
92
+ write(writer, index < present.length - 1 ? ",\n" : "\n");
93
+ });
94
+ write(writer, `${closing}}`);
95
+ }
96
+ function formatToolValue(value, options = {}) {
97
+ const requested = options.maxChars;
98
+ const max = requested === void 0 || Number.isNaN(requested) ? TOOL_VALUE_MAX_CHARS : Math.max(0, Math.floor(requested));
99
+ if (typeof value === "string") return {
100
+ text: value.slice(0, max),
101
+ language: "text",
102
+ truncated: value.length > max
103
+ };
104
+ if (value === void 0 || typeof value === "symbol" || typeof value === "function") return {
105
+ text: describeNonJson(value).slice(0, max),
106
+ language: "text",
107
+ truncated: false
108
+ };
109
+ const writer = {
110
+ out: [],
111
+ length: 0,
112
+ max
113
+ };
114
+ let truncated = false;
115
+ try {
116
+ writeValue(writer, value, 0, []);
117
+ } catch (error) {
118
+ truncated = true;
119
+ if (!(error instanceof BudgetSpent) && writer.out.length === 0) return {
120
+ text: "[Unreadable]",
121
+ language: "text",
122
+ truncated: false
123
+ };
124
+ }
125
+ const joined = writer.out.join("");
126
+ return {
127
+ text: joined.length > max ? joined.slice(0, max) : joined,
128
+ language: "json",
129
+ truncated: truncated || joined.length > max
130
+ };
131
+ }
132
+ //#endregion
133
+ export { TOOL_VALUE_MAX_CHARS, formatToolValue };
134
+
135
+ //# sourceMappingURL=format-tool-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-tool-value.js","names":[],"sources":["../../../../src/components/composites/tool/format-tool-value.ts"],"sourcesContent":["/**\n * Turning a tool's input or output into text, safely.\n *\n * A tool call's payload is whatever the model sent and whatever the tool\n * returned: it can be a megabyte of log, an object that refers to itself, a\n * `BigInt` (which `JSON.stringify` throws on), or a getter that throws. A\n * transcript component that calls `JSON.stringify` on that and renders the result\n * is one hostile payload away from a frozen tab or a blank page, so this is a\n * small serializer of our own rather than a call to the built-in one:\n *\n * - **It never throws.** Anything it cannot read becomes a marker string.\n * - **It stops early.** Output is written into a budget of `maxChars`; the moment\n * the budget is spent it stops walking, so the cost is bounded by the budget and\n * not by the size of the value.\n * - **It says when it stopped.** `truncated` is true whenever text was cut, so the\n * caller can tell the reader the view is partial instead of passing off a cut\n * JSON document as the whole thing.\n * - **It does not lie about types.** Values JSON cannot carry are written as what\n * they are (`12n`, `undefined`, `NaN`) rather than coerced to `null`, which\n * would read as the tool having returned null.\n *\n * Strings are returned as given, not quoted and not re-parsed: re-serializing a\n * JSON string would silently round numbers beyond double precision.\n */\nexport type ToolValueText = Readonly<{\n text: string\n /** `json` for structured values, `text` for strings and anything that is not JSON. */\n language: 'json' | 'text'\n /** True when `text` is only the start of the value. */\n truncated: boolean\n}>\n\n/** Characters shown per section unless the caller says otherwise. */\nexport const TOOL_VALUE_MAX_CHARS = 20_000\n\n/** Nesting deeper than this is written as a marker. */\nconst MAX_DEPTH = 12\n\nclass BudgetSpent extends Error {}\n\ntype Writer = {\n out: string[]\n length: number\n max: number\n}\n\nfunction write(writer: Writer, chunk: string) {\n writer.out.push(chunk)\n writer.length += chunk.length\n if (writer.length > writer.max) throw new BudgetSpent()\n}\n\n/** A JSON string literal, without stringifying more than the budget could hold. */\nfunction quote(writer: Writer, value: string): string {\n const room = Math.max(0, writer.max - writer.length)\n // Past the budget the result is thrown away, so the tail need not be well formed.\n return value.length > room + 1\n ? JSON.stringify(value.slice(0, room + 1)).slice(0, -1)\n : JSON.stringify(value)\n}\n\nfunction describeNonJson(value: unknown): string {\n switch (typeof value) {\n case 'undefined':\n return 'undefined'\n case 'bigint':\n return `${value}n`\n case 'symbol':\n return value.toString()\n case 'function':\n return `[Function${value.name ? ` ${value.name}` : ''}]`\n default:\n return String(value)\n }\n}\n\n/** At most `limit` items: each costs at least a character, so more could never be shown. */\nfunction take<T>(source: Iterable<T>, limit: number): T[] {\n const taken: T[] = []\n for (const item of source) {\n if (taken.length > limit) break\n taken.push(item)\n }\n return taken\n}\n\nfunction readEntries(value: object, limit: number): [string, unknown][] {\n const entries: [string, unknown][] = []\n for (const key of Object.keys(value).slice(0, limit + 1)) {\n try {\n entries.push([key, (value as Record<string, unknown>)[key]])\n } catch {\n entries.push([key, '[Unreadable]'])\n }\n }\n return entries\n}\n\nfunction writeValue(writer: Writer, value: unknown, depth: number, ancestors: object[]) {\n if (value === null) return write(writer, 'null')\n if (typeof value === 'string') return write(writer, quote(writer, value))\n if (typeof value === 'number') {\n return write(writer, Number.isFinite(value) ? JSON.stringify(value) : String(value))\n }\n if (typeof value === 'boolean') return write(writer, String(value))\n if (typeof value !== 'object') {\n // bigint, undefined, symbol, function: written as what they are, in quotes\n // only where a bare token would be mistaken for the surrounding structure.\n const text = describeNonJson(value)\n return write(\n writer,\n typeof value === 'bigint' || typeof value === 'undefined' ? text : quote(writer, text)\n )\n }\n\n if (ancestors.includes(value)) return write(writer, '\"[Circular]\"')\n\n let subject: unknown = value\n if (!Array.isArray(value) && typeof (value as { toJSON?: unknown }).toJSON === 'function') {\n try {\n subject = (value as { toJSON: () => unknown }).toJSON()\n } catch {\n return write(writer, '\"[Unreadable]\"')\n }\n if (typeof subject !== 'object' || subject === null) {\n return writeValue(writer, subject, depth, ancestors)\n }\n }\n const node = subject as object\n\n if (ArrayBuffer.isView(node) || node instanceof ArrayBuffer) {\n return write(\n writer,\n quote(writer, `[${node.constructor.name}: ${node.byteLength.toLocaleString('en')} bytes]`)\n )\n }\n\n let items: unknown[] | undefined\n let fields: [string, unknown][] | undefined\n if (Array.isArray(node)) items = node\n else if (node instanceof Set) items = take(node, writer.max)\n else if (node instanceof Map) items = take(node, writer.max).map(([key, entry]) => [key, entry])\n else if (node instanceof Error) {\n fields = [\n ['name', node.name],\n ['message', node.message],\n ]\n } else fields = readEntries(node, writer.max)\n\n if (depth >= MAX_DEPTH) {\n return write(writer, quote(writer, items ? `[Array(${items.length})]` : '[Object]'))\n }\n\n const nested = [...ancestors, value]\n const indent = ' '.repeat(depth + 1)\n const closing = ' '.repeat(depth)\n\n if (items) {\n if (items.length === 0) return write(writer, '[]')\n write(writer, '[\\n')\n // Indexed rather than `forEach`, which skips the holes of a sparse array: a\n // million-slot hole would loop a million times without ever spending the budget.\n for (let index = 0; index < items.length; index += 1) {\n write(writer, indent)\n writeValue(writer, items[index], depth + 1, nested)\n write(writer, index < items.length - 1 ? ',\\n' : '\\n')\n }\n return write(writer, `${closing}]`)\n }\n\n const present = fields ?? []\n if (present.length === 0) return write(writer, '{}')\n write(writer, '{\\n')\n present.forEach(([key, entry], index) => {\n write(writer, `${indent}${quote(writer, key)}: `)\n writeValue(writer, entry, depth + 1, nested)\n write(writer, index < present.length - 1 ? ',\\n' : '\\n')\n })\n write(writer, `${closing}}`)\n}\n\nexport function formatToolValue(\n value: unknown,\n options: { maxChars?: number } = {}\n): ToolValueText {\n const requested = options.maxChars\n const max =\n requested === undefined || Number.isNaN(requested)\n ? TOOL_VALUE_MAX_CHARS\n : Math.max(0, Math.floor(requested))\n\n if (typeof value === 'string') {\n return {\n text: value.slice(0, max),\n language: 'text',\n truncated: value.length > max,\n }\n }\n if (value === undefined || typeof value === 'symbol' || typeof value === 'function') {\n return { text: describeNonJson(value).slice(0, max), language: 'text', truncated: false }\n }\n\n const writer: Writer = { out: [], length: 0, max }\n let truncated = false\n try {\n writeValue(writer, value, 0, [])\n } catch (error) {\n // Anything other than the budget running out is a bug in a getter or a proxy\n // we could not foresee; the reader still gets what was written so far.\n truncated = true\n if (!(error instanceof BudgetSpent) && writer.out.length === 0) {\n return { text: '[Unreadable]', language: 'text', truncated: false }\n }\n }\n const joined = writer.out.join('')\n return {\n text: joined.length > max ? joined.slice(0, max) : joined,\n language: 'json',\n truncated: truncated || joined.length > max,\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { Tool, TOOL_STATUS_LABELS, type ToolProps, type ToolStatus } from './tool';
2
+ export { formatToolValue, TOOL_VALUE_MAX_CHARS, type ToolValueText } from './format-tool-value';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/tool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAA;AAClF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { TOOL_VALUE_MAX_CHARS, formatToolValue } from "./format-tool-value.js";
2
+ import { TOOL_STATUS_LABELS, Tool } from "./tool.js";
3
+ export { TOOL_STATUS_LABELS, TOOL_VALUE_MAX_CHARS, Tool, formatToolValue };
@@ -0,0 +1,69 @@
1
+ import { type JSX } from 'solid-js';
2
+ import { type TraceLineProps } from '../../ui/trace';
3
+ /**
4
+ * Tool.
5
+ *
6
+ * One tool call, from what was asked to what came back, as a `TraceLine`: the
7
+ * tool's name and a short description on the line, and — when there is anything
8
+ * to show — an input section, an output section and an error underneath. Reach
9
+ * for `Subagent` when the "tool" is another agent with steps of its own, for a
10
+ * bare `CodeBlock` when the point is the output itself and not the call that made
11
+ * it, and for a confirmation (passed as `children`) when the reader has to decide
12
+ * something about the call.
13
+ *
14
+ * ## Everything is optional, and absence is not a claim
15
+ *
16
+ * A call with no `status` shows no mark at all — an event that merely arrived is
17
+ * not "done". `input`, `output` and `errorText` each render a section only when
18
+ * the host passed them: no empty "Output" box under a call that is still running,
19
+ * and no invented "No output" under one that failed. An error with no output is
20
+ * just the error. A call with nothing to expand is a plain line, not a
21
+ * disclosure that opens onto nothing.
22
+ *
23
+ * Two statuses are words, not only marks, because the glyphs for them are easy to
24
+ * misread: `awaiting-approval` and `denied` also show a badge. Both are spoken
25
+ * once (the badge is hidden from assistive technology and the status word is
26
+ * read in its place). A call awaiting approval opens by default, since it is the
27
+ * one state in which the reader has something to do. The component never decides
28
+ * whether an approval is allowed: the controls live in `children`, supplied by
29
+ * the host, or are absent.
30
+ *
31
+ * ## Payloads are untrusted and unbounded
32
+ *
33
+ * `input` and `output` are `unknown` — whatever the model sent and the tool
34
+ * returned. They go through `formatToolValue`, which cannot throw (circular
35
+ * references, `BigInt`, throwing getters) and stops after `maxChars`; a cut view
36
+ * says so rather than presenting half a document as the whole. Sections render in
37
+ * a small `CodeBlock` with a capped height. A string is shown as given; anything
38
+ * structured is pretty-printed JSON. The sections mount only when the line is
39
+ * opened, so a transcript of hundreds of calls formats none of them until asked.
40
+ *
41
+ * A `Tool` is a line: place it inside a `Trace`.
42
+ */
43
+ export type ToolStatus = 'pending' | 'running' | 'success' | 'error' | 'awaiting-approval' | 'denied' | 'cancelled';
44
+ /**
45
+ * The words spoken (and, for the last three, shown) for each status. `denied` is
46
+ * a decision about the call; `cancelled` is the run being stopped while the call
47
+ * was in flight. Give a call `cancelled` only when the host knows that call was
48
+ * stopped: a run ending does not by itself say what became of each call.
49
+ */
50
+ export declare const TOOL_STATUS_LABELS: Readonly<Record<ToolStatus, string>>;
51
+ export type ToolProps = Omit<TraceLineProps, 'title' | 'status' | 'statusLabel' | 'href' | 'onSelect' | 'selectHaspopup'> & {
52
+ /** The tool's name, as the host knows it. Rendered as text. */
53
+ name: string;
54
+ /** What this call is for: a path, a query, a command. */
55
+ description?: JSX.Element;
56
+ status?: ToolStatus;
57
+ /** What the model asked the tool to do. Any value; omit it to show no section. */
58
+ input?: unknown;
59
+ /** What the tool returned. Any value; omit it to show no section. */
60
+ output?: unknown;
61
+ /** The failure, as text. */
62
+ errorText?: string;
63
+ /** Characters of each section shown before it is cut. Defaults to 20,000. */
64
+ maxChars?: number;
65
+ /** Extra detail below the sections: an approval, a link to the full output. */
66
+ children?: JSX.Element;
67
+ };
68
+ export declare function Tool(props: ToolProps): JSX.Element;
69
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/tool/tool.tsx"],"names":[],"mappings":"AACA,OAAO,EAA6D,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAG9F,OAAO,EAA0B,KAAK,cAAc,EAAoB,MAAM,gBAAgB,CAAA;AAY9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,SAAS,GACT,SAAS,GACT,OAAO,GACP,mBAAmB,GACnB,QAAQ,GACR,WAAW,CAAA;AAEf;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAQnE,CAAA;AAYD,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,cAAc,EACd,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,gBAAgB,CAC5E,GAAG;IACF,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACzB,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAwCD,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,eA6EpC"}
@@ -0,0 +1,214 @@
1
+ import { Badge } from "../../ui/badge/badge.js";
2
+ import { CodeBlock } from "../../ui/code-block/code-block.js";
3
+ import { TraceDetail, TraceLine } from "../../ui/trace/trace.js";
4
+ import { formatToolValue } from "./format-tool-value.js";
5
+ import { createComponent, insert, memo, mergeProps, template } from "solid-js/web";
6
+ import { Wrench } from "lucide-solid";
7
+ import { Show, children, createMemo, splitProps } from "solid-js";
8
+ //#region src/components/composites/tool/tool.tsx
9
+ var _tmpl$ = /*#__PURE__*/ template(`<p class="m-0 px-1 text-xs text-muted-foreground">Showing the first <!> characters.`);
10
+ var _tmpl$2 = /*#__PURE__*/ template(`<div class="flex min-w-0 flex-col gap-1">`);
11
+ var _tmpl$3 = /*#__PURE__*/ template(`<span class="flex items-center gap-2">`);
12
+ /**
13
+ * `TraceLine` reads its children twice: once to decide whether the line can
14
+ * expand, and once to draw them when it is open. A function child is returned
15
+ * unevaluated by the first read and run once, when the content mounts, by the
16
+ * second — so a folded line builds none of its body. Solid's `insert` unwraps
17
+ * functions; the JSX types simply do not admit them.
18
+ */
19
+ var deferred = (render) => render;
20
+ /**
21
+ * The words spoken (and, for the last three, shown) for each status. `denied` is
22
+ * a decision about the call; `cancelled` is the run being stopped while the call
23
+ * was in flight. Give a call `cancelled` only when the host knows that call was
24
+ * stopped: a run ending does not by itself say what became of each call.
25
+ */
26
+ var TOOL_STATUS_LABELS = {
27
+ pending: "Pending",
28
+ running: "Running",
29
+ success: "Completed",
30
+ error: "Failed",
31
+ "awaiting-approval": "Awaiting approval",
32
+ denied: "Denied",
33
+ cancelled: "Cancelled"
34
+ };
35
+ var TRACE_STATUS = {
36
+ pending: "pending",
37
+ running: "running",
38
+ success: "success",
39
+ error: "error",
40
+ "awaiting-approval": "pending",
41
+ denied: "cancelled",
42
+ cancelled: "cancelled"
43
+ };
44
+ var SECTION_MAX_HEIGHT = "16rem";
45
+ function Section(props) {
46
+ const formatted = createMemo(() => formatToolValue(props.value, { maxChars: props.maxChars }));
47
+ const marks = createMemo(() => {
48
+ if (!props.failure) return void 0;
49
+ const lines = formatted().text.split("\n").length;
50
+ return Object.fromEntries(Array.from({ length: lines }, (_, index) => [index + 1, "error"]));
51
+ });
52
+ return (() => {
53
+ var _el$ = _tmpl$2();
54
+ insert(_el$, createComponent(CodeBlock, {
55
+ size: "sm",
56
+ get title() {
57
+ return props.title;
58
+ },
59
+ get language() {
60
+ return memo(() => !!props.failure)() ? "error" : formatted().language;
61
+ },
62
+ get code() {
63
+ return formatted().text;
64
+ },
65
+ get lineMarks() {
66
+ return marks();
67
+ },
68
+ get complete() {
69
+ return props.complete ?? true;
70
+ },
71
+ maxHeight: SECTION_MAX_HEIGHT,
72
+ get wrap() {
73
+ return formatted().language === "text";
74
+ }
75
+ }), null);
76
+ insert(_el$, createComponent(Show, {
77
+ get when() {
78
+ return formatted().truncated;
79
+ },
80
+ get children() {
81
+ var _el$2 = _tmpl$(), _el$5 = _el$2.firstChild.nextSibling;
82
+ _el$5.nextSibling;
83
+ insert(_el$2, () => props.maxChars.toLocaleString("en"), _el$5);
84
+ return _el$2;
85
+ }
86
+ }), null);
87
+ return _el$;
88
+ })();
89
+ }
90
+ function Tool(props) {
91
+ const [local, rest] = splitProps(props, [
92
+ "name",
93
+ "description",
94
+ "status",
95
+ "input",
96
+ "output",
97
+ "errorText",
98
+ "maxChars",
99
+ "icon",
100
+ "meta",
101
+ "defaultOpen",
102
+ "children"
103
+ ]);
104
+ const maxChars = () => local.maxChars ?? 2e4;
105
+ const hasInput = () => local.input !== void 0;
106
+ const hasOutput = () => local.output !== void 0;
107
+ const hasError = () => local.errorText !== void 0 && local.errorText !== "";
108
+ const extra = children(() => local.children);
109
+ const hasDetail = () => hasInput() || hasOutput() || hasError() || extra.toArray().length > 0;
110
+ const detail = () => createComponent(TraceDetail, {
111
+ "class": "flex flex-col gap-2",
112
+ get children() {
113
+ return [
114
+ createComponent(Show, {
115
+ get when() {
116
+ return hasInput();
117
+ },
118
+ get children() {
119
+ return createComponent(Section, {
120
+ title: "Input",
121
+ get value() {
122
+ return local.input;
123
+ },
124
+ get maxChars() {
125
+ return maxChars();
126
+ }
127
+ });
128
+ }
129
+ }),
130
+ createComponent(Show, {
131
+ get when() {
132
+ return hasOutput();
133
+ },
134
+ get children() {
135
+ return createComponent(Section, {
136
+ title: "Output",
137
+ get value() {
138
+ return local.output;
139
+ },
140
+ get maxChars() {
141
+ return maxChars();
142
+ },
143
+ get complete() {
144
+ return local.status !== "running";
145
+ }
146
+ });
147
+ }
148
+ }),
149
+ createComponent(Show, {
150
+ get when() {
151
+ return hasError();
152
+ },
153
+ get children() {
154
+ return createComponent(Section, {
155
+ title: "Error",
156
+ get value() {
157
+ return local.errorText;
158
+ },
159
+ get maxChars() {
160
+ return maxChars();
161
+ },
162
+ failure: true
163
+ });
164
+ }
165
+ }),
166
+ memo(() => extra())
167
+ ];
168
+ }
169
+ });
170
+ const wordBadge = () => local.status === "awaiting-approval" || local.status === "denied" || local.status === "cancelled" ? (() => {
171
+ var _el$6 = _tmpl$3();
172
+ insert(_el$6, createComponent(Badge, {
173
+ "aria-hidden": "true",
174
+ size: "sm",
175
+ get variant() {
176
+ return local.status === "awaiting-approval" ? "warning" : "outline";
177
+ },
178
+ get children() {
179
+ return TOOL_STATUS_LABELS[local.status];
180
+ }
181
+ }), null);
182
+ insert(_el$6, () => local.meta, null);
183
+ return _el$6;
184
+ })() : local.meta;
185
+ return createComponent(TraceLine, mergeProps({
186
+ get icon() {
187
+ return local.icon ?? createComponent(Wrench, {});
188
+ },
189
+ get title() {
190
+ return local.name;
191
+ },
192
+ get description() {
193
+ return local.description;
194
+ },
195
+ get status() {
196
+ return memo(() => !!local.status)() ? TRACE_STATUS[local.status] : void 0;
197
+ },
198
+ get statusLabel() {
199
+ return memo(() => !!local.status)() ? TOOL_STATUS_LABELS[local.status] : void 0;
200
+ },
201
+ get meta() {
202
+ return wordBadge();
203
+ },
204
+ get defaultOpen() {
205
+ return local.defaultOpen ?? local.status === "awaiting-approval";
206
+ }
207
+ }, rest, { get children() {
208
+ return memo(() => !!hasDetail())() ? deferred(detail) : void 0;
209
+ } }));
210
+ }
211
+ //#endregion
212
+ export { TOOL_STATUS_LABELS, Tool };
213
+
214
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","names":["Wrench","children","resolveChildren","createMemo","Show","splitProps","JSX","Badge","CodeBlock","CodeLineMark","TraceDetail","TraceLine","TraceLineProps","TraceStatus","formatToolValue","TOOL_VALUE_MAX_CHARS","deferred","render","Element","ToolStatus","TOOL_STATUS_LABELS","Readonly","Record","pending","running","success","error","denied","cancelled","TRACE_STATUS","ToolProps","Omit","name","description","status","input","output","errorText","maxChars","SECTION_MAX_HEIGHT","Section","props","title","value","complete","failure","formatted","marks","undefined","lines","text","split","length","Object","fromEntries","Array","from","_","index","_el$","_tmpl$2","_$insert","_$createComponent","size","language","_$memo","code","lineMarks","maxHeight","wrap","when","truncated","_el$2","_tmpl$","_el$3","firstChild","_el$5","nextSibling","_el$4","toLocaleString","Tool","local","rest","hasInput","hasOutput","hasError","extra","hasDetail","toArray","detail","wordBadge","_el$6","_tmpl$3","variant","meta","_$mergeProps","icon","statusLabel","defaultOpen","_$createComponent","_$memo","resolveChildren","_$mergeProps"],"sources":["../../../../src/components/composites/tool/tool.tsx"],"sourcesContent":["import { Wrench } from 'lucide-solid'\nimport { children as resolveChildren, createMemo, Show, splitProps, type JSX } from 'solid-js'\nimport { Badge } from '../../ui/badge'\nimport { CodeBlock, type CodeLineMark } from '../../ui/code-block'\nimport { TraceDetail, TraceLine, type TraceLineProps, type TraceStatus } from '../../ui/trace'\nimport { formatToolValue, TOOL_VALUE_MAX_CHARS } from './format-tool-value'\n\n/**\n * `TraceLine` reads its children twice: once to decide whether the line can\n * expand, and once to draw them when it is open. A function child is returned\n * unevaluated by the first read and run once, when the content mounts, by the\n * second — so a folded line builds none of its body. Solid's `insert` unwraps\n * functions; the JSX types simply do not admit them.\n */\nconst deferred = (render: () => JSX.Element) => render as unknown as JSX.Element\n\n/**\n * Tool.\n *\n * One tool call, from what was asked to what came back, as a `TraceLine`: the\n * tool's name and a short description on the line, and — when there is anything\n * to show — an input section, an output section and an error underneath. Reach\n * for `Subagent` when the \"tool\" is another agent with steps of its own, for a\n * bare `CodeBlock` when the point is the output itself and not the call that made\n * it, and for a confirmation (passed as `children`) when the reader has to decide\n * something about the call.\n *\n * ## Everything is optional, and absence is not a claim\n *\n * A call with no `status` shows no mark at all — an event that merely arrived is\n * not \"done\". `input`, `output` and `errorText` each render a section only when\n * the host passed them: no empty \"Output\" box under a call that is still running,\n * and no invented \"No output\" under one that failed. An error with no output is\n * just the error. A call with nothing to expand is a plain line, not a\n * disclosure that opens onto nothing.\n *\n * Two statuses are words, not only marks, because the glyphs for them are easy to\n * misread: `awaiting-approval` and `denied` also show a badge. Both are spoken\n * once (the badge is hidden from assistive technology and the status word is\n * read in its place). A call awaiting approval opens by default, since it is the\n * one state in which the reader has something to do. The component never decides\n * whether an approval is allowed: the controls live in `children`, supplied by\n * the host, or are absent.\n *\n * ## Payloads are untrusted and unbounded\n *\n * `input` and `output` are `unknown` — whatever the model sent and the tool\n * returned. They go through `formatToolValue`, which cannot throw (circular\n * references, `BigInt`, throwing getters) and stops after `maxChars`; a cut view\n * says so rather than presenting half a document as the whole. Sections render in\n * a small `CodeBlock` with a capped height. A string is shown as given; anything\n * structured is pretty-printed JSON. The sections mount only when the line is\n * opened, so a transcript of hundreds of calls formats none of them until asked.\n *\n * A `Tool` is a line: place it inside a `Trace`.\n */\nexport type ToolStatus =\n | 'pending'\n | 'running'\n | 'success'\n | 'error'\n | 'awaiting-approval'\n | 'denied'\n | 'cancelled'\n\n/**\n * The words spoken (and, for the last three, shown) for each status. `denied` is\n * a decision about the call; `cancelled` is the run being stopped while the call\n * was in flight. Give a call `cancelled` only when the host knows that call was\n * stopped: a run ending does not by itself say what became of each call.\n */\nexport const TOOL_STATUS_LABELS: Readonly<Record<ToolStatus, string>> = {\n pending: 'Pending',\n running: 'Running',\n success: 'Completed',\n error: 'Failed',\n 'awaiting-approval': 'Awaiting approval',\n denied: 'Denied',\n cancelled: 'Cancelled',\n}\n\nconst TRACE_STATUS: Readonly<Record<ToolStatus, TraceStatus>> = {\n pending: 'pending',\n running: 'running',\n success: 'success',\n error: 'error',\n 'awaiting-approval': 'pending',\n denied: 'cancelled',\n cancelled: 'cancelled',\n}\n\nexport type ToolProps = Omit<\n TraceLineProps,\n 'title' | 'status' | 'statusLabel' | 'href' | 'onSelect' | 'selectHaspopup'\n> & {\n /** The tool's name, as the host knows it. Rendered as text. */\n name: string\n /** What this call is for: a path, a query, a command. */\n description?: JSX.Element\n status?: ToolStatus\n /** What the model asked the tool to do. Any value; omit it to show no section. */\n input?: unknown\n /** What the tool returned. Any value; omit it to show no section. */\n output?: unknown\n /** The failure, as text. */\n errorText?: string\n /** Characters of each section shown before it is cut. Defaults to 20,000. */\n maxChars?: number\n /** Extra detail below the sections: an approval, a link to the full output. */\n children?: JSX.Element\n}\n\nconst SECTION_MAX_HEIGHT = '16rem'\n\nfunction Section(props: {\n title: string\n value: unknown\n maxChars: number\n complete?: boolean\n failure?: boolean\n}) {\n const formatted = createMemo(() => formatToolValue(props.value, { maxChars: props.maxChars }))\n // Every line is marked as an error rather than recolouring the block, which\n // keeps the mark in the gutter (a glyph, not colour alone) and the copy exact.\n const marks = createMemo((): Readonly<Record<number, CodeLineMark>> | undefined => {\n if (!props.failure) return undefined\n const lines = formatted().text.split('\\n').length\n return Object.fromEntries(Array.from({ length: lines }, (_, index) => [index + 1, 'error']))\n })\n return (\n <div class=\"flex min-w-0 flex-col gap-1\">\n <CodeBlock\n size=\"sm\"\n title={props.title}\n language={props.failure ? 'error' : formatted().language}\n code={formatted().text}\n lineMarks={marks()}\n complete={props.complete ?? true}\n maxHeight={SECTION_MAX_HEIGHT}\n wrap={formatted().language === 'text'}\n />\n <Show when={formatted().truncated}>\n <p class=\"m-0 px-1 text-xs text-muted-foreground\">\n Showing the first {props.maxChars.toLocaleString('en')} characters.\n </p>\n </Show>\n </div>\n )\n}\n\nexport function Tool(props: ToolProps) {\n const [local, rest] = splitProps(props, [\n 'name',\n 'description',\n 'status',\n 'input',\n 'output',\n 'errorText',\n 'maxChars',\n 'icon',\n 'meta',\n 'defaultOpen',\n 'children',\n ])\n const maxChars = () => local.maxChars ?? TOOL_VALUE_MAX_CHARS\n const hasInput = () => local.input !== undefined\n const hasOutput = () => local.output !== undefined\n const hasError = () => local.errorText !== undefined && local.errorText !== ''\n // Resolved once: a host's approval controls are created once and keep their\n // state and focus however often the line is folded.\n const extra = resolveChildren(() => local.children)\n const hasDetail = () => hasInput() || hasOutput() || hasError() || extra.toArray().length > 0\n\n const detail = () => (\n <TraceDetail class=\"flex flex-col gap-2\">\n <Show when={hasInput()}>\n <Section title=\"Input\" value={local.input} maxChars={maxChars()} />\n </Show>\n <Show when={hasOutput()}>\n <Section\n title=\"Output\"\n value={local.output}\n maxChars={maxChars()}\n complete={local.status !== 'running'}\n />\n </Show>\n <Show when={hasError()}>\n <Section title=\"Error\" value={local.errorText} maxChars={maxChars()} failure />\n </Show>\n {extra()}\n </TraceDetail>\n )\n\n // Words as well as marks for the states whose glyph is easy to misread. The\n // badge is hidden from assistive technology: the status word is already spoken.\n const wordBadge = () =>\n local.status === 'awaiting-approval' ||\n local.status === 'denied' ||\n local.status === 'cancelled' ? (\n <span class=\"flex items-center gap-2\">\n <Badge\n aria-hidden=\"true\"\n size=\"sm\"\n variant={local.status === 'awaiting-approval' ? 'warning' : 'outline'}\n >\n {TOOL_STATUS_LABELS[local.status]}\n </Badge>\n {local.meta}\n </span>\n ) : (\n local.meta\n )\n\n return (\n <TraceLine\n icon={local.icon ?? <Wrench />}\n title={local.name}\n description={local.description}\n status={local.status ? TRACE_STATUS[local.status] : undefined}\n statusLabel={local.status ? TOOL_STATUS_LABELS[local.status] : undefined}\n meta={wordBadge()}\n defaultOpen={local.defaultOpen ?? local.status === 'awaiting-approval'}\n {...rest}\n >\n {hasDetail() ? deferred(detail) : undefined}\n </TraceLine>\n )\n}\n"],"mappings":"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"}