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.
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar-view/calendar-view.js.map +1 -1
- package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-artifact/chat-artifact.js.map +1 -1
- package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments2.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js +38 -14
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-context-meter/chat-context-meter2.js.map +1 -1
- package/dist/components/chat-message/chat-message.js.map +1 -1
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js +88 -33
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-message/chat-message2.js.map +1 -1
- package/dist/components/chat-message/style.js +5 -0
- package/dist/components/chat-plan/chat-plan.js +9 -4
- package/dist/components/chat-plan/chat-plan.js.map +1 -1
- package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js +64 -32
- package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-plan/chat-plan2.js +6 -0
- package/dist/components/chat-plan/chat-plan2.js.map +1 -0
- package/dist/components/chat-plan/index.js +1 -1
- package/dist/components/chat-plan/style.js +1 -0
- package/dist/components/chat-reasoning/chat-reasoning.js.map +1 -1
- package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-citation.js.map +1 -1
- package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js +52 -14
- package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-sources.js.map +1 -1
- package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js +6 -4
- package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-sources2.js.map +1 -1
- package/dist/components/chat-sources/index.js +1 -1
- package/dist/components/chat-steps/chat-steps.js +9 -4
- package/dist/components/chat-steps/chat-steps.js.map +1 -1
- package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js +20 -13
- package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-steps/chat-steps2.js +6 -0
- package/dist/components/chat-steps/chat-steps2.js.map +1 -0
- package/dist/components/chat-steps/index.js +1 -1
- package/dist/components/chat-steps/style.js +1 -0
- package/dist/components/chat-tool-call/chat-tool-call.js.map +1 -1
- package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js +38 -12
- package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-tool-call/chat-tool-call2.js.map +1 -1
- package/dist/components/chat-tool-call/style.js +1 -0
- package/dist/components/code-block/code-block.js.map +1 -1
- package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js +37 -5
- package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/collapse/collapse-item.js.map +1 -1
- package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/collapse/collapse-transition.js +3 -1
- package/dist/components/collapse/collapse-transition.js.map +1 -1
- package/dist/components/collapse/index.js +1 -2
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/color-mode/color-mode-button.js.map +1 -1
- package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-mode/color-mode-select.js.map +1 -1
- package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-mode/color-mode-switch.js.map +1 -1
- package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-panel/color-panel.js.map +1 -1
- package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/comment-thread/comment-thread.js.map +1 -1
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/comment-thread/style.js +2 -0
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js +26 -11
- package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/context-menu/index.js +2 -0
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/copy-button/copy-button.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/descriptions/descriptions.js.map +1 -1
- package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/descriptions/descriptions2.js.map +1 -1
- package/dist/components/dropdown/dropdown-button.js.map +1 -1
- package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-group.js +6 -0
- package/dist/components/dropdown/dropdown-group.js.map +1 -0
- package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/dropdown/dropdown-item.js.map +1 -1
- package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js +31 -9
- package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-items.js.map +1 -1
- package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js +77 -52
- package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-radio-group.js.map +1 -1
- package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js +23 -5
- package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-sub.js.map +1 -1
- package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js +5 -4
- package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown2.js.map +1 -1
- package/dist/components/dropdown/index.js +4 -5
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown/item-components.js +11 -0
- package/dist/components/dropdown/item-components.js.map +1 -0
- package/dist/components/dropdown/menu-entries.js +14 -0
- package/dist/components/dropdown/menu-entries.js.map +1 -0
- package/dist/components/dropdown/menu-keys.js +1 -1
- package/dist/components/dropdown/menu-keys.js.map +1 -1
- package/dist/components/ellipsis/ellipsis.js.map +1 -1
- package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js +10 -10
- package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/infinite-scroll/infinite-scroll.js.map +1 -1
- package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input-date/segment-field.js.map +1 -1
- package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input-date/style.js +1 -0
- package/dist/components/input-time/style.js +1 -0
- package/dist/components/layout/layout-aside-trigger.js.map +1 -1
- package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout-aside.js.map +1 -1
- package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout-footer.js.map +1 -1
- package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout.js.map +1 -1
- package/dist/components/markdown/index.js +9 -0
- package/dist/components/markdown/index.js.map +1 -0
- package/dist/components/markdown/markdown.js +6 -0
- package/dist/components/markdown/markdown.js.map +1 -0
- package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js +225 -0
- package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/markdown/parse-block.js +577 -0
- package/dist/components/markdown/parse-block.js.map +1 -0
- package/dist/components/markdown/parse-inline.js +626 -0
- package/dist/components/markdown/parse-inline.js.map +1 -0
- package/dist/components/markdown/parser.js +308 -0
- package/dist/components/markdown/parser.js.map +1 -0
- package/dist/components/markdown/render.js +424 -0
- package/dist/components/markdown/render.js.map +1 -0
- package/dist/components/markdown/style.d.ts +1 -0
- package/dist/components/markdown/style.js +10 -0
- package/dist/components/markdown/url.js +16 -0
- package/dist/components/markdown/url.js.map +1 -0
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-list.js.map +1 -1
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-popup.js.map +1 -1
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js +33 -21
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu.js +16 -13
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu2.js.map +1 -1
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/node-graph/layout.js +136 -31
- package/dist/components/node-graph/layout.js.map +1 -1
- package/dist/components/node-graph/node-graph-legend.js.map +1 -1
- package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/node-graph/node-graph.js.map +1 -1
- package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/pagination/pagination-gap.js.map +1 -1
- package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/popconfirm/index.js +2 -0
- package/dist/components/popconfirm/index.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/popover/index.js +2 -0
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js +12 -5
- package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/progress-group/progress-group.js.map +1 -1
- package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/qrcode/qrcode.js.map +1 -1
- package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js +10 -2
- package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/status-dot/index.js +7 -0
- package/dist/components/status-dot/index.js.map +1 -0
- package/dist/components/status-dot/status-dot.js +26 -0
- package/dist/components/status-dot/status-dot.js.map +1 -0
- package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js +43 -0
- package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js.map +1 -0
- package/dist/components/status-dot/status-dot2.js +6 -0
- package/dist/components/status-dot/status-dot2.js.map +1 -0
- package/dist/components/status-dot/style.d.ts +1 -0
- package/dist/components/status-dot/style.js +2 -0
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js +19 -14
- package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js +117 -47
- package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs2.js.map +1 -1
- package/dist/components/tag/tag.js.map +1 -1
- package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js +21 -4
- package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/timeline/style.js +1 -0
- package/dist/components/timeline/timeline-item.js.map +1 -1
- package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tooltip/index.js +2 -0
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js +55 -8
- package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/transfer/transfer-list.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tree/tree.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/upload/upload2.js.map +1 -1
- package/dist/components/user/user.js.map +1 -1
- package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/use-popup.js +30 -5
- package/dist/composables/use-popup.js.map +1 -1
- package/dist/index.js +23 -17
- package/dist/index.js.map +1 -1
- package/dist/locale/en.js +13 -8
- package/dist/locale/en.js.map +1 -1
- package/dist/locale/zh-cn.js +13 -8
- package/dist/locale/zh-cn.js.map +1 -1
- package/dist/locale/zh-tw.js +13 -8
- package/dist/locale/zh-tw.js.map +1 -1
- package/dist/plugin.js +21 -14
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/components/button/button.d.ts +5 -1
- package/dist/types/components/calendar-view/calendar-view.d.ts +6 -0
- package/dist/types/components/calendar-view/calendar-view.vue.d.ts +1 -0
- package/dist/types/components/calendar-view/index.d.ts +3 -0
- package/dist/types/components/chat-artifact/chat-artifact.d.ts +2 -1
- package/dist/types/components/chat-attachments/chat-attachments.d.ts +2 -2
- package/dist/types/components/chat-confirm/chat-confirm.d.ts +7 -2
- package/dist/types/components/chat-list/index.d.ts +3 -3
- package/dist/types/components/chat-message/chat-message.d.ts +26 -3
- package/dist/types/components/chat-message/chat-message.vue.d.ts +4 -3
- package/dist/types/components/chat-message/index.d.ts +7 -4
- package/dist/types/components/chat-plan/chat-plan.d.ts +19 -2
- package/dist/types/components/chat-plan/chat-plan.vue.d.ts +2 -0
- package/dist/types/components/chat-plan/index.d.ts +6 -0
- package/dist/types/components/chat-sources/chat-sources.d.ts +6 -1
- package/dist/types/components/chat-steps/chat-steps.d.ts +10 -4
- package/dist/types/components/chat-steps/chat-steps.vue.d.ts +1 -1
- package/dist/types/components/chat-steps/index.d.ts +3 -3
- package/dist/types/components/chat-tool-call/chat-tool-call.d.ts +12 -3
- package/dist/types/components/chat-tool-call/chat-tool-call.vue.d.ts +1 -0
- package/dist/types/components/chat-tool-call/index.d.ts +3 -0
- package/dist/types/components/checkbox/index.d.ts +5 -5
- package/dist/types/components/code-block/code-block.d.ts +11 -0
- package/dist/types/components/code-block/code-block.vue.d.ts +3 -1
- package/dist/types/components/code-block/index.d.ts +9 -3
- package/dist/types/components/collapse/collapse-transition.d.ts +2 -7
- package/dist/types/components/collapse/collapse.vue.d.ts +1 -1
- package/dist/types/components/collapse/index.d.ts +5 -6
- package/dist/types/components/context-menu/context-menu.d.ts +37 -4
- package/dist/types/components/context-menu/context-menu.vue.d.ts +2 -0
- package/dist/types/components/context-menu/index.d.ts +5 -0
- package/dist/types/components/copy-button/copy-button.vue.d.ts +1 -1
- package/dist/types/components/copy-button/index.d.ts +1 -1
- package/dist/types/components/descriptions/descriptions.d.ts +9 -1
- package/dist/types/components/descriptions/descriptions.vue.d.ts +1 -0
- package/dist/types/components/descriptions/index.d.ts +3 -0
- package/dist/types/components/dropdown/dropdown-group.vue.d.ts +13 -0
- package/dist/types/components/dropdown/dropdown-items.vue.d.ts +2 -2
- package/dist/types/components/dropdown/dropdown-radio-group.vue.d.ts +8 -4
- package/dist/types/components/dropdown/dropdown.d.ts +28 -6
- package/dist/types/components/dropdown/dropdown.vue.d.ts +1 -1
- package/dist/types/components/dropdown/index.d.ts +10 -81
- package/dist/types/components/dropdown/item-components.d.ts +103 -0
- package/dist/types/components/dropdown/menu-entries.d.ts +4 -0
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/components/layout/index.d.ts +12 -6
- package/dist/types/components/layout/layout-aside.vue.d.ts +1 -1
- package/dist/types/components/layout/layout-footer.vue.d.ts +4 -2
- package/dist/types/components/layout/layout.d.ts +4 -0
- package/dist/types/components/markdown/index.d.ts +58 -0
- package/dist/types/components/markdown/markdown.d.ts +251 -0
- package/dist/types/components/markdown/markdown.vue.d.ts +22 -0
- package/dist/types/components/markdown/parse-block.d.ts +61 -0
- package/dist/types/components/markdown/parse-inline.d.ts +19 -0
- package/dist/types/components/markdown/parser.d.ts +22 -0
- package/dist/types/components/markdown/render.d.ts +84 -0
- package/dist/types/components/markdown/url.d.ts +10 -0
- package/dist/types/components/masonry/index.d.ts +3 -3
- package/dist/types/components/menu/index.d.ts +8 -3
- package/dist/types/components/menu/menu.d.ts +16 -5
- package/dist/types/components/menu/menu.vue.d.ts +3 -1
- package/dist/types/components/menubar/menubar.d.ts +1 -1
- package/dist/types/components/node-graph/layout.d.ts +16 -0
- package/dist/types/components/node-graph/node-graph.d.ts +1 -1
- package/dist/types/components/popover/index.d.ts +3 -3
- package/dist/types/components/popover/popover.vue.d.ts +1 -1
- package/dist/types/components/progress-group/index.d.ts +3 -0
- package/dist/types/components/progress-group/progress-group.d.ts +7 -0
- package/dist/types/components/progress-group/progress-group.vue.d.ts +1 -0
- package/dist/types/components/qrcode/index.d.ts +3 -0
- package/dist/types/components/qrcode/qrcode.d.ts +5 -0
- package/dist/types/components/qrcode/qrcode.vue.d.ts +1 -0
- package/dist/types/components/sortable/index.d.ts +3 -3
- package/dist/types/components/status-dot/index.d.ts +51 -0
- package/dist/types/components/status-dot/status-dot.d.ts +46 -0
- package/dist/types/components/status-dot/status-dot.vue.d.ts +46 -0
- package/dist/types/components/steps/steps.d.ts +1 -1
- package/dist/types/components/switch/index.d.ts +3 -3
- package/dist/types/components/table/index.d.ts +4 -3
- package/dist/types/components/table/table.d.ts +6 -1
- package/dist/types/components/tabs/index.d.ts +3 -0
- package/dist/types/components/tabs/tabs.d.ts +16 -3
- package/dist/types/components/tabs/tabs.vue.d.ts +1 -0
- package/dist/types/components/timeline/index.d.ts +3 -3
- package/dist/types/components/timeline/timeline-item.vue.d.ts +1 -1
- package/dist/types/components/virtual-list/index.d.ts +3 -3
- package/dist/types/composables/use-popup.d.ts +15 -5
- package/dist/types/locale/types.d.ts +18 -7
- package/dist/types/utils/only-child.d.ts +3 -1
- package/dist/types/utils/pointer.d.ts +5 -0
- package/dist/types/utils/safe-url.d.ts +14 -0
- package/dist/types/utils/status-check.d.ts +8 -0
- package/dist/utils/install.js +5 -0
- package/dist/utils/install.js.map +1 -1
- package/dist/utils/only-child.js +56 -5
- package/dist/utils/only-child.js.map +1 -1
- package/dist/utils/pointer.js +6 -1
- package/dist/utils/pointer.js.map +1 -1
- package/dist/utils/safe-url.js +57 -0
- package/dist/utils/safe-url.js.map +1 -0
- package/dist/utils/status-check.js +27 -0
- package/dist/utils/status-check.js.map +1 -0
- package/package.json +3 -3
package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -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: '
|
|
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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"}
|
package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useNamespace } from "../../utils/namespace.js";
|
|
2
2
|
import { useLocale } from "../config-provider/use-config.js";
|
|
3
|
-
import
|
|
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(
|
|
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","
|
|
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
|
|
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
|
|
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
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
201
|
-
key:
|
|
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(() => [
|
|
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
|
-
},
|
|
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(
|
|
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 === "
|
|
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 === "
|
|
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 === "
|
|
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(
|
|
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,
|
|
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(
|
|
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(
|
|
357
|
+
__props.editable && isUser.value ? (openBlock(), createBlock(unref(DouTooltip), {
|
|
303
358
|
key: 2,
|
|
304
359
|
content: unref(t)("chat.edit")
|
|
305
360
|
}, {
|
package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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":[
|
|
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"}
|