@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,144 @@
1
+ import { parseMessageText, type MessageBlock, type MessageInline } from './parse-message-text'
2
+
3
+ /**
4
+ * Citations that arrive as positions in the text, placed as markers.
5
+ *
6
+ * A producer that cites a passage says *where*: a half-open span of the exact
7
+ * text and the sources behind it. `MessageText` binds `[^n]` markers, so this
8
+ * turns the one into the other without ever changing what the text says:
9
+ *
10
+ * - A marker goes at the **end** of the span, nowhere else, and only for numbers
11
+ * within `count`. Several spans ending at one place share one marker.
12
+ * - **The parser is the judge of where a marker may go.** The text is parsed
13
+ * without the markers and again with them; a marker is kept only if everything
14
+ * that is not a marker reads exactly as before. A position inside a code
15
+ * block, an inline code span, a link target or anything else the parser reads
16
+ * as something other than prose changes that reading, so it is dropped (the
17
+ * source still belongs in `Sources`; it just has no badge there). No second
18
+ * copy of the Markdown rules exists to drift from the real one.
19
+ * - **Text that already has footnote marks gets none.** `[^1]` typed by a model
20
+ * would otherwise be indistinguishable from a marker placed here, and a
21
+ * citation must never come from the text alone.
22
+ *
23
+ * The result's `text` is for display only. Copy the original.
24
+ */
25
+ export type CitationPlacement = Readonly<{
26
+ /** Offset into the text after which the marker goes (the span's end). */
27
+ end: number
28
+ /** 1-based positions in the host's source list. */
29
+ numbers: readonly number[]
30
+ }>
31
+
32
+ export type PlacedCitations = Readonly<{
33
+ /** The text with markers, for `MessageText` with `citations`. */
34
+ text: string
35
+ /** Distinct end positions that received a marker. */
36
+ placed: number
37
+ /** Those positions, ascending: a span is represented exactly when its end is among them. */
38
+ ends: readonly number[]
39
+ /** Distinct end positions left without one, for any reason. */
40
+ skipped: number
41
+ /** The text had footnote marks of its own, so nothing was placed. */
42
+ collision: boolean
43
+ }>
44
+
45
+ const FOOTNOTE = /\[\^\d/
46
+ const PER_MARKER = 6
47
+
48
+ function marker(numbers: readonly number[]): string {
49
+ const parts: string[] = []
50
+ for (let index = 0; index < numbers.length; index += PER_MARKER) {
51
+ parts.push(`[^${numbers.slice(index, index + PER_MARKER).join(',')}]`)
52
+ }
53
+ return parts.join('')
54
+ }
55
+
56
+ function normalise(nodes: readonly MessageInline[]): unknown[] {
57
+ const out: unknown[] = []
58
+ for (const node of nodes) {
59
+ if (node.kind === 'cite') continue
60
+ if (node.kind === 'strong' || node.kind === 'em' || node.kind === 'link') {
61
+ out.push({ ...node, children: normalise(node.children) })
62
+ continue
63
+ }
64
+ const last = out.at(-1) as { kind?: string; text?: string } | undefined
65
+ if (node.kind === 'text' && last?.kind === 'text') {
66
+ out[out.length - 1] = { kind: 'text', text: `${last.text}${node.text}` }
67
+ } else {
68
+ out.push(node)
69
+ }
70
+ }
71
+ return out
72
+ }
73
+
74
+ /** What the blocks say with the markers and every `raw` slice taken out. */
75
+ function reading(blocks: readonly MessageBlock[]): string {
76
+ return JSON.stringify(
77
+ blocks.map((block) => {
78
+ const { raw: _raw, ...rest } = block
79
+ if (block.kind === 'list') return { ...rest, items: block.items.map(normalise) }
80
+ if (block.kind === 'code') return rest
81
+ return { ...rest, inline: normalise(block.inline) }
82
+ })
83
+ )
84
+ }
85
+
86
+ export function placeCitationMarkers(
87
+ text: string,
88
+ citations: readonly CitationPlacement[],
89
+ count: number
90
+ ): PlacedCitations {
91
+ const byEnd = new Map<number, Set<number>>()
92
+ for (const { end, numbers } of citations) {
93
+ if (!Number.isInteger(end) || end <= 0 || end > text.length) continue
94
+ for (const number of numbers) {
95
+ if (!Number.isInteger(number) || number < 1 || number > count) continue
96
+ const set = byEnd.get(end) ?? new Set<number>()
97
+ set.add(number)
98
+ byEnd.set(end, set)
99
+ }
100
+ }
101
+ const candidates = [...byEnd.entries()]
102
+ .toSorted(([left], [right]) => left - right)
103
+ .map(([end, numbers]) => ({ end, marker: marker([...numbers].toSorted((a, b) => a - b)) }))
104
+ if (candidates.length === 0) return { text, placed: 0, ends: [], skipped: 0, collision: false }
105
+ if (FOOTNOTE.test(text)) {
106
+ return { text, placed: 0, ends: [], skipped: candidates.length, collision: true }
107
+ }
108
+
109
+ const insert = (chosen: readonly { end: number; marker: string }[]): string => {
110
+ let out = ''
111
+ let cursor = 0
112
+ for (const item of chosen) {
113
+ out += text.slice(cursor, item.end) + item.marker
114
+ cursor = item.end
115
+ }
116
+ return out + text.slice(cursor)
117
+ }
118
+
119
+ const baseline = reading(parseMessageText(text))
120
+ const holds = (chosen: readonly { end: number; marker: string }[]) =>
121
+ reading(parseMessageText(insert(chosen), { citations: count })) === baseline
122
+
123
+ // Usual case: every position is prose, one check covers all of them.
124
+ if (holds(candidates)) {
125
+ return {
126
+ text: insert(candidates),
127
+ placed: candidates.length,
128
+ ends: candidates.map((candidate) => candidate.end),
129
+ skipped: 0,
130
+ collision: false,
131
+ }
132
+ }
133
+ const accepted: { end: number; marker: string }[] = []
134
+ for (const candidate of candidates) {
135
+ if (holds([...accepted, candidate])) accepted.push(candidate)
136
+ }
137
+ return {
138
+ text: insert(accepted),
139
+ placed: accepted.length,
140
+ ends: accepted.map((candidate) => candidate.end),
141
+ skipped: candidates.length - accepted.length,
142
+ collision: false,
143
+ }
144
+ }
@@ -0,0 +1,23 @@
1
+ export {
2
+ Message,
3
+ MessageActions,
4
+ MessageContent,
5
+ MessageFooter,
6
+ MessageHeader,
7
+ MessageText,
8
+ type MessageCitations,
9
+ type MessageCodeBlockInfo,
10
+ type MessageCodeBlockProps,
11
+ type MessageProps,
12
+ type MessageRole,
13
+ type MessageTextProps,
14
+ } from './message'
15
+ export { placeCitationMarkers, type CitationPlacement, type PlacedCitations } from './cite-ranges'
16
+ export {
17
+ parseInline,
18
+ parseMessageText,
19
+ safeHref,
20
+ type MessageBlock,
21
+ type MessageInline,
22
+ type ParseInlineOptions,
23
+ } from './parse-message-text'
@@ -0,0 +1,434 @@
1
+ import {
2
+ createMemo,
3
+ For,
4
+ Index,
5
+ Match,
6
+ Show,
7
+ splitProps,
8
+ Switch,
9
+ type ComponentProps,
10
+ type JSX,
11
+ } from 'solid-js'
12
+ import { cn } from '#lib/utils'
13
+ import { CodeBlock, InlineCode, type CodeBlockProps } from '../code-block'
14
+ import { parseMessageText, type MessageBlock, type MessageInline } from './parse-message-text'
15
+
16
+ /**
17
+ * Message.
18
+ *
19
+ * One turn. The two speakers are laid out differently on purpose, and that is
20
+ * the whole design:
21
+ *
22
+ * - **The person's turn is a bubble on the trailing edge** — short, bounded, and
23
+ * easy to find when scrolling back through a long session.
24
+ * - **The assistant's turn is the page.** It has no surface, spans the reading
25
+ * column, and holds everything the agent did *for that request* — activity
26
+ * (a `Trace`), prose, code, a pending decision — in one place, so a turn
27
+ * reads as an answer with its working underneath it rather than as a chain of
28
+ * unrelated cards.
29
+ *
30
+ * `label` is the turn's accessible name ("You", "Assistant"): the avatar and
31
+ * name are not drawn for every turn, because a transcript that repeats a speaker
32
+ * on every line is one nobody reads, but the name must still be announced.
33
+ * `streaming` sets `aria-busy`, which tells assistive technology to wait for the
34
+ * turn to settle before reading it instead of announcing every token.
35
+ *
36
+ * `anchorId` is the stable identity `MessageScroller` uses to keep the reader's
37
+ * place when older turns are inserted above it.
38
+ */
39
+ export type MessageRole = 'user' | 'assistant' | 'system'
40
+
41
+ export type MessageProps = Omit<ComponentProps<'article'>, 'role'> & {
42
+ role: MessageRole
43
+ /** The turn's accessible name. */
44
+ label: string
45
+ streaming?: boolean
46
+ anchorId?: string
47
+ }
48
+
49
+ export function Message(props: MessageProps) {
50
+ const [local, rest] = splitProps(props, [
51
+ 'class',
52
+ 'role',
53
+ 'label',
54
+ 'streaming',
55
+ 'anchorId',
56
+ 'children',
57
+ ])
58
+ return (
59
+ <article
60
+ data-slot="message"
61
+ data-role={local.role}
62
+ data-anchor-id={local.anchorId}
63
+ aria-label={local.label}
64
+ aria-busy={local.streaming || undefined}
65
+ class={cn(
66
+ 'group/message mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-2 py-2',
67
+ // The engine may skip layout for turns far off screen; the intrinsic size
68
+ // keeps the scrollbar honest while it does.
69
+ '[content-visibility:auto] [contain-intrinsic-size:auto_6rem]',
70
+ {
71
+ 'items-end ps-[clamp(0rem,12%,4rem)]': local.role === 'user',
72
+ 'items-stretch': local.role !== 'user',
73
+ },
74
+ local.class
75
+ )}
76
+ {...rest}
77
+ >
78
+ {local.children}
79
+ </article>
80
+ )
81
+ }
82
+
83
+ /** The speaker's mark and name, for the turns that draw one. */
84
+ export function MessageHeader(
85
+ props: ComponentProps<'header'> & { avatar?: JSX.Element; time?: JSX.Element }
86
+ ) {
87
+ const [local, rest] = splitProps(props, ['class', 'avatar', 'time', 'children'])
88
+ return (
89
+ <header
90
+ data-slot="message-header"
91
+ class={cn('flex items-center gap-2 text-xs text-muted-foreground', local.class)}
92
+ {...rest}
93
+ >
94
+ <Show when={local.avatar}>{local.avatar}</Show>
95
+ <span class="font-medium text-foreground">{local.children}</span>
96
+ <Show when={local.time}>
97
+ <span class="tabular-nums">{local.time}</span>
98
+ </Show>
99
+ </header>
100
+ )
101
+ }
102
+
103
+ /** The turn's parts, stacked. Gap is the rhythm between prose, activity and code. */
104
+ export function MessageContent(props: ComponentProps<'div'>) {
105
+ const [local, rest] = splitProps(props, ['class', 'children'])
106
+ return (
107
+ <div
108
+ data-slot="message-content"
109
+ class={cn(
110
+ 'flex w-full max-w-3xl min-w-0 flex-col gap-3 font-content text-content',
111
+ local.class
112
+ )}
113
+ {...rest}
114
+ >
115
+ {local.children}
116
+ </div>
117
+ )
118
+ }
119
+
120
+ /**
121
+ * Actions that belong to the turn (copy, retry). Hidden until the turn is hovered
122
+ * or focused so the column is not a wall of buttons, but never `display: none`:
123
+ * a control that only exists under the pointer cannot be reached by keyboard,
124
+ * and on a touch screen there is no hover, so coarse pointers always see them.
125
+ */
126
+ export function MessageActions(props: ComponentProps<'div'>) {
127
+ const [local, rest] = splitProps(props, ['class', 'children'])
128
+ return (
129
+ <div
130
+ data-slot="message-actions"
131
+ class={cn(
132
+ 'flex items-center gap-1 opacity-0 transition-opacity ease-out group-focus-within/message:opacity-100 group-hover/message:opacity-100 [@media(hover:none)]:opacity-100',
133
+ local.class
134
+ )}
135
+ {...rest}
136
+ >
137
+ {local.children}
138
+ </div>
139
+ )
140
+ }
141
+
142
+ export function MessageFooter(props: ComponentProps<'footer'>) {
143
+ const [local, rest] = splitProps(props, ['class', 'children'])
144
+ return (
145
+ <footer
146
+ data-slot="message-footer"
147
+ class={cn('flex min-w-0 items-center gap-2 text-xs text-muted-foreground', local.class)}
148
+ {...rest}
149
+ >
150
+ {local.children}
151
+ </footer>
152
+ )
153
+ }
154
+
155
+ /** The props of a fenced block the host may set. */
156
+ export type MessageCodeBlockProps = Pick<
157
+ CodeBlockProps,
158
+ 'loadHighlight' | 'maxHeight' | 'wrap' | 'showLineNumbers' | 'lineMarks' | 'lineLimit'
159
+ >
160
+
161
+ /** What the host is told about a fenced block when it chooses that block's props. */
162
+ export type MessageCodeBlockInfo = Readonly<{
163
+ /** Position among the text's fenced blocks, from 0. */
164
+ index: number
165
+ language: string | undefined
166
+ code: string
167
+ complete: boolean
168
+ }>
169
+
170
+ /**
171
+ * How `MessageText` draws citation markers. `count` is how many sources the host
172
+ * has; a `[^n]` marker is a citation only when every `n` is within it. `render`
173
+ * receives the 1-based source numbers and draws the marker, so the host decides
174
+ * what a number means (`messageCitations` in the inline-citation composite does
175
+ * this for a `Source` list).
176
+ */
177
+ export type MessageCitations = Readonly<{
178
+ count: number
179
+ render: (numbers: readonly number[]) => JSX.Element
180
+ }>
181
+
182
+ export type MessageTextProps = Omit<ComponentProps<'div'>, 'children'> & {
183
+ text: string
184
+ /** True while text may still arrive: a trailing open fence renders as partial code. */
185
+ streaming?: boolean
186
+ /**
187
+ * Forwarded to each fenced block, e.g. to supply a lazy highlighter. A function
188
+ * chooses per block, which is how line marks reach a block: marks belong to the
189
+ * host's knowledge of the code (a diff, a failing line), never to the text.
190
+ */
191
+ codeBlockProps?: MessageCodeBlockProps | ((block: MessageCodeBlockInfo) => MessageCodeBlockProps)
192
+ /** Without it, `[^1]` stays the literal text it was written as. */
193
+ citations?: MessageCitations
194
+ }
195
+
196
+ function sameBlock(a: MessageBlock | undefined, b: MessageBlock): boolean {
197
+ return (
198
+ a !== undefined &&
199
+ a.kind === b.kind &&
200
+ a.raw === b.raw &&
201
+ (a.kind !== 'code' || (b.kind === 'code' && a.complete === b.complete))
202
+ )
203
+ }
204
+
205
+ /**
206
+ * Text, read safely.
207
+ *
208
+ * Renders `parseMessageText`'s blocks as elements: nothing is interpreted as
209
+ * HTML and a link only becomes an anchor when its scheme is http, https or
210
+ * mailto. Blocks are kept by *position* and reuse their previous parsed object
211
+ * when unchanged, so a streaming turn updates the block that is growing and
212
+ * leaves every earlier paragraph and code block — and any selection or focus
213
+ * inside them — untouched.
214
+ */
215
+ export function MessageText(props: MessageTextProps) {
216
+ const [local, rest] = splitProps(props, [
217
+ 'class',
218
+ 'text',
219
+ 'streaming',
220
+ 'codeBlockProps',
221
+ 'citations',
222
+ ])
223
+ let previous: readonly MessageBlock[] = []
224
+ let previousCount = 0
225
+ // Only the number of sources reaches the parser, so a new `render` function
226
+ // does not reparse the text, and a changed count does.
227
+ const citationCount = () => local.citations?.count ?? 0
228
+ const blocks = createMemo(() => {
229
+ const count = citationCount()
230
+ if (count !== previousCount) previous = []
231
+ previousCount = count
232
+ const next = parseMessageText(local.text, {
233
+ streaming: local.streaming,
234
+ citations: count || undefined,
235
+ })
236
+ const merged = next.map((block, index) =>
237
+ sameBlock(previous[index], block) ? previous[index]! : block
238
+ )
239
+ previous = merged
240
+ return merged
241
+ })
242
+ // The nth fenced block, so a host can address it. Blocks keep their positions
243
+ // while text streams in after them, so an index stays attached to its block.
244
+ const codeIndexes = createMemo(() => {
245
+ let next = 0
246
+ return blocks().map((block) => (block.kind === 'code' ? next++ : -1))
247
+ })
248
+ const lastIsProse = () => {
249
+ const last = blocks().at(-1)
250
+ return last !== undefined && last.kind !== 'code'
251
+ }
252
+ return (
253
+ <div data-slot="message-text" class={cn('flex min-w-0 flex-col gap-3', local.class)} {...rest}>
254
+ <Index each={blocks()}>
255
+ {(block, index) => (
256
+ <BlockView
257
+ block={block()}
258
+ codeProps={local.codeBlockProps}
259
+ codeIndex={() => codeIndexes()[index] ?? 0}
260
+ citations={local.citations}
261
+ />
262
+ )}
263
+ </Index>
264
+ <Show when={local.streaming && lastIsProse()}>
265
+ <span class="streaming-caret" aria-hidden="true" />
266
+ </Show>
267
+ </div>
268
+ )
269
+ }
270
+
271
+ function BlockView(props: {
272
+ block: MessageBlock
273
+ codeProps?: MessageTextProps['codeBlockProps']
274
+ codeIndex: () => number
275
+ citations?: MessageCitations
276
+ }) {
277
+ return (
278
+ <Switch>
279
+ <Match when={props.block.kind === 'code' && props.block}>
280
+ {(block) => {
281
+ const code = () => block() as Extract<MessageBlock, { kind: 'code' }>
282
+ const chosen = () => {
283
+ const choice = props.codeProps
284
+ return typeof choice === 'function'
285
+ ? choice({
286
+ index: props.codeIndex(),
287
+ language: code().language,
288
+ code: code().code,
289
+ complete: code().complete,
290
+ })
291
+ : choice
292
+ }
293
+ return (
294
+ <CodeBlock
295
+ code={code().code}
296
+ language={code().language}
297
+ complete={code().complete}
298
+ {...chosen()}
299
+ />
300
+ )
301
+ }}
302
+ </Match>
303
+ <Match when={props.block.kind === 'heading' && props.block}>
304
+ {(block) => {
305
+ const heading = () => block() as Extract<MessageBlock, { kind: 'heading' }>
306
+ return (
307
+ <p
308
+ role="heading"
309
+ aria-level={heading().level + 2}
310
+ class="font-semibold text-foreground [overflow-wrap:anywhere]"
311
+ >
312
+ <Inline nodes={heading().inline} citations={props.citations} />
313
+ </p>
314
+ )
315
+ }}
316
+ </Match>
317
+ <Match when={props.block.kind === 'list' && props.block}>
318
+ {(block) => {
319
+ const list = () => block() as Extract<MessageBlock, { kind: 'list' }>
320
+ return (
321
+ <Show
322
+ when={list().ordered}
323
+ fallback={
324
+ <ul class="m-0 ms-5 flex list-disc flex-col gap-1 p-0 marker:text-muted-foreground">
325
+ <For each={list().items}>
326
+ {(item) => (
327
+ <li class="[overflow-wrap:anywhere]">
328
+ <Inline nodes={item} citations={props.citations} />
329
+ </li>
330
+ )}
331
+ </For>
332
+ </ul>
333
+ }
334
+ >
335
+ <ol
336
+ start={list().start}
337
+ class="m-0 ms-5 flex list-decimal flex-col gap-1 p-0 marker:text-muted-foreground"
338
+ >
339
+ <For each={list().items}>
340
+ {(item) => (
341
+ <li class="[overflow-wrap:anywhere]">
342
+ <Inline nodes={item} citations={props.citations} />
343
+ </li>
344
+ )}
345
+ </For>
346
+ </ol>
347
+ </Show>
348
+ )
349
+ }}
350
+ </Match>
351
+ <Match when={props.block.kind === 'quote' && props.block}>
352
+ {(block) => {
353
+ const quote = () => block() as Extract<MessageBlock, { kind: 'quote' }>
354
+ return (
355
+ <blockquote class="m-0 border-s-2 border-border ps-3 whitespace-pre-wrap text-muted-foreground [overflow-wrap:anywhere]">
356
+ <Inline nodes={quote().inline} citations={props.citations} />
357
+ </blockquote>
358
+ )
359
+ }}
360
+ </Match>
361
+ <Match when={props.block.kind === 'paragraph' && props.block}>
362
+ {(block) => {
363
+ const paragraph = () => block() as Extract<MessageBlock, { kind: 'paragraph' }>
364
+ return (
365
+ <p class="m-0 whitespace-pre-wrap [overflow-wrap:anywhere]">
366
+ <Inline nodes={paragraph().inline} citations={props.citations} />
367
+ </p>
368
+ )
369
+ }}
370
+ </Match>
371
+ </Switch>
372
+ )
373
+ }
374
+
375
+ function Inline(props: { nodes: readonly MessageInline[]; citations?: MessageCitations }) {
376
+ return (
377
+ <For each={props.nodes}>
378
+ {(node) => (
379
+ <Switch>
380
+ <Match when={node.kind === 'text' && node}>
381
+ {(text) => (text() as { text: string }).text}
382
+ </Match>
383
+ <Match when={node.kind === 'code' && node}>
384
+ {(code) => <InlineCode>{(code() as { text: string }).text}</InlineCode>}
385
+ </Match>
386
+ <Match when={node.kind === 'strong' && node}>
387
+ {(strong) => (
388
+ <strong class="font-semibold">
389
+ <Inline
390
+ nodes={(strong() as { children: readonly MessageInline[] }).children}
391
+ citations={props.citations}
392
+ />
393
+ </strong>
394
+ )}
395
+ </Match>
396
+ <Match when={node.kind === 'em' && node}>
397
+ {(em) => (
398
+ <em>
399
+ <Inline
400
+ nodes={(em() as { children: readonly MessageInline[] }).children}
401
+ citations={props.citations}
402
+ />
403
+ </em>
404
+ )}
405
+ </Match>
406
+ <Match when={node.kind === 'link' && node}>
407
+ {(link) => (
408
+ <a
409
+ href={(link() as { href: string }).href}
410
+ target="_blank"
411
+ rel="noreferrer noopener"
412
+ class="text-primary underline underline-offset-2 hover:no-underline"
413
+ >
414
+ <Inline nodes={(link() as { children: readonly MessageInline[] }).children} />
415
+ </a>
416
+ )}
417
+ </Match>
418
+ <Match when={node.kind === 'cite' && node}>
419
+ {(cite) => {
420
+ const marker = () => cite() as { numbers: readonly number[]; raw: string }
421
+ // The parser read this as a citation only while the host had sources;
422
+ // if they have gone since, the marker is the text it was written as.
423
+ // Match invokes this callback untracked; JSX keeps renderer and
424
+ // same-count source replacements reactive without replacing the block.
425
+ return (
426
+ <>{props.citations ? props.citations.render(marker().numbers) : marker().raw}</>
427
+ )
428
+ }}
429
+ </Match>
430
+ </Switch>
431
+ )}
432
+ </For>
433
+ )
434
+ }