@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,62 @@
1
+ import { type JSX } from 'solid-js';
2
+ import { type TraceLineProps } from '../../ui/trace';
3
+ /**
4
+ * Reasoning.
5
+ *
6
+ * The agent's thinking, as a `TraceLine`: a title that says what state it is in,
7
+ * and a body that is the text the host chose to show. Reach for `ChainOfThought`
8
+ * when the thinking is a sequence of discrete steps with their own status, and
9
+ * for a plain `MessageText` when the text is simply part of the answer.
10
+ *
11
+ * ## It shows what it is given, and nothing else
12
+ *
13
+ * `text` is whatever the host has decided is user-visible — a provider's reasoning
14
+ * summary, a model's visible scratchpad. This component never implies there is
15
+ * more behind it: no "show full reasoning" control, no placeholder body, no
16
+ * ellipsis standing in for hidden content. With no `text` and no `streaming` the
17
+ * line is a plain, non-expandable line titled "Reasoning", because there is
18
+ * nothing to open.
19
+ *
20
+ * ## The title is the state
21
+ *
22
+ * - `streaming` — "Thinking…", with the running mark and shimmer.
23
+ * - finished with a `duration` (seconds) — "Thought for 4s".
24
+ * - finished without one — "Reasoning". A duration the host did not measure is
25
+ * not invented.
26
+ *
27
+ * ## Open while it is arriving, closed once it is done
28
+ *
29
+ * While streaming the body is open so the reader can follow along; when the
30
+ * stream ends it folds away so the settled transcript stays one quiet column. The
31
+ * reader's own toggle wins in both directions and is remembered until the next
32
+ * stream begins, so someone who closed it mid-stream is not re-opened and
33
+ * someone who opened it afterwards is not folded. Pass `open` and `onOpenChange`
34
+ * to own the state instead.
35
+ *
36
+ * ## Bounded, and stable while it grows
37
+ *
38
+ * The body is `MessageText`, so the text is untrusted and rendered as text (see
39
+ * its doc comment), and earlier paragraphs keep their DOM while the last one
40
+ * grows. The scroller is capped; while streaming it follows the newest text only
41
+ * if the reader has not scrolled up, so reading the start of a long thought is
42
+ * not interrupted by the end of it.
43
+ */
44
+ /** `4` → `4s`, `65` → `1m 5s`. Nothing for a value that is not a finite duration. */
45
+ export declare function formatDuration(seconds: number | undefined): string | undefined;
46
+ /** The line's title for a state. Exported so a host can say the same thing elsewhere. */
47
+ export declare function reasoningTitle(state: {
48
+ streaming?: boolean;
49
+ duration?: number;
50
+ }): string;
51
+ export type ReasoningProps = Omit<TraceLineProps, 'title' | 'description' | 'status' | 'statusLabel' | 'defaultOpen' | 'children' | 'href' | 'onSelect' | 'selectHaspopup'> & {
52
+ /** The reasoning the host marked as user-visible. Untrusted text. */
53
+ text?: string;
54
+ /** True while text may still arrive. */
55
+ streaming?: boolean;
56
+ /** Seconds the thinking took, if the host measured it. */
57
+ duration?: number;
58
+ /** Replaces the state-derived title, e.g. for another language. */
59
+ title?: JSX.Element;
60
+ };
61
+ export declare function Reasoning(props: ReasoningProps): JSX.Element;
62
+ //# sourceMappingURL=reasoning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reasoning.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/reasoning/reasoning.tsx"],"names":[],"mappings":"AACA,OAAO,EAA8C,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAG/E,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAK5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAU9E;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIxF;AAKD,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,cAAc,EACZ,OAAO,GACP,aAAa,GACb,QAAQ,GACR,aAAa,GACb,aAAa,GACb,UAAU,GACV,MAAM,GACN,UAAU,GACV,gBAAgB,CACnB,GAAG;IACF,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,KAAK,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACpB,CAAA;AAkCD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,eA+C9C"}
@@ -0,0 +1,156 @@
1
+ import { MessageText } from "../../ui/message/message.js";
2
+ import { ScrollArea } from "../../ui/scroll-area/scroll-area.js";
3
+ import { TraceDetail, TraceLine } from "../../ui/trace/trace.js";
4
+ import { createComponent, memo, mergeProps } from "solid-js/web";
5
+ import { Brain } from "lucide-solid";
6
+ import { createEffect, createSignal, on, splitProps } from "solid-js";
7
+ //#region src/components/composites/reasoning/reasoning.tsx
8
+ var deferred = (render) => render;
9
+ /**
10
+ * Reasoning.
11
+ *
12
+ * The agent's thinking, as a `TraceLine`: a title that says what state it is in,
13
+ * and a body that is the text the host chose to show. Reach for `ChainOfThought`
14
+ * when the thinking is a sequence of discrete steps with their own status, and
15
+ * for a plain `MessageText` when the text is simply part of the answer.
16
+ *
17
+ * ## It shows what it is given, and nothing else
18
+ *
19
+ * `text` is whatever the host has decided is user-visible — a provider's reasoning
20
+ * summary, a model's visible scratchpad. This component never implies there is
21
+ * more behind it: no "show full reasoning" control, no placeholder body, no
22
+ * ellipsis standing in for hidden content. With no `text` and no `streaming` the
23
+ * line is a plain, non-expandable line titled "Reasoning", because there is
24
+ * nothing to open.
25
+ *
26
+ * ## The title is the state
27
+ *
28
+ * - `streaming` — "Thinking…", with the running mark and shimmer.
29
+ * - finished with a `duration` (seconds) — "Thought for 4s".
30
+ * - finished without one — "Reasoning". A duration the host did not measure is
31
+ * not invented.
32
+ *
33
+ * ## Open while it is arriving, closed once it is done
34
+ *
35
+ * While streaming the body is open so the reader can follow along; when the
36
+ * stream ends it folds away so the settled transcript stays one quiet column. The
37
+ * reader's own toggle wins in both directions and is remembered until the next
38
+ * stream begins, so someone who closed it mid-stream is not re-opened and
39
+ * someone who opened it afterwards is not folded. Pass `open` and `onOpenChange`
40
+ * to own the state instead.
41
+ *
42
+ * ## Bounded, and stable while it grows
43
+ *
44
+ * The body is `MessageText`, so the text is untrusted and rendered as text (see
45
+ * its doc comment), and earlier paragraphs keep their DOM while the last one
46
+ * grows. The scroller is capped; while streaming it follows the newest text only
47
+ * if the reader has not scrolled up, so reading the start of a long thought is
48
+ * not interrupted by the end of it.
49
+ */
50
+ /** `4` → `4s`, `65` → `1m 5s`. Nothing for a value that is not a finite duration. */
51
+ function formatDuration(seconds) {
52
+ if (seconds === void 0 || !Number.isFinite(seconds) || seconds < 0) return void 0;
53
+ const total = Math.round(seconds);
54
+ if (total === 0) return "<1s";
55
+ if (total < 60) return `${total}s`;
56
+ const hours = Math.floor(total / 3600);
57
+ const minutes = Math.floor(total % 3600 / 60);
58
+ const rest = total % 60;
59
+ if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
60
+ return rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`;
61
+ }
62
+ /** The line's title for a state. Exported so a host can say the same thing elsewhere. */
63
+ function reasoningTitle(state) {
64
+ if (state.streaming) return "Thinking…";
65
+ const duration = formatDuration(state.duration);
66
+ return duration ? `Thought for ${duration}` : "Reasoning";
67
+ }
68
+ /** Within this many pixels of the end counts as "following". */
69
+ var FOLLOW_SLOP = 16;
70
+ function ReasoningBody(props) {
71
+ let scroller;
72
+ let following = true;
73
+ createEffect(() => {
74
+ props.text;
75
+ if (props.streaming && following && scroller) scroller.scrollTop = scroller.scrollHeight;
76
+ });
77
+ return createComponent(TraceDetail, { get children() {
78
+ return createComponent(ScrollArea, {
79
+ ref: (element) => scroller = element,
80
+ role: "region",
81
+ "aria-label": "Reasoning text",
82
+ "class": "max-h-72",
83
+ onScroll: (event) => {
84
+ const element = event.currentTarget;
85
+ following = element.scrollHeight - element.scrollTop - element.clientHeight <= FOLLOW_SLOP;
86
+ },
87
+ get children() {
88
+ return createComponent(MessageText, {
89
+ get text() {
90
+ return props.text;
91
+ },
92
+ get streaming() {
93
+ return props.streaming;
94
+ },
95
+ codeBlockProps: {
96
+ maxHeight: "16rem",
97
+ wrap: true
98
+ }
99
+ });
100
+ }
101
+ });
102
+ } });
103
+ }
104
+ function Reasoning(props) {
105
+ const [local, rest] = splitProps(props, [
106
+ "text",
107
+ "streaming",
108
+ "duration",
109
+ "title",
110
+ "icon",
111
+ "open",
112
+ "onOpenChange"
113
+ ]);
114
+ const [chosen, setChosen] = createSignal();
115
+ const open = () => local.open ?? chosen() ?? local.streaming === true;
116
+ const hasBody = () => (local.text ?? "").trim() !== "" || local.streaming === true;
117
+ createEffect(on(() => local.streaming, (streaming) => {
118
+ if (streaming) setChosen(void 0);
119
+ }, { defer: true }));
120
+ const body = () => createComponent(ReasoningBody, {
121
+ get text() {
122
+ return local.text ?? "";
123
+ },
124
+ get streaming() {
125
+ return local.streaming;
126
+ }
127
+ });
128
+ return createComponent(TraceLine, mergeProps({
129
+ get icon() {
130
+ return local.icon ?? createComponent(Brain, {});
131
+ },
132
+ get title() {
133
+ return local.title ?? reasoningTitle({
134
+ streaming: local.streaming,
135
+ duration: local.duration
136
+ });
137
+ },
138
+ get status() {
139
+ return local.streaming ? "running" : void 0;
140
+ },
141
+ statusLabel: "In progress",
142
+ get open() {
143
+ return open();
144
+ },
145
+ onOpenChange: (value) => {
146
+ setChosen(value);
147
+ local.onOpenChange?.(value);
148
+ }
149
+ }, rest, { get children() {
150
+ return memo(() => !!hasBody())() ? deferred(body) : void 0;
151
+ } }));
152
+ }
153
+ //#endregion
154
+ export { Reasoning, formatDuration, reasoningTitle };
155
+
156
+ //# sourceMappingURL=reasoning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reasoning.js","names":["Brain","createEffect","createSignal","on","splitProps","JSX","MessageText","ScrollArea","TraceDetail","TraceLine","TraceLineProps","deferred","render","Element","formatDuration","seconds","undefined","Number","isFinite","total","Math","round","hours","floor","minutes","rest","reasoningTitle","state","streaming","duration","FOLLOW_SLOP","ReasoningProps","Omit","text","title","ReasoningBody","props","scroller","HTMLDivElement","following","scrollTop","scrollHeight","_$createComponent","children","ref","element","role","onScroll","event","currentTarget","clientHeight","codeBlockProps","maxHeight","wrap","Reasoning","local","chosen","setChosen","open","hasBody","trim","defer","body","_$mergeProps","icon","status","statusLabel","onOpenChange","value","_$memo","_$createComponent","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/reasoning/reasoning.tsx"],"sourcesContent":["import { Brain } from 'lucide-solid'\nimport { createEffect, createSignal, on, splitProps, type JSX } from 'solid-js'\nimport { MessageText } from '../../ui/message'\nimport { ScrollArea } from '../../ui/scroll-area'\nimport { TraceDetail, TraceLine, type TraceLineProps } from '../../ui/trace'\n\n// A function child runs once, when the content mounts (see `deferred` in `tool.tsx`).\nconst deferred = (render: () => JSX.Element) => render as unknown as JSX.Element\n\n/**\n * Reasoning.\n *\n * The agent's thinking, as a `TraceLine`: a title that says what state it is in,\n * and a body that is the text the host chose to show. Reach for `ChainOfThought`\n * when the thinking is a sequence of discrete steps with their own status, and\n * for a plain `MessageText` when the text is simply part of the answer.\n *\n * ## It shows what it is given, and nothing else\n *\n * `text` is whatever the host has decided is user-visible — a provider's reasoning\n * summary, a model's visible scratchpad. This component never implies there is\n * more behind it: no \"show full reasoning\" control, no placeholder body, no\n * ellipsis standing in for hidden content. With no `text` and no `streaming` the\n * line is a plain, non-expandable line titled \"Reasoning\", because there is\n * nothing to open.\n *\n * ## The title is the state\n *\n * - `streaming` — \"Thinking…\", with the running mark and shimmer.\n * - finished with a `duration` (seconds) — \"Thought for 4s\".\n * - finished without one — \"Reasoning\". A duration the host did not measure is\n * not invented.\n *\n * ## Open while it is arriving, closed once it is done\n *\n * While streaming the body is open so the reader can follow along; when the\n * stream ends it folds away so the settled transcript stays one quiet column. The\n * reader's own toggle wins in both directions and is remembered until the next\n * stream begins, so someone who closed it mid-stream is not re-opened and\n * someone who opened it afterwards is not folded. Pass `open` and `onOpenChange`\n * to own the state instead.\n *\n * ## Bounded, and stable while it grows\n *\n * The body is `MessageText`, so the text is untrusted and rendered as text (see\n * its doc comment), and earlier paragraphs keep their DOM while the last one\n * grows. The scroller is capped; while streaming it follows the newest text only\n * if the reader has not scrolled up, so reading the start of a long thought is\n * not interrupted by the end of it.\n */\n\n/** `4` → `4s`, `65` → `1m 5s`. Nothing for a value that is not a finite duration. */\nexport function formatDuration(seconds: number | undefined): string | undefined {\n if (seconds === undefined || !Number.isFinite(seconds) || seconds < 0) return undefined\n const total = Math.round(seconds)\n if (total === 0) return '<1s'\n if (total < 60) return `${total}s`\n const hours = Math.floor(total / 3600)\n const minutes = Math.floor((total % 3600) / 60)\n const rest = total % 60\n if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`\n return rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`\n}\n\n/** The line's title for a state. Exported so a host can say the same thing elsewhere. */\nexport function reasoningTitle(state: { streaming?: boolean; duration?: number }): string {\n if (state.streaming) return 'Thinking…'\n const duration = formatDuration(state.duration)\n return duration ? `Thought for ${duration}` : 'Reasoning'\n}\n\n/** Within this many pixels of the end counts as \"following\". */\nconst FOLLOW_SLOP = 16\n\nexport type ReasoningProps = Omit<\n TraceLineProps,\n | 'title'\n | 'description'\n | 'status'\n | 'statusLabel'\n | 'defaultOpen'\n | 'children'\n | 'href'\n | 'onSelect'\n | 'selectHaspopup'\n> & {\n /** The reasoning the host marked as user-visible. Untrusted text. */\n text?: string\n /** True while text may still arrive. */\n streaming?: boolean\n /** Seconds the thinking took, if the host measured it. */\n duration?: number\n /** Replaces the state-derived title, e.g. for another language. */\n title?: JSX.Element\n}\n\nfunction ReasoningBody(props: { text: string; streaming?: boolean }) {\n let scroller: HTMLDivElement | undefined\n let following = true\n\n createEffect(() => {\n // Read for the dependency: new text is the event that may need following.\n void props.text\n if (props.streaming && following && scroller) scroller.scrollTop = scroller.scrollHeight\n })\n\n return (\n <TraceDetail>\n <ScrollArea\n ref={(element) => (scroller = element)}\n role=\"region\"\n aria-label=\"Reasoning text\"\n class=\"max-h-72\"\n onScroll={(event) => {\n const element = event.currentTarget\n following = element.scrollHeight - element.scrollTop - element.clientHeight <= FOLLOW_SLOP\n }}\n >\n <MessageText\n text={props.text}\n streaming={props.streaming}\n codeBlockProps={{ maxHeight: '16rem', wrap: true }}\n />\n </ScrollArea>\n </TraceDetail>\n )\n}\n\nexport function Reasoning(props: ReasoningProps) {\n const [local, rest] = splitProps(props, [\n 'text',\n 'streaming',\n 'duration',\n 'title',\n 'icon',\n 'open',\n 'onOpenChange',\n ])\n // `undefined` means \"the reader has not decided\", which is what lets the stream\n // open and close the line on its own.\n const [chosen, setChosen] = createSignal<boolean>()\n const open = () => local.open ?? chosen() ?? local.streaming === true\n const hasBody = () => (local.text ?? '').trim() !== '' || local.streaming === true\n\n createEffect(\n on(\n () => local.streaming,\n (streaming) => {\n if (streaming) setChosen(undefined)\n },\n { defer: true }\n )\n )\n\n // A function child runs only when the content mounts, so a folded line parses nothing.\n const body = () => <ReasoningBody text={local.text ?? ''} streaming={local.streaming} />\n\n return (\n <TraceLine\n icon={local.icon ?? <Brain />}\n title={\n local.title ?? reasoningTitle({ streaming: local.streaming, duration: local.duration })\n }\n status={local.streaming ? 'running' : undefined}\n statusLabel=\"In progress\"\n open={open()}\n onOpenChange={(value) => {\n setChosen(value)\n local.onOpenChange?.(value)\n }}\n {...rest}\n >\n {hasBody() ? deferred(body) : undefined}\n </TraceLine>\n )\n}\n"],"mappings":";;;;;;;AAOA,IAAMW,YAAYC,WAA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6ChD,SAAgBE,eAAeC,SAAiD;CAC9E,IAAIA,YAAYC,KAAAA,KAAa,CAACC,OAAOC,SAASH,OAAO,KAAKA,UAAU,GAAG,OAAOC,KAAAA;CAC9E,MAAMG,QAAQC,KAAKC,MAAMN,OAAO;CAChC,IAAII,UAAU,GAAG,OAAO;CACxB,IAAIA,QAAQ,IAAI,OAAO,GAAGA,MAAK;CAC/B,MAAMG,QAAQF,KAAKG,MAAMJ,QAAQ,IAAI;CACrC,MAAMK,UAAUJ,KAAKG,MAAOJ,QAAQ,OAAQ,EAAE;CAC9C,MAAMM,OAAON,QAAQ;CACrB,IAAIG,QAAQ,GAAG,OAAOE,UAAU,IAAI,GAAGF,MAAK,IAAKE,QAAO,KAAM,GAAGF,MAAK;CACtE,OAAOG,OAAO,IAAI,GAAGD,QAAO,IAAKC,KAAI,KAAM,GAAGD,QAAO;AACvD;;AAGA,SAAgBE,eAAeC,OAA2D;CACxF,IAAIA,MAAMC,WAAW,OAAO;CAC5B,MAAMC,WAAWf,eAAea,MAAME,QAAQ;CAC9C,OAAOA,WAAW,eAAeA,aAAa;AAChD;;AAGA,IAAMC,cAAc;AAwBpB,SAASK,cAAcC,OAA8C;CACnE,IAAIC;CACJ,IAAIE,YAAY;CAEhBtC,mBAAmB;EAEjB,MAAWgC;EACX,IAAIG,MAAMR,aAAaW,aAAaF,UAAUA,SAASG,YAAYH,SAASI;CAC9E,CAAC;CAED,OAAAC,gBACGlC,aAAW,EAAA,IAAAmC,WAAA;EAAA,OAAAD,gBACTnC,YAAU;GAAAqC,MACHC,YAAaR,WAAWQ;GAC9BC,MAAI;GAAA,cAAA;GAAA,SAAA;GAGJC,WAAWC,UAAU;IACnB,MAAMH,UAAUG,MAAMC;IACtBV,YAAYM,QAAQJ,eAAeI,QAAQL,YAAYK,QAAQK,gBAAgBpB;GACjF;GAAC,IAAAa,WAAA;IAAA,OAAAD,gBAEApC,aAAW;KAAA,IACV2B,OAAI;MAAA,OAAEG,MAAMH;KAAI;KAAA,IAChBL,YAAS;MAAA,OAAEQ,MAAMR;KAAS;KAC1BuB,gBAAgB;MAAEC,WAAW;MAASC,MAAM;KAAK;IAAC,CAAA;GAAA;EAAA,CAAA;CAAA,EAAA,CAAA;AAK5D;AAEA,SAAgBC,UAAUlB,OAAuB;CAC/C,MAAM,CAACmB,OAAO9B,QAAQrB,WAAWgC,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;CAAc,CACf;CAGD,MAAM,CAACoB,QAAQC,aAAavD,aAAsB;CAClD,MAAMwD,aAAaH,MAAMG,QAAQF,OAAO,KAAKD,MAAM3B,cAAc;CACjE,MAAM+B,iBAAiBJ,MAAMtB,QAAQ,GAAA,CAAI2B,KAAK,MAAM,MAAML,MAAM3B,cAAc;CAE9E3B,aACEE,SACQoD,MAAM3B,YACXA,cAAc;EACb,IAAIA,WAAW6B,UAAUzC,KAAAA,CAAS;CACpC,GACA,EAAE6C,OAAO,KAAK,CAChB,CACF;CAGA,MAAMC,aAAOpB,gBAAOP,eAAa;EAAA,IAACF,OAAI;GAAA,OAAEsB,MAAMtB,QAAQ;EAAE;EAAA,IAAEL,YAAS;GAAA,OAAE2B,MAAM3B;EAAS;CAAA,CAAA;CAEpF,OAAAc,gBACGjC,WAASsD,WAAA;EAAA,IACRC,OAAI;GAAA,OAAET,MAAMS,QAAItB,gBAAK1C,OAAK,CAAA,CAAA;EAAG;EAAA,IAC7BkC,QAAK;GAAA,OACHqB,MAAMrB,SAASR,eAAe;IAAEE,WAAW2B,MAAM3B;IAAWC,UAAU0B,MAAM1B;GAAS,CAAC;EAAC;EAAA,IAEzFoC,SAAM;GAAA,OAAEV,MAAM3B,YAAY,YAAYZ,KAAAA;EAAS;EAC/CkD,aAAW;EAAA,IACXR,OAAI;GAAA,OAAEA,KAAK;EAAC;EACZS,eAAeC,UAAU;GACvBX,UAAUW,KAAK;GACfb,MAAMY,eAAeC,KAAK;EAC5B;CAAC,GACG3C,MAAI,EAAA,IAAAkB,WAAA;EAAA,OAEP0B,WAAA,CAAA,CAAAV,QAAQ,CAAC,CAAA,CAAA,IAAGhD,SAASmD,IAAI,IAAI9C,KAAAA;CAAS,EAAA,CAAA,CAAA;AAG7C"}
@@ -0,0 +1,3 @@
1
+ export { Sources, type SourcesProps } from './sources';
2
+ export { boundText, safeSourceUrl, sourceHost, sourceTitle, sourcesLabel, SOURCE_SNIPPET_LIMIT, SOURCE_TITLE_LIMIT, type Source, } from './source';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/sources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EACL,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,MAAM,GACZ,MAAM,UAAU,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { SOURCE_SNIPPET_LIMIT, SOURCE_TITLE_LIMIT, boundText, safeSourceUrl, sourceHost, sourceTitle, sourcesLabel } from "./source.js";
2
+ import { Sources } from "./sources.js";
3
+ export { SOURCE_SNIPPET_LIMIT, SOURCE_TITLE_LIMIT, Sources, boundText, safeSourceUrl, sourceHost, sourceTitle, sourcesLabel };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * What a reply drew on.
3
+ *
4
+ * Every field except `title` is optional because a source is only as much as the
5
+ * host knew: a search result has a snippet, a file has no URL, a tool result has
6
+ * neither. Nothing is inferred from what is missing, and two entries that share a
7
+ * URL stay two entries — the host may have cited two passages of one page, and a
8
+ * list that quietly merged them would also renumber every citation after it.
9
+ */
10
+ export type Source = Readonly<{
11
+ /** A stable key for streaming updates. Falls back to position. */
12
+ id?: string;
13
+ title: string;
14
+ url?: string;
15
+ snippet?: string;
16
+ }>;
17
+ /** Titles and snippets come from the open web; these keep one of them from owning the layout. */
18
+ export declare const SOURCE_TITLE_LIMIT = 160;
19
+ export declare const SOURCE_SNIPPET_LIMIT = 480;
20
+ /**
21
+ * Untrusted text, made safe to lay out: hidden and direction-overriding
22
+ * characters removed, runs of whitespace (including newlines) collapsed to one
23
+ * space, and clipped to `limit` with an ellipsis. It is still only ever rendered
24
+ * as a text node — this is about length and spoofing, not escaping.
25
+ */
26
+ export declare function boundText(value: string, limit: number): string;
27
+ /**
28
+ * A URL a link may point at: `http:`, `https:` or `mailto:`, no embedded
29
+ * credentials. `safeHref` (the message parser's own gate) already refuses other
30
+ * schemes, whitespace and control characters and over-long values; credentials are
31
+ * refused here as well because `https://trusted.example@evil.example/` shows a
32
+ * host that is not the one the link goes to.
33
+ */
34
+ export declare function safeSourceUrl(value: string | undefined): string | undefined;
35
+ /**
36
+ * The host to show beside a title, taken from the parsed URL (so an
37
+ * internationalised name appears in its `xn--` form and a look-alike cannot pass
38
+ * for the real one). A mailto source shows its address. Undefined when the URL is
39
+ * absent or unsafe: nothing is guessed.
40
+ */
41
+ export declare function sourceHost(value: string | undefined): string | undefined;
42
+ /** The line a collapsed list shows. One source is singular; the count is the list's length. */
43
+ export declare function sourcesLabel(count: number): string;
44
+ /** What to call a source: its title, else its host, else an honest placeholder. */
45
+ export declare function sourceTitle(source: Source): string;
46
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/sources/source.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;IAC5B,kEAAkE;IAClE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAC,CAAA;AAEF,iGAAiG;AACjG,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC,eAAO,MAAM,oBAAoB,MAAM,CAAA;AA4BvC;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAW3E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAYxE;AAED,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -0,0 +1,74 @@
1
+ import { safeHref } from "../../ui/message/parse-message-text.js";
2
+ //#region src/components/composites/sources/source.ts
3
+ /** Titles and snippets come from the open web; these keep one of them from owning the layout. */
4
+ var SOURCE_TITLE_LIMIT = 160;
5
+ var SOURCE_SNIPPET_LIMIT = 480;
6
+ function isHidden(code) {
7
+ return code <= 8 || code === 11 || code === 12 || code >= 14 && code <= 31 || code === 127 || code === 8206 || code === 8207 || code >= 8234 && code <= 8238 || code >= 8294 && code <= 8297;
8
+ }
9
+ function stripHidden(value) {
10
+ let out = "";
11
+ for (let index = 0; index < value.length; index += 1) if (!isHidden(value.charCodeAt(index))) out += value.charAt(index);
12
+ return out;
13
+ }
14
+ /**
15
+ * Untrusted text, made safe to lay out: hidden and direction-overriding
16
+ * characters removed, runs of whitespace (including newlines) collapsed to one
17
+ * space, and clipped to `limit` with an ellipsis. It is still only ever rendered
18
+ * as a text node — this is about length and spoofing, not escaping.
19
+ */
20
+ function boundText(value, limit) {
21
+ const clean = stripHidden(value.length > limit * 4 ? value.slice(0, limit * 4) : value).replace(/\s+/g, " ").trim();
22
+ if (clean.length <= limit) return clean;
23
+ const clipped = clean.slice(0, limit);
24
+ const last = clipped.charCodeAt(clipped.length - 1);
25
+ return `${(last >= 55296 && last <= 56319 ? clipped.slice(0, -1) : clipped).trimEnd()}…`;
26
+ }
27
+ /**
28
+ * A URL a link may point at: `http:`, `https:` or `mailto:`, no embedded
29
+ * credentials. `safeHref` (the message parser's own gate) already refuses other
30
+ * schemes, whitespace and control characters and over-long values; credentials are
31
+ * refused here as well because `https://trusted.example@evil.example/` shows a
32
+ * host that is not the one the link goes to.
33
+ */
34
+ function safeSourceUrl(value) {
35
+ if (value === void 0) return void 0;
36
+ const href = safeHref(value);
37
+ if (href === void 0) return void 0;
38
+ try {
39
+ const url = new URL(href);
40
+ if (url.username !== "" || url.password !== "") return void 0;
41
+ } catch {
42
+ return;
43
+ }
44
+ return href;
45
+ }
46
+ /**
47
+ * The host to show beside a title, taken from the parsed URL (so an
48
+ * internationalised name appears in its `xn--` form and a look-alike cannot pass
49
+ * for the real one). A mailto source shows its address. Undefined when the URL is
50
+ * absent or unsafe: nothing is guessed.
51
+ */
52
+ function sourceHost(value) {
53
+ const href = safeSourceUrl(value);
54
+ if (href === void 0) return void 0;
55
+ try {
56
+ const url = new URL(href);
57
+ if (url.protocol === "mailto:") return boundText(decodeURIComponent(url.pathname), 80) || void 0;
58
+ return url.hostname || void 0;
59
+ } catch {
60
+ return;
61
+ }
62
+ }
63
+ /** The line a collapsed list shows. One source is singular; the count is the list's length. */
64
+ function sourcesLabel(count) {
65
+ return `Used ${count} ${count === 1 ? "source" : "sources"}`;
66
+ }
67
+ /** What to call a source: its title, else its host, else an honest placeholder. */
68
+ function sourceTitle(source) {
69
+ return boundText(source.title, 160) || sourceHost(source.url) || "Untitled source";
70
+ }
71
+ //#endregion
72
+ export { SOURCE_SNIPPET_LIMIT, SOURCE_TITLE_LIMIT, boundText, safeSourceUrl, sourceHost, sourceTitle, sourcesLabel };
73
+
74
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","names":[],"sources":["../../../../src/components/composites/sources/source.ts"],"sourcesContent":["import { safeHref } from '../../ui/message/parse-message-text'\n\n/**\n * What a reply drew on.\n *\n * Every field except `title` is optional because a source is only as much as the\n * host knew: a search result has a snippet, a file has no URL, a tool result has\n * neither. Nothing is inferred from what is missing, and two entries that share a\n * URL stay two entries — the host may have cited two passages of one page, and a\n * list that quietly merged them would also renumber every citation after it.\n */\nexport type Source = Readonly<{\n /** A stable key for streaming updates. Falls back to position. */\n id?: string\n title: string\n url?: string\n snippet?: string\n}>\n\n/** Titles and snippets come from the open web; these keep one of them from owning the layout. */\nexport const SOURCE_TITLE_LIMIT = 160\nexport const SOURCE_SNIPPET_LIMIT = 480\n\n// C0 controls other than tab and newline, DEL, and the bidirectional marks,\n// overrides and isolates: the last group is how a title can be made to read as a\n// different string than the one that is stored. Tested by code point rather than\n// by a regular expression so no control or invisible character appears in this file.\nfunction isHidden(code: number): boolean {\n return (\n code <= 0x08 ||\n code === 0x0b ||\n code === 0x0c ||\n (code >= 0x0e && code <= 0x1f) ||\n code === 0x7f ||\n code === 0x200e ||\n code === 0x200f ||\n (code >= 0x202a && code <= 0x202e) ||\n (code >= 0x2066 && code <= 0x2069)\n )\n}\n\nfunction stripHidden(value: string): string {\n let out = ''\n for (let index = 0; index < value.length; index += 1) {\n if (!isHidden(value.charCodeAt(index))) out += value.charAt(index)\n }\n return out\n}\n\n/**\n * Untrusted text, made safe to lay out: hidden and direction-overriding\n * characters removed, runs of whitespace (including newlines) collapsed to one\n * space, and clipped to `limit` with an ellipsis. It is still only ever rendered\n * as a text node — this is about length and spoofing, not escaping.\n */\nexport function boundText(value: string, limit: number): string {\n // Clip before the regex passes so a multi-megabyte value costs a slice, not a scan.\n const head = value.length > limit * 4 ? value.slice(0, limit * 4) : value\n const clean = stripHidden(head).replace(/\\s+/g, ' ').trim()\n if (clean.length <= limit) return clean\n const clipped = clean.slice(0, limit)\n // Never end on half of a surrogate pair: it renders as a replacement glyph.\n const last = clipped.charCodeAt(clipped.length - 1)\n const whole = last >= 0xd800 && last <= 0xdbff ? clipped.slice(0, -1) : clipped\n return `${whole.trimEnd()}…`\n}\n\n/**\n * A URL a link may point at: `http:`, `https:` or `mailto:`, no embedded\n * credentials. `safeHref` (the message parser's own gate) already refuses other\n * schemes, whitespace and control characters and over-long values; credentials are\n * refused here as well because `https://trusted.example@evil.example/` shows a\n * host that is not the one the link goes to.\n */\nexport function safeSourceUrl(value: string | undefined): string | undefined {\n if (value === undefined) return undefined\n const href = safeHref(value)\n if (href === undefined) return undefined\n try {\n const url = new URL(href)\n if (url.username !== '' || url.password !== '') return undefined\n } catch {\n return undefined\n }\n return href\n}\n\n/**\n * The host to show beside a title, taken from the parsed URL (so an\n * internationalised name appears in its `xn--` form and a look-alike cannot pass\n * for the real one). A mailto source shows its address. Undefined when the URL is\n * absent or unsafe: nothing is guessed.\n */\nexport function sourceHost(value: string | undefined): string | undefined {\n const href = safeSourceUrl(value)\n if (href === undefined) return undefined\n try {\n const url = new URL(href)\n if (url.protocol === 'mailto:') {\n return boundText(decodeURIComponent(url.pathname), 80) || undefined\n }\n return url.hostname || undefined\n } catch {\n return undefined\n }\n}\n\n/** The line a collapsed list shows. One source is singular; the count is the list's length. */\nexport function sourcesLabel(count: number): string {\n return `Used ${count} ${count === 1 ? 'source' : 'sources'}`\n}\n\n/** What to call a source: its title, else its host, else an honest placeholder. */\nexport function sourceTitle(source: Source): string {\n return boundText(source.title, SOURCE_TITLE_LIMIT) || sourceHost(source.url) || 'Untitled source'\n}\n"],"mappings":";;;AAoBA,IAAa,qBAAqB;AAClC,IAAa,uBAAuB;AAMpC,SAAS,SAAS,MAAuB;CACvC,OACE,QAAQ,KACR,SAAS,MACT,SAAS,MACR,QAAQ,MAAQ,QAAQ,MACzB,SAAS,OACT,SAAS,QACT,SAAS,QACR,QAAQ,QAAU,QAAQ,QAC1B,QAAQ,QAAU,QAAQ;AAE/B;AAEA,SAAS,YAAY,OAAuB;CAC1C,IAAI,MAAM;CACV,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GACjD,IAAI,CAAC,SAAS,MAAM,WAAW,KAAK,CAAC,GAAG,OAAO,MAAM,OAAO,KAAK;CAEnE,OAAO;AACT;;;;;;;AAQA,SAAgB,UAAU,OAAe,OAAuB;CAG9D,MAAM,QAAQ,YADD,MAAM,SAAS,QAAQ,IAAI,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,KACtC,CAAC,CAAC,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;CAC1D,IAAI,MAAM,UAAU,OAAO,OAAO;CAClC,MAAM,UAAU,MAAM,MAAM,GAAG,KAAK;CAEpC,MAAM,OAAO,QAAQ,WAAW,QAAQ,SAAS,CAAC;CAElD,OAAO,IADO,QAAQ,SAAU,QAAQ,QAAS,QAAQ,MAAM,GAAG,EAAE,IAAI,QAAA,CACxD,QAAQ,EAAE;AAC5B;;;;;;;;AASA,SAAgB,cAAc,OAA+C;CAC3E,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,MAAM,OAAO,SAAS,KAAK;CAC3B,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,IAAI;EACxB,IAAI,IAAI,aAAa,MAAM,IAAI,aAAa,IAAI,OAAO,KAAA;CACzD,QAAQ;EACN;CACF;CACA,OAAO;AACT;;;;;;;AAQA,SAAgB,WAAW,OAA+C;CACxE,MAAM,OAAO,cAAc,KAAK;CAChC,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,IAAI;EACxB,IAAI,IAAI,aAAa,WACnB,OAAO,UAAU,mBAAmB,IAAI,QAAQ,GAAG,EAAE,KAAK,KAAA;EAE5D,OAAO,IAAI,YAAY,KAAA;CACzB,QAAQ;EACN;CACF;AACF;;AAGA,SAAgB,aAAa,OAAuB;CAClD,OAAO,QAAQ,MAAM,GAAG,UAAU,IAAI,WAAW;AACnD;;AAGA,SAAgB,YAAY,QAAwB;CAClD,OAAO,UAAU,OAAO,OAAA,GAAyB,KAAK,WAAW,OAAO,GAAG,KAAK;AAClF"}
@@ -0,0 +1,45 @@
1
+ import { type TraceProps } from '../../ui/trace';
2
+ import { type Source } from './source';
3
+ /**
4
+ * Sources.
5
+ *
6
+ * The links a reply used, as one `Trace` line — "Used 4 sources" — that expands
7
+ * into the list. It lives under the answer with the rest of the agent's activity
8
+ * rather than as a card of its own, because a reader who wants to check a claim
9
+ * will open it and one who does not should not have to scroll past it. For a
10
+ * marker inside a sentence use `InlineCitation`, which points at the same
11
+ * `Source` shape; the two are numbered the same way (position in this list).
12
+ *
13
+ * ## What it will and will not say
14
+ *
15
+ * - **No sources, no line.** An empty list renders nothing: "Used 0 sources" is a
16
+ * claim about an answer that may simply not have been grounded.
17
+ * - **A row is a link only with a safe address.** `http:`, `https:` and `mailto:`
18
+ * without embedded credentials (`safeSourceUrl`). Any other address is not
19
+ * linked and not printed — the row says the address was not linked, so the
20
+ * reader knows something was withheld instead of finding a dead title.
21
+ * - **The host is read from the parsed URL**, never from the title, so a title
22
+ * that reads "docs.example.com" cannot make a link to somewhere else look like it.
23
+ * - **Nothing is merged.** Two entries that share a URL are two rows, with their
24
+ * own numbers; the host may have cited two passages and the citations point at
25
+ * positions.
26
+ * - **Hostile and long values are bounded.** Titles, hosts and snippets are
27
+ * clipped and stripped of direction overrides (`boundText`), and are only ever
28
+ * text nodes.
29
+ * - **A long list is shown in pages.** Past `initialVisible` the rest is behind a
30
+ * button that names how many there are, so a 200-source answer is not 200 rows
31
+ * the moment it opens. The button stays in place and toggles, so focus is never
32
+ * left on a control that has just disappeared.
33
+ */
34
+ export type SourcesProps = Omit<TraceProps, 'children'> & {
35
+ sources: readonly Source[];
36
+ /** Replaces the default "Used N sources" for another language or a different verb. */
37
+ label?: string;
38
+ open?: boolean;
39
+ defaultOpen?: boolean;
40
+ onOpenChange?: (open: boolean) => void;
41
+ /** Rows shown before the "Show all" button. Default 25. */
42
+ initialVisible?: number;
43
+ };
44
+ export declare function Sources(props: SourcesProps): import("solid-js").JSX.Element;
45
+ //# sourceMappingURL=sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/sources/sources.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC/E,OAAO,EAOL,KAAK,MAAM,EACZ,MAAM,UAAU,CAAA;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG;IACxD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAID,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,kCA+C1C"}
@@ -0,0 +1,175 @@
1
+ import { Button } from "../../ui/button/button.js";
2
+ import { TextLink } from "../../ui/text-link/text-link.js";
3
+ import { Trace, TraceDetail, TraceLine } from "../../ui/trace/trace.js";
4
+ import { boundText, safeSourceUrl, sourceHost, sourceTitle, sourcesLabel } from "./source.js";
5
+ import { createComponent, insert, memo, mergeProps, template } from "solid-js/web";
6
+ import { BookOpen } from "lucide-solid";
7
+ import { For, Show, createSignal, splitProps } from "solid-js";
8
+ //#region src/components/composites/sources/sources.tsx
9
+ var _tmpl$ = /*#__PURE__*/ template(`<ol class="m-0 flex list-none flex-col gap-2 p-0"aria-label="Sources used">`);
10
+ var _tmpl$2 = /*#__PURE__*/ template(`<span class="text-xs text-muted-foreground [overflow-wrap:anywhere]">`);
11
+ var _tmpl$3 = /*#__PURE__*/ template(`<p class="m-0 line-clamp-3 text-xs text-muted-foreground [overflow-wrap:anywhere]">`);
12
+ var _tmpl$4 = /*#__PURE__*/ template(`<li data-slot=source class="flex min-w-0 items-baseline gap-2"><span aria-hidden=true class="w-5 shrink-0 text-end text-xs text-muted-foreground tabular-nums"></span><div class="flex min-w-0 flex-1 flex-col gap-0.5">`);
13
+ var _tmpl$5 = /*#__PURE__*/ template(`<span class="text-sm text-foreground [overflow-wrap:anywhere]"><span class=visually-hidden>Source <!>: `);
14
+ var _tmpl$6 = /*#__PURE__*/ template(`<span class=visually-hidden>Source <!>: `);
15
+ var _tmpl$7 = /*#__PURE__*/ template(`<span class=visually-hidden> (opens in a new tab)`);
16
+ var DEFAULT_VISIBLE = 25;
17
+ function Sources(props) {
18
+ const [local, rest] = splitProps(props, [
19
+ "sources",
20
+ "label",
21
+ "open",
22
+ "defaultOpen",
23
+ "onOpenChange",
24
+ "initialVisible"
25
+ ]);
26
+ const [expanded, setExpanded] = createSignal(false);
27
+ const limit = () => Math.max(1, Math.floor(local.initialVisible ?? DEFAULT_VISIBLE));
28
+ const hidden = () => Math.max(0, local.sources.length - limit());
29
+ const visible = () => expanded() ? local.sources : local.sources.slice(0, limit());
30
+ return createComponent(Show, {
31
+ get when() {
32
+ return local.sources.length > 0;
33
+ },
34
+ get children() {
35
+ return createComponent(Trace, mergeProps({
36
+ "aria-label": "Sources",
37
+ "data-slot": "sources"
38
+ }, rest, { get children() {
39
+ return createComponent(TraceLine, {
40
+ get icon() {
41
+ return createComponent(BookOpen, {});
42
+ },
43
+ get title() {
44
+ return local.label ?? sourcesLabel(local.sources.length);
45
+ },
46
+ get open() {
47
+ return local.open;
48
+ },
49
+ get defaultOpen() {
50
+ return local.defaultOpen;
51
+ },
52
+ get onOpenChange() {
53
+ return local.onOpenChange;
54
+ },
55
+ get children() {
56
+ return createComponent(TraceDetail, { get children() {
57
+ return [(() => {
58
+ var _el$ = _tmpl$();
59
+ insert(_el$, createComponent(For, {
60
+ get each() {
61
+ return visible();
62
+ },
63
+ children: (source, index) => createComponent(SourceRow, {
64
+ source,
65
+ get position() {
66
+ return index() + 1;
67
+ }
68
+ })
69
+ }));
70
+ return _el$;
71
+ })(), createComponent(Show, {
72
+ get when() {
73
+ return hidden() > 0;
74
+ },
75
+ get children() {
76
+ return createComponent(Button, {
77
+ type: "button",
78
+ variant: "ghost",
79
+ size: "xs",
80
+ "class": "mt-1",
81
+ get ["aria-expanded"]() {
82
+ return expanded();
83
+ },
84
+ onClick: () => setExpanded((value) => !value),
85
+ get children() {
86
+ return memo(() => !!expanded())() ? "Show fewer sources" : `Show all ${local.sources.length} sources`;
87
+ }
88
+ });
89
+ }
90
+ })];
91
+ } });
92
+ }
93
+ });
94
+ } }));
95
+ }
96
+ });
97
+ }
98
+ function SourceRow(props) {
99
+ const href = () => safeSourceUrl(props.source.url);
100
+ const host = () => sourceHost(props.source.url);
101
+ const title = () => sourceTitle(props.source);
102
+ const snippet = () => props.source.snippet ? boundText(props.source.snippet, 480) : "";
103
+ const withheld = () => props.source.url !== void 0 && props.source.url !== "" && !href();
104
+ return (() => {
105
+ var _el$2 = _tmpl$4(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
106
+ insert(_el$3, () => props.position);
107
+ insert(_el$4, createComponent(Show, {
108
+ get when() {
109
+ return href();
110
+ },
111
+ get fallback() {
112
+ return (() => {
113
+ var _el$7 = _tmpl$5(), _el$8 = _el$7.firstChild, _el$1 = _el$8.firstChild.nextSibling;
114
+ _el$1.nextSibling;
115
+ insert(_el$8, () => props.position, _el$1);
116
+ insert(_el$7, title, null);
117
+ return _el$7;
118
+ })();
119
+ },
120
+ children: (url) => createComponent(TextLink, {
121
+ get href() {
122
+ return url();
123
+ },
124
+ target: "_blank",
125
+ rel: "noreferrer noopener",
126
+ "class": "w-fit max-w-full text-sm [overflow-wrap:anywhere]",
127
+ get children() {
128
+ return [
129
+ (() => {
130
+ var _el$10 = _tmpl$6(), _el$13 = _el$10.firstChild.nextSibling;
131
+ _el$13.nextSibling;
132
+ insert(_el$10, () => props.position, _el$13);
133
+ return _el$10;
134
+ })(),
135
+ memo(() => title()),
136
+ _tmpl$7()
137
+ ];
138
+ }
139
+ })
140
+ }), null);
141
+ insert(_el$4, createComponent(Show, {
142
+ get when() {
143
+ return host() || withheld();
144
+ },
145
+ get children() {
146
+ var _el$5 = _tmpl$2();
147
+ insert(_el$5, host, null);
148
+ insert(_el$5, createComponent(Show, {
149
+ get when() {
150
+ return withheld();
151
+ },
152
+ get children() {
153
+ return [memo(() => host() ? " · " : ""), "Address not linked"];
154
+ }
155
+ }), null);
156
+ return _el$5;
157
+ }
158
+ }), null);
159
+ insert(_el$4, createComponent(Show, {
160
+ get when() {
161
+ return snippet();
162
+ },
163
+ get children() {
164
+ var _el$6 = _tmpl$3();
165
+ insert(_el$6, snippet);
166
+ return _el$6;
167
+ }
168
+ }), null);
169
+ return _el$2;
170
+ })();
171
+ }
172
+ //#endregion
173
+ export { Sources };
174
+
175
+ //# sourceMappingURL=sources.js.map