dou-ui 0.1.0-alpha.2 → 0.1.0-alpha.3

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 (386) hide show
  1. package/dist/components/button/button.js.map +1 -1
  2. package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js +2 -1
  3. package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  4. package/dist/components/calendar-view/calendar-view.js.map +1 -1
  5. package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js +7 -2
  6. package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/cascader/cascader.js.map +1 -1
  8. package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js +3 -3
  9. package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/chat-artifact/chat-artifact.js.map +1 -1
  11. package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js +8 -2
  12. package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/chat-attachments/chat-attachments.js.map +1 -1
  14. package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js +11 -2
  15. package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js.map +1 -1
  16. package/dist/components/chat-attachments/chat-attachments2.js.map +1 -1
  17. package/dist/components/chat-confirm/chat-confirm.js.map +1 -1
  18. package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js +38 -14
  19. package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  20. package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js +2 -2
  21. package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/chat-context-meter/chat-context-meter2.js.map +1 -1
  23. package/dist/components/chat-message/chat-message.js.map +1 -1
  24. package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js +88 -33
  25. package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/chat-message/chat-message2.js.map +1 -1
  27. package/dist/components/chat-message/style.js +5 -0
  28. package/dist/components/chat-plan/chat-plan.js +9 -4
  29. package/dist/components/chat-plan/chat-plan.js.map +1 -1
  30. package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js +64 -32
  31. package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js.map +1 -1
  32. package/dist/components/chat-plan/chat-plan2.js +6 -0
  33. package/dist/components/chat-plan/chat-plan2.js.map +1 -0
  34. package/dist/components/chat-plan/index.js +1 -1
  35. package/dist/components/chat-plan/style.js +1 -0
  36. package/dist/components/chat-reasoning/chat-reasoning.js.map +1 -1
  37. package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js +4 -4
  38. package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js.map +1 -1
  39. package/dist/components/chat-sources/chat-citation.js.map +1 -1
  40. package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js +52 -14
  41. package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/chat-sources/chat-sources.js.map +1 -1
  43. package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js +6 -4
  44. package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/chat-sources/chat-sources2.js.map +1 -1
  46. package/dist/components/chat-sources/index.js +1 -1
  47. package/dist/components/chat-steps/chat-steps.js +9 -4
  48. package/dist/components/chat-steps/chat-steps.js.map +1 -1
  49. package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js +20 -13
  50. package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/chat-steps/chat-steps2.js +6 -0
  52. package/dist/components/chat-steps/chat-steps2.js.map +1 -0
  53. package/dist/components/chat-steps/index.js +1 -1
  54. package/dist/components/chat-steps/style.js +1 -0
  55. package/dist/components/chat-tool-call/chat-tool-call.js.map +1 -1
  56. package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js +38 -12
  57. package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/chat-tool-call/chat-tool-call2.js.map +1 -1
  59. package/dist/components/chat-tool-call/style.js +1 -0
  60. package/dist/components/code-block/code-block.js.map +1 -1
  61. package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js +37 -5
  62. package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/collapse/collapse-item.js.map +1 -1
  64. package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js +2 -2
  65. package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/collapse/collapse-transition.js +3 -1
  67. package/dist/components/collapse/collapse-transition.js.map +1 -1
  68. package/dist/components/collapse/index.js +1 -2
  69. package/dist/components/collapse/index.js.map +1 -1
  70. package/dist/components/color-mode/color-mode-button.js.map +1 -1
  71. package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js +2 -2
  72. package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/color-mode/color-mode-select.js.map +1 -1
  74. package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js +2 -2
  75. package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/color-mode/color-mode-switch.js.map +1 -1
  77. package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js +2 -2
  78. package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  79. package/dist/components/color-panel/color-panel.js.map +1 -1
  80. package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js +5 -5
  81. package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/color-picker/color-picker.js.map +1 -1
  83. package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js +2 -2
  84. package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/comment-thread/comment-thread.js.map +1 -1
  86. package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js +15 -15
  87. package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/comment-thread/style.js +2 -0
  89. package/dist/components/context-menu/context-menu.js.map +1 -1
  90. package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js +26 -11
  91. package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  92. package/dist/components/context-menu/index.js +2 -0
  93. package/dist/components/context-menu/index.js.map +1 -1
  94. package/dist/components/copy-button/copy-button.vue_vue_type_script_setup_true_lang.js +1 -1
  95. package/dist/components/descriptions/descriptions.js.map +1 -1
  96. package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js +3 -1
  97. package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  98. package/dist/components/descriptions/descriptions2.js.map +1 -1
  99. package/dist/components/dropdown/dropdown-button.js.map +1 -1
  100. package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js +5 -5
  101. package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  102. package/dist/components/dropdown/dropdown-group.js +6 -0
  103. package/dist/components/dropdown/dropdown-group.js.map +1 -0
  104. package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js +42 -0
  105. package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js.map +1 -0
  106. package/dist/components/dropdown/dropdown-item.js.map +1 -1
  107. package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js +31 -9
  108. package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/dropdown/dropdown-items.js.map +1 -1
  110. package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js +77 -52
  111. package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/dropdown/dropdown-radio-group.js.map +1 -1
  113. package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js +23 -5
  114. package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/dropdown/dropdown-sub.js.map +1 -1
  116. package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js +5 -4
  117. package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/dropdown/dropdown.js.map +1 -1
  119. package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js +2 -1
  120. package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
  121. package/dist/components/dropdown/dropdown2.js.map +1 -1
  122. package/dist/components/dropdown/index.js +4 -5
  123. package/dist/components/dropdown/index.js.map +1 -1
  124. package/dist/components/dropdown/item-components.js +11 -0
  125. package/dist/components/dropdown/item-components.js.map +1 -0
  126. package/dist/components/dropdown/menu-entries.js +14 -0
  127. package/dist/components/dropdown/menu-entries.js.map +1 -0
  128. package/dist/components/dropdown/menu-keys.js +1 -1
  129. package/dist/components/dropdown/menu-keys.js.map +1 -1
  130. package/dist/components/ellipsis/ellipsis.js.map +1 -1
  131. package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js +2 -2
  132. package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/image-cropper/image-cropper.js.map +1 -1
  134. package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js +10 -10
  135. package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/infinite-scroll/infinite-scroll.js.map +1 -1
  137. package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js +2 -2
  138. package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/input-date/segment-field.js.map +1 -1
  140. package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js +2 -2
  141. package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js.map +1 -1
  142. package/dist/components/input-date/style.js +1 -0
  143. package/dist/components/input-time/style.js +1 -0
  144. package/dist/components/layout/layout-aside-trigger.js.map +1 -1
  145. package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js +2 -2
  146. package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  147. package/dist/components/layout/layout-aside.js.map +1 -1
  148. package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js +3 -3
  149. package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js.map +1 -1
  150. package/dist/components/layout/layout-footer.js.map +1 -1
  151. package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js +5 -1
  152. package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  153. package/dist/components/layout/layout.js.map +1 -1
  154. package/dist/components/markdown/index.js +9 -0
  155. package/dist/components/markdown/index.js.map +1 -0
  156. package/dist/components/markdown/markdown.js +6 -0
  157. package/dist/components/markdown/markdown.js.map +1 -0
  158. package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js +225 -0
  159. package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js.map +1 -0
  160. package/dist/components/markdown/parse-block.js +577 -0
  161. package/dist/components/markdown/parse-block.js.map +1 -0
  162. package/dist/components/markdown/parse-inline.js +626 -0
  163. package/dist/components/markdown/parse-inline.js.map +1 -0
  164. package/dist/components/markdown/parser.js +308 -0
  165. package/dist/components/markdown/parser.js.map +1 -0
  166. package/dist/components/markdown/render.js +424 -0
  167. package/dist/components/markdown/render.js.map +1 -0
  168. package/dist/components/markdown/style.d.ts +1 -0
  169. package/dist/components/markdown/style.js +10 -0
  170. package/dist/components/markdown/url.js +16 -0
  171. package/dist/components/markdown/url.js.map +1 -0
  172. package/dist/components/menu/menu-item.js.map +1 -1
  173. package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js +3 -2
  174. package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  175. package/dist/components/menu/menu-list.js.map +1 -1
  176. package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js +2 -2
  177. package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
  178. package/dist/components/menu/menu-popup.js.map +1 -1
  179. package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js +33 -21
  180. package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/components/menu/menu.js +16 -13
  182. package/dist/components/menu/menu.js.map +1 -1
  183. package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js +4 -1
  184. package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  185. package/dist/components/menu/menu2.js.map +1 -1
  186. package/dist/components/menubar/menubar.js.map +1 -1
  187. package/dist/components/node-graph/layout.js +136 -31
  188. package/dist/components/node-graph/layout.js.map +1 -1
  189. package/dist/components/node-graph/node-graph-legend.js.map +1 -1
  190. package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js +5 -5
  191. package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js.map +1 -1
  192. package/dist/components/node-graph/node-graph.js.map +1 -1
  193. package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js +3 -3
  194. package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js.map +1 -1
  195. package/dist/components/pagination/pagination-gap.js.map +1 -1
  196. package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js +2 -2
  197. package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/components/pagination/pagination.js.map +1 -1
  199. package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js +7 -7
  200. package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  201. package/dist/components/popconfirm/index.js +2 -0
  202. package/dist/components/popconfirm/index.js.map +1 -1
  203. package/dist/components/popconfirm/popconfirm.js.map +1 -1
  204. package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js +6 -2
  205. package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  206. package/dist/components/popover/index.js +2 -0
  207. package/dist/components/popover/index.js.map +1 -1
  208. package/dist/components/popover/popover.js.map +1 -1
  209. package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js +12 -5
  210. package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/components/progress-group/progress-group.js.map +1 -1
  212. package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js +11 -4
  213. package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/components/qrcode/qrcode.js.map +1 -1
  215. package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js +10 -2
  216. package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js.map +1 -1
  217. package/dist/components/select/select.js.map +1 -1
  218. package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js +2 -2
  219. package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/components/slider/slider.js.map +1 -1
  221. package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js +2 -2
  222. package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/components/status-dot/index.js +7 -0
  224. package/dist/components/status-dot/index.js.map +1 -0
  225. package/dist/components/status-dot/status-dot.js +26 -0
  226. package/dist/components/status-dot/status-dot.js.map +1 -0
  227. package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js +43 -0
  228. package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js.map +1 -0
  229. package/dist/components/status-dot/status-dot2.js +6 -0
  230. package/dist/components/status-dot/status-dot2.js.map +1 -0
  231. package/dist/components/status-dot/style.d.ts +1 -0
  232. package/dist/components/status-dot/style.js +2 -0
  233. package/dist/components/steps/steps.js.map +1 -1
  234. package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js +6 -6
  235. package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
  236. package/dist/components/table/table.js.map +1 -1
  237. package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js +19 -14
  238. package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js.map +1 -1
  239. package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js +1 -0
  240. package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  241. package/dist/components/tabs/tabs.js.map +1 -1
  242. package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js +117 -47
  243. package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/tabs/tabs2.js.map +1 -1
  245. package/dist/components/tag/tag.js.map +1 -1
  246. package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js +21 -4
  247. package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
  248. package/dist/components/timeline/style.js +1 -0
  249. package/dist/components/timeline/timeline-item.js.map +1 -1
  250. package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js +6 -2
  251. package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  252. package/dist/components/tooltip/index.js +2 -0
  253. package/dist/components/tooltip/index.js.map +1 -1
  254. package/dist/components/tooltip/tooltip.js.map +1 -1
  255. package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js +55 -8
  256. package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  257. package/dist/components/tour/tour.js.map +1 -1
  258. package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js +3 -3
  259. package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js.map +1 -1
  260. package/dist/components/transfer/transfer-list.vue_vue_type_script_setup_true_lang.js +1 -1
  261. package/dist/components/tree/tree.vue_vue_type_script_setup_true_lang.js +1 -1
  262. package/dist/components/tree-select/tree-select.js.map +1 -1
  263. package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js +3 -3
  264. package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  265. package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js +2 -2
  266. package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  267. package/dist/components/upload/upload2.js.map +1 -1
  268. package/dist/components/user/user.js.map +1 -1
  269. package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js +2 -2
  270. package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js.map +1 -1
  271. package/dist/composables/use-popup.js +30 -5
  272. package/dist/composables/use-popup.js.map +1 -1
  273. package/dist/index.js +23 -17
  274. package/dist/index.js.map +1 -1
  275. package/dist/locale/en.js +13 -8
  276. package/dist/locale/en.js.map +1 -1
  277. package/dist/locale/zh-cn.js +13 -8
  278. package/dist/locale/zh-cn.js.map +1 -1
  279. package/dist/locale/zh-tw.js +13 -8
  280. package/dist/locale/zh-tw.js.map +1 -1
  281. package/dist/plugin.js +21 -14
  282. package/dist/plugin.js.map +1 -1
  283. package/dist/style.css +1 -1
  284. package/dist/types/components/button/button.d.ts +5 -1
  285. package/dist/types/components/calendar-view/calendar-view.d.ts +6 -0
  286. package/dist/types/components/calendar-view/calendar-view.vue.d.ts +1 -0
  287. package/dist/types/components/calendar-view/index.d.ts +3 -0
  288. package/dist/types/components/chat-artifact/chat-artifact.d.ts +2 -1
  289. package/dist/types/components/chat-attachments/chat-attachments.d.ts +2 -2
  290. package/dist/types/components/chat-confirm/chat-confirm.d.ts +7 -2
  291. package/dist/types/components/chat-list/index.d.ts +3 -3
  292. package/dist/types/components/chat-message/chat-message.d.ts +26 -3
  293. package/dist/types/components/chat-message/chat-message.vue.d.ts +4 -3
  294. package/dist/types/components/chat-message/index.d.ts +7 -4
  295. package/dist/types/components/chat-plan/chat-plan.d.ts +19 -2
  296. package/dist/types/components/chat-plan/chat-plan.vue.d.ts +2 -0
  297. package/dist/types/components/chat-plan/index.d.ts +6 -0
  298. package/dist/types/components/chat-sources/chat-sources.d.ts +6 -1
  299. package/dist/types/components/chat-steps/chat-steps.d.ts +10 -4
  300. package/dist/types/components/chat-steps/chat-steps.vue.d.ts +1 -1
  301. package/dist/types/components/chat-steps/index.d.ts +3 -3
  302. package/dist/types/components/chat-tool-call/chat-tool-call.d.ts +12 -3
  303. package/dist/types/components/chat-tool-call/chat-tool-call.vue.d.ts +1 -0
  304. package/dist/types/components/chat-tool-call/index.d.ts +3 -0
  305. package/dist/types/components/checkbox/index.d.ts +5 -5
  306. package/dist/types/components/code-block/code-block.d.ts +11 -0
  307. package/dist/types/components/code-block/code-block.vue.d.ts +3 -1
  308. package/dist/types/components/code-block/index.d.ts +9 -3
  309. package/dist/types/components/collapse/collapse-transition.d.ts +2 -7
  310. package/dist/types/components/collapse/collapse.vue.d.ts +1 -1
  311. package/dist/types/components/collapse/index.d.ts +5 -6
  312. package/dist/types/components/context-menu/context-menu.d.ts +37 -4
  313. package/dist/types/components/context-menu/context-menu.vue.d.ts +2 -0
  314. package/dist/types/components/context-menu/index.d.ts +5 -0
  315. package/dist/types/components/copy-button/copy-button.vue.d.ts +1 -1
  316. package/dist/types/components/copy-button/index.d.ts +1 -1
  317. package/dist/types/components/descriptions/descriptions.d.ts +9 -1
  318. package/dist/types/components/descriptions/descriptions.vue.d.ts +1 -0
  319. package/dist/types/components/descriptions/index.d.ts +3 -0
  320. package/dist/types/components/dropdown/dropdown-group.vue.d.ts +13 -0
  321. package/dist/types/components/dropdown/dropdown-items.vue.d.ts +2 -2
  322. package/dist/types/components/dropdown/dropdown-radio-group.vue.d.ts +8 -4
  323. package/dist/types/components/dropdown/dropdown.d.ts +28 -6
  324. package/dist/types/components/dropdown/dropdown.vue.d.ts +1 -1
  325. package/dist/types/components/dropdown/index.d.ts +10 -81
  326. package/dist/types/components/dropdown/item-components.d.ts +103 -0
  327. package/dist/types/components/dropdown/menu-entries.d.ts +4 -0
  328. package/dist/types/components/index.d.ts +2 -0
  329. package/dist/types/components/layout/index.d.ts +12 -6
  330. package/dist/types/components/layout/layout-aside.vue.d.ts +1 -1
  331. package/dist/types/components/layout/layout-footer.vue.d.ts +4 -2
  332. package/dist/types/components/layout/layout.d.ts +4 -0
  333. package/dist/types/components/markdown/index.d.ts +58 -0
  334. package/dist/types/components/markdown/markdown.d.ts +251 -0
  335. package/dist/types/components/markdown/markdown.vue.d.ts +22 -0
  336. package/dist/types/components/markdown/parse-block.d.ts +61 -0
  337. package/dist/types/components/markdown/parse-inline.d.ts +19 -0
  338. package/dist/types/components/markdown/parser.d.ts +22 -0
  339. package/dist/types/components/markdown/render.d.ts +84 -0
  340. package/dist/types/components/markdown/url.d.ts +10 -0
  341. package/dist/types/components/masonry/index.d.ts +3 -3
  342. package/dist/types/components/menu/index.d.ts +8 -3
  343. package/dist/types/components/menu/menu.d.ts +16 -5
  344. package/dist/types/components/menu/menu.vue.d.ts +3 -1
  345. package/dist/types/components/menubar/menubar.d.ts +1 -1
  346. package/dist/types/components/node-graph/layout.d.ts +16 -0
  347. package/dist/types/components/node-graph/node-graph.d.ts +1 -1
  348. package/dist/types/components/popover/index.d.ts +3 -3
  349. package/dist/types/components/popover/popover.vue.d.ts +1 -1
  350. package/dist/types/components/progress-group/index.d.ts +3 -0
  351. package/dist/types/components/progress-group/progress-group.d.ts +7 -0
  352. package/dist/types/components/progress-group/progress-group.vue.d.ts +1 -0
  353. package/dist/types/components/qrcode/index.d.ts +3 -0
  354. package/dist/types/components/qrcode/qrcode.d.ts +5 -0
  355. package/dist/types/components/qrcode/qrcode.vue.d.ts +1 -0
  356. package/dist/types/components/sortable/index.d.ts +3 -3
  357. package/dist/types/components/status-dot/index.d.ts +51 -0
  358. package/dist/types/components/status-dot/status-dot.d.ts +46 -0
  359. package/dist/types/components/status-dot/status-dot.vue.d.ts +46 -0
  360. package/dist/types/components/steps/steps.d.ts +1 -1
  361. package/dist/types/components/switch/index.d.ts +3 -3
  362. package/dist/types/components/table/index.d.ts +4 -3
  363. package/dist/types/components/table/table.d.ts +6 -1
  364. package/dist/types/components/tabs/index.d.ts +3 -0
  365. package/dist/types/components/tabs/tabs.d.ts +16 -3
  366. package/dist/types/components/tabs/tabs.vue.d.ts +1 -0
  367. package/dist/types/components/timeline/index.d.ts +3 -3
  368. package/dist/types/components/timeline/timeline-item.vue.d.ts +1 -1
  369. package/dist/types/components/virtual-list/index.d.ts +3 -3
  370. package/dist/types/composables/use-popup.d.ts +15 -5
  371. package/dist/types/locale/types.d.ts +18 -7
  372. package/dist/types/utils/only-child.d.ts +3 -1
  373. package/dist/types/utils/pointer.d.ts +5 -0
  374. package/dist/types/utils/safe-url.d.ts +14 -0
  375. package/dist/types/utils/status-check.d.ts +8 -0
  376. package/dist/utils/install.js +5 -0
  377. package/dist/utils/install.js.map +1 -1
  378. package/dist/utils/only-child.js +56 -5
  379. package/dist/utils/only-child.js.map +1 -1
  380. package/dist/utils/pointer.js +6 -1
  381. package/dist/utils/pointer.js.map +1 -1
  382. package/dist/utils/safe-url.js +57 -0
  383. package/dist/utils/safe-url.js.map +1 -0
  384. package/dist/utils/status-check.js +27 -0
  385. package/dist/utils/status-check.js.map +1 -0
  386. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"chat-confirm.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_renderSlot","_createVNode","_createTextVNode","_toDisplayString","_createCommentVNode","_createBlock","_withCtx"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon } from '@dou-ui/icons'\nimport { computed, useId } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'pending',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst hasTitle = computed(() => !!props.title || !!slots.title)\nconst pending = computed(() => props.status === 'pending')\n</script>\n\n<template>\n <div\n :class=\"[ns.b(), ns.m(tone), ns.is(status)]\"\n role=\"group\"\n :aria-labelledby=\"hasTitle ? `${id}-title` : undefined\"\n >\n <div :class=\"ns.e('header')\">\n <span :class=\"ns.e('icon')\" aria-hidden=\"true\">\n <slot name=\"icon\"><ShieldIcon /></slot>\n </span>\n <div :class=\"ns.e('text')\">\n <div v-if=\"hasTitle\" :id=\"`${id}-title`\" :class=\"ns.e('title')\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"description\" :class=\"ns.e('description')\">{{ description }}</div>\n </div>\n <span v-if=\"!pending\" :class=\"ns.e('result')\" role=\"status\">\n <CheckIcon v-if=\"status === 'approved'\" aria-hidden=\"true\" />\n <CloseIcon v-else aria-hidden=\"true\" />\n {{ status === 'approved' ? t('chat.approved') : t('chat.denied') }}\n </span>\n </div>\n <div v-if=\"slots.default\" :class=\"ns.e('detail')\"><slot /></div>\n <div v-if=\"pending\" :class=\"ns.e('actions')\">\n <DouButton size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'deny')\">\n {{ denyText ?? t('chat.deny') }}\n </DouButton>\n <DouButton v-if=\"allowAlways\" size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'always')\">\n {{ t('chat.allowAlways') }}\n </DouButton>\n <DouButton\n size=\"sm\"\n :tone=\"tone === 'danger' ? 'danger' : 'neutral'\"\n @click=\"emit('decide', 'approve')\"\n >\n {{ approveText ?? t('chat.approve') }}\n </DouButton>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAUA,MAAM,QAAQ;EAKd,MAAM,OAAO;EACb,MAAM,QAAQA,SAAA;EAEd,MAAM,KAAK,aAAa,cAAc;EACtC,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,KAAK,MAAM;EAEjB,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,MAAM,KAAK;EAC9D,MAAM,UAAU,eAAe,MAAM,WAAW,SAAS;;GAIvD,OAAAC,UAAA,GAAAC,mBAqCM,OAAA;IApCH,OAAKC,eAAA;KAAGC,MAAA,EAAA,CAAE,CAAC,EAAC;KAAIA,MAAA,EAAA,CAAE,CAAC,EAAE,QAAA,IAAI;KAAGA,MAAA,EAAA,CAAE,CAAC,GAAG,QAAA,MAAM;IAAA,CAAA;IACzC,MAAK;IACJ,mBAAiB,SAAA,QAAQ,GAAMA,MAAA,EAAA,EAAE,UAAW,KAAA;;IAE7CC,mBAeM,OAAA,EAfA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA,E;KACfC,mBAEO,QAAA;MAFA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;MAAU,eAAY;K,IACtCE,WAAuC,KAAA,QAAA,QAAA,CAAA,SAAA,CAArBC,YAAcH,MAAA,UAAA,CAAA,C;KAElCC,mBAKM,OAAA,EALA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,E,IACJ,SAAA,SAAXH,UAAA,GAAAC,mBAEM,OAAA;;MAFgB,IAAE,GAAKE,MAAA,EAAA,EAAE;MAAW,OAAKD,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;K,IACnDE,WAAqC,KAAA,QAAA,SAAA,CAAA,SAAA,CAAfE,gBAAAC,gBAAA,QAAA,KAAK,GAAA,CAAA,C,sDAElB,QAAA,eAAXR,UAAA,GAAAC,mBAA4E,OAAA;;MAAnD,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,aAAA,CAAA;KAAoB,GAAAK,gBAAA,QAAA,WAAW,GAAA,CAAA,K;KAExD,CAAA,QAAA,SAAbR,UAAA,GAAAC,mBAIO,QAAA;;MAJgB,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;MAAY,MAAK;K,IAChC,QAAA,WAAM,cAAvBH,UAAA,GAAAU,YAA6DP,MAAA,SAAA,GAAA;;MAArB,eAAY;K,OACpDH,UAAA,GAAAU,YAAuCP,MAAA,SAAA,GAAA;;MAArB,eAAY;K,KAASI,gBAAA,MACvCC,gBAAG,QAAA,WAAM,aAAkBL,MAAA,CAAA,CAAC,CAAA,eAAA,IAAoBA,MAAA,CAAA,CAAC,CAAA,aAAA,CAAA,GAAA,CAAA,C;;IAG1C,MAAM,WAAjBH,UAAA,GAAAC,mBAAgE,OAAA;;KAArC,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;I,IAAYE,WAAQ,KAAA,QAAA,SAAA,C;IAC/C,QAAA,SAAXL,UAAA,GAAAC,mBAcM,OAAA;;KAde,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA;;KAC9BG,YAEYH,MAAA,SAAA,GAAA;MAFD,MAAK;MAAK,SAAQ;MAAW,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,UAAA,MAAA;;MACjD,SAAAQ,cAAgC,CAA7BJ,gBAAAC,gBAAA,QAAA,YAAYL,MAAA,CAAA,CAAC,CAAA,WAAA,CAAA,GAAA,CAAA,C;;;KAED,QAAA,eAAjBH,UAAA,GAAAU,YAEYP,MAAA,SAAA,GAAA;;MAFkB,MAAK;MAAK,SAAQ;MAAW,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,UAAA,QAAA;;MACpE,SAAAQ,cAA2B,CAAxBJ,gBAAAC,gBAAAL,MAAA,CAAA,CAAC,CAAA,kBAAA,CAAA,GAAA,CAAA,C;;;KAENG,YAMYH,MAAA,SAAA,GAAA;MALV,MAAK;MACJ,MAAM,QAAA,SAAI,WAAA,WAAA;MACV,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,UAAA,SAAA;;MAEZ,SAAAQ,cAAsC,CAAnCJ,gBAAAC,gBAAA,QAAA,eAAeL,MAAA,CAAA,CAAC,CAAA,cAAA,CAAA,GAAA,CAAA,C"}
1
+ {"version":3,"file":"chat-confirm.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_renderSlot","_createVNode","_createTextVNode","_toDisplayString","_createCommentVNode","_Fragment","_createBlock","_resolveDynamicComponent","_withCtx"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon, UndoIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useStatusCheck } from '../../utils/status-check'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'waiting',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst hasTitle = computed(() => !!props.title || !!slots.title)\nconst waiting = computed(() => props.status === 'waiting')\n// How each answered or withdrawn request reads once it has collapsed.\nconst outcomes = {\n approved: { icon: CheckIcon, text: 'chat.approved' },\n denied: { icon: CloseIcon, text: 'chat.denied' },\n withdrawn: { icon: UndoIcon, text: 'chat.withdrawn' },\n} as const\nconst outcome = computed(() =>\n Object.hasOwn(outcomes, props.status)\n ? outcomes[props.status as keyof typeof outcomes]\n : undefined,\n)\n\n// Answering or withdrawing removes the buttons; if focus was on one, keep it\n// on the card instead of losing it to the page. The watcher runs before the\n// DOM updates, while the focused button is still there to find.\nconst root = ref<HTMLElement>()\nwatch(\n () => props.status,\n (now, before) => {\n if (before !== 'waiting' || now === 'waiting') return\n if (!root.value?.contains(document.activeElement)) return\n void nextTick(() => root.value?.focus({ preventScroll: true }))\n },\n)\n\nconst statuses = ['waiting', 'approved', 'denied', 'withdrawn']\nuseStatusCheck('DouChatConfirm', () => [props.status], statuses, { pending: 'waiting' })\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[ns.b(), ns.m(tone), ns.is(status)]\"\n role=\"group\"\n tabindex=\"-1\"\n :aria-labelledby=\"hasTitle ? `${id}-title` : undefined\"\n >\n <div :class=\"ns.e('header')\">\n <span :class=\"ns.e('icon')\" aria-hidden=\"true\">\n <slot name=\"icon\"><ShieldIcon /></slot>\n </span>\n <div :class=\"ns.e('text')\">\n <div v-if=\"hasTitle\" :id=\"`${id}-title`\" :class=\"ns.e('title')\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"description\" :class=\"ns.e('description')\">{{ description }}</div>\n </div>\n <!-- always there, so screen readers announce the outcome when it appears -->\n <span :class=\"ns.e('result')\" role=\"status\">\n <template v-if=\"outcome\">\n <component :is=\"outcome.icon\" aria-hidden=\"true\" />\n {{ t(outcome.text) }}\n </template>\n </span>\n </div>\n <div v-if=\"slots.default\" :class=\"ns.e('detail')\"><slot /></div>\n <div v-if=\"waiting\" :class=\"ns.e('actions')\">\n <DouButton size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'deny')\">\n {{ denyText ?? t('chat.deny') }}\n </DouButton>\n <DouButton v-if=\"allowAlways\" size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'always')\">\n {{ t('chat.allowAlways') }}\n </DouButton>\n <DouButton\n size=\"sm\"\n :tone=\"tone === 'danger' ? 'danger' : 'neutral'\"\n @click=\"emit('decide', 'approve')\"\n >\n {{ approveText ?? t('chat.approve') }}\n </DouButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { useNamespace } from "../../utils/namespace.js";
2
2
  import { useLocale } from "../config-provider/use-config.js";
3
- import tooltip_default from "../tooltip/tooltip.js";
3
+ import { DouTooltip } from "../tooltip/index.js";
4
4
  import { compactNumber } from "./chat-context-meter.js";
5
5
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, openBlock, toDisplayString, unref, withCtx } from "vue";
6
6
  // src/components/chat-context-meter/chat-context-meter.vue?vue&type=script&setup=true&lang.ts
@@ -40,7 +40,7 @@ var chat_context_meter_vue_vue_type_script_setup_true_lang_default = /*@__PURE__
40
40
  }));
41
41
  const CIRCUMFERENCE = 2 * Math.PI * 6;
42
42
  return (_ctx, _cache) => {
43
- return openBlock(), createBlock(tooltip_default, { content: text.value }, {
43
+ return openBlock(), createBlock(unref(DouTooltip), { content: text.value }, {
44
44
  default: withCtx(() => [createElementVNode("span", mergeProps(_ctx.$attrs, {
45
45
  class: [unref(ns).b(), unref(ns).m(tone.value)],
46
46
  role: "meter",
@@ -1 +1 @@
1
- {"version":3,"file":"chat-context-meter.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","DouTooltip","_withCtx","_createElementVNode","_mergeProps","_unref","_createElementBlock","_normalizeClass","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/chat-context-meter/chat-context-meter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useLocale } from '../config-provider/use-config'\nimport DouTooltip from '../tooltip/tooltip.vue'\nimport { compactNumber } from './chat-context-meter'\nimport type { ChatContextMeterProps } from './chat-context-meter'\n\ndefineOptions({ name: 'DouChatContextMeter', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatContextMeterProps>(), {\n used: 0,\n total: 0,\n warnAt: 0.8,\n dangerAt: 0.95,\n showLabel: false,\n})\n\nconst ns = useNamespace('chat-context-meter')\nconst { t } = useLocale()\n\nconst share = computed(() =>\n props.total > 0 ? Math.min(Math.max(props.used / props.total, 0), 1) : 0,\n)\nconst percent = computed(() => Math.round(share.value * 100))\nconst tone = computed(() =>\n share.value >= props.dangerAt ? 'danger' : share.value >= props.warnAt ? 'warning' : 'neutral',\n)\nconst fmt = (value: number) => (props.format ?? compactNumber)(value)\nconst text = computed(() =>\n t('chat.context', { used: fmt(props.used), total: fmt(props.total), percent: percent.value }),\n)\n\n// r = 6 on a 16 box; the circumference drives the dash\nconst CIRCUMFERENCE = 2 * Math.PI * 6\n</script>\n\n<template>\n <DouTooltip :content=\"text\">\n <span\n v-bind=\"$attrs\"\n :class=\"[ns.b(), ns.m(tone)]\"\n role=\"meter\"\n tabindex=\"0\"\n :aria-label=\"t('chat.contextLabel')\"\n :aria-valuenow=\"percent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuetext=\"text\"\n >\n <svg :class=\"ns.e('ring')\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle :class=\"ns.e('track')\" cx=\"8\" cy=\"8\" r=\"6\" />\n <circle\n :class=\"ns.e('bar')\"\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n :stroke-dasharray=\"`${CIRCUMFERENCE * share} ${CIRCUMFERENCE}`\"\n />\n </svg>\n <span v-if=\"showLabel\" :class=\"ns.e('label')\">{{ percent }}%</span>\n </span>\n </DouTooltip>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUA,MAAM,QAAQ;EAQd,MAAM,KAAK,aAAa,oBAAoB;EAC5C,MAAM,EAAE,MAAM,UAAU;EAExB,MAAM,QAAQ,eACZ,MAAM,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CACzE;EACA,MAAM,UAAU,eAAe,KAAK,MAAM,MAAM,QAAQ,GAAG,CAAC;EAC5D,MAAM,OAAO,eACX,MAAM,SAAS,MAAM,WAAW,WAAW,MAAM,SAAS,MAAM,SAAS,YAAY,SACvF;EACA,MAAM,OAAO,WAAmB,MAAM,UAAU,cAAA,CAAe,KAAK;EACpE,MAAM,OAAO,eACX,EAAE,gBAAgB;GAAE,MAAM,IAAI,MAAM,IAAI;GAAG,OAAO,IAAI,MAAM,KAAK;GAAG,SAAS,QAAQ;EAAM,CAAC,CAC9F;EAGA,MAAM,gBAAgB,IAAI,KAAK,KAAK;;GAIlC,OAAAC,UAAA,GAAAC,YAwBaC,iBAAA,EAxBA,SAAS,KAAA,MAAI,GAAA;IACxB,SAAAC,cAsBO,CAtBPC,mBAsBO,QAtBPC,WACUN,KAqBH,QArBS;KACb,OAAK,CAAGO,MAAA,EAAA,CAAE,CAAC,EAAC,GAAIA,MAAA,EAAA,CAAE,CAAC,EAAE,KAAA,KAAI,CAAA;KAC1B,MAAK;KACL,UAAS;KACR,cAAYA,MAAA,CAAA,CAAC,CAAA,mBAAA;KACb,iBAAe,QAAA;KAChB,iBAAc;KACd,iBAAc;KACb,kBAAgB,KAAA;I,MAEjBN,UAAA,GAAAO,mBASM,OAAA;KATA,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;KAAU,SAAQ;KAAY,eAAY;I,IACzDF,mBAAqD,UAAA;KAA5C,OAAKI,eAAEF,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;KAAW,IAAG;KAAI,IAAG;KAAI,GAAE;I,aAC/CF,mBAME,UAAA;KALC,OAAKI,eAAEF,MAAA,EAAA,CAAE,CAAC,EAAC,KAAA,CAAA;KACZ,IAAG;KACH,IAAG;KACH,GAAE;KACD,oBAAgB,GAAK,gBAAgB,MAAA,MAAK,GAAI;I,gCAGvC,QAAA,aAAZN,UAAA,GAAAO,mBAAmE,QAAA;;KAA3C,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;IAAc,GAAAG,gBAAA,QAAA,KAAO,IAAG,KAAC,CAAA,K"}
1
+ {"version":3,"file":"chat-context-meter.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_unref","_withCtx","_createElementVNode","_mergeProps","_createElementBlock","_normalizeClass","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/chat-context-meter/chat-context-meter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouTooltip } from '../tooltip'\nimport { compactNumber } from './chat-context-meter'\nimport type { ChatContextMeterProps } from './chat-context-meter'\n\ndefineOptions({ name: 'DouChatContextMeter', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatContextMeterProps>(), {\n used: 0,\n total: 0,\n warnAt: 0.8,\n dangerAt: 0.95,\n showLabel: false,\n})\n\nconst ns = useNamespace('chat-context-meter')\nconst { t } = useLocale()\n\nconst share = computed(() =>\n props.total > 0 ? Math.min(Math.max(props.used / props.total, 0), 1) : 0,\n)\nconst percent = computed(() => Math.round(share.value * 100))\nconst tone = computed(() =>\n share.value >= props.dangerAt ? 'danger' : share.value >= props.warnAt ? 'warning' : 'neutral',\n)\nconst fmt = (value: number) => (props.format ?? compactNumber)(value)\nconst text = computed(() =>\n t('chat.context', { used: fmt(props.used), total: fmt(props.total), percent: percent.value }),\n)\n\n// r = 6 on a 16 box; the circumference drives the dash\nconst CIRCUMFERENCE = 2 * Math.PI * 6\n</script>\n\n<template>\n <DouTooltip :content=\"text\">\n <span\n v-bind=\"$attrs\"\n :class=\"[ns.b(), ns.m(tone)]\"\n role=\"meter\"\n tabindex=\"0\"\n :aria-label=\"t('chat.contextLabel')\"\n :aria-valuenow=\"percent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuetext=\"text\"\n >\n <svg :class=\"ns.e('ring')\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle :class=\"ns.e('track')\" cx=\"8\" cy=\"8\" r=\"6\" />\n <circle\n :class=\"ns.e('bar')\"\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n :stroke-dasharray=\"`${CIRCUMFERENCE * share} ${CIRCUMFERENCE}`\"\n />\n </svg>\n <span v-if=\"showLabel\" :class=\"ns.e('label')\">{{ percent }}%</span>\n </span>\n </DouTooltip>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUA,MAAM,QAAQ;EAQd,MAAM,KAAK,aAAa,oBAAoB;EAC5C,MAAM,EAAE,MAAM,UAAU;EAExB,MAAM,QAAQ,eACZ,MAAM,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CACzE;EACA,MAAM,UAAU,eAAe,KAAK,MAAM,MAAM,QAAQ,GAAG,CAAC;EAC5D,MAAM,OAAO,eACX,MAAM,SAAS,MAAM,WAAW,WAAW,MAAM,SAAS,MAAM,SAAS,YAAY,SACvF;EACA,MAAM,OAAO,WAAmB,MAAM,UAAU,cAAA,CAAe,KAAK;EACpE,MAAM,OAAO,eACX,EAAE,gBAAgB;GAAE,MAAM,IAAI,MAAM,IAAI;GAAG,OAAO,IAAI,MAAM,KAAK;GAAG,SAAS,QAAQ;EAAM,CAAC,CAC9F;EAGA,MAAM,gBAAgB,IAAI,KAAK,KAAK;;GAIlC,OAAAC,UAAA,GAAAC,YAwBaC,MAAA,UAAA,GAAA,EAxBA,SAAS,KAAA,MAAI,GAAA;IACxB,SAAAC,cAsBO,CAtBPC,mBAsBO,QAtBPC,WACUN,KAqBH,QArBS;KACb,OAAK,CAAGG,MAAA,EAAA,CAAE,CAAC,EAAC,GAAIA,MAAA,EAAA,CAAE,CAAC,EAAE,KAAA,KAAI,CAAA;KAC1B,MAAK;KACL,UAAS;KACR,cAAYA,MAAA,CAAA,CAAC,CAAA,mBAAA;KACb,iBAAe,QAAA;KAChB,iBAAc;KACd,iBAAc;KACb,kBAAgB,KAAA;I,MAEjBF,UAAA,GAAAM,mBASM,OAAA;KATA,OAAKC,eAAEL,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;KAAU,SAAQ;KAAY,eAAY;I,IACzDE,mBAAqD,UAAA;KAA5C,OAAKG,eAAEL,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;KAAW,IAAG;KAAI,IAAG;KAAI,GAAE;I,aAC/CE,mBAME,UAAA;KALC,OAAKG,eAAEL,MAAA,EAAA,CAAE,CAAC,EAAC,KAAA,CAAA;KACZ,IAAG;KACH,IAAG;KACH,GAAE;KACD,oBAAgB,GAAK,gBAAgB,MAAA,MAAK,GAAI;I,gCAGvC,QAAA,aAAZF,UAAA,GAAAM,mBAAmE,QAAA;;KAA3C,OAAKC,eAAEL,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;IAAc,GAAAM,gBAAA,QAAA,KAAO,IAAG,KAAC,CAAA,K"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-context-meter2.js","names":["_sfc_main"],"sources":["../../../src/components/chat-context-meter/chat-context-meter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useLocale } from '../config-provider/use-config'\nimport DouTooltip from '../tooltip/tooltip.vue'\nimport { compactNumber } from './chat-context-meter'\nimport type { ChatContextMeterProps } from './chat-context-meter'\n\ndefineOptions({ name: 'DouChatContextMeter', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatContextMeterProps>(), {\n used: 0,\n total: 0,\n warnAt: 0.8,\n dangerAt: 0.95,\n showLabel: false,\n})\n\nconst ns = useNamespace('chat-context-meter')\nconst { t } = useLocale()\n\nconst share = computed(() =>\n props.total > 0 ? Math.min(Math.max(props.used / props.total, 0), 1) : 0,\n)\nconst percent = computed(() => Math.round(share.value * 100))\nconst tone = computed(() =>\n share.value >= props.dangerAt ? 'danger' : share.value >= props.warnAt ? 'warning' : 'neutral',\n)\nconst fmt = (value: number) => (props.format ?? compactNumber)(value)\nconst text = computed(() =>\n t('chat.context', { used: fmt(props.used), total: fmt(props.total), percent: percent.value }),\n)\n\n// r = 6 on a 16 box; the circumference drives the dash\nconst CIRCUMFERENCE = 2 * Math.PI * 6\n</script>\n\n<template>\n <DouTooltip :content=\"text\">\n <span\n v-bind=\"$attrs\"\n :class=\"[ns.b(), ns.m(tone)]\"\n role=\"meter\"\n tabindex=\"0\"\n :aria-label=\"t('chat.contextLabel')\"\n :aria-valuenow=\"percent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuetext=\"text\"\n >\n <svg :class=\"ns.e('ring')\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle :class=\"ns.e('track')\" cx=\"8\" cy=\"8\" r=\"6\" />\n <circle\n :class=\"ns.e('bar')\"\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n :stroke-dasharray=\"`${CIRCUMFERENCE * share} ${CIRCUMFERENCE}`\"\n />\n </svg>\n <span v-if=\"showLabel\" :class=\"ns.e('label')\">{{ percent }}%</span>\n </span>\n </DouTooltip>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"chat-context-meter2.js","names":["_sfc_main"],"sources":["../../../src/components/chat-context-meter/chat-context-meter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouTooltip } from '../tooltip'\nimport { compactNumber } from './chat-context-meter'\nimport type { ChatContextMeterProps } from './chat-context-meter'\n\ndefineOptions({ name: 'DouChatContextMeter', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatContextMeterProps>(), {\n used: 0,\n total: 0,\n warnAt: 0.8,\n dangerAt: 0.95,\n showLabel: false,\n})\n\nconst ns = useNamespace('chat-context-meter')\nconst { t } = useLocale()\n\nconst share = computed(() =>\n props.total > 0 ? Math.min(Math.max(props.used / props.total, 0), 1) : 0,\n)\nconst percent = computed(() => Math.round(share.value * 100))\nconst tone = computed(() =>\n share.value >= props.dangerAt ? 'danger' : share.value >= props.warnAt ? 'warning' : 'neutral',\n)\nconst fmt = (value: number) => (props.format ?? compactNumber)(value)\nconst text = computed(() =>\n t('chat.context', { used: fmt(props.used), total: fmt(props.total), percent: percent.value }),\n)\n\n// r = 6 on a 16 box; the circumference drives the dash\nconst CIRCUMFERENCE = 2 * Math.PI * 6\n</script>\n\n<template>\n <DouTooltip :content=\"text\">\n <span\n v-bind=\"$attrs\"\n :class=\"[ns.b(), ns.m(tone)]\"\n role=\"meter\"\n tabindex=\"0\"\n :aria-label=\"t('chat.contextLabel')\"\n :aria-valuenow=\"percent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuetext=\"text\"\n >\n <svg :class=\"ns.e('ring')\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle :class=\"ns.e('track')\" cx=\"8\" cy=\"8\" r=\"6\" />\n <circle\n :class=\"ns.e('bar')\"\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n :stroke-dasharray=\"`${CIRCUMFERENCE * share} ${CIRCUMFERENCE}`\"\n />\n </svg>\n <span v-if=\"showLabel\" :class=\"ns.e('label')\">{{ percent }}%</span>\n </span>\n </DouTooltip>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.js","names":[],"sources":["../../../src/components/chat-message/chat-message.ts"],"sourcesContent":["import type { ChatArtifactKind, ChatArtifactStatus } from '../chat-artifact/chat-artifact'\nimport type { ChatAttachment } from '../chat-attachments/chat-attachments'\nimport type {\n ChatConfirmDecision,\n ChatConfirmStatus,\n ChatConfirmTone,\n} from '../chat-confirm/chat-confirm'\nimport type { ChatPlanItem } from '../chat-plan/chat-plan'\nimport type { ChatSource } from '../chat-sources/chat-sources'\nimport type { ChatStep } from '../chat-steps/chat-steps'\nimport type { ChatToolCallStatus } from '../chat-tool-call/chat-tool-call'\n\n/** Who wrote the message. */\nexport type ChatMessageSender = 'user' | 'assistant' | 'system'\n\nexport interface ChatTextPart {\n type: 'text'\n text: string\n /** More text is still coming. */\n streaming?: boolean\n}\nexport interface ChatReasoningPart {\n type: 'reasoning'\n text: string\n thinking?: boolean\n /** Seconds it took. */\n duration?: number\n}\nexport interface ChatToolPart {\n type: 'tool'\n name?: string\n title?: string\n status?: ChatToolCallStatus\n input?: unknown\n output?: unknown\n}\nexport interface ChatStepsPart {\n type: 'steps'\n items: ChatStep[]\n running?: boolean\n title?: string\n}\nexport interface ChatPlanPart {\n type: 'plan'\n items: ChatPlanItem[]\n title?: string\n}\nexport interface ChatSourcesPart {\n type: 'sources'\n items: ChatSource[]\n}\nexport interface ChatFilesPart {\n type: 'files'\n files: ChatAttachment[]\n}\nexport interface ChatArtifactPart {\n type: 'artifact'\n /** Handed back with `artifact`, to tell artifacts apart. */\n id?: string | number\n title: string\n kind?: ChatArtifactKind\n description?: string\n status?: ChatArtifactStatus\n active?: boolean\n}\nexport interface ChatConfirmPart {\n type: 'confirm'\n /** Handed back with `confirm`, to tell requests apart. */\n id?: string | number\n title: string\n description?: string\n status?: ChatConfirmStatus\n allowAlways?: boolean\n tone?: ChatConfirmTone\n /** Shown as monospace detail, e.g. the command to run or a diff. */\n detail?: string\n}\n/** Any other part; render it with the `part` slot. */\nexport interface ChatCustomPart {\n type: string\n [key: string]: unknown\n}\n\nexport type ChatMessagePart =\n | ChatTextPart\n | ChatReasoningPart\n | ChatToolPart\n | ChatStepsPart\n | ChatPlanPart\n | ChatSourcesPart\n | ChatFilesPart\n | ChatArtifactPart\n | ChatConfirmPart\n\nexport interface ChatMessageProps {\n sender?: ChatMessageSender\n /**\n * What the message is made of, in order: text, reasoning, tool calls,\n * steps, a plan, sources, files, artifacts and confirmations may follow\n * one another in any order.\n */\n parts?: (ChatMessagePart | ChatCustomPart)[]\n /** Shorthand for a message of one text part. */\n content?: string\n /** No part has arrived yet: show the waiting dots, like ChatBubble's. */\n loading?: boolean\n /** Show a copy button among the actions, copying the text parts. */\n copyable?: boolean\n /** Offer an edit button on the person's own messages; saving emits `edit`. */\n editable?: boolean\n /** How many versions of this message there are, e.g. after regenerating. Two or more show a switcher. */\n versions?: number\n /** Which version is shown, from 1. Bound with `v-model:version`. */\n version?: number\n}\n\nexport interface ChatMessageEmits {\n 'update:version': [version: number]\n /** An edited message was saved, with its new text. */\n edit: [text: string]\n /** A confirmation part was answered. */\n confirm: [part: ChatConfirmPart, decision: ChatConfirmDecision]\n /** An artifact part was pressed. */\n artifact: [part: ChatArtifactPart]\n}\n\nexport interface ChatMessageSlots {\n /**\n * Renders a text part, e.g. through a Markdown renderer. `text` is what\n * has been revealed so far.\n */\n text?: (props: { part: ChatTextPart; text: string; index: number }) => unknown\n /** Renders parts of a type the message does not know. */\n part?: (props: { part: ChatCustomPart; index: number }) => unknown\n /** Buttons after the built-in actions, e.g. regenerate or feedback. */\n actions?: () => unknown\n /** Replaces all parts, for a message laid out by hand. */\n default?: () => unknown\n}\n\n/** The text of a message, for copying: its text parts, one paragraph each. */\nexport function messageText(parts: readonly { type: string; text?: unknown }[]): string {\n return parts\n .filter((part) => part.type === 'text' && typeof part.text === 'string')\n .map((part) => part.text as string)\n .join('\\n\\n')\n}\n"],"mappings":";;AA6IA,SAAgB,YAAY,OAA4D;CACtF,OAAO,MACJ,QAAQ,SAAS,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,QAAQ,CAAC,CACvE,KAAK,SAAS,KAAK,IAAc,CAAC,CAClC,KAAK,MAAM;AAChB"}
1
+ {"version":3,"file":"chat-message.js","names":[],"sources":["../../../src/components/chat-message/chat-message.ts"],"sourcesContent":["import type { ChatArtifactKind, ChatArtifactStatus } from '../chat-artifact/chat-artifact'\nimport type { ChatAttachment } from '../chat-attachments/chat-attachments'\nimport type {\n ChatConfirmDecision,\n ChatConfirmStatus,\n ChatConfirmTone,\n} from '../chat-confirm/chat-confirm'\nimport type { ChatPlanItem } from '../chat-plan/chat-plan'\nimport type { ChatSource } from '../chat-sources/chat-sources'\nimport type { ChatStep } from '../chat-steps/chat-steps'\nimport type { ChatToolCallStatus } from '../chat-tool-call/chat-tool-call'\nimport type { MarkdownProps, MarkdownSlots } from '../markdown/markdown'\n\n/** Options for the Markdown of text and reasoning parts. */\nexport type ChatMessageMarkdown = Pick<\n MarkdownProps,\n 'smooth' | 'speed' | 'caret' | 'linkTarget' | 'sanitizeUrl'\n>\n\n/** Who wrote the message. */\nexport type ChatMessageSender = 'user' | 'assistant' | 'system'\n\nexport interface ChatTextPart {\n type: 'text'\n text: string\n /** More text is still coming. */\n streaming?: boolean\n}\nexport interface ChatReasoningPart {\n type: 'reasoning'\n text: string\n thinking?: boolean\n /** Seconds it took. */\n duration?: number\n}\nexport interface ChatToolPart {\n type: 'tool'\n name?: string\n title?: string\n status?: ChatToolCallStatus\n input?: unknown\n output?: unknown\n live?: boolean\n}\nexport interface ChatStepsPart {\n type: 'steps'\n items: ChatStep[]\n live?: boolean\n title?: string\n}\nexport interface ChatPlanPart {\n type: 'plan'\n items: ChatPlanItem[]\n title?: string\n collapsible?: boolean\n live?: boolean\n}\nexport interface ChatSourcesPart {\n type: 'sources'\n items: ChatSource[]\n}\nexport interface ChatFilesPart {\n type: 'files'\n files: ChatAttachment[]\n}\nexport interface ChatArtifactPart {\n type: 'artifact'\n /** Handed back with `artifact`, to tell artifacts apart. */\n id?: string | number\n title: string\n kind?: ChatArtifactKind\n description?: string\n status?: ChatArtifactStatus\n active?: boolean\n}\nexport interface ChatConfirmPart {\n type: 'confirm'\n /** Handed back with `confirm`, to tell requests apart. */\n id?: string | number\n title: string\n description?: string\n status?: ChatConfirmStatus\n allowAlways?: boolean\n tone?: ChatConfirmTone\n /** Shown as monospace detail, e.g. the command to run or a diff. */\n detail?: string\n}\n/** Any other part; render it with the `part` slot. */\nexport interface ChatCustomPart {\n type: string\n [key: string]: unknown\n}\n\nexport type ChatMessagePart =\n | ChatTextPart\n | ChatReasoningPart\n | ChatToolPart\n | ChatStepsPart\n | ChatPlanPart\n | ChatSourcesPart\n | ChatFilesPart\n | ChatArtifactPart\n | ChatConfirmPart\n\nexport interface ChatMessageProps {\n sender?: ChatMessageSender\n /**\n * What the message is made of, in order: text, reasoning, tool calls,\n * steps, a plan, sources, files, artifacts and confirmations may follow\n * one another in any order.\n */\n parts?: (ChatMessagePart | ChatCustomPart)[]\n /** Shorthand for a message of one text part. */\n content?: string\n /**\n * Render text and reasoning parts as Markdown, streaming included. `[1]`\n * in the text becomes a citation of the message's sources parts. An\n * object turns it on with options for the Markdown component, such as\n * `sanitizeUrl`. Set it for every message in the ConfigProvider's\n * `defaults`.\n */\n markdown?: boolean | ChatMessageMarkdown\n /** No part has arrived yet: show the waiting dots, like ChatBubble's. */\n loading?: boolean\n /** Show a copy button among the actions, copying the text parts. */\n copyable?: boolean\n /** Offer an edit button on the person's own messages; saving emits `edit`. */\n editable?: boolean\n /** How many versions of this message there are, e.g. after regenerating. Two or more show a switcher. */\n versions?: number\n /** Which version is shown, from 1. Bound with `v-model:version`. */\n version?: number\n}\n\nexport interface ChatMessageEmits {\n 'update:version': [version: number]\n /** An edited message was saved, with its new text. */\n edit: [text: string]\n /** A confirmation part was answered. */\n confirm: [part: ChatConfirmPart, decision: ChatConfirmDecision]\n /** An artifact part was pressed. */\n artifact: [part: ChatArtifactPart]\n}\n\nexport interface ChatMessageSlots {\n /**\n * Renders a text part by hand, in place of plain text or `markdown`.\n * `text` is what has been revealed so far; `part.text` is all of it.\n * `sources` are the message's sources, for citations.\n */\n text?: (props: {\n part: ChatTextPart\n text: string\n index: number\n sources: ChatSource[]\n }) => unknown\n /** Renders parts of a type the message does not know. */\n part?: (props: { part: ChatCustomPart; index: number }) => unknown\n /** Buttons after the built-in actions, e.g. regenerate or feedback. */\n actions?: () => unknown\n /** Replaces all parts, for a message laid out by hand. */\n default?: () => unknown\n}\n\n/**\n * The Markdown component's slots, with a `markdown-` prefix, for text\n * rendered with `markdown`: `markdown-code`, `markdown-container-tip`, ...\n */\nexport type ChatMessageMarkdownSlots = {\n [K in keyof MarkdownSlots as `markdown-${K & string}`]: MarkdownSlots[K]\n}\n\n/** The text of a message, for copying: its text parts, one paragraph each. */\nexport function messageText(parts: readonly { type: string; text?: unknown }[]): string {\n return parts\n .filter((part) => part.type === 'text' && typeof part.text === 'string')\n .map((part) => part.text as string)\n .join('\\n\\n')\n}\n"],"mappings":";;AA6KA,SAAgB,YAAY,OAA4D;CACtF,OAAO,MACJ,QAAQ,SAAS,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,QAAQ,CAAC,CACvE,KAAK,SAAS,KAAK,IAAc,CAAC,CAClC,KAAK,MAAM;AAChB"}
@@ -2,17 +2,20 @@ import { useNamespace } from "../../utils/namespace.js";
2
2
  import { useLocale } from "../config-provider/use-config.js";
3
3
  import { isComposing } from "../../utils/keyboard.js";
4
4
  import { DouButton } from "../button/index.js";
5
- import chat_artifact_default from "../chat-artifact/chat-artifact.js";
6
- import chat_attachments_default from "../chat-attachments/chat-attachments2.js";
7
- import chat_confirm_default from "../chat-confirm/chat-confirm.js";
8
- import tooltip_default from "../tooltip/tooltip.js";
9
- import chat_plan_default from "../chat-plan/chat-plan.js";
10
- import chat_reasoning_default from "../chat-reasoning/chat-reasoning.js";
11
- import chat_sources_default from "../chat-sources/chat-sources2.js";
12
- import chat_steps_default from "../chat-steps/chat-steps.js";
13
- import chat_tool_call_default from "../chat-tool-call/chat-tool-call2.js";
14
- import copy_button_default from "../copy-button/copy-button.js";
15
- import stream_text_default from "../stream-text/stream-text2.js";
5
+ import { DouChatArtifact } from "../chat-artifact/index.js";
6
+ import { DouChatAttachments } from "../chat-attachments/index.js";
7
+ import { DouChatConfirm } from "../chat-confirm/index.js";
8
+ import { DouTooltip } from "../tooltip/index.js";
9
+ import { planRunning } from "../chat-plan/chat-plan.js";
10
+ import { DouChatPlan } from "../chat-plan/index.js";
11
+ import { DouChatReasoning } from "../chat-reasoning/index.js";
12
+ import { DouChatSources } from "../chat-sources/index.js";
13
+ import { stepsLive } from "../chat-steps/chat-steps.js";
14
+ import { DouChatSteps } from "../chat-steps/index.js";
15
+ import { DouChatToolCall } from "../chat-tool-call/index.js";
16
+ import { DouCopyButton } from "../copy-button/index.js";
17
+ import { DouMarkdown } from "../markdown/index.js";
18
+ import { DouStreamText } from "../stream-text/index.js";
16
19
  import { messageText } from "./chat-message.js";
17
20
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useSlots, useTemplateRef, vModelText, withCtx, withDirectives } from "vue";
18
21
  import { ChevronLeftIcon, ChevronRightIcon, EditIcon } from "@dou-ui/icons";
@@ -21,6 +24,7 @@ var _hoisted_1 = ["aria-busy"];
21
24
  var _hoisted_2 = ["aria-label"];
22
25
  var _hoisted_3 = ["aria-label"];
23
26
  var _hoisted_4 = ["aria-label"];
27
+ var PREFIX = "markdown-";
24
28
  var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
25
29
  name: "DouChatMessage",
26
30
  __name: "chat-message",
@@ -28,6 +32,10 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
28
32
  sender: { default: "assistant" },
29
33
  parts: {},
30
34
  content: {},
35
+ markdown: {
36
+ type: [Boolean, Object],
37
+ default: false
38
+ },
31
39
  loading: {
32
40
  type: Boolean,
33
41
  default: false
@@ -59,13 +67,28 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
59
67
  type: "text",
60
68
  text: props.content
61
69
  }]));
70
+ const markdownOptions = computed(() => typeof props.markdown === "object" ? props.markdown : void 0);
71
+ const markdownSlots = () => Object.keys(slots).filter((name) => name.startsWith(PREFIX)).map((name) => ({
72
+ name,
73
+ inner: name.slice(9)
74
+ }));
62
75
  const isUser = computed(() => props.sender === "user");
63
76
  const files = computed(() => isUser.value ? parts.value.filter((p) => p.type === "files") : []);
64
77
  const body = computed(() => isUser.value ? parts.value.filter((p) => p.type !== "files") : parts.value);
65
78
  const text = computed(() => messageText(parts.value));
79
+ let lastSources = [];
80
+ const sources = computed(() => {
81
+ const next = parts.value.flatMap((part) => part.type === "sources" ? part.items ?? [] : []);
82
+ if (next.length === lastSources.length && next.every((s, i) => s === lastSources[i])) return lastSources;
83
+ return lastSources = next;
84
+ });
66
85
  const busy = computed(() => props.loading || parts.value.some((part) => {
67
86
  const p = part;
68
- return !!p.streaming || !!p.thinking || !!p.running || p.status === "running";
87
+ const working = p.status === "running" && p.type !== "artifact" && p.live !== false;
88
+ const live = p.live;
89
+ const steps = p.type === "steps" && stepsLive(p.items, live);
90
+ const plan = p.type === "plan" && planRunning(p.items, live);
91
+ return !!p.streaming || !!p.thinking || steps || plan || working;
69
92
  }));
70
93
  const innerVersion = ref(props.versions);
71
94
  const version = computed(() => Math.min(props.version ?? innerVersion.value, props.versions));
@@ -145,7 +168,7 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
145
168
  key: 0,
146
169
  class: normalizeClass(unref(ns).e("files"))
147
170
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(files.value, (part, index) => {
148
- return openBlock(), createBlock(chat_attachments_default, {
171
+ return openBlock(), createBlock(unref(DouChatAttachments), {
149
172
  key: `f${index}`,
150
173
  "model-value": asFiles(part).files,
151
174
  removable: false
@@ -180,8 +203,26 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
180
203
  key: 2,
181
204
  class: normalizeClass(unref(ns).e("content"))
182
205
  }, [renderSlot(_ctx.$slots, "default", {}, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(body.value, (part, index) => {
183
- return openBlock(), createElementBlock(Fragment, { key: index }, [part.type === "text" ? (openBlock(), createBlock(stream_text_default, {
206
+ return openBlock(), createElementBlock(Fragment, { key: index }, [part.type === "text" && __props.markdown && !slots.text ? (openBlock(), createBlock(unref(DouMarkdown), mergeProps({
184
207
  key: 0,
208
+ ref_for: true
209
+ }, markdownOptions.value, {
210
+ class: unref(ns).e("text"),
211
+ content: asText(part).text,
212
+ streaming: !!asText(part).streaming,
213
+ sources: sources.value.length ? sources.value : void 0
214
+ }), createSlots({ _: 2 }, [renderList(markdownSlots(), (slot) => {
215
+ return {
216
+ name: slot.inner,
217
+ fn: withCtx((scope) => [renderSlot(_ctx.$slots, slot.name, mergeProps({ ref_for: true }, scope))])
218
+ };
219
+ })]), 1040, [
220
+ "class",
221
+ "content",
222
+ "streaming",
223
+ "sources"
224
+ ])) : part.type === "text" ? (openBlock(), createBlock(unref(DouStreamText), {
225
+ key: 1,
185
226
  class: normalizeClass(unref(ns).e("text")),
186
227
  content: asText(part).text,
187
228
  streaming: !!asText(part).streaming
@@ -190,45 +231,59 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
190
231
  fn: withCtx(({ text: shown }) => [renderSlot(_ctx.$slots, "text", {
191
232
  part: asText(part),
192
233
  text: shown,
193
- index
234
+ index,
235
+ sources: sources.value
194
236
  })]),
195
237
  key: "0"
196
238
  } : void 0]), 1032, [
197
239
  "class",
198
240
  "content",
199
241
  "streaming"
200
- ])) : part.type === "reasoning" ? (openBlock(), createBlock(chat_reasoning_default, {
201
- key: 1,
242
+ ])) : part.type === "reasoning" ? (openBlock(), createBlock(unref(DouChatReasoning), {
243
+ key: 2,
202
244
  thinking: !!asReasoning(part).thinking,
203
245
  duration: asReasoning(part).duration
204
246
  }, {
205
- default: withCtx(() => [createVNode(stream_text_default, {
247
+ default: withCtx(() => [__props.markdown ? (openBlock(), createBlock(unref(DouMarkdown), mergeProps({
248
+ key: 0,
249
+ ref_for: true
250
+ }, markdownOptions.value, {
206
251
  content: asReasoning(part).text,
207
252
  streaming: !!asReasoning(part).thinking,
208
253
  caret: false
209
- }, null, 8, ["content", "streaming"])]),
254
+ }), createSlots({ _: 2 }, [renderList(markdownSlots(), (slot) => {
255
+ return {
256
+ name: slot.inner,
257
+ fn: withCtx((scope) => [renderSlot(_ctx.$slots, slot.name, mergeProps({ ref_for: true }, scope))])
258
+ };
259
+ })]), 1040, ["content", "streaming"])) : (openBlock(), createBlock(unref(DouStreamText), {
260
+ key: 1,
261
+ content: asReasoning(part).text,
262
+ streaming: !!asReasoning(part).thinking,
263
+ caret: false
264
+ }, null, 8, ["content", "streaming"]))]),
210
265
  _: 2
211
- }, 1032, ["thinking", "duration"])) : part.type === "tool" ? (openBlock(), createBlock(chat_tool_call_default, mergeProps({
212
- key: 2,
213
- ref_for: true
214
- }, rest(part)), null, 16)) : part.type === "steps" ? (openBlock(), createBlock(chat_steps_default, mergeProps({
266
+ }, 1032, ["thinking", "duration"])) : part.type === "tool" ? (openBlock(), createBlock(unref(DouChatToolCall), mergeProps({
215
267
  key: 3,
216
268
  ref_for: true
217
- }, rest(part)), null, 16)) : part.type === "plan" ? (openBlock(), createBlock(chat_plan_default, mergeProps({
269
+ }, rest(part)), null, 16)) : part.type === "steps" ? (openBlock(), createBlock(unref(DouChatSteps), mergeProps({
218
270
  key: 4,
219
271
  ref_for: true
220
- }, rest(part)), null, 16)) : part.type === "sources" ? (openBlock(), createBlock(chat_sources_default, mergeProps({
272
+ }, rest(part)), null, 16)) : part.type === "plan" ? (openBlock(), createBlock(unref(DouChatPlan), mergeProps({
221
273
  key: 5,
222
274
  ref_for: true
223
- }, rest(part)), null, 16)) : part.type === "files" ? (openBlock(), createBlock(chat_attachments_default, {
275
+ }, rest(part)), null, 16)) : part.type === "sources" ? (openBlock(), createBlock(unref(DouChatSources), mergeProps({
224
276
  key: 6,
277
+ ref_for: true
278
+ }, rest(part)), null, 16)) : part.type === "files" ? (openBlock(), createBlock(unref(DouChatAttachments), {
279
+ key: 7,
225
280
  "model-value": asFiles(part).files,
226
281
  removable: false
227
- }, null, 8, ["model-value"])) : part.type === "artifact" ? (openBlock(), createBlock(chat_artifact_default, mergeProps({
228
- key: 7,
229
- ref_for: true
230
- }, rest(part), { onOpen: ($event) => emit("artifact", asArtifact(part)) }), null, 16, ["onOpen"])) : part.type === "confirm" ? (openBlock(), createBlock(chat_confirm_default, {
282
+ }, null, 8, ["model-value"])) : part.type === "artifact" ? (openBlock(), createBlock(unref(DouChatArtifact), mergeProps({
231
283
  key: 8,
284
+ ref_for: true
285
+ }, rest(part), { onOpen: ($event) => emit("artifact", asArtifact(part)) }), null, 16, ["onOpen"])) : part.type === "confirm" ? (openBlock(), createBlock(unref(DouChatConfirm), {
286
+ key: 9,
232
287
  title: asConfirm(part).title,
233
288
  description: asConfirm(part).description,
234
289
  status: asConfirm(part).status,
@@ -251,7 +306,7 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
251
306
  ])) : !unref(known).has(part.type) ? renderSlot(_ctx.$slots, "part", {
252
307
  part,
253
308
  index
254
- }, void 0, void 0, 9) : createCommentVNode("", true)], 64);
309
+ }, void 0, void 0, 10) : createCommentVNode("", true)], 64);
255
310
  }), 128))]), __props.loading ? (openBlock(), createElementBlock("span", {
256
311
  key: 0,
257
312
  class: normalizeClass(unref(ns).e("loading")),
@@ -294,12 +349,12 @@ var chat_message_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
294
349
  _: 1
295
350
  }, 8, ["disabled", "aria-label"])
296
351
  ], 10, _hoisted_4)) : createCommentVNode("", true),
297
- __props.copyable && text.value ? (openBlock(), createBlock(copy_button_default, {
352
+ __props.copyable && text.value ? (openBlock(), createBlock(unref(DouCopyButton), {
298
353
  key: 1,
299
354
  size: "sm",
300
355
  text: text.value
301
356
  }, null, 8, ["text"])) : createCommentVNode("", true),
302
- __props.editable && isUser.value ? (openBlock(), createBlock(tooltip_default, {
357
+ __props.editable && isUser.value ? (openBlock(), createBlock(unref(DouTooltip), {
303
358
  key: 2,
304
359
  content: unref(t)("chat.edit")
305
360
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_createBlock","DouChatAttachments","_createCommentVNode","_withDirectives","_createElementVNode","_vModelText","_createVNode","_withCtx","_createTextVNode","_toDisplayString","_renderSlot","DouStreamText","_createSlots","DouChatReasoning","DouChatToolCall","_mergeProps","DouChatSteps","DouChatPlan","DouChatSources","DouChatArtifact","DouChatConfirm","DouCopyButton","DouTooltip"],"sources":["../../../src/components/chat-message/chat-message.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon, EditIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { DouButton } from '../button'\nimport DouChatArtifact from '../chat-artifact/chat-artifact.vue'\nimport DouChatAttachments from '../chat-attachments/chat-attachments.vue'\nimport DouChatConfirm from '../chat-confirm/chat-confirm.vue'\nimport DouChatPlan from '../chat-plan/chat-plan.vue'\nimport DouChatReasoning from '../chat-reasoning/chat-reasoning.vue'\nimport DouChatSources from '../chat-sources/chat-sources.vue'\nimport DouChatSteps from '../chat-steps/chat-steps.vue'\nimport DouChatToolCall from '../chat-tool-call/chat-tool-call.vue'\nimport { useLocale } from '../config-provider/use-config'\nimport DouCopyButton from '../copy-button/copy-button.vue'\nimport DouStreamText from '../stream-text/stream-text.vue'\nimport DouTooltip from '../tooltip/tooltip.vue'\nimport { messageText } from './chat-message'\nimport type {\n ChatArtifactPart,\n ChatConfirmPart,\n ChatCustomPart,\n ChatMessageEmits,\n ChatMessagePart,\n ChatMessageProps,\n ChatMessageSlots,\n} from './chat-message'\n\ndefineOptions({ name: 'DouChatMessage' })\n\nconst props = withDefaults(defineProps<ChatMessageProps>(), {\n sender: 'assistant',\n loading: false,\n copyable: true,\n editable: false,\n versions: 1,\n version: undefined,\n})\nconst emit = defineEmits<ChatMessageEmits>()\nconst slots = defineSlots<ChatMessageSlots>()\n\nconst ns = useNamespace('chat-message')\nconst { t } = useLocale()\n\ntype AnyPart = ChatMessagePart | ChatCustomPart\n\nconst parts = computed<AnyPart[]>(\n () => props.parts ?? (props.content === undefined ? [] : [{ type: 'text', text: props.content }]),\n)\nconst isUser = computed(() => props.sender === 'user')\n// the person's attachments sit above their bubble, not inside it\nconst files = computed(() => (isUser.value ? parts.value.filter((p) => p.type === 'files') : []))\nconst body = computed(() =>\n isUser.value ? parts.value.filter((p) => p.type !== 'files') : parts.value,\n)\nconst text = computed(() => messageText(parts.value as { type: string; text?: unknown }[]))\n\nconst busy = computed(\n () =>\n props.loading ||\n parts.value.some((part) => {\n const p = part as Record<string, unknown>\n return !!p.streaming || !!p.thinking || !!p.running || p.status === 'running'\n }),\n)\n\nconst innerVersion = ref(props.versions)\nconst version = computed(() => Math.min(props.version ?? innerVersion.value, props.versions))\nfunction step(delta: number) {\n const next = Math.min(Math.max(version.value + delta, 1), props.versions)\n innerVersion.value = next\n emit('update:version', next)\n}\n\nconst showActions = computed(\n () =>\n !busy.value &&\n (props.versions > 1 ||\n (props.copyable && !!text.value) ||\n (props.editable && isUser.value) ||\n !!slots.actions),\n)\n\n// editing in place\nconst editing = ref(false)\nconst draft = ref('')\nconst editorRef = useTemplateRef<HTMLTextAreaElement>('editor')\nfunction startEdit() {\n draft.value = text.value\n editing.value = true\n void nextTick(() => {\n const el = editorRef.value\n el?.focus()\n el?.setSelectionRange(el.value.length, el.value.length)\n fitEditor()\n })\n}\nfunction cancelEdit() {\n editing.value = false\n}\nfunction saveEdit() {\n if (!draft.value.trim()) return\n editing.value = false\n emit('edit', draft.value)\n}\nfunction fitEditor() {\n const el = editorRef.value\n if (!el) return\n el.style.height = 'auto'\n el.style.height = `${el.scrollHeight}px`\n}\nfunction onEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault()\n cancelEdit()\n } else if (event.key === 'Enter' && !event.shiftKey && !isComposing(event)) {\n event.preventDefault()\n saveEdit()\n }\n}\n\nconst asText = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'text' }>\nconst asReasoning = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'reasoning' }>\nconst asFiles = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'files' }>\nconst asConfirm = (part: AnyPart) => part as ChatConfirmPart\nconst asArtifact = (part: AnyPart) => part as ChatArtifactPart\nconst known = new Set([\n 'text',\n 'reasoning',\n 'tool',\n 'steps',\n 'plan',\n 'sources',\n 'files',\n 'artifact',\n 'confirm',\n])\n// props for the part components, without the `type` discriminator\nconst rest = (part: AnyPart) => {\n const { type: _type, ...others } = part as Record<string, unknown>\n return others\n}\n</script>\n\n<template>\n <div\n :class=\"[ns.b(), ns.m(sender), ns.is('loading', loading), ns.is('editing', editing)]\"\n :aria-busy=\"busy || undefined\"\n >\n <div v-if=\"files.length && !editing\" :class=\"ns.e('files')\">\n <template v-for=\"(part, index) in files\" :key=\"`f${index}`\">\n <DouChatAttachments :model-value=\"asFiles(part).files\" :removable=\"false\" />\n </template>\n </div>\n\n <div v-if=\"editing\" :class=\"ns.e('editor')\">\n <textarea\n ref=\"editor\"\n v-model=\"draft\"\n :class=\"ns.e('editor-native')\"\n rows=\"1\"\n :aria-label=\"t('chat.edit')\"\n @input=\"fitEditor\"\n @keydown=\"onEditorKeydown\"\n />\n <div :class=\"ns.e('editor-actions')\">\n <DouButton size=\"sm\" variant=\"ghost\" @click=\"cancelEdit\">{{ t('chat.cancel') }}</DouButton>\n <DouButton size=\"sm\" :disabled=\"!draft.trim()\" @click=\"saveEdit\">\n {{ t('chat.send') }}\n </DouButton>\n </div>\n </div>\n\n <div v-else-if=\"body.length || loading || slots.default\" :class=\"ns.e('content')\">\n <slot>\n <template v-for=\"(part, index) in body\" :key=\"index\">\n <DouStreamText\n v-if=\"part.type === 'text'\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n >\n <template v-if=\"slots.text\" #default=\"{ text: shown }\">\n <slot name=\"text\" :part=\"asText(part)\" :text=\"shown\" :index=\"index\" />\n </template>\n </DouStreamText>\n <DouChatReasoning\n v-else-if=\"part.type === 'reasoning'\"\n :thinking=\"!!asReasoning(part).thinking\"\n :duration=\"asReasoning(part).duration\"\n >\n <DouStreamText\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n />\n </DouChatReasoning>\n <DouChatToolCall v-else-if=\"part.type === 'tool'\" v-bind=\"rest(part)\" />\n <DouChatSteps v-else-if=\"part.type === 'steps'\" v-bind=\"rest(part)\" />\n <DouChatPlan v-else-if=\"part.type === 'plan'\" v-bind=\"rest(part)\" />\n <DouChatSources v-else-if=\"part.type === 'sources'\" v-bind=\"rest(part)\" />\n <DouChatAttachments\n v-else-if=\"part.type === 'files'\"\n :model-value=\"asFiles(part).files\"\n :removable=\"false\"\n />\n <DouChatArtifact\n v-else-if=\"part.type === 'artifact'\"\n v-bind=\"rest(part)\"\n @open=\"emit('artifact', asArtifact(part))\"\n />\n <DouChatConfirm\n v-else-if=\"part.type === 'confirm'\"\n :title=\"asConfirm(part).title\"\n :description=\"asConfirm(part).description\"\n :status=\"asConfirm(part).status\"\n :allow-always=\"asConfirm(part).allowAlways\"\n :tone=\"asConfirm(part).tone\"\n @decide=\"emit('confirm', asConfirm(part), $event)\"\n >\n <pre v-if=\"asConfirm(part).detail\" :class=\"ns.e('code')\">{{\n asConfirm(part).detail\n }}</pre>\n </DouChatConfirm>\n <slot\n v-else-if=\"!known.has(part.type)\"\n name=\"part\"\n :part=\"part as ChatCustomPart\"\n :index=\"index\"\n />\n </template>\n </slot>\n <span v-if=\"loading\" :class=\"ns.e('loading')\" role=\"status\" :aria-label=\"t('chat.loading')\">\n <i /><i /><i />\n </span>\n </div>\n\n <div v-if=\"showActions && !editing\" :class=\"ns.e('actions')\">\n <div\n v-if=\"versions > 1\"\n :class=\"ns.e('versions')\"\n role=\"group\"\n :aria-label=\"t('chat.versions')\"\n >\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version <= 1\"\n :aria-label=\"t('chat.previousVersion')\"\n @click=\"step(-1)\"\n >\n <ChevronLeftIcon />\n </DouButton>\n <span :class=\"ns.e('version')\">{{ version }} / {{ versions }}</span>\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version >= versions\"\n :aria-label=\"t('chat.nextVersion')\"\n @click=\"step(1)\"\n >\n <ChevronRightIcon />\n </DouButton>\n </div>\n <DouCopyButton v-if=\"copyable && text\" size=\"sm\" :text=\"text\" />\n <DouTooltip v-if=\"editable && isUser\" :content=\"t('chat.edit')\">\n <DouButton variant=\"ghost\" size=\"sm\" :aria-label=\"t('chat.edit')\" @click=\"startEdit\">\n <EditIcon />\n </DouButton>\n </DouTooltip>\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-message.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_createBlock","_createCommentVNode","_withDirectives","_createElementVNode","_vModelText","_createVNode","_withCtx","_createTextVNode","_toDisplayString","_renderSlot","_mergeProps","_createSlots"],"sources":["../../../src/components/chat-message/chat-message.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon, EditIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { DouButton } from '../button'\nimport { DouChatArtifact } from '../chat-artifact'\nimport { DouChatAttachments } from '../chat-attachments'\nimport { DouChatConfirm } from '../chat-confirm'\nimport { DouChatPlan } from '../chat-plan'\nimport { planRunning, type ChatPlanItem } from '../chat-plan/chat-plan'\nimport { DouChatReasoning } from '../chat-reasoning'\nimport { DouChatSources } from '../chat-sources'\nimport { DouChatSteps } from '../chat-steps'\nimport { stepsLive, type ChatStep } from '../chat-steps/chat-steps'\nimport { DouChatToolCall } from '../chat-tool-call'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouCopyButton } from '../copy-button'\nimport { DouMarkdown } from '../markdown'\nimport type { ChatSource } from '../chat-sources/chat-sources'\nimport { DouStreamText } from '../stream-text'\nimport { DouTooltip } from '../tooltip'\nimport { messageText } from './chat-message'\nimport type {\n ChatArtifactPart,\n ChatConfirmPart,\n ChatCustomPart,\n ChatMessageEmits,\n ChatMessagePart,\n ChatMessageMarkdownSlots,\n ChatMessageProps,\n ChatMessageSlots,\n} from './chat-message'\n\ndefineOptions({ name: 'DouChatMessage' })\n\nconst props = withDefaults(defineProps<ChatMessageProps>(), {\n sender: 'assistant',\n loading: false,\n copyable: true,\n editable: false,\n markdown: false,\n versions: 1,\n version: undefined,\n})\nconst emit = defineEmits<ChatMessageEmits>()\nconst slots = defineSlots<ChatMessageSlots & ChatMessageMarkdownSlots>()\n\nconst ns = useNamespace('chat-message')\nconst { t } = useLocale()\n\ntype AnyPart = ChatMessagePart | ChatCustomPart\n\nconst parts = computed<AnyPart[]>(\n () => props.parts ?? (props.content === undefined ? [] : [{ type: 'text', text: props.content }]),\n)\nconst markdownOptions = computed(() =>\n typeof props.markdown === 'object' ? props.markdown : undefined,\n)\n// `markdown-code` here is the Markdown component's `code`\nconst PREFIX = 'markdown-'\nconst markdownSlots = () =>\n Object.keys(slots)\n .filter((name) => name.startsWith(PREFIX))\n .map((name) => ({\n name: name as keyof ChatMessageMarkdownSlots,\n inner: name.slice(PREFIX.length),\n }))\nconst isUser = computed(() => props.sender === 'user')\n// the person's attachments sit above their bubble, not inside it\nconst files = computed(() => (isUser.value ? parts.value.filter((p) => p.type === 'files') : []))\nconst body = computed(() =>\n isUser.value ? parts.value.filter((p) => p.type !== 'files') : parts.value,\n)\nconst text = computed(() => messageText(parts.value as { type: string; text?: unknown }[]))\n// Every source of the message, numbered in order, for `[1]` in Markdown\n// text. The same array while the sources stay the same, so text that\n// streams in does not redraw the whole reply.\nlet lastSources: ChatSource[] = []\nconst sources = computed(() => {\n const next = parts.value.flatMap((part) =>\n part.type === 'sources' ? ((part as { items?: ChatSource[] }).items ?? []) : [],\n )\n if (next.length === lastSources.length && next.every((s, i) => s === lastSources[i]))\n return lastSources\n return (lastSources = next)\n})\n\nconst busy = computed(\n () =>\n props.loading ||\n parts.value.some((part) => {\n const p = part as Record<string, unknown>\n // an artifact can keep being made after the reply ends, so it doesn't hold the actions back\n const working = p.status === 'running' && p.type !== 'artifact' && p.live !== false\n // busy exactly when steps or a plan show themselves running\n const live = p.live as boolean | undefined\n const steps = p.type === 'steps' && stepsLive(p.items as ChatStep[] | undefined, live)\n const plan = p.type === 'plan' && planRunning(p.items as ChatPlanItem[] | undefined, live)\n return !!p.streaming || !!p.thinking || steps || plan || working\n }),\n)\n\nconst innerVersion = ref(props.versions)\nconst version = computed(() => Math.min(props.version ?? innerVersion.value, props.versions))\nfunction step(delta: number) {\n const next = Math.min(Math.max(version.value + delta, 1), props.versions)\n innerVersion.value = next\n emit('update:version', next)\n}\n\nconst showActions = computed(\n () =>\n !busy.value &&\n (props.versions > 1 ||\n (props.copyable && !!text.value) ||\n (props.editable && isUser.value) ||\n !!slots.actions),\n)\n\n// editing in place\nconst editing = ref(false)\nconst draft = ref('')\nconst editorRef = useTemplateRef<HTMLTextAreaElement>('editor')\nfunction startEdit() {\n draft.value = text.value\n editing.value = true\n void nextTick(() => {\n const el = editorRef.value\n el?.focus()\n el?.setSelectionRange(el.value.length, el.value.length)\n fitEditor()\n })\n}\nfunction cancelEdit() {\n editing.value = false\n}\nfunction saveEdit() {\n if (!draft.value.trim()) return\n editing.value = false\n emit('edit', draft.value)\n}\nfunction fitEditor() {\n const el = editorRef.value\n if (!el) return\n el.style.height = 'auto'\n el.style.height = `${el.scrollHeight}px`\n}\nfunction onEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault()\n cancelEdit()\n } else if (event.key === 'Enter' && !event.shiftKey && !isComposing(event)) {\n event.preventDefault()\n saveEdit()\n }\n}\n\nconst asText = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'text' }>\nconst asReasoning = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'reasoning' }>\nconst asFiles = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'files' }>\nconst asConfirm = (part: AnyPart) => part as ChatConfirmPart\nconst asArtifact = (part: AnyPart) => part as ChatArtifactPart\nconst known = new Set([\n 'text',\n 'reasoning',\n 'tool',\n 'steps',\n 'plan',\n 'sources',\n 'files',\n 'artifact',\n 'confirm',\n])\n// props for the part components, without the `type` discriminator\nconst rest = (part: AnyPart) => {\n const { type: _type, ...others } = part as Record<string, unknown>\n return others\n}\n</script>\n\n<template>\n <div\n :class=\"[ns.b(), ns.m(sender), ns.is('loading', loading), ns.is('editing', editing)]\"\n :aria-busy=\"busy || undefined\"\n >\n <div v-if=\"files.length && !editing\" :class=\"ns.e('files')\">\n <template v-for=\"(part, index) in files\" :key=\"`f${index}`\">\n <DouChatAttachments :model-value=\"asFiles(part).files\" :removable=\"false\" />\n </template>\n </div>\n\n <div v-if=\"editing\" :class=\"ns.e('editor')\">\n <textarea\n ref=\"editor\"\n v-model=\"draft\"\n :class=\"ns.e('editor-native')\"\n rows=\"1\"\n :aria-label=\"t('chat.edit')\"\n @input=\"fitEditor\"\n @keydown=\"onEditorKeydown\"\n />\n <div :class=\"ns.e('editor-actions')\">\n <DouButton size=\"sm\" variant=\"ghost\" @click=\"cancelEdit\">{{ t('chat.cancel') }}</DouButton>\n <DouButton size=\"sm\" :disabled=\"!draft.trim()\" @click=\"saveEdit\">\n {{ t('chat.send') }}\n </DouButton>\n </div>\n </div>\n\n <div v-else-if=\"body.length || loading || slots.default\" :class=\"ns.e('content')\">\n <slot>\n <template v-for=\"(part, index) in body\" :key=\"index\">\n <DouMarkdown\n v-if=\"part.type === 'text' && markdown && !slots.text\"\n v-bind=\"markdownOptions\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n :sources=\"sources.length ? sources : undefined\"\n >\n <template v-for=\"slot in markdownSlots()\" :key=\"slot.name\" #[slot.inner]=\"scope\">\n <slot :name=\"slot.name\" v-bind=\"scope\" />\n </template>\n </DouMarkdown>\n <DouStreamText\n v-else-if=\"part.type === 'text'\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n >\n <template v-if=\"slots.text\" #default=\"{ text: shown }\">\n <slot\n name=\"text\"\n :part=\"asText(part)\"\n :text=\"shown\"\n :index=\"index\"\n :sources=\"sources\"\n />\n </template>\n </DouStreamText>\n <DouChatReasoning\n v-else-if=\"part.type === 'reasoning'\"\n :thinking=\"!!asReasoning(part).thinking\"\n :duration=\"asReasoning(part).duration\"\n >\n <DouMarkdown\n v-if=\"markdown\"\n v-bind=\"markdownOptions\"\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n >\n <template v-for=\"slot in markdownSlots()\" :key=\"slot.name\" #[slot.inner]=\"scope\">\n <slot :name=\"slot.name\" v-bind=\"scope\" />\n </template>\n </DouMarkdown>\n <DouStreamText\n v-else\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n />\n </DouChatReasoning>\n <DouChatToolCall v-else-if=\"part.type === 'tool'\" v-bind=\"rest(part)\" />\n <DouChatSteps v-else-if=\"part.type === 'steps'\" v-bind=\"rest(part)\" />\n <DouChatPlan v-else-if=\"part.type === 'plan'\" v-bind=\"rest(part)\" />\n <DouChatSources v-else-if=\"part.type === 'sources'\" v-bind=\"rest(part)\" />\n <DouChatAttachments\n v-else-if=\"part.type === 'files'\"\n :model-value=\"asFiles(part).files\"\n :removable=\"false\"\n />\n <DouChatArtifact\n v-else-if=\"part.type === 'artifact'\"\n v-bind=\"rest(part)\"\n @open=\"emit('artifact', asArtifact(part))\"\n />\n <DouChatConfirm\n v-else-if=\"part.type === 'confirm'\"\n :title=\"asConfirm(part).title\"\n :description=\"asConfirm(part).description\"\n :status=\"asConfirm(part).status\"\n :allow-always=\"asConfirm(part).allowAlways\"\n :tone=\"asConfirm(part).tone\"\n @decide=\"emit('confirm', asConfirm(part), $event)\"\n >\n <pre v-if=\"asConfirm(part).detail\" :class=\"ns.e('code')\">{{\n asConfirm(part).detail\n }}</pre>\n </DouChatConfirm>\n <slot\n v-else-if=\"!known.has(part.type)\"\n name=\"part\"\n :part=\"part as ChatCustomPart\"\n :index=\"index\"\n />\n </template>\n </slot>\n <span v-if=\"loading\" :class=\"ns.e('loading')\" role=\"status\" :aria-label=\"t('chat.loading')\">\n <i /><i /><i />\n </span>\n </div>\n\n <div v-if=\"showActions && !editing\" :class=\"ns.e('actions')\">\n <div\n v-if=\"versions > 1\"\n :class=\"ns.e('versions')\"\n role=\"group\"\n :aria-label=\"t('chat.versions')\"\n >\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version <= 1\"\n :aria-label=\"t('chat.previousVersion')\"\n @click=\"step(-1)\"\n >\n <ChevronLeftIcon />\n </DouButton>\n <span :class=\"ns.e('version')\">{{ version }} / {{ versions }}</span>\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version >= versions\"\n :aria-label=\"t('chat.nextVersion')\"\n @click=\"step(1)\"\n >\n <ChevronRightIcon />\n </DouButton>\n </div>\n <DouCopyButton v-if=\"copyable && text\" size=\"sm\" :text=\"text\" />\n <DouTooltip v-if=\"editable && isUser\" :content=\"t('chat.edit')\">\n <DouButton variant=\"ghost\" size=\"sm\" :aria-label=\"t('chat.edit')\" @click=\"startEdit\">\n <EditIcon />\n </DouButton>\n </DouTooltip>\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message2.js","names":["_sfc_main"],"sources":["../../../src/components/chat-message/chat-message.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon, EditIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { DouButton } from '../button'\nimport DouChatArtifact from '../chat-artifact/chat-artifact.vue'\nimport DouChatAttachments from '../chat-attachments/chat-attachments.vue'\nimport DouChatConfirm from '../chat-confirm/chat-confirm.vue'\nimport DouChatPlan from '../chat-plan/chat-plan.vue'\nimport DouChatReasoning from '../chat-reasoning/chat-reasoning.vue'\nimport DouChatSources from '../chat-sources/chat-sources.vue'\nimport DouChatSteps from '../chat-steps/chat-steps.vue'\nimport DouChatToolCall from '../chat-tool-call/chat-tool-call.vue'\nimport { useLocale } from '../config-provider/use-config'\nimport DouCopyButton from '../copy-button/copy-button.vue'\nimport DouStreamText from '../stream-text/stream-text.vue'\nimport DouTooltip from '../tooltip/tooltip.vue'\nimport { messageText } from './chat-message'\nimport type {\n ChatArtifactPart,\n ChatConfirmPart,\n ChatCustomPart,\n ChatMessageEmits,\n ChatMessagePart,\n ChatMessageProps,\n ChatMessageSlots,\n} from './chat-message'\n\ndefineOptions({ name: 'DouChatMessage' })\n\nconst props = withDefaults(defineProps<ChatMessageProps>(), {\n sender: 'assistant',\n loading: false,\n copyable: true,\n editable: false,\n versions: 1,\n version: undefined,\n})\nconst emit = defineEmits<ChatMessageEmits>()\nconst slots = defineSlots<ChatMessageSlots>()\n\nconst ns = useNamespace('chat-message')\nconst { t } = useLocale()\n\ntype AnyPart = ChatMessagePart | ChatCustomPart\n\nconst parts = computed<AnyPart[]>(\n () => props.parts ?? (props.content === undefined ? [] : [{ type: 'text', text: props.content }]),\n)\nconst isUser = computed(() => props.sender === 'user')\n// the person's attachments sit above their bubble, not inside it\nconst files = computed(() => (isUser.value ? parts.value.filter((p) => p.type === 'files') : []))\nconst body = computed(() =>\n isUser.value ? parts.value.filter((p) => p.type !== 'files') : parts.value,\n)\nconst text = computed(() => messageText(parts.value as { type: string; text?: unknown }[]))\n\nconst busy = computed(\n () =>\n props.loading ||\n parts.value.some((part) => {\n const p = part as Record<string, unknown>\n return !!p.streaming || !!p.thinking || !!p.running || p.status === 'running'\n }),\n)\n\nconst innerVersion = ref(props.versions)\nconst version = computed(() => Math.min(props.version ?? innerVersion.value, props.versions))\nfunction step(delta: number) {\n const next = Math.min(Math.max(version.value + delta, 1), props.versions)\n innerVersion.value = next\n emit('update:version', next)\n}\n\nconst showActions = computed(\n () =>\n !busy.value &&\n (props.versions > 1 ||\n (props.copyable && !!text.value) ||\n (props.editable && isUser.value) ||\n !!slots.actions),\n)\n\n// editing in place\nconst editing = ref(false)\nconst draft = ref('')\nconst editorRef = useTemplateRef<HTMLTextAreaElement>('editor')\nfunction startEdit() {\n draft.value = text.value\n editing.value = true\n void nextTick(() => {\n const el = editorRef.value\n el?.focus()\n el?.setSelectionRange(el.value.length, el.value.length)\n fitEditor()\n })\n}\nfunction cancelEdit() {\n editing.value = false\n}\nfunction saveEdit() {\n if (!draft.value.trim()) return\n editing.value = false\n emit('edit', draft.value)\n}\nfunction fitEditor() {\n const el = editorRef.value\n if (!el) return\n el.style.height = 'auto'\n el.style.height = `${el.scrollHeight}px`\n}\nfunction onEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault()\n cancelEdit()\n } else if (event.key === 'Enter' && !event.shiftKey && !isComposing(event)) {\n event.preventDefault()\n saveEdit()\n }\n}\n\nconst asText = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'text' }>\nconst asReasoning = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'reasoning' }>\nconst asFiles = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'files' }>\nconst asConfirm = (part: AnyPart) => part as ChatConfirmPart\nconst asArtifact = (part: AnyPart) => part as ChatArtifactPart\nconst known = new Set([\n 'text',\n 'reasoning',\n 'tool',\n 'steps',\n 'plan',\n 'sources',\n 'files',\n 'artifact',\n 'confirm',\n])\n// props for the part components, without the `type` discriminator\nconst rest = (part: AnyPart) => {\n const { type: _type, ...others } = part as Record<string, unknown>\n return others\n}\n</script>\n\n<template>\n <div\n :class=\"[ns.b(), ns.m(sender), ns.is('loading', loading), ns.is('editing', editing)]\"\n :aria-busy=\"busy || undefined\"\n >\n <div v-if=\"files.length && !editing\" :class=\"ns.e('files')\">\n <template v-for=\"(part, index) in files\" :key=\"`f${index}`\">\n <DouChatAttachments :model-value=\"asFiles(part).files\" :removable=\"false\" />\n </template>\n </div>\n\n <div v-if=\"editing\" :class=\"ns.e('editor')\">\n <textarea\n ref=\"editor\"\n v-model=\"draft\"\n :class=\"ns.e('editor-native')\"\n rows=\"1\"\n :aria-label=\"t('chat.edit')\"\n @input=\"fitEditor\"\n @keydown=\"onEditorKeydown\"\n />\n <div :class=\"ns.e('editor-actions')\">\n <DouButton size=\"sm\" variant=\"ghost\" @click=\"cancelEdit\">{{ t('chat.cancel') }}</DouButton>\n <DouButton size=\"sm\" :disabled=\"!draft.trim()\" @click=\"saveEdit\">\n {{ t('chat.send') }}\n </DouButton>\n </div>\n </div>\n\n <div v-else-if=\"body.length || loading || slots.default\" :class=\"ns.e('content')\">\n <slot>\n <template v-for=\"(part, index) in body\" :key=\"index\">\n <DouStreamText\n v-if=\"part.type === 'text'\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n >\n <template v-if=\"slots.text\" #default=\"{ text: shown }\">\n <slot name=\"text\" :part=\"asText(part)\" :text=\"shown\" :index=\"index\" />\n </template>\n </DouStreamText>\n <DouChatReasoning\n v-else-if=\"part.type === 'reasoning'\"\n :thinking=\"!!asReasoning(part).thinking\"\n :duration=\"asReasoning(part).duration\"\n >\n <DouStreamText\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n />\n </DouChatReasoning>\n <DouChatToolCall v-else-if=\"part.type === 'tool'\" v-bind=\"rest(part)\" />\n <DouChatSteps v-else-if=\"part.type === 'steps'\" v-bind=\"rest(part)\" />\n <DouChatPlan v-else-if=\"part.type === 'plan'\" v-bind=\"rest(part)\" />\n <DouChatSources v-else-if=\"part.type === 'sources'\" v-bind=\"rest(part)\" />\n <DouChatAttachments\n v-else-if=\"part.type === 'files'\"\n :model-value=\"asFiles(part).files\"\n :removable=\"false\"\n />\n <DouChatArtifact\n v-else-if=\"part.type === 'artifact'\"\n v-bind=\"rest(part)\"\n @open=\"emit('artifact', asArtifact(part))\"\n />\n <DouChatConfirm\n v-else-if=\"part.type === 'confirm'\"\n :title=\"asConfirm(part).title\"\n :description=\"asConfirm(part).description\"\n :status=\"asConfirm(part).status\"\n :allow-always=\"asConfirm(part).allowAlways\"\n :tone=\"asConfirm(part).tone\"\n @decide=\"emit('confirm', asConfirm(part), $event)\"\n >\n <pre v-if=\"asConfirm(part).detail\" :class=\"ns.e('code')\">{{\n asConfirm(part).detail\n }}</pre>\n </DouChatConfirm>\n <slot\n v-else-if=\"!known.has(part.type)\"\n name=\"part\"\n :part=\"part as ChatCustomPart\"\n :index=\"index\"\n />\n </template>\n </slot>\n <span v-if=\"loading\" :class=\"ns.e('loading')\" role=\"status\" :aria-label=\"t('chat.loading')\">\n <i /><i /><i />\n </span>\n </div>\n\n <div v-if=\"showActions && !editing\" :class=\"ns.e('actions')\">\n <div\n v-if=\"versions > 1\"\n :class=\"ns.e('versions')\"\n role=\"group\"\n :aria-label=\"t('chat.versions')\"\n >\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version <= 1\"\n :aria-label=\"t('chat.previousVersion')\"\n @click=\"step(-1)\"\n >\n <ChevronLeftIcon />\n </DouButton>\n <span :class=\"ns.e('version')\">{{ version }} / {{ versions }}</span>\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version >= versions\"\n :aria-label=\"t('chat.nextVersion')\"\n @click=\"step(1)\"\n >\n <ChevronRightIcon />\n </DouButton>\n </div>\n <DouCopyButton v-if=\"copyable && text\" size=\"sm\" :text=\"text\" />\n <DouTooltip v-if=\"editable && isUser\" :content=\"t('chat.edit')\">\n <DouButton variant=\"ghost\" size=\"sm\" :aria-label=\"t('chat.edit')\" @click=\"startEdit\">\n <EditIcon />\n </DouButton>\n </DouTooltip>\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"chat-message2.js","names":["_sfc_main"],"sources":["../../../src/components/chat-message/chat-message.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ChevronLeftIcon, ChevronRightIcon, EditIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { DouButton } from '../button'\nimport { DouChatArtifact } from '../chat-artifact'\nimport { DouChatAttachments } from '../chat-attachments'\nimport { DouChatConfirm } from '../chat-confirm'\nimport { DouChatPlan } from '../chat-plan'\nimport { planRunning, type ChatPlanItem } from '../chat-plan/chat-plan'\nimport { DouChatReasoning } from '../chat-reasoning'\nimport { DouChatSources } from '../chat-sources'\nimport { DouChatSteps } from '../chat-steps'\nimport { stepsLive, type ChatStep } from '../chat-steps/chat-steps'\nimport { DouChatToolCall } from '../chat-tool-call'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouCopyButton } from '../copy-button'\nimport { DouMarkdown } from '../markdown'\nimport type { ChatSource } from '../chat-sources/chat-sources'\nimport { DouStreamText } from '../stream-text'\nimport { DouTooltip } from '../tooltip'\nimport { messageText } from './chat-message'\nimport type {\n ChatArtifactPart,\n ChatConfirmPart,\n ChatCustomPart,\n ChatMessageEmits,\n ChatMessagePart,\n ChatMessageMarkdownSlots,\n ChatMessageProps,\n ChatMessageSlots,\n} from './chat-message'\n\ndefineOptions({ name: 'DouChatMessage' })\n\nconst props = withDefaults(defineProps<ChatMessageProps>(), {\n sender: 'assistant',\n loading: false,\n copyable: true,\n editable: false,\n markdown: false,\n versions: 1,\n version: undefined,\n})\nconst emit = defineEmits<ChatMessageEmits>()\nconst slots = defineSlots<ChatMessageSlots & ChatMessageMarkdownSlots>()\n\nconst ns = useNamespace('chat-message')\nconst { t } = useLocale()\n\ntype AnyPart = ChatMessagePart | ChatCustomPart\n\nconst parts = computed<AnyPart[]>(\n () => props.parts ?? (props.content === undefined ? [] : [{ type: 'text', text: props.content }]),\n)\nconst markdownOptions = computed(() =>\n typeof props.markdown === 'object' ? props.markdown : undefined,\n)\n// `markdown-code` here is the Markdown component's `code`\nconst PREFIX = 'markdown-'\nconst markdownSlots = () =>\n Object.keys(slots)\n .filter((name) => name.startsWith(PREFIX))\n .map((name) => ({\n name: name as keyof ChatMessageMarkdownSlots,\n inner: name.slice(PREFIX.length),\n }))\nconst isUser = computed(() => props.sender === 'user')\n// the person's attachments sit above their bubble, not inside it\nconst files = computed(() => (isUser.value ? parts.value.filter((p) => p.type === 'files') : []))\nconst body = computed(() =>\n isUser.value ? parts.value.filter((p) => p.type !== 'files') : parts.value,\n)\nconst text = computed(() => messageText(parts.value as { type: string; text?: unknown }[]))\n// Every source of the message, numbered in order, for `[1]` in Markdown\n// text. The same array while the sources stay the same, so text that\n// streams in does not redraw the whole reply.\nlet lastSources: ChatSource[] = []\nconst sources = computed(() => {\n const next = parts.value.flatMap((part) =>\n part.type === 'sources' ? ((part as { items?: ChatSource[] }).items ?? []) : [],\n )\n if (next.length === lastSources.length && next.every((s, i) => s === lastSources[i]))\n return lastSources\n return (lastSources = next)\n})\n\nconst busy = computed(\n () =>\n props.loading ||\n parts.value.some((part) => {\n const p = part as Record<string, unknown>\n // an artifact can keep being made after the reply ends, so it doesn't hold the actions back\n const working = p.status === 'running' && p.type !== 'artifact' && p.live !== false\n // busy exactly when steps or a plan show themselves running\n const live = p.live as boolean | undefined\n const steps = p.type === 'steps' && stepsLive(p.items as ChatStep[] | undefined, live)\n const plan = p.type === 'plan' && planRunning(p.items as ChatPlanItem[] | undefined, live)\n return !!p.streaming || !!p.thinking || steps || plan || working\n }),\n)\n\nconst innerVersion = ref(props.versions)\nconst version = computed(() => Math.min(props.version ?? innerVersion.value, props.versions))\nfunction step(delta: number) {\n const next = Math.min(Math.max(version.value + delta, 1), props.versions)\n innerVersion.value = next\n emit('update:version', next)\n}\n\nconst showActions = computed(\n () =>\n !busy.value &&\n (props.versions > 1 ||\n (props.copyable && !!text.value) ||\n (props.editable && isUser.value) ||\n !!slots.actions),\n)\n\n// editing in place\nconst editing = ref(false)\nconst draft = ref('')\nconst editorRef = useTemplateRef<HTMLTextAreaElement>('editor')\nfunction startEdit() {\n draft.value = text.value\n editing.value = true\n void nextTick(() => {\n const el = editorRef.value\n el?.focus()\n el?.setSelectionRange(el.value.length, el.value.length)\n fitEditor()\n })\n}\nfunction cancelEdit() {\n editing.value = false\n}\nfunction saveEdit() {\n if (!draft.value.trim()) return\n editing.value = false\n emit('edit', draft.value)\n}\nfunction fitEditor() {\n const el = editorRef.value\n if (!el) return\n el.style.height = 'auto'\n el.style.height = `${el.scrollHeight}px`\n}\nfunction onEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault()\n cancelEdit()\n } else if (event.key === 'Enter' && !event.shiftKey && !isComposing(event)) {\n event.preventDefault()\n saveEdit()\n }\n}\n\nconst asText = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'text' }>\nconst asReasoning = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'reasoning' }>\nconst asFiles = (part: AnyPart) => part as Extract<ChatMessagePart, { type: 'files' }>\nconst asConfirm = (part: AnyPart) => part as ChatConfirmPart\nconst asArtifact = (part: AnyPart) => part as ChatArtifactPart\nconst known = new Set([\n 'text',\n 'reasoning',\n 'tool',\n 'steps',\n 'plan',\n 'sources',\n 'files',\n 'artifact',\n 'confirm',\n])\n// props for the part components, without the `type` discriminator\nconst rest = (part: AnyPart) => {\n const { type: _type, ...others } = part as Record<string, unknown>\n return others\n}\n</script>\n\n<template>\n <div\n :class=\"[ns.b(), ns.m(sender), ns.is('loading', loading), ns.is('editing', editing)]\"\n :aria-busy=\"busy || undefined\"\n >\n <div v-if=\"files.length && !editing\" :class=\"ns.e('files')\">\n <template v-for=\"(part, index) in files\" :key=\"`f${index}`\">\n <DouChatAttachments :model-value=\"asFiles(part).files\" :removable=\"false\" />\n </template>\n </div>\n\n <div v-if=\"editing\" :class=\"ns.e('editor')\">\n <textarea\n ref=\"editor\"\n v-model=\"draft\"\n :class=\"ns.e('editor-native')\"\n rows=\"1\"\n :aria-label=\"t('chat.edit')\"\n @input=\"fitEditor\"\n @keydown=\"onEditorKeydown\"\n />\n <div :class=\"ns.e('editor-actions')\">\n <DouButton size=\"sm\" variant=\"ghost\" @click=\"cancelEdit\">{{ t('chat.cancel') }}</DouButton>\n <DouButton size=\"sm\" :disabled=\"!draft.trim()\" @click=\"saveEdit\">\n {{ t('chat.send') }}\n </DouButton>\n </div>\n </div>\n\n <div v-else-if=\"body.length || loading || slots.default\" :class=\"ns.e('content')\">\n <slot>\n <template v-for=\"(part, index) in body\" :key=\"index\">\n <DouMarkdown\n v-if=\"part.type === 'text' && markdown && !slots.text\"\n v-bind=\"markdownOptions\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n :sources=\"sources.length ? sources : undefined\"\n >\n <template v-for=\"slot in markdownSlots()\" :key=\"slot.name\" #[slot.inner]=\"scope\">\n <slot :name=\"slot.name\" v-bind=\"scope\" />\n </template>\n </DouMarkdown>\n <DouStreamText\n v-else-if=\"part.type === 'text'\"\n :class=\"ns.e('text')\"\n :content=\"asText(part).text\"\n :streaming=\"!!asText(part).streaming\"\n >\n <template v-if=\"slots.text\" #default=\"{ text: shown }\">\n <slot\n name=\"text\"\n :part=\"asText(part)\"\n :text=\"shown\"\n :index=\"index\"\n :sources=\"sources\"\n />\n </template>\n </DouStreamText>\n <DouChatReasoning\n v-else-if=\"part.type === 'reasoning'\"\n :thinking=\"!!asReasoning(part).thinking\"\n :duration=\"asReasoning(part).duration\"\n >\n <DouMarkdown\n v-if=\"markdown\"\n v-bind=\"markdownOptions\"\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n >\n <template v-for=\"slot in markdownSlots()\" :key=\"slot.name\" #[slot.inner]=\"scope\">\n <slot :name=\"slot.name\" v-bind=\"scope\" />\n </template>\n </DouMarkdown>\n <DouStreamText\n v-else\n :content=\"asReasoning(part).text\"\n :streaming=\"!!asReasoning(part).thinking\"\n :caret=\"false\"\n />\n </DouChatReasoning>\n <DouChatToolCall v-else-if=\"part.type === 'tool'\" v-bind=\"rest(part)\" />\n <DouChatSteps v-else-if=\"part.type === 'steps'\" v-bind=\"rest(part)\" />\n <DouChatPlan v-else-if=\"part.type === 'plan'\" v-bind=\"rest(part)\" />\n <DouChatSources v-else-if=\"part.type === 'sources'\" v-bind=\"rest(part)\" />\n <DouChatAttachments\n v-else-if=\"part.type === 'files'\"\n :model-value=\"asFiles(part).files\"\n :removable=\"false\"\n />\n <DouChatArtifact\n v-else-if=\"part.type === 'artifact'\"\n v-bind=\"rest(part)\"\n @open=\"emit('artifact', asArtifact(part))\"\n />\n <DouChatConfirm\n v-else-if=\"part.type === 'confirm'\"\n :title=\"asConfirm(part).title\"\n :description=\"asConfirm(part).description\"\n :status=\"asConfirm(part).status\"\n :allow-always=\"asConfirm(part).allowAlways\"\n :tone=\"asConfirm(part).tone\"\n @decide=\"emit('confirm', asConfirm(part), $event)\"\n >\n <pre v-if=\"asConfirm(part).detail\" :class=\"ns.e('code')\">{{\n asConfirm(part).detail\n }}</pre>\n </DouChatConfirm>\n <slot\n v-else-if=\"!known.has(part.type)\"\n name=\"part\"\n :part=\"part as ChatCustomPart\"\n :index=\"index\"\n />\n </template>\n </slot>\n <span v-if=\"loading\" :class=\"ns.e('loading')\" role=\"status\" :aria-label=\"t('chat.loading')\">\n <i /><i /><i />\n </span>\n </div>\n\n <div v-if=\"showActions && !editing\" :class=\"ns.e('actions')\">\n <div\n v-if=\"versions > 1\"\n :class=\"ns.e('versions')\"\n role=\"group\"\n :aria-label=\"t('chat.versions')\"\n >\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version <= 1\"\n :aria-label=\"t('chat.previousVersion')\"\n @click=\"step(-1)\"\n >\n <ChevronLeftIcon />\n </DouButton>\n <span :class=\"ns.e('version')\">{{ version }} / {{ versions }}</span>\n <DouButton\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"version >= versions\"\n :aria-label=\"t('chat.nextVersion')\"\n @click=\"step(1)\"\n >\n <ChevronRightIcon />\n </DouButton>\n </div>\n <DouCopyButton v-if=\"copyable && text\" size=\"sm\" :text=\"text\" />\n <DouTooltip v-if=\"editable && isUser\" :content=\"t('chat.edit')\">\n <DouButton variant=\"ghost\" size=\"sm\" :aria-label=\"t('chat.edit')\" @click=\"startEdit\">\n <EditIcon />\n </DouButton>\n </DouTooltip>\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,13 +1,18 @@
1
1
  import '@dou-ui/theme/core.css'
2
2
  import '@dou-ui/theme/components/overlay.css'
3
+ import '@dou-ui/theme/components/alert.css'
4
+ import '@dou-ui/theme/components/status-dot.css'
3
5
  import '@dou-ui/theme/components/button.css'
6
+ import '@dou-ui/theme/components/code-block.css'
4
7
  import '@dou-ui/theme/components/collapse.css'
5
8
  import '@dou-ui/theme/components/copy-button.css'
6
9
  import '@dou-ui/theme/components/kbd.css'
10
+ import '@dou-ui/theme/components/popover.css'
7
11
  import '@dou-ui/theme/components/spinner.css'
8
12
  import '@dou-ui/theme/components/tooltip.css'
9
13
  import '@dou-ui/theme/components/shimmer.css'
10
14
  import '@dou-ui/theme/components/stream-text.css'
15
+ import '@dou-ui/theme/components/markdown.css'
11
16
  import '@dou-ui/theme/components/chat-reasoning.css'
12
17
  import '@dou-ui/theme/components/chat-tool-call.css'
13
18
  import '@dou-ui/theme/components/chat-attachments.css'
@@ -1,6 +1,11 @@
1
- import chat_plan_vue_vue_type_script_setup_true_lang_default from "./chat-plan.vue_vue_type_script_setup_true_lang.js";
2
- // src/components/chat-plan/chat-plan.vue
3
- var chat_plan_default = chat_plan_vue_vue_type_script_setup_true_lang_default;
4
- export { chat_plan_default as default };
1
+ // src/components/chat-plan/chat-plan.ts
2
+ /**
3
+ * Whether the plan shows a step running: one is `running` and the run hasn't
4
+ * stopped. ChatMessage reads the same for `aria-busy`.
5
+ */
6
+ function planRunning(items, live = true) {
7
+ return live && !!items?.some((item) => item.status === "running");
8
+ }
9
+ export { planRunning };
5
10
 
6
11
  //# sourceMappingURL=chat-plan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-plan.js","names":["_sfc_main"],"sources":["../../../src/components/chat-plan/chat-plan.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AlertCircleIcon, CheckIcon, ChevronDownIcon, ListChecksIcon } from '@dou-ui/icons'\nimport { computed, ref, useId } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { CollapseTransition } from '../collapse/collapse-transition'\nimport { useLocale } from '../config-provider/use-config'\nimport DouShimmer from '../shimmer/shimmer.vue'\nimport DouSpinner from '../spinner/spinner.vue'\nimport type { ChatPlanEmits, ChatPlanProps, ChatPlanSlots } from './chat-plan'\n\ndefineOptions({ name: 'DouChatPlan' })\n\nconst props = withDefaults(defineProps<ChatPlanProps>(), {\n items: () => [],\n open: undefined,\n})\nconst emit = defineEmits<ChatPlanEmits>()\ndefineSlots<ChatPlanSlots>()\n\nconst ns = useNamespace('chat-plan')\nconst { t } = useLocale()\nconst id = useId()\n\nconst inner = ref(true)\nconst open = computed(() => props.open ?? inner.value)\nfunction toggle() {\n inner.value = !open.value\n emit('update:open', inner.value)\n}\n\nconst finished = computed(\n () => props.items.filter((item) => item.status === 'done' || item.status === 'skipped').length,\n)\nconst running = computed(() => props.items.some((item) => item.status === 'running'))\n</script>\n\n<template>\n <div :class=\"[ns.b(), ns.is('open', open), ns.is('running', running)]\">\n <button\n :id=\"`${id}-trigger`\"\n type=\"button\"\n :class=\"ns.e('header')\"\n :aria-expanded=\"open\"\n :aria-controls=\"`${id}-panel`\"\n @click=\"toggle\"\n >\n <ListChecksIcon :class=\"ns.e('icon')\" />\n <span :class=\"ns.e('title')\">{{ title ?? t('chat.plan') }}</span>\n <span :class=\"ns.e('count')\">{{ finished }} / {{ items.length }}</span>\n <ChevronDownIcon :class=\"ns.e('arrow')\" />\n </button>\n <CollapseTransition>\n <div\n v-show=\"open\"\n :id=\"`${id}-panel`\"\n role=\"region\"\n :class=\"ns.e('panel')\"\n :aria-labelledby=\"`${id}-trigger`\"\n >\n <ol :class=\"ns.e('list')\">\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.key ?? index\"\n :class=\"[ns.e('item'), ns.is(item.status ?? 'pending')]\"\n >\n <span :class=\"ns.e('mark')\">\n <DouSpinner\n v-if=\"item.status === 'running'\"\n size=\"sm\"\n :label=\"t('chat.stepRunning')\"\n />\n <CheckIcon v-else-if=\"item.status === 'done'\" :label=\"t('chat.stepDone')\" />\n <AlertCircleIcon v-else-if=\"item.status === 'error'\" :label=\"t('chat.stepError')\" />\n <span v-else :class=\"ns.e('dot')\" />\n </span>\n <span :class=\"ns.e('text')\">\n <slot name=\"item\" :item=\"item\" :index=\"index\">\n <span :class=\"ns.e('label')\">\n <DouShimmer :active=\"item.status === 'running'\">{{ item.label }}</DouShimmer>\n </span>\n <span v-if=\"item.description\" :class=\"ns.e('description')\">\n {{ item.description }}\n </span>\n </slot>\n </span>\n </li>\n </ol>\n </div>\n </CollapseTransition>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"chat-plan.js","names":[],"sources":["../../../src/components/chat-plan/chat-plan.ts"],"sourcesContent":["/**\n * `waiting` is a step paused on someone else, such as a confirmation from\n * the user or an outside job, as opposed to `pending`, which hasn't started.\n */\nexport type ChatPlanItemStatus = 'pending' | 'running' | 'waiting' | 'done' | 'skipped' | 'error'\n\nexport interface ChatPlanItem {\n /** Unique within the plan. Defaults to the position. */\n key?: string | number\n label: string\n /** A second line under the label. */\n description?: string\n status?: ChatPlanItemStatus\n}\n\nexport interface ChatPlanProps {\n /** The steps, in order. */\n items?: ChatPlanItem[]\n /** Defaults to the locale's \"Plan\". */\n title?: string\n /** Let the header fold the list away. Off gives a plain panel that always shows the steps. */\n collapsible?: boolean\n /** Expanded or not. Bound with `v-model:open`; open by default. Ignored when not `collapsible`. */\n open?: boolean\n /**\n * The run is going on now. Off once the turn has ended or been stopped: a\n * `running` step stays the current one but holds still, a solid dot in\n * place of the spinner and no shimmer, so the steps needn't be rewritten.\n */\n live?: boolean\n}\n\nexport interface ChatPlanEmits {\n 'update:open': [open: boolean]\n}\n\nexport interface ChatPlanSlots {\n /** Replaces the label and description of each item. */\n item?: (props: { item: ChatPlanItem; index: number }) => unknown\n}\n\n/**\n * Whether the plan shows a step running: one is `running` and the run hasn't\n * stopped. ChatMessage reads the same for `aria-busy`.\n */\nexport function planRunning(items: readonly ChatPlanItem[] | undefined, live = true): boolean {\n return live && !!items?.some((item) => item.status === 'running')\n}\n"],"mappings":";;;;;AA6CA,SAAgB,YAAY,OAA4C,OAAO,MAAe;CAC5F,OAAO,QAAQ,CAAC,CAAC,OAAO,MAAM,SAAS,KAAK,WAAW,SAAS;AAClE"}