@incremark/chat-vue 0.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/LICENSE +22 -0
  2. package/dist/chunk-X3YI3YOK.js +3809 -0
  3. package/dist/chunk-X3YI3YOK.js.map +1 -0
  4. package/dist/components/base/action-button/action-button.vue.d.ts +28 -0
  5. package/dist/components/base/action-button/index.d.ts +5 -0
  6. package/dist/components/base/action-button/types/index.d.ts +9 -0
  7. package/dist/components/base/im-button/im-button.vue.d.ts +30 -0
  8. package/dist/components/base/im-button/index.d.ts +2 -0
  9. package/dist/components/base/im-button/types/index.d.ts +27 -0
  10. package/dist/components/base/im-dropdown/im-dropdown.vue.d.ts +24 -0
  11. package/dist/components/base/im-dropdown/index.d.ts +5 -0
  12. package/dist/components/base/im-dropdown/types/index.d.ts +27 -0
  13. package/dist/components/base/im-popover/im-popover.vue.d.ts +38 -0
  14. package/dist/components/base/im-popover/index.d.ts +2 -0
  15. package/dist/components/base/im-popover/types/index.d.ts +25 -0
  16. package/dist/components/base/im-tooltip/im-tooltip.vue.d.ts +20 -0
  17. package/dist/components/base/im-tooltip/index.d.ts +2 -0
  18. package/dist/components/base/im-tooltip/types/index.d.ts +12 -0
  19. package/dist/components/base/index.d.ts +8 -0
  20. package/dist/components/chain-of-thought/chain-of-thought-step.vue.d.ts +25 -0
  21. package/dist/components/chain-of-thought/chain-of-thought.vue.d.ts +32 -0
  22. package/dist/components/chain-of-thought/composables/index.d.ts +4 -0
  23. package/dist/components/chain-of-thought/composables/useChainOfThought.d.ts +7 -0
  24. package/dist/components/chain-of-thought/index.d.ts +6 -0
  25. package/dist/components/chain-of-thought/types/index.d.ts +76 -0
  26. package/dist/components/error-message/error-message.vue.d.ts +22 -0
  27. package/dist/components/error-message/index.d.ts +5 -0
  28. package/dist/components/error-message/types/index.d.ts +22 -0
  29. package/dist/components/file-preview/composables/index.d.ts +1 -0
  30. package/dist/components/file-preview/composables/useFileType.d.ts +40 -0
  31. package/dist/components/file-preview/file-preview.vue.d.ts +13 -0
  32. package/dist/components/file-preview/index.d.ts +5 -0
  33. package/dist/components/file-preview/types/index.d.ts +44 -0
  34. package/dist/components/index.d.ts +34 -0
  35. package/dist/components/message-actions/composables/index.d.ts +5 -0
  36. package/dist/components/message-actions/composables/useCopyAction.d.ts +20 -0
  37. package/dist/components/message-actions/index.d.ts +11 -0
  38. package/dist/components/message-actions/message-action-copy.vue.d.ts +7 -0
  39. package/dist/components/message-actions/message-action-feedback.vue.d.ts +14 -0
  40. package/dist/components/message-actions/message-action-more.vue.d.ts +10 -0
  41. package/dist/components/message-actions/message-action.vue.d.ts +21 -0
  42. package/dist/components/message-actions/message-actions.vue.d.ts +23 -0
  43. package/dist/components/message-actions/types/index.d.ts +107 -0
  44. package/dist/components/message-bubble/index.d.ts +2 -0
  45. package/dist/components/message-bubble/message-bubble.vue.d.ts +27 -0
  46. package/dist/components/message-bubble/types/index.d.ts +37 -0
  47. package/dist/components/message-renderer/index.d.ts +6 -0
  48. package/dist/components/message-renderer/part-renderer.vue.d.ts +19 -0
  49. package/dist/components/message-renderer/types/index.d.ts +37 -0
  50. package/dist/components/reasoning-message/index.d.ts +5 -0
  51. package/dist/components/reasoning-message/reasoning-message.vue.d.ts +8 -0
  52. package/dist/components/reasoning-message/types/index.d.ts +38 -0
  53. package/dist/components/sender/components/sender-action-button.vue.d.ts +24 -0
  54. package/dist/components/sender/components/sender-attachments.vue.d.ts +11 -0
  55. package/dist/components/sender/components/sender-file-button.vue.d.ts +11 -0
  56. package/dist/components/sender/components/sender-submit-button.vue.d.ts +21 -0
  57. package/dist/components/sender/composables/index.d.ts +2 -0
  58. package/dist/components/sender/composables/useSender.d.ts +31 -0
  59. package/dist/components/sender/index.d.ts +7 -0
  60. package/dist/components/sender/sender.vue.d.ts +66 -0
  61. package/dist/components/sender/types/index.d.ts +174 -0
  62. package/dist/components/sender-input/index.d.ts +1 -0
  63. package/dist/components/sender-input/sender-input.vue.d.ts +36 -0
  64. package/dist/components/sender-input/types/index.d.ts +24 -0
  65. package/dist/components/source-reference/index.d.ts +5 -0
  66. package/dist/components/source-reference/source-reference.vue.d.ts +20 -0
  67. package/dist/components/source-reference/types/index.d.ts +13 -0
  68. package/dist/components/suggestion/index.d.ts +6 -0
  69. package/dist/components/suggestion/suggestion-item.vue.d.ts +21 -0
  70. package/dist/components/suggestion/suggestion.vue.d.ts +22 -0
  71. package/dist/components/suggestion/types/index.d.ts +27 -0
  72. package/dist/components/svg-icon/index.d.ts +1 -0
  73. package/dist/components/svg-icon/svg-icon.vue.d.ts +13 -0
  74. package/dist/components/text-message/index.d.ts +5 -0
  75. package/dist/components/text-message/text-message.vue.d.ts +6 -0
  76. package/dist/components/text-message/types/index.d.ts +32 -0
  77. package/dist/components/tool-call/index.d.ts +5 -0
  78. package/dist/components/tool-call/tool-call.vue.d.ts +18 -0
  79. package/dist/components/tool-call/types/index.d.ts +81 -0
  80. package/dist/components/welcome/index.d.ts +5 -0
  81. package/dist/components/welcome/types/index.d.ts +19 -0
  82. package/dist/components/welcome/welcome.vue.d.ts +28 -0
  83. package/dist/components.js +3 -0
  84. package/dist/components.js.map +1 -0
  85. package/dist/composables/index.d.ts +2 -0
  86. package/dist/composables/useCollapsible.d.ts +4 -0
  87. package/dist/composables/useUIAdapter.d.ts +14 -0
  88. package/dist/index.d.ts +7 -0
  89. package/dist/index.js +30 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/provider/ChatProvider.vue.d.ts +14 -0
  92. package/dist/provider/index.d.ts +4 -0
  93. package/dist/types/adapter.d.ts +64 -0
  94. package/dist/types/index.d.ts +5 -0
  95. package/dist/types/message.d.ts +5 -0
  96. package/dist/types/parts.d.ts +5 -0
  97. package/package.json +83 -0
@@ -0,0 +1,3809 @@
1
+ import { defineComponent, createElementBlock, openBlock, normalizeClass, renderSlot, computed, Fragment, createElementVNode, createBlock, Teleport, createVNode, Transition, withCtx, createCommentVNode, normalizeStyle, mergeModels, useModel, ref, toDisplayString, createTextVNode, useSlots, withDirectives, renderList, createSlots, resolveDynamicComponent, mergeProps, vShow, normalizeProps, toRef, h, watch, provide, inject, nextTick } from 'vue';
2
+ import { createImBem, formatDuration, formatFileSize } from '@incremark/shared';
3
+ import { Icon } from '@iconify/vue';
4
+ import { offset, flip, shift, arrow, useFloating, autoUpdate } from '@floating-ui/vue';
5
+ import { onClickOutside } from '@vueuse/core';
6
+ import { IncremarkContent } from '@incremark/vue';
7
+ import { TOOL_CALL_STATES } from '@incremark/chat-core';
8
+ import { useEditor, EditorContent } from '@tiptap/vue-3';
9
+ import { Document } from '@tiptap/extension-document';
10
+ import { Paragraph } from '@tiptap/extension-paragraph';
11
+ import { Text } from '@tiptap/extension-text';
12
+ import { Placeholder, UndoRedo } from '@tiptap/extensions';
13
+ import { Markdown } from '@tiptap/markdown';
14
+
15
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/svg-icon/svg-icon.vue?type=script
16
+ var svg_icon_default = /* @__PURE__ */ defineComponent({
17
+ __name: "svg-icon",
18
+ setup(__props, { expose: __expose }) {
19
+ __expose();
20
+ const bem = createImBem("svg-icon");
21
+ const __returned__ = { bem };
22
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
23
+ return __returned__;
24
+ }
25
+ });
26
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
27
+ return openBlock(), createElementBlock(
28
+ "span",
29
+ {
30
+ class: normalizeClass($setup.bem())
31
+ },
32
+ [
33
+ renderSlot(_ctx.$slots, "default")
34
+ ],
35
+ 2
36
+ /* CLASS */
37
+ );
38
+ }
39
+
40
+ // src/components/svg-icon/svg-icon.vue
41
+ svg_icon_default.render = render;
42
+ svg_icon_default.__file = "src/components/svg-icon/svg-icon.vue";
43
+ var svg_icon_default2 = svg_icon_default;
44
+ function useChainOfThought(props) {
45
+ const duration = computed(() => {
46
+ if (!props.startTime) return null;
47
+ const end = props.endTime || Date.now();
48
+ return formatDuration(end - props.startTime, props.locale);
49
+ });
50
+ return { duration };
51
+ }
52
+ function useCollapsible(defaultExpanded = true) {
53
+ const expanded = ref(defaultExpanded);
54
+ const toggle = () => {
55
+ expanded.value = !expanded.value;
56
+ };
57
+ return { expanded, toggle };
58
+ }
59
+ var im_button_default = /* @__PURE__ */ defineComponent({
60
+ __name: "im-button",
61
+ props: {
62
+ variant: { type: String, required: false, default: "solid" },
63
+ color: { type: String, required: false, default: "primary" },
64
+ size: { type: String, required: false, default: "md" },
65
+ disabled: { type: Boolean, required: false, default: false },
66
+ loading: { type: Boolean, required: false, default: false },
67
+ block: { type: Boolean, required: false, default: false },
68
+ square: { type: Boolean, required: false, default: false },
69
+ circle: { type: Boolean, required: false, default: false },
70
+ active: { type: Boolean, required: false, default: false }
71
+ },
72
+ emits: ["click"],
73
+ setup(__props, { expose: __expose, emit: __emit }) {
74
+ __expose();
75
+ const props = __props;
76
+ const emit = __emit;
77
+ const bem = createImBem("button");
78
+ const rootClass = computed(() => [
79
+ bem(),
80
+ bem("", props.variant),
81
+ bem("", props.color),
82
+ bem("", props.size),
83
+ props.block && bem("", "block"),
84
+ props.square && bem("", "square"),
85
+ props.circle && bem("", "circle"),
86
+ props.loading && bem("", "loading"),
87
+ props.disabled && bem("", "disabled"),
88
+ props.active && bem("", "active")
89
+ ]);
90
+ const handleClick = (event) => {
91
+ if (!props.disabled && !props.loading) {
92
+ emit("click", event);
93
+ }
94
+ };
95
+ const __returned__ = { props, emit, bem, rootClass, handleClick };
96
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
97
+ return __returned__;
98
+ }
99
+ });
100
+ var _hoisted_1 = ["disabled"];
101
+ function render2(_ctx, _cache, $props, $setup, $data, $options) {
102
+ return openBlock(), createElementBlock("button", {
103
+ class: normalizeClass($setup.rootClass),
104
+ disabled: $props.disabled || $props.loading,
105
+ type: "button",
106
+ onClick: $setup.handleClick
107
+ }, [
108
+ $props.loading ? (openBlock(), createElementBlock(
109
+ "span",
110
+ {
111
+ key: 0,
112
+ class: normalizeClass($setup.bem("spinner"))
113
+ },
114
+ null,
115
+ 2
116
+ /* CLASS */
117
+ )) : renderSlot(_ctx.$slots, "icon", { key: 1 }),
118
+ renderSlot(_ctx.$slots, "default")
119
+ ], 10, _hoisted_1);
120
+ }
121
+
122
+ // src/components/base/im-button/im-button.vue
123
+ im_button_default.render = render2;
124
+ im_button_default.__file = "src/components/base/im-button/im-button.vue";
125
+ var im_button_default2 = im_button_default;
126
+ var im_popover_default = /* @__PURE__ */ defineComponent({
127
+ __name: "im-popover",
128
+ props: /* @__PURE__ */ mergeModels({
129
+ trigger: { type: String, required: false, default: "click" },
130
+ placement: { type: null, required: false, default: "bottom" },
131
+ offset: { type: Number, required: false, default: 8 },
132
+ arrow: { type: Boolean, required: false, default: false },
133
+ disabled: { type: Boolean, required: false, default: false },
134
+ strategy: { type: String, required: false, default: "absolute" },
135
+ to: { type: [String, Function], required: false, skipCheck: true, default: "body" },
136
+ teleportDisabled: { type: Boolean, required: false, default: false }
137
+ }, {
138
+ "visible": { type: Boolean, ...{ default: false } },
139
+ "visibleModifiers": {}
140
+ }),
141
+ emits: ["update:visible"],
142
+ setup(__props, { expose: __expose }) {
143
+ const props = __props;
144
+ const visible = useModel(__props, "visible");
145
+ const bem = createImBem("popover");
146
+ const referenceEl = ref(null);
147
+ const floatingEl = ref(null);
148
+ const arrowEl = ref(null);
149
+ const middleware = computed(() => {
150
+ const list = [offset(props.offset), flip(), shift({ padding: 8 })];
151
+ if (props.arrow) {
152
+ list.push(arrow({ element: arrowEl }));
153
+ }
154
+ return list;
155
+ });
156
+ const { floatingStyles, middlewareData, placement: finalPlacement, isPositioned } = useFloating(referenceEl, floatingEl, {
157
+ placement: computed(() => props.placement),
158
+ strategy: computed(() => props.strategy),
159
+ middleware,
160
+ whileElementsMounted: autoUpdate
161
+ });
162
+ const popoverStyles = computed(() => ({
163
+ ...floatingStyles.value,
164
+ // 在位置计算完成前隐藏,避免从角落飘入
165
+ visibility: isPositioned.value ? "visible" : "hidden"
166
+ }));
167
+ const arrowStyles = computed(() => {
168
+ if (!props.arrow) return {};
169
+ const { x, y } = middlewareData.value.arrow || {};
170
+ const side = finalPlacement.value.split("-")[0];
171
+ const staticSide = { top: "bottom", right: "left", bottom: "top", left: "right" }[side];
172
+ return {
173
+ left: x != null ? `${x}px` : "",
174
+ top: y != null ? `${y}px` : "",
175
+ [staticSide]: "-5px"
176
+ };
177
+ });
178
+ const teleportTarget = computed(() => {
179
+ const { to } = props;
180
+ return typeof to === "function" ? to() : to;
181
+ });
182
+ let hideTimeout = null;
183
+ const show = () => {
184
+ if (hideTimeout) {
185
+ clearTimeout(hideTimeout);
186
+ hideTimeout = null;
187
+ }
188
+ if (!props.disabled) visible.value = true;
189
+ };
190
+ const hide = () => {
191
+ visible.value = false;
192
+ };
193
+ const delayedHide = () => {
194
+ hideTimeout = setTimeout(() => {
195
+ hide();
196
+ }, 100);
197
+ };
198
+ const toggle = () => {
199
+ if (!props.disabled) visible.value = !visible.value;
200
+ };
201
+ onClickOutside(floatingEl, (e) => {
202
+ if (props.trigger === "click" && visible.value) {
203
+ if (referenceEl.value?.contains(e.target)) return;
204
+ hide();
205
+ }
206
+ }, { ignore: [referenceEl] });
207
+ const onFloatingMouseenter = () => {
208
+ if (props.trigger === "hover") {
209
+ show();
210
+ }
211
+ };
212
+ const onFloatingMouseleave = () => {
213
+ if (props.trigger === "hover") {
214
+ delayedHide();
215
+ }
216
+ };
217
+ const onTriggerClick = () => {
218
+ if (props.trigger === "click") {
219
+ toggle();
220
+ }
221
+ };
222
+ const onTriggerMouseenter = () => {
223
+ if (props.trigger === "hover") {
224
+ show();
225
+ }
226
+ };
227
+ const onTriggerMouseleave = () => {
228
+ if (props.trigger === "hover") {
229
+ delayedHide();
230
+ }
231
+ };
232
+ const onTriggerFocus = () => {
233
+ if (props.trigger === "focus") {
234
+ show();
235
+ }
236
+ };
237
+ const onTriggerBlur = () => {
238
+ if (props.trigger === "focus") {
239
+ hide();
240
+ }
241
+ };
242
+ __expose({
243
+ show,
244
+ hide,
245
+ toggle
246
+ });
247
+ const __returned__ = { props, visible, bem, referenceEl, floatingEl, arrowEl, middleware, floatingStyles, middlewareData, finalPlacement, isPositioned, popoverStyles, arrowStyles, teleportTarget, get hideTimeout() {
248
+ return hideTimeout;
249
+ }, set hideTimeout(v) {
250
+ hideTimeout = v;
251
+ }, show, hide, delayedHide, toggle, onFloatingMouseenter, onFloatingMouseleave, onTriggerClick, onTriggerMouseenter, onTriggerMouseleave, onTriggerFocus, onTriggerBlur };
252
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
253
+ return __returned__;
254
+ }
255
+ });
256
+ var _hoisted_12 = ["data-placement"];
257
+ function render3(_ctx, _cache, $props, $setup, $data, $options) {
258
+ return openBlock(), createElementBlock(
259
+ Fragment,
260
+ null,
261
+ [
262
+ createElementVNode(
263
+ "span",
264
+ {
265
+ ref: "referenceEl",
266
+ class: "im-popover-trigger",
267
+ onClick: $setup.onTriggerClick,
268
+ onMouseenter: $setup.onTriggerMouseenter,
269
+ onMouseleave: $setup.onTriggerMouseleave,
270
+ onFocusin: $setup.onTriggerFocus,
271
+ onFocusout: $setup.onTriggerBlur
272
+ },
273
+ [
274
+ renderSlot(_ctx.$slots, "default")
275
+ ],
276
+ 544
277
+ /* NEED_HYDRATION, NEED_PATCH */
278
+ ),
279
+ (openBlock(), createBlock(Teleport, {
280
+ to: $setup.teleportTarget,
281
+ disabled: $props.teleportDisabled
282
+ }, [
283
+ createVNode(Transition, { name: "im-popover-fade" }, {
284
+ default: withCtx(() => [
285
+ $setup.visible ? (openBlock(), createElementBlock("div", {
286
+ key: 0,
287
+ ref: "floatingEl",
288
+ class: normalizeClass($setup.bem()),
289
+ style: normalizeStyle($setup.popoverStyles),
290
+ "data-placement": $setup.finalPlacement,
291
+ onMouseenter: $setup.onFloatingMouseenter,
292
+ onMouseleave: $setup.onFloatingMouseleave
293
+ }, [
294
+ renderSlot(_ctx.$slots, "content"),
295
+ $props.arrow ? (openBlock(), createElementBlock(
296
+ "div",
297
+ {
298
+ key: 0,
299
+ ref: "arrowEl",
300
+ class: normalizeClass($setup.bem("arrow")),
301
+ style: normalizeStyle($setup.arrowStyles)
302
+ },
303
+ null,
304
+ 6
305
+ /* CLASS, STYLE */
306
+ )) : createCommentVNode("v-if", true)
307
+ ], 46, _hoisted_12)) : createCommentVNode("v-if", true)
308
+ ]),
309
+ _: 3
310
+ /* FORWARDED */
311
+ })
312
+ ], 8, ["to", "disabled"]))
313
+ ],
314
+ 64
315
+ /* STABLE_FRAGMENT */
316
+ );
317
+ }
318
+
319
+ // src/components/base/im-popover/im-popover.vue
320
+ im_popover_default.render = render3;
321
+ im_popover_default.__file = "src/components/base/im-popover/im-popover.vue";
322
+ var im_popover_default2 = im_popover_default;
323
+
324
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/base/im-tooltip/im-tooltip.vue?type=script
325
+ var im_tooltip_default = /* @__PURE__ */ defineComponent({
326
+ __name: "im-tooltip",
327
+ props: {
328
+ content: { type: String, required: false },
329
+ placement: { type: null, required: false, default: "top" },
330
+ to: { type: [String, Function], required: false, skipCheck: true, default: "body" },
331
+ teleportDisabled: { type: Boolean, required: false, default: false }
332
+ },
333
+ setup(__props, { expose: __expose }) {
334
+ __expose();
335
+ const props = __props;
336
+ const bem = createImBem("tooltip");
337
+ const __returned__ = { props, bem, get ImPopover() {
338
+ return im_popover_default2;
339
+ } };
340
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
341
+ return __returned__;
342
+ }
343
+ });
344
+ function render4(_ctx, _cache, $props, $setup, $data, $options) {
345
+ return $props.content ? (openBlock(), createBlock($setup["ImPopover"], {
346
+ key: 0,
347
+ trigger: "hover",
348
+ placement: $props.placement,
349
+ offset: 8,
350
+ arrow: true,
351
+ to: $props.to,
352
+ "teleport-disabled": $props.teleportDisabled
353
+ }, {
354
+ content: withCtx(() => [
355
+ createElementVNode(
356
+ "div",
357
+ {
358
+ class: normalizeClass($setup.bem())
359
+ },
360
+ toDisplayString($props.content),
361
+ 3
362
+ /* TEXT, CLASS */
363
+ )
364
+ ]),
365
+ default: withCtx(() => [
366
+ renderSlot(_ctx.$slots, "default")
367
+ ]),
368
+ _: 3
369
+ /* FORWARDED */
370
+ }, 8, ["placement", "to", "teleport-disabled"])) : renderSlot(_ctx.$slots, "default", { key: 1 });
371
+ }
372
+
373
+ // src/components/base/im-tooltip/im-tooltip.vue
374
+ im_tooltip_default.render = render4;
375
+ im_tooltip_default.__file = "src/components/base/im-tooltip/im-tooltip.vue";
376
+ var im_tooltip_default2 = im_tooltip_default;
377
+
378
+ // src/composables/useUIAdapter.ts
379
+ var UI_ADAPTER_KEY = /* @__PURE__ */ Symbol("ui-adapter");
380
+ var defaultAdapter = {
381
+ Button: im_button_default2,
382
+ Tooltip: im_tooltip_default2,
383
+ icons: {}
384
+ };
385
+ function provideUIAdapter(adapter) {
386
+ const merged = {
387
+ ...defaultAdapter,
388
+ ...adapter,
389
+ icons: {
390
+ ...defaultAdapter.icons,
391
+ ...adapter?.icons
392
+ }
393
+ };
394
+ provide(UI_ADAPTER_KEY, merged);
395
+ }
396
+ function useUIAdapter() {
397
+ return inject(UI_ADAPTER_KEY, defaultAdapter);
398
+ }
399
+
400
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/chain-of-thought/chain-of-thought-step.vue?type=script
401
+ var chain_of_thought_step_default = /* @__PURE__ */ defineComponent({
402
+ __name: "chain-of-thought-step",
403
+ props: {
404
+ label: { type: String, required: false },
405
+ status: { type: String, required: false, default: "pending" },
406
+ showDivider: { type: Boolean, required: false, default: false },
407
+ collapsible: { type: Boolean, required: false, default: false },
408
+ defaultExpanded: { type: Boolean, required: false, default: true }
409
+ },
410
+ setup(__props, { expose: __expose }) {
411
+ __expose();
412
+ const props = __props;
413
+ const slots = useSlots();
414
+ const bem = createImBem("cot-step");
415
+ const { expanded, toggle: baseToggle } = useCollapsible(props.defaultExpanded);
416
+ const toggle = () => {
417
+ if (props.collapsible) baseToggle();
418
+ };
419
+ const hasHeader = computed(() => !!props.label || !!slots.header);
420
+ const hasFooter = computed(() => !!slots.footer);
421
+ const __returned__ = { props, slots, bem, expanded, baseToggle, toggle, hasHeader, hasFooter, get Icon() {
422
+ return Icon;
423
+ }, get SvgIcon() {
424
+ return svg_icon_default2;
425
+ } };
426
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
427
+ return __returned__;
428
+ }
429
+ });
430
+ function render5(_ctx, _cache, $props, $setup, $data, $options) {
431
+ return openBlock(), createElementBlock(
432
+ "div",
433
+ {
434
+ class: normalizeClass($setup.bem(void 0, { [$props.status]: true, collapsible: $props.collapsible, collapsed: $props.collapsible && !$setup.expanded }))
435
+ },
436
+ [
437
+ createCommentVNode(" \u56FE\u6807\u4F4D\u7F6E "),
438
+ createVNode($setup["SvgIcon"], {
439
+ class: normalizeClass($setup.bem("icon", { "with-divider": $props.showDivider }))
440
+ }, {
441
+ default: withCtx(() => [
442
+ renderSlot(_ctx.$slots, "icon", {}, () => [
443
+ createCommentVNode(" \u9ED8\u8BA4\u56FE\u6807 "),
444
+ $props.status === "pending" ? (openBlock(), createBlock($setup["Icon"], {
445
+ key: 0,
446
+ icon: "ph:circle"
447
+ })) : $props.status === "active" ? (openBlock(), createBlock($setup["Icon"], {
448
+ key: 1,
449
+ icon: "ph:spinner",
450
+ class: normalizeClass($setup.bem("spinner"))
451
+ }, null, 8, ["class"])) : $props.status === "complete" ? (openBlock(), createBlock($setup["Icon"], {
452
+ key: 2,
453
+ icon: "ph:check-circle"
454
+ })) : $props.status === "error" ? (openBlock(), createBlock($setup["Icon"], {
455
+ key: 3,
456
+ icon: "ph:x-circle"
457
+ })) : createCommentVNode("v-if", true)
458
+ ])
459
+ ]),
460
+ _: 3
461
+ /* FORWARDED */
462
+ }, 8, ["class"]),
463
+ createCommentVNode(" \u5185\u5BB9\u533A\u57DF "),
464
+ createElementVNode(
465
+ "div",
466
+ {
467
+ class: normalizeClass($setup.bem("content"))
468
+ },
469
+ [
470
+ createCommentVNode(" Header: label prop \u6216 header slot "),
471
+ $setup.hasHeader ? (openBlock(), createElementBlock(
472
+ "div",
473
+ {
474
+ key: 0,
475
+ class: normalizeClass($setup.bem("header")),
476
+ onClick: $setup.toggle
477
+ },
478
+ [
479
+ renderSlot(_ctx.$slots, "header", {}, () => [
480
+ createTextVNode(
481
+ toDisplayString($props.label),
482
+ 1
483
+ /* TEXT */
484
+ )
485
+ ]),
486
+ $props.collapsible ? (openBlock(), createBlock($setup["SvgIcon"], {
487
+ key: 0,
488
+ class: normalizeClass($setup.bem("chevron"))
489
+ }, {
490
+ default: withCtx(() => [
491
+ createVNode($setup["Icon"], { icon: "ph:caret-right" })
492
+ ]),
493
+ _: 1
494
+ /* STABLE */
495
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
496
+ ],
497
+ 2
498
+ /* CLASS */
499
+ )) : createCommentVNode("v-if", true),
500
+ createCommentVNode(" Body: \u9ED8\u8BA4 slot "),
501
+ _ctx.$slots.default && (!$props.collapsible || $setup.expanded) ? (openBlock(), createElementBlock(
502
+ "div",
503
+ {
504
+ key: 1,
505
+ class: normalizeClass($setup.bem("body"))
506
+ },
507
+ [
508
+ renderSlot(_ctx.$slots, "default")
509
+ ],
510
+ 2
511
+ /* CLASS */
512
+ )) : createCommentVNode("v-if", true),
513
+ createCommentVNode(" Footer: footer slot "),
514
+ $setup.hasFooter && (!$props.collapsible || $setup.expanded) ? (openBlock(), createElementBlock(
515
+ "div",
516
+ {
517
+ key: 2,
518
+ class: normalizeClass($setup.bem("footer"))
519
+ },
520
+ [
521
+ renderSlot(_ctx.$slots, "footer")
522
+ ],
523
+ 2
524
+ /* CLASS */
525
+ )) : createCommentVNode("v-if", true)
526
+ ],
527
+ 2
528
+ /* CLASS */
529
+ )
530
+ ],
531
+ 2
532
+ /* CLASS */
533
+ );
534
+ }
535
+
536
+ // src/components/chain-of-thought/chain-of-thought-step.vue
537
+ chain_of_thought_step_default.render = render5;
538
+ chain_of_thought_step_default.__file = "src/components/chain-of-thought/chain-of-thought-step.vue";
539
+ var chain_of_thought_step_default2 = chain_of_thought_step_default;
540
+ var reasoning_message_default = /* @__PURE__ */ defineComponent({
541
+ __name: "reasoning-message",
542
+ props: {
543
+ content: { type: String, required: true },
544
+ streaming: { type: Boolean, required: false, default: false },
545
+ plainText: { type: Boolean, required: false, default: false },
546
+ blockquote: { type: Boolean, required: false, default: false },
547
+ incremarkOptions: { type: null, required: false },
548
+ customContainers: { type: Object, required: false },
549
+ customCodeBlocks: { type: Object, required: false },
550
+ codeBlockConfigs: { type: Object, required: false },
551
+ pendingClass: { type: String, required: false }
552
+ },
553
+ setup(__props, { expose: __expose }) {
554
+ __expose();
555
+ const props = __props;
556
+ const bem = createImBem("reasoning");
557
+ const incremarkOptions = computed(() => ({
558
+ gfm: true,
559
+ htmlTree: true,
560
+ containers: true,
561
+ math: true,
562
+ ...props.incremarkOptions
563
+ }));
564
+ const __returned__ = { props, bem, incremarkOptions, get IncremarkContent() {
565
+ return IncremarkContent;
566
+ } };
567
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
568
+ return __returned__;
569
+ }
570
+ });
571
+ function render6(_ctx, _cache, $props, $setup, $data, $options) {
572
+ return openBlock(), createElementBlock(
573
+ "div",
574
+ {
575
+ class: normalizeClass($setup.bem(void 0, { blockquote: $props.blockquote }))
576
+ },
577
+ [
578
+ $props.plainText ? (openBlock(), createElementBlock(
579
+ Fragment,
580
+ { key: 0 },
581
+ [
582
+ createTextVNode(
583
+ toDisplayString($props.content),
584
+ 1
585
+ /* TEXT */
586
+ )
587
+ ],
588
+ 64
589
+ /* STABLE_FRAGMENT */
590
+ )) : (openBlock(), createBlock($setup["IncremarkContent"], {
591
+ key: 1,
592
+ content: $props.content,
593
+ "is-finished": !$props.streaming,
594
+ "incremark-options": $setup.incremarkOptions,
595
+ "custom-containers": $props.customContainers,
596
+ "custom-code-blocks": $props.customCodeBlocks,
597
+ "code-block-configs": $props.codeBlockConfigs,
598
+ "pending-class": $props.pendingClass
599
+ }, null, 8, ["content", "is-finished", "incremark-options", "custom-containers", "custom-code-blocks", "code-block-configs", "pending-class"]))
600
+ ],
601
+ 2
602
+ /* CLASS */
603
+ );
604
+ }
605
+
606
+ // src/components/reasoning-message/reasoning-message.vue
607
+ reasoning_message_default.render = render6;
608
+ reasoning_message_default.__file = "src/components/reasoning-message/reasoning-message.vue";
609
+ var reasoning_message_default2 = reasoning_message_default;
610
+ var text_message_default = /* @__PURE__ */ defineComponent({
611
+ __name: "text-message",
612
+ props: {
613
+ part: { type: null, required: true },
614
+ streaming: { type: Boolean, required: false, default: false },
615
+ incremarkOptions: { type: null, required: false },
616
+ customContainers: { type: Object, required: false },
617
+ customCodeBlocks: { type: Object, required: false },
618
+ codeBlockConfigs: { type: Object, required: false },
619
+ pendingClass: { type: String, required: false }
620
+ },
621
+ setup(__props, { expose: __expose }) {
622
+ __expose();
623
+ const props = __props;
624
+ const bem = createImBem("text-message");
625
+ const incremarkOptions = computed(() => ({
626
+ gfm: true,
627
+ htmlTree: true,
628
+ containers: true,
629
+ math: true,
630
+ ...props.incremarkOptions
631
+ }));
632
+ const isMarkdown = computed(() => props.part.format !== "plain");
633
+ const __returned__ = { props, bem, incremarkOptions, isMarkdown, get IncremarkContent() {
634
+ return IncremarkContent;
635
+ } };
636
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
637
+ return __returned__;
638
+ }
639
+ });
640
+ function render7(_ctx, _cache, $props, $setup, $data, $options) {
641
+ return openBlock(), createElementBlock(
642
+ Fragment,
643
+ null,
644
+ [
645
+ createCommentVNode(" Markdown \u683C\u5F0F "),
646
+ $setup.isMarkdown ? (openBlock(), createBlock($setup["IncremarkContent"], {
647
+ key: 0,
648
+ content: $props.part.content,
649
+ "is-finished": !$props.streaming,
650
+ "incremark-options": $setup.incremarkOptions,
651
+ "custom-containers": $props.customContainers,
652
+ "custom-code-blocks": $props.customCodeBlocks,
653
+ "code-block-configs": $props.codeBlockConfigs,
654
+ "pending-class": $props.pendingClass
655
+ }, null, 8, ["content", "is-finished", "incremark-options", "custom-containers", "custom-code-blocks", "code-block-configs", "pending-class"])) : (openBlock(), createElementBlock(
656
+ Fragment,
657
+ { key: 1 },
658
+ [
659
+ createCommentVNode(" \u7EAF\u6587\u672C\u683C\u5F0F "),
660
+ createElementVNode(
661
+ "div",
662
+ {
663
+ class: normalizeClass($setup.bem("plain"))
664
+ },
665
+ toDisplayString($props.part.content),
666
+ 3
667
+ /* TEXT, CLASS */
668
+ )
669
+ ],
670
+ 2112
671
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
672
+ ))
673
+ ],
674
+ 2112
675
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
676
+ );
677
+ }
678
+
679
+ // src/components/text-message/text-message.vue
680
+ text_message_default.render = render7;
681
+ text_message_default.__file = "src/components/text-message/text-message.vue";
682
+ var text_message_default2 = text_message_default;
683
+
684
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/chain-of-thought/chain-of-thought.vue?type=script
685
+ var chain_of_thought_default = /* @__PURE__ */ defineComponent({
686
+ __name: "chain-of-thought",
687
+ props: /* @__PURE__ */ mergeModels({
688
+ title: { type: String, required: false, default: "\u601D\u8003\u8FC7\u7A0B" },
689
+ loading: { type: Boolean, required: false, default: false },
690
+ loadingAnimation: { type: String, required: false, default: "pulse" },
691
+ startTime: { type: Number, required: false },
692
+ endTime: { type: Number, required: false },
693
+ locale: { type: String, required: false, default: "zh" },
694
+ steps: { type: Array, required: false },
695
+ components: { type: Object, required: false },
696
+ maxHeight: { type: [String, Number], required: false }
697
+ }, {
698
+ "expanded": { type: Boolean, ...{ default: true } },
699
+ "expandedModifiers": {}
700
+ }),
701
+ emits: ["update:expanded"],
702
+ setup(__props, { expose: __expose }) {
703
+ __expose();
704
+ const defaultComponents = {
705
+ reasoning: reasoning_message_default2,
706
+ text: text_message_default2
707
+ };
708
+ const props = __props;
709
+ const expanded = useModel(__props, "expanded");
710
+ const bem = createImBem("cot");
711
+ const { duration } = useChainOfThought(props);
712
+ const mergedComponents = computed(() => ({
713
+ ...defaultComponents,
714
+ ...props.components
715
+ }));
716
+ const contentStyle = computed(() => {
717
+ if (!props.maxHeight) return void 0;
718
+ return {
719
+ maxHeight: typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight,
720
+ overflowY: "auto"
721
+ };
722
+ });
723
+ function toggle() {
724
+ expanded.value = !expanded.value;
725
+ }
726
+ const __returned__ = { defaultComponents, props, expanded, bem, duration, mergedComponents, contentStyle, toggle, get Icon() {
727
+ return Icon;
728
+ }, ChainOfThoughtStep: chain_of_thought_step_default2, get SvgIcon() {
729
+ return svg_icon_default2;
730
+ } };
731
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
732
+ return __returned__;
733
+ }
734
+ });
735
+ var _hoisted_13 = { key: 1 };
736
+ function render8(_ctx, _cache, $props, $setup, $data, $options) {
737
+ return openBlock(), createElementBlock(
738
+ "div",
739
+ {
740
+ class: normalizeClass($setup.bem())
741
+ },
742
+ [
743
+ createElementVNode(
744
+ "div",
745
+ {
746
+ class: normalizeClass($setup.bem("header")),
747
+ onClick: $setup.toggle
748
+ },
749
+ [
750
+ $props.loading ? (openBlock(), createBlock($setup["SvgIcon"], {
751
+ key: 0,
752
+ class: normalizeClass($setup.bem("icon", { loading: true, [$props.loadingAnimation]: true }))
753
+ }, {
754
+ default: withCtx(() => [
755
+ renderSlot(_ctx.$slots, "loading-icon", {}, () => [
756
+ createVNode($setup["Icon"], { icon: "ph:brain" })
757
+ ])
758
+ ]),
759
+ _: 3
760
+ /* FORWARDED */
761
+ }, 8, ["class"])) : _ctx.$slots.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
762
+ key: 1,
763
+ class: normalizeClass($setup.bem("icon"))
764
+ }, {
765
+ default: withCtx(() => [
766
+ renderSlot(_ctx.$slots, "icon")
767
+ ]),
768
+ _: 3
769
+ /* FORWARDED */
770
+ }, 8, ["class"])) : createCommentVNode("v-if", true),
771
+ createElementVNode(
772
+ "div",
773
+ {
774
+ class: normalizeClass($setup.bem("title"))
775
+ },
776
+ [
777
+ createTextVNode(
778
+ toDisplayString($props.title) + " ",
779
+ 1
780
+ /* TEXT */
781
+ ),
782
+ $setup.duration ? (openBlock(), createElementBlock(
783
+ "span",
784
+ {
785
+ key: 0,
786
+ class: normalizeClass($setup.bem("duration"))
787
+ },
788
+ toDisplayString($setup.duration),
789
+ 3
790
+ /* TEXT, CLASS */
791
+ )) : createCommentVNode("v-if", true)
792
+ ],
793
+ 2
794
+ /* CLASS */
795
+ ),
796
+ createVNode($setup["SvgIcon"], {
797
+ class: normalizeClass($setup.bem("chevron", { expanded: $setup.expanded }))
798
+ }, {
799
+ default: withCtx(() => [
800
+ createVNode($setup["Icon"], { icon: "ph:caret-right" })
801
+ ]),
802
+ _: 1
803
+ /* STABLE */
804
+ }, 8, ["class"])
805
+ ],
806
+ 2
807
+ /* CLASS */
808
+ ),
809
+ withDirectives(createElementVNode(
810
+ "div",
811
+ {
812
+ class: normalizeClass($setup.bem("content")),
813
+ style: normalizeStyle($setup.contentStyle)
814
+ },
815
+ [
816
+ $props.steps?.length ? (openBlock(true), createElementBlock(
817
+ Fragment,
818
+ { key: 0 },
819
+ renderList($props.steps, (step, index) => {
820
+ return openBlock(), createBlock($setup["ChainOfThoughtStep"], {
821
+ key: index,
822
+ label: step.label,
823
+ status: step.status,
824
+ "show-divider": step.showDivider,
825
+ collapsible: step.collapsible,
826
+ "default-expanded": step.defaultExpanded
827
+ }, createSlots({
828
+ default: withCtx(() => [
829
+ $setup.mergedComponents[step.type] ? (openBlock(), createBlock(
830
+ resolveDynamicComponent($setup.mergedComponents[step.type]),
831
+ mergeProps({
832
+ key: 0,
833
+ ref_for: true
834
+ }, step.data || {}),
835
+ null,
836
+ 16
837
+ /* FULL_PROPS */
838
+ )) : (openBlock(), createElementBlock(
839
+ "div",
840
+ _hoisted_13,
841
+ "Unknown step type: " + toDisplayString(step.type),
842
+ 1
843
+ /* TEXT */
844
+ ))
845
+ ]),
846
+ _: 2
847
+ /* DYNAMIC */
848
+ }, [
849
+ step.icon ? {
850
+ name: "icon",
851
+ fn: withCtx(() => [
852
+ (openBlock(), createBlock(resolveDynamicComponent(step.icon)))
853
+ ]),
854
+ key: "0"
855
+ } : void 0
856
+ ]), 1032, ["label", "status", "show-divider", "collapsible", "default-expanded"]);
857
+ }),
858
+ 128
859
+ /* KEYED_FRAGMENT */
860
+ )) : renderSlot(_ctx.$slots, "default", { key: 1 })
861
+ ],
862
+ 6
863
+ /* CLASS, STYLE */
864
+ ), [
865
+ [vShow, $setup.expanded]
866
+ ])
867
+ ],
868
+ 2
869
+ /* CLASS */
870
+ );
871
+ }
872
+
873
+ // src/components/chain-of-thought/chain-of-thought.vue
874
+ chain_of_thought_default.render = render8;
875
+ chain_of_thought_default.__file = "src/components/chain-of-thought/chain-of-thought.vue";
876
+ var chain_of_thought_default2 = chain_of_thought_default;
877
+ var tool_call_default = /* @__PURE__ */ defineComponent({
878
+ __name: "tool-call",
879
+ props: {
880
+ part: { type: null, required: true },
881
+ tools: { type: Object, required: false },
882
+ outputRenderers: { type: Object, required: false },
883
+ defaultRenderer: { type: null, required: false },
884
+ stateLabels: { type: Object, required: false },
885
+ stateCategories: { type: Object, required: false },
886
+ showArgs: { type: Boolean, required: false, default: true },
887
+ showOutput: { type: Boolean, required: false, default: true },
888
+ defaultExpanded: { type: Boolean, required: false, default: true }
889
+ },
890
+ setup(__props, { expose: __expose }) {
891
+ __expose();
892
+ const props = __props;
893
+ const expanded = ref(props.defaultExpanded);
894
+ function toggle() {
895
+ expanded.value = !expanded.value;
896
+ }
897
+ const bem = createImBem("tool-call");
898
+ const defaultStateCategories = {
899
+ loading: [TOOL_CALL_STATES.INPUT_STREAMING, TOOL_CALL_STATES.EXECUTING],
900
+ complete: [TOOL_CALL_STATES.OUTPUT_AVAILABLE],
901
+ error: [TOOL_CALL_STATES.OUTPUT_ERROR],
902
+ denied: [TOOL_CALL_STATES.OUTPUT_DENIED],
903
+ approval: [TOOL_CALL_STATES.APPROVAL_REQUESTED]
904
+ };
905
+ const mergedCategories = computed(() => ({
906
+ loading: [...defaultStateCategories.loading || [], ...props.stateCategories?.loading || []],
907
+ complete: [...defaultStateCategories.complete || [], ...props.stateCategories?.complete || []],
908
+ error: [...defaultStateCategories.error || [], ...props.stateCategories?.error || []],
909
+ denied: [...defaultStateCategories.denied || [], ...props.stateCategories?.denied || []],
910
+ approval: [...defaultStateCategories.approval || [], ...props.stateCategories?.approval || []]
911
+ }));
912
+ const toolRenderer = computed(() => {
913
+ if (props.tools?.[props.part.toolName]) {
914
+ return props.tools[props.part.toolName];
915
+ }
916
+ return props.defaultRenderer;
917
+ });
918
+ const outputRenderer = computed(() => {
919
+ return props.outputRenderers?.[props.part.toolName];
920
+ });
921
+ const rendererProps = computed(() => ({
922
+ toolCallId: props.part.toolCallId,
923
+ toolName: props.part.toolName,
924
+ args: props.part.args,
925
+ state: props.part.state,
926
+ output: props.part.output,
927
+ error: props.part.error
928
+ }));
929
+ const outputRendererProps = computed(() => ({
930
+ toolName: props.part.toolName,
931
+ output: props.part.output
932
+ }));
933
+ const isLoading = computed(() => mergedCategories.value.loading.includes(props.part.state));
934
+ const isComplete = computed(() => mergedCategories.value.complete.includes(props.part.state));
935
+ const isError = computed(() => mergedCategories.value.error.includes(props.part.state));
936
+ const isDenied = computed(() => mergedCategories.value.denied.includes(props.part.state));
937
+ const isAwaitingApproval = computed(() => mergedCategories.value.approval.includes(props.part.state));
938
+ const formattedArgs = computed(() => {
939
+ try {
940
+ return JSON.stringify(props.part.args, null, 2);
941
+ } catch {
942
+ return String(props.part.args);
943
+ }
944
+ });
945
+ const formattedOutput = computed(() => {
946
+ if (props.part.output === void 0) return "";
947
+ try {
948
+ return JSON.stringify(props.part.output, null, 2);
949
+ } catch {
950
+ return String(props.part.output);
951
+ }
952
+ });
953
+ const defaultStateLabels = {
954
+ [TOOL_CALL_STATES.INPUT_STREAMING]: "Streaming...",
955
+ [TOOL_CALL_STATES.INPUT_AVAILABLE]: "Ready",
956
+ [TOOL_CALL_STATES.APPROVAL_REQUESTED]: "Awaiting Approval",
957
+ [TOOL_CALL_STATES.APPROVAL_RESPONDED]: "Approved",
958
+ [TOOL_CALL_STATES.EXECUTING]: "Executing...",
959
+ [TOOL_CALL_STATES.OUTPUT_AVAILABLE]: "Completed",
960
+ [TOOL_CALL_STATES.OUTPUT_ERROR]: "Error",
961
+ [TOOL_CALL_STATES.OUTPUT_DENIED]: "Denied"
962
+ };
963
+ const stateLabel = computed(() => {
964
+ const labels = { ...defaultStateLabels, ...props.stateLabels };
965
+ return labels[props.part.state] || props.part.state;
966
+ });
967
+ const __returned__ = { props, expanded, toggle, bem, defaultStateCategories, mergedCategories, toolRenderer, outputRenderer, rendererProps, outputRendererProps, isLoading, isComplete, isError, isDenied, isAwaitingApproval, formattedArgs, formattedOutput, defaultStateLabels, stateLabel, get Icon() {
968
+ return Icon;
969
+ }, get SvgIcon() {
970
+ return svg_icon_default2;
971
+ } };
972
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
973
+ return __returned__;
974
+ }
975
+ });
976
+ var _hoisted_14 = ["data-tool-name", "data-tool-state"];
977
+ var _hoisted_2 = { key: 1 };
978
+ function render9(_ctx, _cache, $props, $setup, $data, $options) {
979
+ return openBlock(), createElementBlock("div", {
980
+ class: normalizeClass([
981
+ $setup.bem(),
982
+ $setup.bem("", $setup.props.part.state),
983
+ { [$setup.bem("", "loading")]: $setup.isLoading }
984
+ ]),
985
+ "data-tool-name": $props.part.toolName,
986
+ "data-tool-state": $props.part.state
987
+ }, [
988
+ createCommentVNode(" \u81EA\u5B9A\u4E49\u6E32\u67D3\u5668 "),
989
+ $setup.toolRenderer ? (openBlock(), createBlock(
990
+ resolveDynamicComponent($setup.toolRenderer),
991
+ normalizeProps(mergeProps({ key: 0 }, $setup.rendererProps)),
992
+ null,
993
+ 16
994
+ /* FULL_PROPS */
995
+ )) : (openBlock(), createElementBlock(
996
+ Fragment,
997
+ { key: 1 },
998
+ [
999
+ createCommentVNode(" \u9ED8\u8BA4\u6E32\u67D3\u5668 "),
1000
+ createCommentVNode(" \u5934\u90E8\uFF1A\u5DE5\u5177\u540D\u79F0 + \u72B6\u6001 "),
1001
+ createElementVNode(
1002
+ "div",
1003
+ {
1004
+ class: normalizeClass($setup.bem("header")),
1005
+ onClick: $setup.toggle
1006
+ },
1007
+ [
1008
+ createElementVNode(
1009
+ "div",
1010
+ {
1011
+ class: normalizeClass($setup.bem("header-left"))
1012
+ },
1013
+ [
1014
+ createVNode($setup["SvgIcon"], {
1015
+ class: normalizeClass($setup.bem("chevron", { expanded: $setup.expanded }))
1016
+ }, {
1017
+ default: withCtx(() => [
1018
+ createVNode($setup["Icon"], { icon: "ph:caret-right" })
1019
+ ]),
1020
+ _: 1
1021
+ /* STABLE */
1022
+ }, 8, ["class"]),
1023
+ createElementVNode(
1024
+ "span",
1025
+ {
1026
+ class: normalizeClass($setup.bem("name"))
1027
+ },
1028
+ toDisplayString($props.part.toolName),
1029
+ 3
1030
+ /* TEXT, CLASS */
1031
+ )
1032
+ ],
1033
+ 2
1034
+ /* CLASS */
1035
+ ),
1036
+ createElementVNode(
1037
+ "span",
1038
+ {
1039
+ class: normalizeClass([$setup.bem("state"), $setup.bem("state", $props.part.state)])
1040
+ },
1041
+ toDisplayString($setup.stateLabel),
1042
+ 3
1043
+ /* TEXT, CLASS */
1044
+ )
1045
+ ],
1046
+ 2
1047
+ /* CLASS */
1048
+ ),
1049
+ $setup.expanded ? (openBlock(), createElementBlock(
1050
+ Fragment,
1051
+ { key: 0 },
1052
+ [
1053
+ createCommentVNode(" \u53C2\u6570 "),
1054
+ $props.showArgs && Object.keys($props.part.args).length > 0 ? (openBlock(), createElementBlock(
1055
+ "div",
1056
+ {
1057
+ key: 0,
1058
+ class: normalizeClass($setup.bem("args"))
1059
+ },
1060
+ [
1061
+ createElementVNode(
1062
+ "pre",
1063
+ null,
1064
+ toDisplayString($setup.formattedArgs),
1065
+ 1
1066
+ /* TEXT */
1067
+ )
1068
+ ],
1069
+ 2
1070
+ /* CLASS */
1071
+ )) : createCommentVNode("v-if", true),
1072
+ createCommentVNode(" \u7ED3\u679C\uFF1A\u4F18\u5148\u4F7F\u7528\u81EA\u5B9A\u4E49\u8F93\u51FA\u6E32\u67D3\u5668 "),
1073
+ $props.showOutput && $setup.isComplete && $props.part.output !== void 0 ? (openBlock(), createElementBlock(
1074
+ "div",
1075
+ {
1076
+ key: 1,
1077
+ class: normalizeClass($setup.bem("output"))
1078
+ },
1079
+ [
1080
+ $setup.outputRenderer ? (openBlock(), createBlock(
1081
+ resolveDynamicComponent($setup.outputRenderer),
1082
+ normalizeProps(mergeProps({ key: 0 }, $setup.outputRendererProps)),
1083
+ null,
1084
+ 16
1085
+ /* FULL_PROPS */
1086
+ )) : (openBlock(), createElementBlock(
1087
+ "pre",
1088
+ _hoisted_2,
1089
+ toDisplayString($setup.formattedOutput),
1090
+ 1
1091
+ /* TEXT */
1092
+ ))
1093
+ ],
1094
+ 2
1095
+ /* CLASS */
1096
+ )) : createCommentVNode("v-if", true),
1097
+ createCommentVNode(" \u9519\u8BEF "),
1098
+ $setup.isError && $props.part.error ? (openBlock(), createElementBlock(
1099
+ "div",
1100
+ {
1101
+ key: 2,
1102
+ class: normalizeClass($setup.bem("error"))
1103
+ },
1104
+ toDisplayString($props.part.error),
1105
+ 3
1106
+ /* TEXT, CLASS */
1107
+ )) : createCommentVNode("v-if", true),
1108
+ createCommentVNode(" \u62D2\u7EDD "),
1109
+ $setup.isDenied ? (openBlock(), createElementBlock(
1110
+ "div",
1111
+ {
1112
+ key: 3,
1113
+ class: normalizeClass($setup.bem("denied"))
1114
+ },
1115
+ " \u7528\u6237\u5DF2\u62D2\u7EDD\u6267\u884C\u6B64\u64CD\u4F5C ",
1116
+ 2
1117
+ /* CLASS */
1118
+ )) : createCommentVNode("v-if", true),
1119
+ createCommentVNode(" \u7B49\u5F85\u5BA1\u6279 "),
1120
+ $setup.isAwaitingApproval ? (openBlock(), createElementBlock(
1121
+ "div",
1122
+ {
1123
+ key: 4,
1124
+ class: normalizeClass($setup.bem("approval"))
1125
+ },
1126
+ [
1127
+ renderSlot(_ctx.$slots, "approval", {}, () => [
1128
+ _cache[0] || (_cache[0] = createElementVNode(
1129
+ "span",
1130
+ null,
1131
+ "\u6B64\u64CD\u4F5C\u9700\u8981\u60A8\u7684\u786E\u8BA4",
1132
+ -1
1133
+ /* CACHED */
1134
+ ))
1135
+ ])
1136
+ ],
1137
+ 2
1138
+ /* CLASS */
1139
+ )) : createCommentVNode("v-if", true)
1140
+ ],
1141
+ 64
1142
+ /* STABLE_FRAGMENT */
1143
+ )) : createCommentVNode("v-if", true)
1144
+ ],
1145
+ 64
1146
+ /* STABLE_FRAGMENT */
1147
+ ))
1148
+ ], 10, _hoisted_14);
1149
+ }
1150
+
1151
+ // src/components/tool-call/tool-call.vue
1152
+ tool_call_default.render = render9;
1153
+ tool_call_default.__file = "src/components/tool-call/tool-call.vue";
1154
+ var tool_call_default2 = tool_call_default;
1155
+
1156
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/message-renderer/part-renderer.vue?type=script
1157
+ var part_renderer_default = /* @__PURE__ */ defineComponent({
1158
+ __name: "part-renderer",
1159
+ props: {
1160
+ part: { type: null, required: true },
1161
+ streaming: { type: Boolean, required: false, default: false },
1162
+ incremarkOptions: { type: null, required: false },
1163
+ customContainers: { type: Object, required: false },
1164
+ customCodeBlocks: { type: Object, required: false },
1165
+ codeBlockConfigs: { type: Object, required: false },
1166
+ pendingClass: { type: String, required: false },
1167
+ parts: { type: Object, required: false }
1168
+ },
1169
+ setup(__props, { expose: __expose }) {
1170
+ __expose();
1171
+ const props = __props;
1172
+ const bem = createImBem("part-renderer");
1173
+ const customComponent = computed(() => {
1174
+ return props.parts?.[props.part.type];
1175
+ });
1176
+ const isBuiltinType = computed(() => {
1177
+ return ["text", "reasoning", "tool-call"].includes(props.part.type);
1178
+ });
1179
+ const __returned__ = { props, bem, customComponent, isBuiltinType, TextMessage: text_message_default2, ReasoningMessage: reasoning_message_default2, ToolCall: tool_call_default2 };
1180
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
1181
+ return __returned__;
1182
+ }
1183
+ });
1184
+ function render10(_ctx, _cache, $props, $setup, $data, $options) {
1185
+ return openBlock(), createElementBlock(
1186
+ Fragment,
1187
+ null,
1188
+ [
1189
+ createCommentVNode(" \u4F18\u5148\u4F7F\u7528 slot \u8986\u76D6 "),
1190
+ renderSlot(_ctx.$slots, $props.part.type, {
1191
+ part: $props.part,
1192
+ streaming: $props.streaming
1193
+ }, () => [
1194
+ createCommentVNode(" \u81EA\u5B9A\u4E49\u7EC4\u4EF6 "),
1195
+ $setup.customComponent ? (openBlock(), createBlock(resolveDynamicComponent($setup.customComponent), {
1196
+ key: 0,
1197
+ part: $props.part,
1198
+ streaming: $props.streaming
1199
+ }, null, 8, ["part", "streaming"])) : $props.part.type === "text" ? (openBlock(), createElementBlock(
1200
+ Fragment,
1201
+ { key: 1 },
1202
+ [
1203
+ createCommentVNode(" TextPart "),
1204
+ createVNode($setup["TextMessage"], {
1205
+ part: $props.part,
1206
+ streaming: $props.streaming,
1207
+ "incremark-options": $props.incremarkOptions,
1208
+ "custom-containers": $props.customContainers,
1209
+ "custom-code-blocks": $props.customCodeBlocks,
1210
+ "code-block-configs": $props.codeBlockConfigs,
1211
+ "pending-class": $props.pendingClass
1212
+ }, null, 8, ["part", "streaming", "incremark-options", "custom-containers", "custom-code-blocks", "code-block-configs", "pending-class"])
1213
+ ],
1214
+ 2112
1215
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1216
+ )) : $props.part.type === "reasoning" ? (openBlock(), createElementBlock(
1217
+ Fragment,
1218
+ { key: 2 },
1219
+ [
1220
+ createCommentVNode(" ReasoningPart "),
1221
+ createVNode($setup["ReasoningMessage"], {
1222
+ content: $props.part.content,
1223
+ streaming: $props.streaming,
1224
+ "incremark-options": $props.incremarkOptions,
1225
+ "custom-containers": $props.customContainers,
1226
+ "custom-code-blocks": $props.customCodeBlocks,
1227
+ "code-block-configs": $props.codeBlockConfigs,
1228
+ "pending-class": $props.pendingClass
1229
+ }, null, 8, ["content", "streaming", "incremark-options", "custom-containers", "custom-code-blocks", "code-block-configs", "pending-class"])
1230
+ ],
1231
+ 2112
1232
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1233
+ )) : $props.part.type === "tool-call" ? (openBlock(), createElementBlock(
1234
+ Fragment,
1235
+ { key: 3 },
1236
+ [
1237
+ createCommentVNode(" ToolCallPart "),
1238
+ createVNode($setup["ToolCall"], { part: $props.part }, null, 8, ["part"])
1239
+ ],
1240
+ 2112
1241
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1242
+ )) : (openBlock(), createElementBlock(
1243
+ Fragment,
1244
+ { key: 4 },
1245
+ [
1246
+ createCommentVNode(" \u672A\u77E5\u7C7B\u578B "),
1247
+ createElementVNode(
1248
+ "div",
1249
+ {
1250
+ class: normalizeClass($setup.bem("unknown"))
1251
+ },
1252
+ " Unknown Part Type: " + toDisplayString($props.part.type),
1253
+ 3
1254
+ /* TEXT, CLASS */
1255
+ )
1256
+ ],
1257
+ 2112
1258
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1259
+ ))
1260
+ ])
1261
+ ],
1262
+ 2112
1263
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1264
+ );
1265
+ }
1266
+
1267
+ // src/components/message-renderer/part-renderer.vue
1268
+ part_renderer_default.render = render10;
1269
+ part_renderer_default.__file = "src/components/message-renderer/part-renderer.vue";
1270
+ var part_renderer_default2 = part_renderer_default;
1271
+ var source_reference_default = /* @__PURE__ */ defineComponent({
1272
+ __name: "source-reference",
1273
+ props: {
1274
+ part: { type: null, required: true },
1275
+ openInNewTab: { type: Boolean, required: false, default: true }
1276
+ },
1277
+ setup(__props, { expose: __expose }) {
1278
+ __expose();
1279
+ const props = __props;
1280
+ const bem = createImBem("source-reference");
1281
+ const isUrl = computed(() => props.part.sourceType === "url");
1282
+ const isDocument = computed(() => props.part.sourceType === "document");
1283
+ const linkTarget = computed(() => props.openInNewTab ? "_blank" : void 0);
1284
+ const linkRel = computed(() => props.openInNewTab ? "noopener noreferrer" : void 0);
1285
+ const fileTypeMap = {
1286
+ // PDF - 红色
1287
+ "application/pdf": { icon: "mdi:file-pdf-box", color: "#FF4B4B" },
1288
+ // Word - 蓝色
1289
+ "application/msword": { icon: "mdi:file-word", color: "#2B579A" },
1290
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { icon: "mdi:file-word", color: "#2B579A" },
1291
+ // Excel - 绿色
1292
+ "application/vnd.ms-excel": { icon: "mdi:file-excel", color: "#217346" },
1293
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { icon: "mdi:file-excel", color: "#217346" },
1294
+ // PowerPoint - 橙色
1295
+ "application/vnd.ms-powerpoint": { icon: "mdi:file-powerpoint", color: "#D24726" },
1296
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": { icon: "mdi:file-powerpoint", color: "#D24726" },
1297
+ // 图片 - 紫色
1298
+ "image/jpeg": { icon: "mdi:file-image", color: "#9B59B6" },
1299
+ "image/png": { icon: "mdi:file-image", color: "#9B59B6" },
1300
+ "image/gif": { icon: "mdi:file-image", color: "#9B59B6" },
1301
+ "image/webp": { icon: "mdi:file-image", color: "#9B59B6" },
1302
+ "image/svg+xml": { icon: "mdi:file-image", color: "#9B59B6" },
1303
+ // 视频 - 深紫色
1304
+ "video/mp4": { icon: "mdi:file-video", color: "#8E44AD" },
1305
+ "video/webm": { icon: "mdi:file-video", color: "#8E44AD" },
1306
+ "video/quicktime": { icon: "mdi:file-video", color: "#8E44AD" },
1307
+ // 音频 - 青色
1308
+ "audio/mpeg": { icon: "mdi:file-music", color: "#1ABC9C" },
1309
+ "audio/wav": { icon: "mdi:file-music", color: "#1ABC9C" },
1310
+ "audio/ogg": { icon: "mdi:file-music", color: "#1ABC9C" },
1311
+ // 压缩文件 - 黄色
1312
+ "application/zip": { icon: "mdi:file-zip", color: "#F39C12" },
1313
+ "application/x-rar-compressed": { icon: "mdi:file-zip", color: "#F39C12" },
1314
+ "application/x-7z-compressed": { icon: "mdi:file-zip", color: "#F39C12" },
1315
+ "application/x-tar": { icon: "mdi:file-zip", color: "#F39C12" },
1316
+ // 文本 - 灰色
1317
+ "text/plain": { icon: "mdi:file-document-outline", color: "#7F8C8D" },
1318
+ "text/html": { icon: "mdi:file-code", color: "#7F8C8D" },
1319
+ "text/css": { icon: "mdi:file-code", color: "#7F8C8D" },
1320
+ "text/javascript": { icon: "mdi:file-code", color: "#7F8C8D" },
1321
+ // JSON/XML
1322
+ "application/json": { icon: "mdi:file-code", color: "#7F8C8D" },
1323
+ "application/xml": { icon: "mdi:file-code", color: "#7F8C8D" },
1324
+ "text/xml": { icon: "mdi:file-code", color: "#7F8C8D" },
1325
+ // Markdown
1326
+ "text/markdown": { icon: "mdi:language-markdown", color: "#7F8C8D" },
1327
+ // 代码文件
1328
+ "application/x-sh": { icon: "mdi:file-code", color: "#7F8C8D" },
1329
+ "application/x-python": { icon: "mdi:language-python", color: "#7F8C8D" }
1330
+ };
1331
+ const getFileTypeFromUrl = (url) => {
1332
+ const extension = url.split(".").pop()?.toLowerCase();
1333
+ if (!extension) return void 0;
1334
+ const extMap = {
1335
+ "pdf": { icon: "mdi:file-pdf-box", color: "#FF4B4B" },
1336
+ "doc": { icon: "mdi:file-word", color: "#2B579A" },
1337
+ "docx": { icon: "mdi:file-word", color: "#2B579A" },
1338
+ "xls": { icon: "mdi:file-excel", color: "#217346" },
1339
+ "xlsx": { icon: "mdi:file-excel", color: "#217346" },
1340
+ "ppt": { icon: "mdi:file-powerpoint", color: "#D24726" },
1341
+ "pptx": { icon: "mdi:file-powerpoint", color: "#D24726" },
1342
+ "jpg": { icon: "mdi:file-image", color: "#9B59B6" },
1343
+ "jpeg": { icon: "mdi:file-image", color: "#9B59B6" },
1344
+ "png": { icon: "mdi:file-image", color: "#9B59B6" },
1345
+ "gif": { icon: "mdi:file-image", color: "#9B59B6" },
1346
+ "webp": { icon: "mdi:file-image", color: "#9B59B6" },
1347
+ "svg": { icon: "mdi:file-image", color: "#9B59B6" },
1348
+ "mp4": { icon: "mdi:file-video", color: "#8E44AD" },
1349
+ "webm": { icon: "mdi:file-video", color: "#8E44AD" },
1350
+ "mov": { icon: "mdi:file-video", color: "#8E44AD" },
1351
+ "mp3": { icon: "mdi:file-music", color: "#1ABC9C" },
1352
+ "wav": { icon: "mdi:file-music", color: "#1ABC9C" },
1353
+ "zip": { icon: "mdi:file-zip", color: "#F39C12" },
1354
+ "rar": { icon: "mdi:file-zip", color: "#F39C12" },
1355
+ "7z": { icon: "mdi:file-zip", color: "#F39C12" },
1356
+ "txt": { icon: "mdi:file-document-outline", color: "#7F8C8D" },
1357
+ "md": { icon: "mdi:language-markdown", color: "#7F8C8D" },
1358
+ "json": { icon: "mdi:file-code", color: "#7F8C8D" },
1359
+ "xml": { icon: "mdi:file-code", color: "#7F8C8D" },
1360
+ "html": { icon: "mdi:file-code", color: "#7F8C8D" },
1361
+ "css": { icon: "mdi:file-code", color: "#7F8C8D" },
1362
+ "js": { icon: "mdi:file-code", color: "#7F8C8D" },
1363
+ "ts": { icon: "mdi:file-code", color: "#7F8C8D" },
1364
+ "py": { icon: "mdi:language-python", color: "#7F8C8D" },
1365
+ "sh": { icon: "mdi:file-code", color: "#7F8C8D" }
1366
+ };
1367
+ return extMap[extension];
1368
+ };
1369
+ const fileTypeInfo = computed(() => {
1370
+ if (isDocument.value && props.part.mediaType) {
1371
+ return fileTypeMap[props.part.mediaType];
1372
+ }
1373
+ if (isUrl.value && props.part.url) {
1374
+ return getFileTypeFromUrl(props.part.url);
1375
+ }
1376
+ return void 0;
1377
+ });
1378
+ const defaultIcon = computed(() => {
1379
+ if (fileTypeInfo.value) {
1380
+ return fileTypeInfo.value.icon;
1381
+ }
1382
+ if (isUrl.value) return "mdi:link-variant";
1383
+ if (isDocument.value) return "mdi:file-document-outline";
1384
+ return void 0;
1385
+ });
1386
+ const iconColor = computed(() => {
1387
+ return fileTypeInfo.value?.color;
1388
+ });
1389
+ const hasDefaultIcon = computed(() => defaultIcon.value !== void 0);
1390
+ const __returned__ = { props, bem, isUrl, isDocument, linkTarget, linkRel, fileTypeMap, getFileTypeFromUrl, fileTypeInfo, defaultIcon, iconColor, hasDefaultIcon, get Icon() {
1391
+ return Icon;
1392
+ }, SvgIcon: svg_icon_default2 };
1393
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
1394
+ return __returned__;
1395
+ }
1396
+ });
1397
+ var _hoisted_15 = ["href", "target", "rel"];
1398
+ function render11(_ctx, _cache, $props, $setup, $data, $options) {
1399
+ return openBlock(), createElementBlock(
1400
+ "div",
1401
+ {
1402
+ class: normalizeClass([$setup.bem(), $setup.bem("", $props.part.sourceType)])
1403
+ },
1404
+ [
1405
+ createCommentVNode(" URL \u7C7B\u578B "),
1406
+ $setup.isUrl && $props.part.url ? (openBlock(), createElementBlock("a", {
1407
+ key: 0,
1408
+ href: $props.part.url,
1409
+ target: $setup.linkTarget,
1410
+ rel: $setup.linkRel,
1411
+ class: normalizeClass($setup.bem("link"))
1412
+ }, [
1413
+ createCommentVNode(" \u56FE\u6807\u63D2\u69FD\uFF0C\u4F18\u5148\u4F7F\u7528\u5916\u90E8\u5B9A\u5236 "),
1414
+ renderSlot(_ctx.$slots, "icon", {}, () => [
1415
+ $setup.hasDefaultIcon ? (openBlock(), createBlock($setup["SvgIcon"], {
1416
+ key: 0,
1417
+ class: normalizeClass($setup.bem("icon")),
1418
+ style: normalizeStyle({ color: $setup.iconColor })
1419
+ }, {
1420
+ default: withCtx(() => [
1421
+ createVNode($setup["Icon"], {
1422
+ icon: $setup.defaultIcon
1423
+ }, null, 8, ["icon"])
1424
+ ]),
1425
+ _: 1
1426
+ /* STABLE */
1427
+ }, 8, ["class", "style"])) : createCommentVNode("v-if", true)
1428
+ ]),
1429
+ createElementVNode(
1430
+ "span",
1431
+ {
1432
+ class: normalizeClass($setup.bem("title"))
1433
+ },
1434
+ toDisplayString($props.part.title || $props.part.url),
1435
+ 3
1436
+ /* TEXT, CLASS */
1437
+ )
1438
+ ], 10, _hoisted_15)) : $setup.isDocument ? (openBlock(), createElementBlock(
1439
+ Fragment,
1440
+ { key: 1 },
1441
+ [
1442
+ createCommentVNode(" \u6587\u6863\u7C7B\u578B "),
1443
+ createElementVNode(
1444
+ "div",
1445
+ {
1446
+ class: normalizeClass($setup.bem("document"))
1447
+ },
1448
+ [
1449
+ renderSlot(_ctx.$slots, "icon", {}, () => [
1450
+ $setup.hasDefaultIcon ? (openBlock(), createBlock($setup["SvgIcon"], {
1451
+ key: 0,
1452
+ class: normalizeClass($setup.bem("icon")),
1453
+ style: normalizeStyle({ color: $setup.iconColor })
1454
+ }, {
1455
+ default: withCtx(() => [
1456
+ createVNode($setup["Icon"], {
1457
+ icon: $setup.defaultIcon
1458
+ }, null, 8, ["icon"])
1459
+ ]),
1460
+ _: 1
1461
+ /* STABLE */
1462
+ }, 8, ["class", "style"])) : createCommentVNode("v-if", true)
1463
+ ]),
1464
+ createElementVNode(
1465
+ "span",
1466
+ {
1467
+ class: normalizeClass($setup.bem("title"))
1468
+ },
1469
+ toDisplayString($props.part.title),
1470
+ 3
1471
+ /* TEXT, CLASS */
1472
+ ),
1473
+ $props.part.mediaType ? (openBlock(), createElementBlock(
1474
+ "span",
1475
+ {
1476
+ key: 0,
1477
+ class: normalizeClass($setup.bem("type"))
1478
+ },
1479
+ toDisplayString($props.part.mediaType),
1480
+ 3
1481
+ /* TEXT, CLASS */
1482
+ )) : createCommentVNode("v-if", true)
1483
+ ],
1484
+ 2
1485
+ /* CLASS */
1486
+ )
1487
+ ],
1488
+ 2112
1489
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1490
+ )) : createCommentVNode("v-if", true),
1491
+ createCommentVNode(" \u652F\u6301\u5B8C\u5168\u81EA\u5B9A\u4E49\u5185\u5BB9 "),
1492
+ renderSlot(_ctx.$slots, "default")
1493
+ ],
1494
+ 2
1495
+ /* CLASS */
1496
+ );
1497
+ }
1498
+
1499
+ // src/components/source-reference/source-reference.vue
1500
+ source_reference_default.render = render11;
1501
+ source_reference_default.__file = "src/components/source-reference/source-reference.vue";
1502
+ var source_reference_default2 = source_reference_default;
1503
+ var mimeTypeMap = {
1504
+ // PDF
1505
+ "application/pdf": "pdf",
1506
+ // Word
1507
+ "application/msword": "word",
1508
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "word",
1509
+ // Excel
1510
+ "application/vnd.ms-excel": "excel",
1511
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "excel",
1512
+ "text/csv": "excel",
1513
+ // PPT
1514
+ "application/vnd.ms-powerpoint": "ppt",
1515
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "ppt",
1516
+ // Archive
1517
+ "application/zip": "archive",
1518
+ "application/x-rar-compressed": "archive",
1519
+ "application/x-7z-compressed": "archive",
1520
+ "application/gzip": "archive",
1521
+ "application/x-tar": "archive",
1522
+ // Code
1523
+ "application/javascript": "code",
1524
+ "application/typescript": "code",
1525
+ "application/json": "code",
1526
+ "application/xml": "code",
1527
+ "text/html": "code",
1528
+ "text/css": "code",
1529
+ "text/javascript": "code",
1530
+ "text/xml": "code",
1531
+ // Text
1532
+ "text/plain": "text",
1533
+ "text/markdown": "text",
1534
+ "text/rtf": "text"
1535
+ };
1536
+ var extensionMap = {
1537
+ // PDF
1538
+ pdf: "pdf",
1539
+ // Word
1540
+ doc: "word",
1541
+ docx: "word",
1542
+ odt: "word",
1543
+ // Excel
1544
+ xls: "excel",
1545
+ xlsx: "excel",
1546
+ csv: "excel",
1547
+ ods: "excel",
1548
+ // PPT
1549
+ ppt: "ppt",
1550
+ pptx: "ppt",
1551
+ odp: "ppt",
1552
+ // Archive
1553
+ zip: "archive",
1554
+ rar: "archive",
1555
+ "7z": "archive",
1556
+ gz: "archive",
1557
+ tar: "archive",
1558
+ // Code
1559
+ js: "code",
1560
+ ts: "code",
1561
+ jsx: "code",
1562
+ tsx: "code",
1563
+ vue: "code",
1564
+ py: "code",
1565
+ java: "code",
1566
+ c: "code",
1567
+ cpp: "code",
1568
+ h: "code",
1569
+ go: "code",
1570
+ rs: "code",
1571
+ rb: "code",
1572
+ php: "code",
1573
+ swift: "code",
1574
+ kt: "code",
1575
+ json: "code",
1576
+ xml: "code",
1577
+ html: "code",
1578
+ css: "code",
1579
+ scss: "code",
1580
+ less: "code",
1581
+ yaml: "code",
1582
+ yml: "code",
1583
+ sh: "code",
1584
+ sql: "code",
1585
+ // Text
1586
+ txt: "text",
1587
+ md: "text",
1588
+ rtf: "text",
1589
+ log: "text"
1590
+ };
1591
+ var categoryConfig = {
1592
+ image: {
1593
+ icon: "vscode-icons:file-type-image",
1594
+ color: "var(--incremark-base-colors-purple-6)",
1595
+ bgColor: "var(--incremark-base-colors-purple-1)"
1596
+ },
1597
+ video: {
1598
+ icon: "vscode-icons:file-type-video",
1599
+ color: "var(--incremark-base-colors-pink-6)",
1600
+ bgColor: "var(--incremark-base-colors-pink-1)"
1601
+ },
1602
+ audio: {
1603
+ icon: "vscode-icons:file-type-audio",
1604
+ color: "var(--incremark-base-colors-cyan-6)",
1605
+ bgColor: "var(--incremark-base-colors-cyan-1)"
1606
+ },
1607
+ pdf: {
1608
+ icon: "vscode-icons:file-type-pdf2",
1609
+ color: "var(--incremark-base-colors-red-6)",
1610
+ bgColor: "var(--incremark-base-colors-red-1)"
1611
+ },
1612
+ word: {
1613
+ icon: "vscode-icons:file-type-word",
1614
+ color: "var(--incremark-base-colors-blue-6)",
1615
+ bgColor: "var(--incremark-base-colors-blue-1)"
1616
+ },
1617
+ excel: {
1618
+ icon: "vscode-icons:file-type-excel",
1619
+ color: "var(--incremark-base-colors-green-6)",
1620
+ bgColor: "var(--incremark-base-colors-green-1)"
1621
+ },
1622
+ ppt: {
1623
+ icon: "vscode-icons:file-type-powerpoint",
1624
+ color: "var(--incremark-base-colors-orange-6)",
1625
+ bgColor: "var(--incremark-base-colors-orange-1)"
1626
+ },
1627
+ archive: {
1628
+ icon: "vscode-icons:file-type-zip",
1629
+ color: "var(--incremark-base-colors-yellow-6)",
1630
+ bgColor: "var(--incremark-base-colors-yellow-1)"
1631
+ },
1632
+ code: {
1633
+ icon: "vscode-icons:file-type-typescript",
1634
+ color: "var(--incremark-base-colors-indigo-6)",
1635
+ bgColor: "var(--incremark-base-colors-indigo-1)"
1636
+ },
1637
+ text: {
1638
+ icon: "vscode-icons:file-type-text",
1639
+ color: "var(--incremark-color-neutral-6)",
1640
+ bgColor: "var(--incremark-color-neutral-2)"
1641
+ },
1642
+ unknown: {
1643
+ icon: "vscode-icons:default-file",
1644
+ color: "var(--incremark-color-neutral-6)",
1645
+ bgColor: "var(--incremark-color-neutral-2)"
1646
+ }
1647
+ };
1648
+ function getExtension(filename) {
1649
+ const parts = filename.toLowerCase().split(".");
1650
+ return parts.length > 1 ? parts[parts.length - 1] : "";
1651
+ }
1652
+ function getFileCategory(mimeType, filename) {
1653
+ if (mimeType) {
1654
+ if (mimeType.startsWith("image/")) return "image";
1655
+ if (mimeType.startsWith("video/")) return "video";
1656
+ if (mimeType.startsWith("audio/")) return "audio";
1657
+ const categoryByMime = mimeTypeMap[mimeType];
1658
+ if (categoryByMime) return categoryByMime;
1659
+ }
1660
+ if (filename) {
1661
+ const ext = getExtension(filename);
1662
+ const categoryByExt = extensionMap[ext];
1663
+ if (categoryByExt) return categoryByExt;
1664
+ }
1665
+ return "unknown";
1666
+ }
1667
+ function getFileTypeConfig(mimeType, filename) {
1668
+ const category = getFileCategory(mimeType, filename);
1669
+ return {
1670
+ category,
1671
+ ...categoryConfig[category]
1672
+ };
1673
+ }
1674
+ function useFileType(mimeType, filename) {
1675
+ const config = computed(() => getFileTypeConfig(mimeType.value, filename.value));
1676
+ const category = computed(() => config.value.category);
1677
+ const icon = computed(() => config.value.icon);
1678
+ const color = computed(() => config.value.color);
1679
+ const bgColor = computed(() => config.value.bgColor);
1680
+ const isImage = computed(() => category.value === "image");
1681
+ const isVideo = computed(() => category.value === "video");
1682
+ const isAudio = computed(() => category.value === "audio");
1683
+ const isPreviewable = computed(() => isImage.value || isVideo.value || isAudio.value);
1684
+ return {
1685
+ config,
1686
+ category,
1687
+ icon,
1688
+ color,
1689
+ bgColor,
1690
+ isImage,
1691
+ isVideo,
1692
+ isAudio,
1693
+ isPreviewable
1694
+ };
1695
+ }
1696
+
1697
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/file-preview/file-preview.vue?type=script
1698
+ var file_preview_default = /* @__PURE__ */ defineComponent({
1699
+ __name: "file-preview",
1700
+ props: {
1701
+ part: { type: null, required: false },
1702
+ file: { type: Object, required: false },
1703
+ maxWidth: { type: Number, required: false, default: 400 },
1704
+ maxHeight: { type: Number, required: false, default: 300 },
1705
+ compact: { type: Boolean, required: false, default: false },
1706
+ removable: { type: Boolean, required: false, default: false }
1707
+ },
1708
+ emits: ["remove"],
1709
+ setup(__props, { expose: __expose, emit: __emit }) {
1710
+ __expose();
1711
+ const props = __props;
1712
+ const emit = __emit;
1713
+ const bem = createImBem("file-preview");
1714
+ const filename = computed(() => props.file?.name ?? props.part?.filename ?? "\u6587\u4EF6");
1715
+ const mimeType = computed(() => props.file?.type ?? props.part?.mediaType);
1716
+ const fileSize = computed(() => props.file?.size);
1717
+ const mimeTypeRef = toRef(() => mimeType.value);
1718
+ const filenameRef = toRef(() => filename.value);
1719
+ const { icon, isImage, isVideo, isAudio } = useFileType(mimeTypeRef, filenameRef);
1720
+ const previewUrl = computed(() => {
1721
+ if (props.file?.url) {
1722
+ return props.file.url;
1723
+ }
1724
+ if (props.part) {
1725
+ if (props.part.data.startsWith("data:") || props.part.data.startsWith("http")) {
1726
+ return props.part.data;
1727
+ }
1728
+ return `data:${props.part.mediaType};base64,${props.part.data}`;
1729
+ }
1730
+ return "";
1731
+ });
1732
+ const previewStyle = computed(() => ({
1733
+ maxWidth: `${props.maxWidth}px`,
1734
+ maxHeight: `${props.maxHeight}px`
1735
+ }));
1736
+ const handleRemove = () => {
1737
+ emit("remove");
1738
+ };
1739
+ const __returned__ = { props, emit, bem, filename, mimeType, fileSize, mimeTypeRef, filenameRef, icon, isImage, isVideo, isAudio, previewUrl, previewStyle, handleRemove, get formatFileSize() {
1740
+ return formatFileSize;
1741
+ }, get Icon() {
1742
+ return Icon;
1743
+ }, get ImButton() {
1744
+ return im_button_default2;
1745
+ } };
1746
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
1747
+ return __returned__;
1748
+ }
1749
+ });
1750
+ var _hoisted_16 = ["src", "alt"];
1751
+ var _hoisted_22 = ["src", "alt"];
1752
+ var _hoisted_3 = ["src"];
1753
+ var _hoisted_4 = ["src"];
1754
+ function render12(_ctx, _cache, $props, $setup, $data, $options) {
1755
+ return openBlock(), createElementBlock(
1756
+ "div",
1757
+ {
1758
+ class: normalizeClass([$setup.bem(), $props.compact && $setup.bem("", "compact")])
1759
+ },
1760
+ [
1761
+ createCommentVNode(" \u7D27\u51D1\u6A21\u5F0F\uFF1A\u7528\u4E8E\u9644\u4EF6\u5217\u8868 "),
1762
+ $props.compact ? (openBlock(), createElementBlock(
1763
+ Fragment,
1764
+ { key: 0 },
1765
+ [
1766
+ createCommentVNode(" \u56FE\u7247\u7F29\u7565\u56FE "),
1767
+ $setup.isImage && $setup.previewUrl ? (openBlock(), createElementBlock(
1768
+ "div",
1769
+ {
1770
+ key: 0,
1771
+ class: normalizeClass($setup.bem("thumbnail"))
1772
+ },
1773
+ [
1774
+ createElementVNode("img", {
1775
+ src: $setup.previewUrl,
1776
+ alt: $setup.filename,
1777
+ class: normalizeClass($setup.bem("thumbnail-img"))
1778
+ }, null, 10, _hoisted_16)
1779
+ ],
1780
+ 2
1781
+ /* CLASS */
1782
+ )) : (openBlock(), createElementBlock(
1783
+ Fragment,
1784
+ { key: 1 },
1785
+ [
1786
+ createCommentVNode(" \u6587\u4EF6\u56FE\u6807\uFF08vscode-icons \u81EA\u5E26\u989C\u8272\uFF09 "),
1787
+ createElementVNode(
1788
+ "div",
1789
+ {
1790
+ class: normalizeClass($setup.bem("icon-box"))
1791
+ },
1792
+ [
1793
+ createVNode($setup["Icon"], {
1794
+ icon: $setup.icon,
1795
+ class: normalizeClass($setup.bem("icon"))
1796
+ }, null, 8, ["icon", "class"])
1797
+ ],
1798
+ 2
1799
+ /* CLASS */
1800
+ )
1801
+ ],
1802
+ 2112
1803
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1804
+ )),
1805
+ createCommentVNode(" \u6587\u4EF6\u4FE1\u606F "),
1806
+ createElementVNode(
1807
+ "div",
1808
+ {
1809
+ class: normalizeClass($setup.bem("info"))
1810
+ },
1811
+ [
1812
+ createElementVNode(
1813
+ "span",
1814
+ {
1815
+ class: normalizeClass($setup.bem("name"))
1816
+ },
1817
+ toDisplayString($setup.filename),
1818
+ 3
1819
+ /* TEXT, CLASS */
1820
+ ),
1821
+ $setup.fileSize ? (openBlock(), createElementBlock(
1822
+ "span",
1823
+ {
1824
+ key: 0,
1825
+ class: normalizeClass($setup.bem("size"))
1826
+ },
1827
+ toDisplayString($setup.formatFileSize($setup.fileSize)),
1828
+ 3
1829
+ /* TEXT, CLASS */
1830
+ )) : createCommentVNode("v-if", true)
1831
+ ],
1832
+ 2
1833
+ /* CLASS */
1834
+ ),
1835
+ createCommentVNode(" \u5220\u9664\u6309\u94AE "),
1836
+ $props.removable ? (openBlock(), createBlock($setup["ImButton"], {
1837
+ key: 2,
1838
+ variant: "ghost",
1839
+ color: "neutral",
1840
+ size: "xs",
1841
+ circle: "",
1842
+ class: normalizeClass($setup.bem("remove")),
1843
+ "aria-label": "\u5220\u9664",
1844
+ onClick: $setup.handleRemove
1845
+ }, {
1846
+ icon: withCtx(() => [
1847
+ createVNode($setup["Icon"], { icon: "mdi:close" })
1848
+ ]),
1849
+ _: 1
1850
+ /* STABLE */
1851
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
1852
+ ],
1853
+ 64
1854
+ /* STABLE_FRAGMENT */
1855
+ )) : (openBlock(), createElementBlock(
1856
+ Fragment,
1857
+ { key: 1 },
1858
+ [
1859
+ createCommentVNode(" \u6807\u51C6\u6A21\u5F0F\uFF1A\u7528\u4E8E\u6D88\u606F\u9884\u89C8 "),
1860
+ createCommentVNode(" \u56FE\u7247\u9884\u89C8 "),
1861
+ $setup.isImage && $setup.previewUrl ? (openBlock(), createElementBlock("img", {
1862
+ key: 0,
1863
+ src: $setup.previewUrl,
1864
+ alt: $setup.filename,
1865
+ class: normalizeClass($setup.bem("image")),
1866
+ style: normalizeStyle($setup.previewStyle)
1867
+ }, null, 14, _hoisted_22)) : $setup.isVideo && $setup.previewUrl ? (openBlock(), createElementBlock(
1868
+ Fragment,
1869
+ { key: 1 },
1870
+ [
1871
+ createCommentVNode(" \u89C6\u9891\u9884\u89C8 "),
1872
+ createElementVNode("video", {
1873
+ src: $setup.previewUrl,
1874
+ class: normalizeClass($setup.bem("video")),
1875
+ style: normalizeStyle($setup.previewStyle),
1876
+ controls: ""
1877
+ }, null, 14, _hoisted_3)
1878
+ ],
1879
+ 2112
1880
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1881
+ )) : $setup.isAudio && $setup.previewUrl ? (openBlock(), createElementBlock(
1882
+ Fragment,
1883
+ { key: 2 },
1884
+ [
1885
+ createCommentVNode(" \u97F3\u9891\u9884\u89C8 "),
1886
+ createElementVNode("audio", {
1887
+ src: $setup.previewUrl,
1888
+ class: normalizeClass($setup.bem("audio")),
1889
+ controls: ""
1890
+ }, null, 10, _hoisted_4)
1891
+ ],
1892
+ 2112
1893
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1894
+ )) : (openBlock(), createElementBlock(
1895
+ Fragment,
1896
+ { key: 3 },
1897
+ [
1898
+ createCommentVNode(" \u5176\u4ED6\u6587\u4EF6 "),
1899
+ createElementVNode(
1900
+ "div",
1901
+ {
1902
+ class: normalizeClass($setup.bem("file"))
1903
+ },
1904
+ [
1905
+ createElementVNode(
1906
+ "div",
1907
+ {
1908
+ class: normalizeClass($setup.bem("icon-box"))
1909
+ },
1910
+ [
1911
+ createVNode($setup["Icon"], {
1912
+ icon: $setup.icon,
1913
+ class: normalizeClass($setup.bem("icon"))
1914
+ }, null, 8, ["icon", "class"])
1915
+ ],
1916
+ 2
1917
+ /* CLASS */
1918
+ ),
1919
+ createElementVNode(
1920
+ "div",
1921
+ {
1922
+ class: normalizeClass($setup.bem("file-info"))
1923
+ },
1924
+ [
1925
+ createElementVNode(
1926
+ "span",
1927
+ {
1928
+ class: normalizeClass($setup.bem("filename"))
1929
+ },
1930
+ toDisplayString($setup.filename),
1931
+ 3
1932
+ /* TEXT, CLASS */
1933
+ ),
1934
+ $setup.mimeType ? (openBlock(), createElementBlock(
1935
+ "span",
1936
+ {
1937
+ key: 0,
1938
+ class: normalizeClass($setup.bem("type"))
1939
+ },
1940
+ toDisplayString($setup.mimeType),
1941
+ 3
1942
+ /* TEXT, CLASS */
1943
+ )) : createCommentVNode("v-if", true)
1944
+ ],
1945
+ 2
1946
+ /* CLASS */
1947
+ )
1948
+ ],
1949
+ 2
1950
+ /* CLASS */
1951
+ )
1952
+ ],
1953
+ 2112
1954
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1955
+ ))
1956
+ ],
1957
+ 64
1958
+ /* STABLE_FRAGMENT */
1959
+ ))
1960
+ ],
1961
+ 2
1962
+ /* CLASS */
1963
+ );
1964
+ }
1965
+
1966
+ // src/components/file-preview/file-preview.vue
1967
+ file_preview_default.render = render12;
1968
+ file_preview_default.__file = "src/components/file-preview/file-preview.vue";
1969
+ var file_preview_default2 = file_preview_default;
1970
+ var message_bubble_default = /* @__PURE__ */ defineComponent({
1971
+ __name: "message-bubble",
1972
+ props: {
1973
+ placement: { type: String, required: false, default: "start" },
1974
+ variant: { type: String, required: false, default: "filled" },
1975
+ shape: { type: String, required: false, default: "default" },
1976
+ width: { type: String, required: false, default: "block" },
1977
+ loading: { type: Boolean, required: false, default: false },
1978
+ streaming: { type: Boolean, required: false, default: false }
1979
+ },
1980
+ setup(__props, { expose: __expose }) {
1981
+ __expose();
1982
+ const props = __props;
1983
+ const bem = createImBem("message-bubble");
1984
+ const rootClass = computed(() => [
1985
+ bem(),
1986
+ bem("", props.placement),
1987
+ bem("", props.width),
1988
+ props.loading && bem("", "loading"),
1989
+ props.streaming && bem("", "streaming")
1990
+ ]);
1991
+ const contentClass = computed(() => [
1992
+ bem("content"),
1993
+ bem("content", props.variant),
1994
+ bem("content", props.shape)
1995
+ ]);
1996
+ const __returned__ = { props, bem, rootClass, contentClass };
1997
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
1998
+ return __returned__;
1999
+ }
2000
+ });
2001
+ function render13(_ctx, _cache, $props, $setup, $data, $options) {
2002
+ return openBlock(), createElementBlock(
2003
+ "div",
2004
+ {
2005
+ class: normalizeClass($setup.rootClass)
2006
+ },
2007
+ [
2008
+ createCommentVNode(" \u5934\u50CF\u63D2\u69FD "),
2009
+ _ctx.$slots.avatar ? (openBlock(), createElementBlock(
2010
+ "div",
2011
+ {
2012
+ key: 0,
2013
+ class: normalizeClass($setup.bem("avatar"))
2014
+ },
2015
+ [
2016
+ renderSlot(_ctx.$slots, "avatar")
2017
+ ],
2018
+ 2
2019
+ /* CLASS */
2020
+ )) : createCommentVNode("v-if", true),
2021
+ createCommentVNode(" \u4E3B\u4F53\u533A\u57DF "),
2022
+ createElementVNode(
2023
+ "div",
2024
+ {
2025
+ class: normalizeClass($setup.bem("main"))
2026
+ },
2027
+ [
2028
+ createCommentVNode(" \u5934\u90E8\u63D2\u69FD "),
2029
+ _ctx.$slots.header ? (openBlock(), createElementBlock(
2030
+ "div",
2031
+ {
2032
+ key: 0,
2033
+ class: normalizeClass($setup.bem("header"))
2034
+ },
2035
+ [
2036
+ renderSlot(_ctx.$slots, "header")
2037
+ ],
2038
+ 2
2039
+ /* CLASS */
2040
+ )) : createCommentVNode("v-if", true),
2041
+ createCommentVNode(" \u5185\u5BB9\u533A\u57DF "),
2042
+ createElementVNode(
2043
+ "div",
2044
+ {
2045
+ class: normalizeClass($setup.contentClass)
2046
+ },
2047
+ [
2048
+ renderSlot(_ctx.$slots, "default")
2049
+ ],
2050
+ 2
2051
+ /* CLASS */
2052
+ ),
2053
+ createCommentVNode(" \u5E95\u90E8\u63D2\u69FD "),
2054
+ _ctx.$slots.footer ? (openBlock(), createElementBlock(
2055
+ "div",
2056
+ {
2057
+ key: 1,
2058
+ class: normalizeClass($setup.bem("footer"))
2059
+ },
2060
+ [
2061
+ renderSlot(_ctx.$slots, "footer")
2062
+ ],
2063
+ 2
2064
+ /* CLASS */
2065
+ )) : createCommentVNode("v-if", true)
2066
+ ],
2067
+ 2
2068
+ /* CLASS */
2069
+ )
2070
+ ],
2071
+ 2
2072
+ /* CLASS */
2073
+ );
2074
+ }
2075
+
2076
+ // src/components/message-bubble/message-bubble.vue
2077
+ message_bubble_default.render = render13;
2078
+ message_bubble_default.__file = "src/components/message-bubble/message-bubble.vue";
2079
+ var message_bubble_default2 = message_bubble_default;
2080
+ var action_button_default = /* @__PURE__ */ defineComponent({
2081
+ __name: "action-button",
2082
+ props: {
2083
+ ariaLabel: { type: String, required: false },
2084
+ intent: { type: String, required: false, default: "action" },
2085
+ size: { type: String, required: false, default: "sm" },
2086
+ square: { type: Boolean, required: false, default: false },
2087
+ circle: { type: Boolean, required: false, default: false },
2088
+ disabled: { type: Boolean, required: false, default: false },
2089
+ loading: { type: Boolean, required: false, default: false },
2090
+ active: { type: Boolean, required: false, default: false }
2091
+ },
2092
+ emits: ["click"],
2093
+ setup(__props, { expose: __expose, emit: __emit }) {
2094
+ __expose();
2095
+ const props = __props;
2096
+ const emit = __emit;
2097
+ const { Button } = useUIAdapter();
2098
+ const buttonProps = computed(() => {
2099
+ const intentMap = {
2100
+ action: { variant: "ghost", color: "neutral" },
2101
+ primary: { variant: "solid", color: "primary" },
2102
+ secondary: { variant: "outline", color: "neutral" },
2103
+ danger: { variant: "solid", color: "error" }
2104
+ };
2105
+ const { variant, color } = intentMap[props.intent] || intentMap.action;
2106
+ return {
2107
+ variant,
2108
+ color,
2109
+ size: props.size,
2110
+ square: props.square,
2111
+ circle: props.circle,
2112
+ disabled: props.disabled,
2113
+ loading: props.loading,
2114
+ active: props.active,
2115
+ // 传递原始 options,供自定义 adapter 使用
2116
+ options: {
2117
+ intent: props.intent,
2118
+ size: props.size,
2119
+ square: props.square,
2120
+ circle: props.circle,
2121
+ disabled: props.disabled,
2122
+ loading: props.loading,
2123
+ active: props.active
2124
+ }
2125
+ };
2126
+ });
2127
+ const handleClick = (event) => {
2128
+ if (!props.disabled && !props.loading) {
2129
+ emit("click", event);
2130
+ }
2131
+ };
2132
+ const __returned__ = { props, emit, Button, buttonProps, handleClick };
2133
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2134
+ return __returned__;
2135
+ }
2136
+ });
2137
+ function render14(_ctx, _cache, $props, $setup, $data, $options) {
2138
+ return openBlock(), createBlock(resolveDynamicComponent($setup.Button), mergeProps($setup.buttonProps, {
2139
+ "aria-label": $props.ariaLabel,
2140
+ "aria-pressed": $setup.props.active,
2141
+ onClick: $setup.handleClick
2142
+ }), {
2143
+ icon: withCtx(() => [
2144
+ renderSlot(_ctx.$slots, "icon")
2145
+ ]),
2146
+ default: withCtx(() => [
2147
+ renderSlot(_ctx.$slots, "default")
2148
+ ]),
2149
+ _: 3
2150
+ /* FORWARDED */
2151
+ }, 16, ["aria-label", "aria-pressed"]);
2152
+ }
2153
+
2154
+ // src/components/base/action-button/action-button.vue
2155
+ action_button_default.render = render14;
2156
+ action_button_default.__file = "src/components/base/action-button/action-button.vue";
2157
+ var action_button_default2 = action_button_default;
2158
+
2159
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/message-actions/message-action.vue?type=script
2160
+ var message_action_default = /* @__PURE__ */ defineComponent({
2161
+ __name: "message-action",
2162
+ props: {
2163
+ icon: { type: null, required: false },
2164
+ tooltip: { type: String, required: false },
2165
+ label: { type: String, required: false },
2166
+ loading: { type: Boolean, required: false, default: false },
2167
+ disabled: { type: Boolean, required: false, default: false }
2168
+ },
2169
+ emits: ["click"],
2170
+ setup(__props, { expose: __expose, emit: __emit }) {
2171
+ __expose();
2172
+ const props = __props;
2173
+ const emit = __emit;
2174
+ const bem = createImBem("message-action");
2175
+ const { Tooltip } = useUIAdapter();
2176
+ const rootClass = computed(() => [
2177
+ bem(),
2178
+ props.loading && bem("", "loading"),
2179
+ props.disabled && bem("", "disabled")
2180
+ ]);
2181
+ const handleClick = (event) => {
2182
+ if (!props.disabled && !props.loading) {
2183
+ emit("click", event);
2184
+ }
2185
+ };
2186
+ const __returned__ = { props, emit, bem, Tooltip, rootClass, handleClick, get ActionButton() {
2187
+ return action_button_default2;
2188
+ }, get SvgIcon() {
2189
+ return svg_icon_default2;
2190
+ } };
2191
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2192
+ return __returned__;
2193
+ }
2194
+ });
2195
+ function render15(_ctx, _cache, $props, $setup, $data, $options) {
2196
+ return openBlock(), createBlock(resolveDynamicComponent($setup.Tooltip), { content: $props.tooltip }, {
2197
+ default: withCtx(() => [
2198
+ createVNode($setup["ActionButton"], {
2199
+ class: normalizeClass($setup.rootClass),
2200
+ intent: "action",
2201
+ size: "sm",
2202
+ square: "",
2203
+ disabled: $props.disabled,
2204
+ loading: $props.loading,
2205
+ "aria-label": $props.label || $props.tooltip,
2206
+ onClick: $setup.handleClick
2207
+ }, {
2208
+ default: withCtx(() => [
2209
+ renderSlot(_ctx.$slots, "default", {}, () => [
2210
+ $props.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
2211
+ key: 0,
2212
+ class: normalizeClass($setup.bem("icon"))
2213
+ }, {
2214
+ default: withCtx(() => [
2215
+ (openBlock(), createBlock(resolveDynamicComponent($props.icon)))
2216
+ ]),
2217
+ _: 1
2218
+ /* STABLE */
2219
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
2220
+ ])
2221
+ ]),
2222
+ _: 3
2223
+ /* FORWARDED */
2224
+ }, 8, ["class", "disabled", "loading", "aria-label"])
2225
+ ]),
2226
+ _: 3
2227
+ /* FORWARDED */
2228
+ }, 8, ["content"]);
2229
+ }
2230
+
2231
+ // src/components/message-actions/message-action.vue
2232
+ message_action_default.render = render15;
2233
+ message_action_default.__file = "src/components/message-actions/message-action.vue";
2234
+ var message_action_default2 = message_action_default;
2235
+ function useCopyAction(text, options = {}) {
2236
+ const { resetDelay = 2e3 } = options;
2237
+ const copied = ref(false);
2238
+ const copy = async () => {
2239
+ try {
2240
+ await navigator.clipboard.writeText(text.value);
2241
+ copied.value = true;
2242
+ setTimeout(() => {
2243
+ copied.value = false;
2244
+ }, resetDelay);
2245
+ } catch (err) {
2246
+ console.error("Failed to copy text:", err);
2247
+ }
2248
+ };
2249
+ return { copied, copy };
2250
+ }
2251
+
2252
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/message-actions/message-action-copy.vue?type=script
2253
+ var message_action_copy_default = /* @__PURE__ */ defineComponent({
2254
+ __name: "message-action-copy",
2255
+ props: {
2256
+ text: { type: String, required: true },
2257
+ copiedTooltip: { type: String, required: false, default: "\u5DF2\u590D\u5236" },
2258
+ tooltip: { type: String, required: false, default: "\u590D\u5236" }
2259
+ },
2260
+ setup(__props, { expose: __expose }) {
2261
+ __expose();
2262
+ const props = __props;
2263
+ const { icons } = useUIAdapter();
2264
+ const { copied, copy } = useCopyAction(toRef(props, "text"));
2265
+ const defaultCopyIcon = h(Icon, { icon: "ph:copy" });
2266
+ const defaultCheckIcon = h(Icon, { icon: "ph:check" });
2267
+ const currentIcon = computed(() => {
2268
+ if (copied.value) {
2269
+ return icons?.check || defaultCheckIcon;
2270
+ }
2271
+ return icons?.copy || defaultCopyIcon;
2272
+ });
2273
+ const currentTooltip = computed(() => {
2274
+ return copied.value ? props.copiedTooltip : props.tooltip;
2275
+ });
2276
+ const __returned__ = { props, icons, copied, copy, defaultCopyIcon, defaultCheckIcon, currentIcon, currentTooltip, MessageAction: message_action_default2 };
2277
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2278
+ return __returned__;
2279
+ }
2280
+ });
2281
+ function render16(_ctx, _cache, $props, $setup, $data, $options) {
2282
+ return openBlock(), createBlock($setup["MessageAction"], {
2283
+ icon: $setup.currentIcon,
2284
+ tooltip: $setup.currentTooltip,
2285
+ label: $setup.currentTooltip,
2286
+ onClick: $setup.copy
2287
+ }, null, 8, ["icon", "tooltip", "label", "onClick"]);
2288
+ }
2289
+
2290
+ // src/components/message-actions/message-action-copy.vue
2291
+ message_action_copy_default.render = render16;
2292
+ message_action_copy_default.__file = "src/components/message-actions/message-action-copy.vue";
2293
+ var message_action_copy_default2 = message_action_copy_default;
2294
+ var message_action_feedback_default = /* @__PURE__ */ defineComponent({
2295
+ __name: "message-action-feedback",
2296
+ props: {
2297
+ value: { type: String, required: false, default: "default" },
2298
+ likeTooltip: { type: String, required: false, default: "\u6709\u5E2E\u52A9" },
2299
+ dislikeTooltip: { type: String, required: false, default: "\u6CA1\u5E2E\u52A9" }
2300
+ },
2301
+ emits: ["update:value", "change"],
2302
+ setup(__props, { expose: __expose, emit: __emit }) {
2303
+ __expose();
2304
+ const props = __props;
2305
+ const emit = __emit;
2306
+ const bem = createImBem("message-action-feedback");
2307
+ const { icons } = useUIAdapter();
2308
+ const defaultThumbUp = h(Icon, { icon: "ph:thumbs-up" });
2309
+ const defaultThumbUpFill = h(Icon, { icon: "ph:thumbs-up-fill" });
2310
+ const defaultThumbDown = h(Icon, { icon: "ph:thumbs-down" });
2311
+ const defaultThumbDownFill = h(Icon, { icon: "ph:thumbs-down-fill" });
2312
+ const likeIcon = computed(() => {
2313
+ if (props.value === "like") {
2314
+ return icons?.thumbUpFilled || defaultThumbUpFill;
2315
+ }
2316
+ return icons?.thumbUp || defaultThumbUp;
2317
+ });
2318
+ const dislikeIcon = computed(() => {
2319
+ if (props.value === "dislike") {
2320
+ return icons?.thumbDownFilled || defaultThumbDownFill;
2321
+ }
2322
+ return icons?.thumbDown || defaultThumbDown;
2323
+ });
2324
+ const handleLike = () => {
2325
+ const newValue = props.value === "like" ? "default" : "like";
2326
+ emit("update:value", newValue);
2327
+ emit("change", newValue);
2328
+ };
2329
+ const handleDislike = () => {
2330
+ const newValue = props.value === "dislike" ? "default" : "dislike";
2331
+ emit("update:value", newValue);
2332
+ emit("change", newValue);
2333
+ };
2334
+ const showLike = computed(() => props.value === "default" || props.value === "like");
2335
+ const showDislike = computed(() => props.value === "default" || props.value === "dislike");
2336
+ const __returned__ = { props, emit, bem, icons, defaultThumbUp, defaultThumbUpFill, defaultThumbDown, defaultThumbDownFill, likeIcon, dislikeIcon, handleLike, handleDislike, showLike, showDislike, MessageAction: message_action_default2 };
2337
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2338
+ return __returned__;
2339
+ }
2340
+ });
2341
+ function render17(_ctx, _cache, $props, $setup, $data, $options) {
2342
+ return openBlock(), createElementBlock(
2343
+ "span",
2344
+ {
2345
+ class: normalizeClass($setup.bem())
2346
+ },
2347
+ [
2348
+ $setup.showLike ? (openBlock(), createBlock($setup["MessageAction"], {
2349
+ key: 0,
2350
+ icon: $setup.likeIcon,
2351
+ tooltip: $props.likeTooltip,
2352
+ label: $props.likeTooltip,
2353
+ class: normalizeClass([$setup.bem("like"), $props.value === "like" && $setup.bem("like", "active")]),
2354
+ onClick: $setup.handleLike
2355
+ }, null, 8, ["icon", "tooltip", "label", "class"])) : createCommentVNode("v-if", true),
2356
+ $setup.showDislike ? (openBlock(), createBlock($setup["MessageAction"], {
2357
+ key: 1,
2358
+ icon: $setup.dislikeIcon,
2359
+ tooltip: $props.dislikeTooltip,
2360
+ label: $props.dislikeTooltip,
2361
+ class: normalizeClass([$setup.bem("dislike"), $props.value === "dislike" && $setup.bem("dislike", "active")]),
2362
+ onClick: $setup.handleDislike
2363
+ }, null, 8, ["icon", "tooltip", "label", "class"])) : createCommentVNode("v-if", true)
2364
+ ],
2365
+ 2
2366
+ /* CLASS */
2367
+ );
2368
+ }
2369
+
2370
+ // src/components/message-actions/message-action-feedback.vue
2371
+ message_action_feedback_default.render = render17;
2372
+ message_action_feedback_default.__file = "src/components/message-actions/message-action-feedback.vue";
2373
+ var message_action_feedback_default2 = message_action_feedback_default;
2374
+ var im_dropdown_default = /* @__PURE__ */ defineComponent({
2375
+ __name: "im-dropdown",
2376
+ props: {
2377
+ items: { type: Array, required: true },
2378
+ placement: { type: null, required: false, default: "bottom-start" },
2379
+ offset: { type: Number, required: false, default: 4 },
2380
+ disabled: { type: Boolean, required: false, default: false },
2381
+ to: { type: [String, Function], required: false, skipCheck: true, default: "body" },
2382
+ teleportDisabled: { type: Boolean, required: false, default: false }
2383
+ },
2384
+ emits: ["select"],
2385
+ setup(__props, { expose: __expose, emit: __emit }) {
2386
+ __expose();
2387
+ const props = __props;
2388
+ const emit = __emit;
2389
+ const bem = createImBem("dropdown");
2390
+ const visible = ref(false);
2391
+ const handleSelect = (item) => {
2392
+ if (item.disabled || item.divider) return;
2393
+ emit("select", item);
2394
+ visible.value = false;
2395
+ };
2396
+ const __returned__ = { props, emit, bem, visible, handleSelect, get ImPopover() {
2397
+ return im_popover_default2;
2398
+ }, get SvgIcon() {
2399
+ return svg_icon_default2;
2400
+ } };
2401
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2402
+ return __returned__;
2403
+ }
2404
+ });
2405
+ var _hoisted_17 = ["onClick"];
2406
+ function render18(_ctx, _cache, $props, $setup, $data, $options) {
2407
+ return openBlock(), createBlock($setup["ImPopover"], {
2408
+ visible: $setup.visible,
2409
+ "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => $setup.visible = $event),
2410
+ trigger: "click",
2411
+ placement: $props.placement,
2412
+ offset: $props.offset,
2413
+ disabled: $props.disabled,
2414
+ to: $props.to,
2415
+ "teleport-disabled": $props.teleportDisabled
2416
+ }, {
2417
+ content: withCtx(() => [
2418
+ createElementVNode(
2419
+ "div",
2420
+ {
2421
+ class: normalizeClass($setup.bem("menu"))
2422
+ },
2423
+ [
2424
+ (openBlock(true), createElementBlock(
2425
+ Fragment,
2426
+ null,
2427
+ renderList($props.items, (item) => {
2428
+ return openBlock(), createElementBlock(
2429
+ Fragment,
2430
+ {
2431
+ key: item.key
2432
+ },
2433
+ [
2434
+ item.divider ? (openBlock(), createElementBlock(
2435
+ "div",
2436
+ {
2437
+ key: 0,
2438
+ class: normalizeClass($setup.bem("divider"))
2439
+ },
2440
+ null,
2441
+ 2
2442
+ /* CLASS */
2443
+ )) : (openBlock(), createElementBlock("div", {
2444
+ key: 1,
2445
+ class: normalizeClass([$setup.bem("item"), { [$setup.bem("item", "disabled")]: item.disabled }]),
2446
+ onClick: ($event) => $setup.handleSelect(item)
2447
+ }, [
2448
+ item.icon ? (openBlock(), createElementBlock(
2449
+ "span",
2450
+ {
2451
+ key: 0,
2452
+ class: normalizeClass($setup.bem("icon"))
2453
+ },
2454
+ [
2455
+ createVNode(
2456
+ $setup["SvgIcon"],
2457
+ null,
2458
+ {
2459
+ default: withCtx(() => [
2460
+ (openBlock(), createBlock(resolveDynamicComponent(item.icon)))
2461
+ ]),
2462
+ _: 2
2463
+ /* DYNAMIC */
2464
+ },
2465
+ 1024
2466
+ /* DYNAMIC_SLOTS */
2467
+ )
2468
+ ],
2469
+ 2
2470
+ /* CLASS */
2471
+ )) : createCommentVNode("v-if", true),
2472
+ createElementVNode(
2473
+ "span",
2474
+ {
2475
+ class: normalizeClass($setup.bem("label"))
2476
+ },
2477
+ toDisplayString(item.label),
2478
+ 3
2479
+ /* TEXT, CLASS */
2480
+ )
2481
+ ], 10, _hoisted_17))
2482
+ ],
2483
+ 64
2484
+ /* STABLE_FRAGMENT */
2485
+ );
2486
+ }),
2487
+ 128
2488
+ /* KEYED_FRAGMENT */
2489
+ ))
2490
+ ],
2491
+ 2
2492
+ /* CLASS */
2493
+ )
2494
+ ]),
2495
+ default: withCtx(() => [
2496
+ renderSlot(_ctx.$slots, "default")
2497
+ ]),
2498
+ _: 3
2499
+ /* FORWARDED */
2500
+ }, 8, ["visible", "placement", "offset", "disabled", "to", "teleport-disabled"]);
2501
+ }
2502
+
2503
+ // src/components/base/im-dropdown/im-dropdown.vue
2504
+ im_dropdown_default.render = render18;
2505
+ im_dropdown_default.__file = "src/components/base/im-dropdown/im-dropdown.vue";
2506
+ var im_dropdown_default2 = im_dropdown_default;
2507
+ var message_action_more_default = /* @__PURE__ */ defineComponent({
2508
+ __name: "message-action-more",
2509
+ props: {
2510
+ items: { type: Array, required: true },
2511
+ tooltip: { type: String, required: false, default: "\u66F4\u591A" }
2512
+ },
2513
+ emits: ["select"],
2514
+ setup(__props, { expose: __expose, emit: __emit }) {
2515
+ __expose();
2516
+ const props = __props;
2517
+ const emit = __emit;
2518
+ const bem = createImBem("message-action-more");
2519
+ const { Tooltip } = useUIAdapter();
2520
+ const defaultMoreIcon = h(Icon, { icon: "ph:dots-three" });
2521
+ const dropdownItems = computed(() => {
2522
+ return props.items.map((item) => ({
2523
+ key: item.key,
2524
+ label: item.label,
2525
+ icon: item.icon,
2526
+ disabled: item.disabled,
2527
+ divider: item.divider
2528
+ }));
2529
+ });
2530
+ const handleSelect = (dropdownItem) => {
2531
+ const item = props.items.find((i) => i.key === dropdownItem.key);
2532
+ if (item) {
2533
+ emit("select", item);
2534
+ }
2535
+ };
2536
+ const __returned__ = { props, emit, bem, Tooltip, defaultMoreIcon, dropdownItems, handleSelect, get ImDropdown() {
2537
+ return im_dropdown_default2;
2538
+ }, get ActionButton() {
2539
+ return action_button_default2;
2540
+ }, get SvgIcon() {
2541
+ return svg_icon_default2;
2542
+ } };
2543
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2544
+ return __returned__;
2545
+ }
2546
+ });
2547
+ function render19(_ctx, _cache, $props, $setup, $data, $options) {
2548
+ return openBlock(), createBlock($setup["ImDropdown"], {
2549
+ items: $setup.dropdownItems,
2550
+ placement: "bottom-end",
2551
+ onSelect: $setup.handleSelect
2552
+ }, {
2553
+ default: withCtx(() => [
2554
+ (openBlock(), createBlock(resolveDynamicComponent($setup.Tooltip), { content: $props.tooltip }, {
2555
+ default: withCtx(() => [
2556
+ createVNode($setup["ActionButton"], {
2557
+ class: normalizeClass($setup.bem()),
2558
+ intent: "action",
2559
+ size: "sm",
2560
+ square: "",
2561
+ "aria-label": $props.tooltip
2562
+ }, {
2563
+ default: withCtx(() => [
2564
+ createVNode($setup["SvgIcon"], {
2565
+ class: normalizeClass($setup.bem("icon"))
2566
+ }, {
2567
+ default: withCtx(() => [
2568
+ (openBlock(), createBlock(resolveDynamicComponent($setup.defaultMoreIcon)))
2569
+ ]),
2570
+ _: 1
2571
+ /* STABLE */
2572
+ }, 8, ["class"])
2573
+ ]),
2574
+ _: 1
2575
+ /* STABLE */
2576
+ }, 8, ["class", "aria-label"])
2577
+ ]),
2578
+ _: 1
2579
+ /* STABLE */
2580
+ }, 8, ["content"]))
2581
+ ]),
2582
+ _: 1
2583
+ /* STABLE */
2584
+ }, 8, ["items"]);
2585
+ }
2586
+
2587
+ // src/components/message-actions/message-action-more.vue
2588
+ message_action_more_default.render = render19;
2589
+ message_action_more_default.__file = "src/components/message-actions/message-action-more.vue";
2590
+ var message_action_more_default2 = message_action_more_default;
2591
+
2592
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/message-actions/message-actions.vue?type=script
2593
+ var message_actions_default = /* @__PURE__ */ defineComponent({
2594
+ __name: "message-actions",
2595
+ props: {
2596
+ variant: { type: String, required: false, default: "borderless" },
2597
+ actions: { type: Array, required: false },
2598
+ maxVisible: { type: Number, required: false, default: Infinity },
2599
+ feedbackValue: { type: String, required: false }
2600
+ },
2601
+ emits: ["action", "update:feedbackValue"],
2602
+ setup(__props, { expose: __expose, emit: __emit }) {
2603
+ __expose();
2604
+ const props = __props;
2605
+ const emit = __emit;
2606
+ const slots = useSlots();
2607
+ const bem = createImBem("message-actions");
2608
+ const rootClass = computed(() => [
2609
+ bem(),
2610
+ bem("", props.variant)
2611
+ ]);
2612
+ const useConfigMode = computed(() => {
2613
+ return props.actions && props.actions.length > 0 && !slots.default;
2614
+ });
2615
+ const visibleActions = computed(() => {
2616
+ if (!props.actions) return [];
2617
+ return props.actions.slice(0, props.maxVisible);
2618
+ });
2619
+ const moreActions = computed(() => {
2620
+ if (!props.actions || props.actions.length <= props.maxVisible) return [];
2621
+ return props.actions.slice(props.maxVisible).map((item) => ({
2622
+ key: item.key,
2623
+ label: item.label || item.tooltip || item.key,
2624
+ icon: item.icon,
2625
+ disabled: item.disabled
2626
+ }));
2627
+ });
2628
+ const handleAction = (item) => {
2629
+ if (item.handler) {
2630
+ item.handler();
2631
+ }
2632
+ emit("action", item);
2633
+ };
2634
+ const handleMoreSelect = (moreItem) => {
2635
+ const item = props.actions?.find((a) => a.key === moreItem.key);
2636
+ if (item) {
2637
+ handleAction(item);
2638
+ }
2639
+ };
2640
+ const handleFeedbackChange = (value) => {
2641
+ emit("update:feedbackValue", value);
2642
+ };
2643
+ const __returned__ = { props, emit, slots, bem, rootClass, useConfigMode, visibleActions, moreActions, handleAction, handleMoreSelect, handleFeedbackChange, MessageAction: message_action_default2, MessageActionCopy: message_action_copy_default2, MessageActionFeedback: message_action_feedback_default2, MessageActionMore: message_action_more_default2 };
2644
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2645
+ return __returned__;
2646
+ }
2647
+ });
2648
+ function render20(_ctx, _cache, $props, $setup, $data, $options) {
2649
+ return openBlock(), createElementBlock(
2650
+ "div",
2651
+ {
2652
+ class: normalizeClass($setup.rootClass)
2653
+ },
2654
+ [
2655
+ createCommentVNode(" \u914D\u7F6E\u65B9\u5F0F "),
2656
+ $setup.useConfigMode ? (openBlock(), createElementBlock(
2657
+ Fragment,
2658
+ { key: 0 },
2659
+ [
2660
+ (openBlock(true), createElementBlock(
2661
+ Fragment,
2662
+ null,
2663
+ renderList($setup.visibleActions, (item) => {
2664
+ return openBlock(), createElementBlock(
2665
+ Fragment,
2666
+ {
2667
+ key: item.key
2668
+ },
2669
+ [
2670
+ createCommentVNode(" \u590D\u5236\u7C7B\u578B "),
2671
+ item.type === "copy" && item.copyText ? (openBlock(), createBlock($setup["MessageActionCopy"], {
2672
+ key: 0,
2673
+ text: item.copyText,
2674
+ tooltip: item.tooltip
2675
+ }, null, 8, ["text", "tooltip"])) : item.type === "feedback" ? (openBlock(), createElementBlock(
2676
+ Fragment,
2677
+ { key: 1 },
2678
+ [
2679
+ createCommentVNode(" \u53CD\u9988\u7C7B\u578B "),
2680
+ createVNode($setup["MessageActionFeedback"], {
2681
+ value: $props.feedbackValue,
2682
+ "onUpdate:value": $setup.handleFeedbackChange
2683
+ }, null, 8, ["value"])
2684
+ ],
2685
+ 2112
2686
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2687
+ )) : (openBlock(), createElementBlock(
2688
+ Fragment,
2689
+ { key: 2 },
2690
+ [
2691
+ createCommentVNode(" \u81EA\u5B9A\u4E49\u7C7B\u578B "),
2692
+ createVNode($setup["MessageAction"], {
2693
+ icon: item.icon,
2694
+ tooltip: item.tooltip,
2695
+ disabled: item.disabled,
2696
+ onClick: ($event) => $setup.handleAction(item)
2697
+ }, null, 8, ["icon", "tooltip", "disabled", "onClick"])
2698
+ ],
2699
+ 2112
2700
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2701
+ ))
2702
+ ],
2703
+ 64
2704
+ /* STABLE_FRAGMENT */
2705
+ );
2706
+ }),
2707
+ 128
2708
+ /* KEYED_FRAGMENT */
2709
+ )),
2710
+ createCommentVNode(" \u66F4\u591A\u64CD\u4F5C "),
2711
+ $setup.moreActions.length > 0 ? (openBlock(), createBlock($setup["MessageActionMore"], {
2712
+ key: 0,
2713
+ items: $setup.moreActions,
2714
+ onSelect: $setup.handleMoreSelect
2715
+ }, null, 8, ["items"])) : createCommentVNode("v-if", true)
2716
+ ],
2717
+ 64
2718
+ /* STABLE_FRAGMENT */
2719
+ )) : (openBlock(), createElementBlock(
2720
+ Fragment,
2721
+ { key: 1 },
2722
+ [
2723
+ createCommentVNode(" slot \u65B9\u5F0F "),
2724
+ renderSlot(_ctx.$slots, "default")
2725
+ ],
2726
+ 2112
2727
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2728
+ ))
2729
+ ],
2730
+ 2
2731
+ /* CLASS */
2732
+ );
2733
+ }
2734
+
2735
+ // src/components/message-actions/message-actions.vue
2736
+ message_actions_default.render = render20;
2737
+ message_actions_default.__file = "src/components/message-actions/message-actions.vue";
2738
+ var message_actions_default2 = message_actions_default;
2739
+ var defaultPlaceholder = "Type something...";
2740
+ var sender_input_default = /* @__PURE__ */ defineComponent({
2741
+ __name: "sender-input",
2742
+ props: /* @__PURE__ */ mergeModels({
2743
+ placeholder: { type: String, required: false, default: defaultPlaceholder },
2744
+ disabled: { type: Boolean, required: false, default: false },
2745
+ bordered: { type: Boolean, required: false, default: false },
2746
+ maxHeight: { type: [String, Number], required: false },
2747
+ submitType: { type: String, required: false, default: "enter" }
2748
+ }, {
2749
+ "modelValue": { type: String, ...{ default: "" } },
2750
+ "modelModifiers": {}
2751
+ }),
2752
+ emits: /* @__PURE__ */ mergeModels(["focus", "blur", "change", "paste", "pasteFile", "submit"], ["update:modelValue"]),
2753
+ setup(__props, { expose: __expose, emit: __emit }) {
2754
+ const props = __props;
2755
+ const emit = __emit;
2756
+ const modelValue = useModel(__props, "modelValue");
2757
+ const bem = createImBem("sender-input");
2758
+ const modelValueChangeByEditor = ref(false);
2759
+ const setContentByModelValue = ref(false);
2760
+ const handleKeyDown = (event) => {
2761
+ if (props.disabled) return false;
2762
+ const isEnter = event.key === "Enter";
2763
+ const hasShift = event.shiftKey;
2764
+ const hasMeta = event.metaKey || event.ctrlKey;
2765
+ if (!isEnter) return false;
2766
+ if (hasMeta) {
2767
+ event.preventDefault();
2768
+ emit("submit");
2769
+ return true;
2770
+ }
2771
+ if (props.submitType === "enter" && !hasShift) {
2772
+ event.preventDefault();
2773
+ emit("submit");
2774
+ return true;
2775
+ } else if (props.submitType === "shiftEnter" && hasShift) {
2776
+ event.preventDefault();
2777
+ emit("submit");
2778
+ return true;
2779
+ }
2780
+ return false;
2781
+ };
2782
+ const editor = useEditor({
2783
+ editorProps: {
2784
+ editable: () => !props.disabled,
2785
+ attributes: {
2786
+ class: bem("editor")
2787
+ },
2788
+ handleKeyDown: (_view, event) => {
2789
+ return handleKeyDown(event);
2790
+ },
2791
+ handlePaste: (_view, event) => {
2792
+ const files = Array.from(event.clipboardData?.files || []);
2793
+ if (files.length > 0) {
2794
+ emit("pasteFile", files);
2795
+ return true;
2796
+ }
2797
+ return false;
2798
+ }
2799
+ },
2800
+ content: modelValue.value,
2801
+ extensions: [
2802
+ Markdown,
2803
+ Document,
2804
+ Paragraph.configure(),
2805
+ Text,
2806
+ Placeholder.configure({
2807
+ placeholder: () => props.placeholder || defaultPlaceholder,
2808
+ showOnlyWhenEditable: false
2809
+ }),
2810
+ UndoRedo
2811
+ ],
2812
+ onFocus: (options) => {
2813
+ emit("focus", options.event);
2814
+ },
2815
+ onBlur: (options) => {
2816
+ emit("blur", options.event);
2817
+ },
2818
+ onUpdate: (options) => {
2819
+ if (setContentByModelValue.value) {
2820
+ setContentByModelValue.value = false;
2821
+ return;
2822
+ }
2823
+ const markdownContent = options.editor.getMarkdown().trim();
2824
+ if (markdownContent === modelValue.value) {
2825
+ return;
2826
+ }
2827
+ modelValueChangeByEditor.value = true;
2828
+ modelValue.value = markdownContent;
2829
+ }
2830
+ });
2831
+ watch(() => props.placeholder, (newPlaceholder) => {
2832
+ const newPlaceholderValue = newPlaceholder || defaultPlaceholder;
2833
+ editor.value?.commands.setMeta("placeholder", newPlaceholderValue);
2834
+ });
2835
+ watch(modelValue, (newVal) => {
2836
+ if (modelValueChangeByEditor.value) {
2837
+ modelValueChangeByEditor.value = false;
2838
+ return;
2839
+ }
2840
+ const newContent = newVal ?? "";
2841
+ setContentByModelValue.value = true;
2842
+ editor.value?.commands.setContent(newContent);
2843
+ });
2844
+ watch(() => props.disabled, (newDisable) => {
2845
+ editor.value?.setEditable(!newDisable);
2846
+ });
2847
+ const maxHeightValue = computed(() => {
2848
+ if (!props.maxHeight) return void 0;
2849
+ return typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight;
2850
+ });
2851
+ const handleClick = () => {
2852
+ nextTick(() => {
2853
+ if (editor.value?.isEditable && !editor.value.isFocused) {
2854
+ editor.value?.commands.focus();
2855
+ }
2856
+ });
2857
+ };
2858
+ const focus = () => {
2859
+ editor.value?.commands.focus();
2860
+ };
2861
+ const blur = () => {
2862
+ editor.value?.commands.blur();
2863
+ };
2864
+ const clear = () => {
2865
+ editor.value?.commands.clearContent();
2866
+ modelValue.value = "";
2867
+ };
2868
+ const insert = (text) => {
2869
+ editor.value?.commands.insertContent(text);
2870
+ };
2871
+ __expose({
2872
+ focus,
2873
+ blur,
2874
+ clear,
2875
+ insert
2876
+ });
2877
+ const __returned__ = { defaultPlaceholder, props, emit, modelValue, bem, modelValueChangeByEditor, setContentByModelValue, handleKeyDown, editor, maxHeightValue, handleClick, focus, blur, clear, insert, get EditorContent() {
2878
+ return EditorContent;
2879
+ } };
2880
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2881
+ return __returned__;
2882
+ }
2883
+ });
2884
+ function render21(_ctx, _cache, $props, $setup, $data, $options) {
2885
+ return openBlock(), createBlock($setup["EditorContent"], {
2886
+ class: normalizeClass($setup.bem("", {
2887
+ bordered: $setup.props.bordered,
2888
+ disabled: $setup.props.disabled
2889
+ })),
2890
+ style: normalizeStyle({
2891
+ "--im-sender-input-max-height": $setup.maxHeightValue
2892
+ }),
2893
+ editor: $setup.editor,
2894
+ onClick: $setup.handleClick
2895
+ }, null, 8, ["class", "style", "editor"]);
2896
+ }
2897
+
2898
+ // src/components/sender-input/sender-input.vue
2899
+ sender_input_default.render = render21;
2900
+ sender_input_default.__file = "src/components/sender-input/sender-input.vue";
2901
+ var sender_input_default2 = sender_input_default;
2902
+ var sender_submit_button_default = /* @__PURE__ */ defineComponent({
2903
+ __name: "sender-submit-button",
2904
+ props: {
2905
+ disabled: { type: Boolean, required: false, default: false },
2906
+ loading: { type: Boolean, required: false, default: false }
2907
+ },
2908
+ emits: ["click"],
2909
+ setup(__props, { expose: __expose, emit: __emit }) {
2910
+ __expose();
2911
+ const props = __props;
2912
+ const emit = __emit;
2913
+ const bem = createImBem("sender-submit-button");
2914
+ const buttonColor = computed(() => props.loading ? "neutral" : "primary");
2915
+ const isDisabled = computed(() => props.disabled && !props.loading);
2916
+ const handleClick = (event) => {
2917
+ if (!props.loading && props.disabled) {
2918
+ return;
2919
+ }
2920
+ emit("click", event);
2921
+ };
2922
+ const __returned__ = { props, emit, bem, buttonColor, isDisabled, handleClick, get Icon() {
2923
+ return Icon;
2924
+ }, ImButton: im_button_default2, SvgIcon: svg_icon_default2 };
2925
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2926
+ return __returned__;
2927
+ }
2928
+ });
2929
+ function render22(_ctx, _cache, $props, $setup, $data, $options) {
2930
+ return openBlock(), createBlock($setup["ImButton"], {
2931
+ class: normalizeClass($setup.bem("", { loading: $setup.props.loading })),
2932
+ variant: "solid",
2933
+ color: $setup.buttonColor,
2934
+ size: "sm",
2935
+ square: "",
2936
+ disabled: $setup.isDisabled,
2937
+ "aria-label": $setup.props.loading ? "\u505C\u6B62" : "\u53D1\u9001",
2938
+ onClick: $setup.handleClick
2939
+ }, {
2940
+ default: withCtx(() => [
2941
+ renderSlot(_ctx.$slots, "default", {}, () => [
2942
+ createVNode($setup["SvgIcon"], {
2943
+ class: normalizeClass($setup.bem("icon"))
2944
+ }, {
2945
+ default: withCtx(() => [
2946
+ createVNode($setup["Icon"], {
2947
+ icon: $setup.props.loading ? "mdi:stop" : "mdi:arrow-up"
2948
+ }, null, 8, ["icon"])
2949
+ ]),
2950
+ _: 1
2951
+ /* STABLE */
2952
+ }, 8, ["class"])
2953
+ ])
2954
+ ]),
2955
+ _: 3
2956
+ /* FORWARDED */
2957
+ }, 8, ["class", "color", "disabled", "aria-label"]);
2958
+ }
2959
+
2960
+ // src/components/sender/components/sender-submit-button.vue
2961
+ sender_submit_button_default.render = render22;
2962
+ sender_submit_button_default.__file = "src/components/sender/components/sender-submit-button.vue";
2963
+ var sender_submit_button_default2 = sender_submit_button_default;
2964
+ var attachmentId = 0;
2965
+ function isFileTypeAccepted(file, accept) {
2966
+ if (!accept) return true;
2967
+ const acceptTypes = accept.split(",").map((t) => t.trim());
2968
+ return acceptTypes.some((type) => {
2969
+ if (type.startsWith(".")) {
2970
+ return file.name.toLowerCase().endsWith(type.toLowerCase());
2971
+ } else if (type.endsWith("/*")) {
2972
+ const baseType = type.slice(0, -2);
2973
+ return file.type.startsWith(baseType);
2974
+ } else {
2975
+ return file.type === type;
2976
+ }
2977
+ });
2978
+ }
2979
+ function useSender(options) {
2980
+ const { props, emit, modelValue, attachments, inputRef } = options;
2981
+ const canSubmit = computed(() => {
2982
+ const hasContent = modelValue.value.trim().length > 0;
2983
+ const hasAttachments = attachments.value.length > 0;
2984
+ return !props.disabled && !props.loading && (hasContent || hasAttachments);
2985
+ });
2986
+ const submit = () => {
2987
+ if (!canSubmit.value) return;
2988
+ const message = {
2989
+ content: modelValue.value.trim(),
2990
+ attachments: attachments.value.length > 0 ? [...attachments.value] : void 0
2991
+ };
2992
+ emit("submit", message);
2993
+ if (props.clearOnSubmit !== false) {
2994
+ modelValue.value = "";
2995
+ attachments.value = [];
2996
+ inputRef.value?.clear();
2997
+ }
2998
+ };
2999
+ const cancel = () => {
3000
+ emit("cancel");
3001
+ };
3002
+ const focus = () => {
3003
+ inputRef.value?.focus();
3004
+ };
3005
+ const blur = () => {
3006
+ inputRef.value?.blur();
3007
+ };
3008
+ const clear = () => {
3009
+ modelValue.value = "";
3010
+ attachments.value = [];
3011
+ inputRef.value?.clear();
3012
+ };
3013
+ const addFiles = (files) => {
3014
+ for (const file of files) {
3015
+ if (!isFileTypeAccepted(file, props.accept)) {
3016
+ emit("fileError", { type: "type", file, message: `\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ${file.type || file.name}` });
3017
+ continue;
3018
+ }
3019
+ if (props.maxSize && file.size > props.maxSize) {
3020
+ emit("fileError", { type: "size", file, message: `\u6587\u4EF6\u8FC7\u5927: ${file.name}` });
3021
+ continue;
3022
+ }
3023
+ if (props.maxFiles && attachments.value.length >= props.maxFiles) {
3024
+ emit("fileError", { type: "count", file, message: `\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 ${props.maxFiles} \u4E2A\u6587\u4EF6` });
3025
+ break;
3026
+ }
3027
+ const attachment = {
3028
+ id: `attachment-${++attachmentId}`,
3029
+ name: file.name,
3030
+ size: file.size,
3031
+ type: file.type,
3032
+ url: URL.createObjectURL(file),
3033
+ file
3034
+ };
3035
+ attachments.value.push(attachment);
3036
+ }
3037
+ };
3038
+ const removeAttachment = (id) => {
3039
+ const index = attachments.value.findIndex((a) => a.id === id);
3040
+ if (index !== -1) {
3041
+ const attachment = attachments.value[index];
3042
+ if (attachment.url?.startsWith("blob:")) {
3043
+ URL.revokeObjectURL(attachment.url);
3044
+ }
3045
+ attachments.value.splice(index, 1);
3046
+ }
3047
+ };
3048
+ return {
3049
+ canSubmit,
3050
+ submit,
3051
+ cancel,
3052
+ focus,
3053
+ blur,
3054
+ clear,
3055
+ addFiles,
3056
+ removeAttachment
3057
+ };
3058
+ }
3059
+
3060
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/sender/sender.vue?type=script
3061
+ var sender_default = /* @__PURE__ */ defineComponent({
3062
+ __name: "sender",
3063
+ props: /* @__PURE__ */ mergeModels({
3064
+ modelValue: { type: String, required: false },
3065
+ attachments: { type: Array, required: false },
3066
+ placeholder: { type: String, required: false, default: "Type something..." },
3067
+ disabled: { type: Boolean, required: false, default: false },
3068
+ bordered: { type: Boolean, required: false, default: true },
3069
+ loading: { type: Boolean, required: false, default: false },
3070
+ maxHeight: { type: [String, Number], required: false },
3071
+ submitType: { type: String, required: false, default: "enter" },
3072
+ clearOnSubmit: { type: Boolean, required: false, default: true },
3073
+ accept: { type: String, required: false },
3074
+ maxFiles: { type: Number, required: false },
3075
+ maxSize: { type: Number, required: false }
3076
+ }, {
3077
+ "modelValue": { type: String, ...{ default: "" } },
3078
+ "modelModifiers": {},
3079
+ "attachments": { type: Array, ...{ default: () => [] } },
3080
+ "attachmentsModifiers": {}
3081
+ }),
3082
+ emits: /* @__PURE__ */ mergeModels(["submit", "cancel", "fileError"], ["update:modelValue", "update:attachments"]),
3083
+ setup(__props, { expose: __expose, emit: __emit }) {
3084
+ const props = __props;
3085
+ const emit = __emit;
3086
+ const modelValue = useModel(__props, "modelValue");
3087
+ const attachments = useModel(__props, "attachments");
3088
+ const bem = createImBem("sender");
3089
+ const inputRef = ref();
3090
+ const {
3091
+ canSubmit,
3092
+ submit,
3093
+ cancel,
3094
+ focus,
3095
+ blur,
3096
+ clear,
3097
+ addFiles,
3098
+ removeAttachment
3099
+ } = useSender({
3100
+ props,
3101
+ emit,
3102
+ modelValue,
3103
+ attachments,
3104
+ inputRef
3105
+ });
3106
+ const handleInputSubmit = () => {
3107
+ submit();
3108
+ };
3109
+ const handleSubmitClick = () => {
3110
+ if (props.loading) {
3111
+ cancel();
3112
+ } else {
3113
+ submit();
3114
+ }
3115
+ };
3116
+ const handlePasteFile = (files) => {
3117
+ addFiles(files);
3118
+ };
3119
+ const fileConfig = computed(() => ({
3120
+ accept: props.accept,
3121
+ maxFiles: props.maxFiles,
3122
+ maxSize: props.maxSize
3123
+ }));
3124
+ provide("sender", {
3125
+ value: modelValue,
3126
+ attachments,
3127
+ disabled: toRef(props, "disabled"),
3128
+ loading: toRef(props, "loading"),
3129
+ canSubmit,
3130
+ submit,
3131
+ cancel,
3132
+ addFiles,
3133
+ removeAttachment,
3134
+ fileConfig: fileConfig.value
3135
+ });
3136
+ __expose({
3137
+ focus,
3138
+ blur,
3139
+ clear,
3140
+ submit,
3141
+ addFiles,
3142
+ removeAttachment
3143
+ });
3144
+ const __returned__ = { props, emit, modelValue, attachments, bem, inputRef, canSubmit, submit, cancel, focus, blur, clear, addFiles, removeAttachment, handleInputSubmit, handleSubmitClick, handlePasteFile, fileConfig, get SenderInput() {
3145
+ return sender_input_default2;
3146
+ }, SenderSubmitButton: sender_submit_button_default2 };
3147
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3148
+ return __returned__;
3149
+ }
3150
+ });
3151
+ function render23(_ctx, _cache, $props, $setup, $data, $options) {
3152
+ return openBlock(), createElementBlock(
3153
+ "div",
3154
+ {
3155
+ class: normalizeClass($setup.bem())
3156
+ },
3157
+ [
3158
+ createCommentVNode(" Header \u63D2\u69FD "),
3159
+ renderSlot(_ctx.$slots, "header"),
3160
+ createCommentVNode(" \u4E3B\u4F53\u5185\u5BB9\u533A "),
3161
+ createElementVNode(
3162
+ "div",
3163
+ {
3164
+ class: normalizeClass($setup.bem("box", {
3165
+ bordered: $setup.props.bordered,
3166
+ disabled: $setup.props.disabled
3167
+ }))
3168
+ },
3169
+ [
3170
+ createCommentVNode(" \u9644\u4EF6\u533A\u57DF\u63D2\u69FD "),
3171
+ renderSlot(_ctx.$slots, "attachments", {
3172
+ attachments: $setup.attachments,
3173
+ remove: $setup.removeAttachment
3174
+ }),
3175
+ createCommentVNode(" \u8F93\u5165\u6846 "),
3176
+ createVNode($setup["SenderInput"], {
3177
+ ref: "inputRef",
3178
+ modelValue: $setup.modelValue,
3179
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.modelValue = $event),
3180
+ class: normalizeClass($setup.bem("input")),
3181
+ placeholder: $setup.props.placeholder,
3182
+ disabled: $setup.props.disabled || $setup.props.loading,
3183
+ "max-height": $setup.props.maxHeight,
3184
+ "submit-type": $setup.props.submitType,
3185
+ onSubmit: $setup.handleInputSubmit,
3186
+ onPasteFile: $setup.handlePasteFile
3187
+ }, null, 8, ["modelValue", "class", "placeholder", "disabled", "max-height", "submit-type"]),
3188
+ createCommentVNode(" \u5DE5\u5177\u680F "),
3189
+ createElementVNode(
3190
+ "div",
3191
+ {
3192
+ class: normalizeClass($setup.bem("toolbar"))
3193
+ },
3194
+ [
3195
+ createCommentVNode(" \u5DE6\u4FA7\u64CD\u4F5C\u533A "),
3196
+ createElementVNode(
3197
+ "div",
3198
+ {
3199
+ class: normalizeClass($setup.bem("prefix"))
3200
+ },
3201
+ [
3202
+ renderSlot(_ctx.$slots, "prefix")
3203
+ ],
3204
+ 2
3205
+ /* CLASS */
3206
+ ),
3207
+ createCommentVNode(" \u53F3\u4FA7\u64CD\u4F5C\u533A "),
3208
+ createElementVNode(
3209
+ "div",
3210
+ {
3211
+ class: normalizeClass($setup.bem("suffix"))
3212
+ },
3213
+ [
3214
+ renderSlot(_ctx.$slots, "suffix"),
3215
+ createCommentVNode(" \u9ED8\u8BA4\u53D1\u9001\u6309\u94AE "),
3216
+ createVNode($setup["SenderSubmitButton"], {
3217
+ disabled: !$setup.canSubmit,
3218
+ loading: $setup.props.loading,
3219
+ onClick: $setup.handleSubmitClick
3220
+ }, null, 8, ["disabled", "loading"])
3221
+ ],
3222
+ 2
3223
+ /* CLASS */
3224
+ )
3225
+ ],
3226
+ 2
3227
+ /* CLASS */
3228
+ )
3229
+ ],
3230
+ 2
3231
+ /* CLASS */
3232
+ ),
3233
+ createCommentVNode(" Footer \u63D2\u69FD "),
3234
+ renderSlot(_ctx.$slots, "footer")
3235
+ ],
3236
+ 2
3237
+ /* CLASS */
3238
+ );
3239
+ }
3240
+
3241
+ // src/components/sender/sender.vue
3242
+ sender_default.render = render23;
3243
+ sender_default.__file = "src/components/sender/sender.vue";
3244
+ var sender_default2 = sender_default;
3245
+ var sender_action_button_default = /* @__PURE__ */ defineComponent({
3246
+ __name: "sender-action-button",
3247
+ props: {
3248
+ disabled: { type: Boolean, required: false, default: false },
3249
+ active: { type: Boolean, required: false, default: false },
3250
+ square: { type: Boolean, required: false, default: false },
3251
+ ariaLabel: { type: String, required: false }
3252
+ },
3253
+ emits: ["click"],
3254
+ setup(__props, { expose: __expose, emit: __emit }) {
3255
+ __expose();
3256
+ const props = __props;
3257
+ const emit = __emit;
3258
+ const bem = createImBem("sender-action-button");
3259
+ const handleClick = (event) => {
3260
+ if (!props.disabled) {
3261
+ emit("click", event);
3262
+ }
3263
+ };
3264
+ const __returned__ = { props, emit, bem, handleClick, ActionButton: action_button_default2 };
3265
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3266
+ return __returned__;
3267
+ }
3268
+ });
3269
+ function render24(_ctx, _cache, $props, $setup, $data, $options) {
3270
+ return openBlock(), createBlock($setup["ActionButton"], {
3271
+ class: normalizeClass([$setup.bem("", { active: $setup.props.active })]),
3272
+ intent: "action",
3273
+ size: "sm",
3274
+ square: $setup.props.square,
3275
+ disabled: $setup.props.disabled,
3276
+ "aria-label": $setup.props.ariaLabel,
3277
+ onClick: $setup.handleClick
3278
+ }, {
3279
+ icon: withCtx(() => [
3280
+ renderSlot(_ctx.$slots, "icon")
3281
+ ]),
3282
+ default: withCtx(() => [
3283
+ renderSlot(_ctx.$slots, "default")
3284
+ ]),
3285
+ _: 3
3286
+ /* FORWARDED */
3287
+ }, 8, ["class", "square", "disabled", "aria-label"]);
3288
+ }
3289
+
3290
+ // src/components/sender/components/sender-action-button.vue
3291
+ sender_action_button_default.render = render24;
3292
+ sender_action_button_default.__file = "src/components/sender/components/sender-action-button.vue";
3293
+ var sender_action_button_default2 = sender_action_button_default;
3294
+ var sender_file_button_default = /* @__PURE__ */ defineComponent({
3295
+ __name: "sender-file-button",
3296
+ props: {
3297
+ accept: { type: String, required: false },
3298
+ multiple: { type: Boolean, required: false },
3299
+ ariaLabel: { type: String, required: false }
3300
+ },
3301
+ setup(__props, { expose: __expose }) {
3302
+ __expose();
3303
+ const props = __props;
3304
+ const sender = inject("sender");
3305
+ const inputRef = ref();
3306
+ const handleClick = () => {
3307
+ inputRef.value?.click();
3308
+ };
3309
+ const handleChange = (event) => {
3310
+ const input = event.target;
3311
+ const files = Array.from(input.files || []);
3312
+ if (files.length > 0) {
3313
+ sender?.addFiles(files);
3314
+ }
3315
+ input.value = "";
3316
+ };
3317
+ const acceptValue = props.accept ?? sender?.fileConfig.accept;
3318
+ const __returned__ = { props, sender, inputRef, handleClick, handleChange, acceptValue, get Icon() {
3319
+ return Icon;
3320
+ }, get SvgIcon() {
3321
+ return svg_icon_default2;
3322
+ }, SenderActionButton: sender_action_button_default2 };
3323
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3324
+ return __returned__;
3325
+ }
3326
+ });
3327
+ var _hoisted_18 = ["accept", "multiple"];
3328
+ function render25(_ctx, _cache, $props, $setup, $data, $options) {
3329
+ return openBlock(), createElementBlock(
3330
+ Fragment,
3331
+ null,
3332
+ [
3333
+ createVNode($setup["SenderActionButton"], {
3334
+ square: "",
3335
+ "aria-label": $props.ariaLabel || "\u6DFB\u52A0\u6587\u4EF6",
3336
+ disabled: $setup.sender?.disabled.value,
3337
+ onClick: $setup.handleClick
3338
+ }, {
3339
+ icon: withCtx(() => [
3340
+ createVNode($setup["SvgIcon"], null, {
3341
+ default: withCtx(() => [
3342
+ createVNode($setup["Icon"], { icon: "mdi:attachment" })
3343
+ ]),
3344
+ _: 1
3345
+ /* STABLE */
3346
+ })
3347
+ ]),
3348
+ _: 1
3349
+ /* STABLE */
3350
+ }, 8, ["aria-label", "disabled"]),
3351
+ createElementVNode("input", {
3352
+ ref: "inputRef",
3353
+ type: "file",
3354
+ accept: $setup.acceptValue,
3355
+ multiple: $props.multiple !== false,
3356
+ style: { "display": "none" },
3357
+ onChange: $setup.handleChange
3358
+ }, null, 40, _hoisted_18)
3359
+ ],
3360
+ 64
3361
+ /* STABLE_FRAGMENT */
3362
+ );
3363
+ }
3364
+
3365
+ // src/components/sender/components/sender-file-button.vue
3366
+ sender_file_button_default.render = render25;
3367
+ sender_file_button_default.__file = "src/components/sender/components/sender-file-button.vue";
3368
+ var sender_attachments_default = /* @__PURE__ */ defineComponent({
3369
+ __name: "sender-attachments",
3370
+ props: {
3371
+ attachments: { type: Array, required: true }
3372
+ },
3373
+ emits: ["remove"],
3374
+ setup(__props, { expose: __expose, emit: __emit }) {
3375
+ __expose();
3376
+ const emit = __emit;
3377
+ const bem = createImBem("sender-attachments");
3378
+ const handleRemove = (id) => {
3379
+ emit("remove", id);
3380
+ };
3381
+ const __returned__ = { emit, bem, handleRemove, get FilePreview() {
3382
+ return file_preview_default2;
3383
+ } };
3384
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3385
+ return __returned__;
3386
+ }
3387
+ });
3388
+ function render26(_ctx, _cache, $props, $setup, $data, $options) {
3389
+ return $props.attachments.length > 0 ? (openBlock(), createElementBlock(
3390
+ "div",
3391
+ {
3392
+ key: 0,
3393
+ class: normalizeClass($setup.bem())
3394
+ },
3395
+ [
3396
+ (openBlock(true), createElementBlock(
3397
+ Fragment,
3398
+ null,
3399
+ renderList($props.attachments, (attachment) => {
3400
+ return openBlock(), createBlock($setup["FilePreview"], {
3401
+ key: attachment.id,
3402
+ file: {
3403
+ name: attachment.name,
3404
+ type: attachment.type,
3405
+ size: attachment.size,
3406
+ url: attachment.url
3407
+ },
3408
+ compact: "",
3409
+ removable: "",
3410
+ onRemove: ($event) => $setup.handleRemove(attachment.id)
3411
+ }, null, 8, ["file", "onRemove"]);
3412
+ }),
3413
+ 128
3414
+ /* KEYED_FRAGMENT */
3415
+ ))
3416
+ ],
3417
+ 2
3418
+ /* CLASS */
3419
+ )) : createCommentVNode("v-if", true);
3420
+ }
3421
+
3422
+ // src/components/sender/components/sender-attachments.vue
3423
+ sender_attachments_default.render = render26;
3424
+ sender_attachments_default.__file = "src/components/sender/components/sender-attachments.vue";
3425
+ var suggestion_item_default = /* @__PURE__ */ defineComponent({
3426
+ __name: "suggestion-item",
3427
+ props: {
3428
+ item: { type: Object, required: true }
3429
+ },
3430
+ emits: ["click"],
3431
+ setup(__props, { expose: __expose, emit: __emit }) {
3432
+ __expose();
3433
+ const props = __props;
3434
+ const emit = __emit;
3435
+ const bem = createImBem("suggestion-item");
3436
+ const handleClick = () => {
3437
+ if (!props.item.disabled) {
3438
+ emit("click", props.item);
3439
+ }
3440
+ };
3441
+ const __returned__ = { props, emit, bem, handleClick, get Icon() {
3442
+ return Icon;
3443
+ }, SvgIcon: svg_icon_default2 };
3444
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3445
+ return __returned__;
3446
+ }
3447
+ });
3448
+ var _hoisted_19 = ["disabled"];
3449
+ function render27(_ctx, _cache, $props, $setup, $data, $options) {
3450
+ return openBlock(), createElementBlock("button", {
3451
+ type: "button",
3452
+ class: normalizeClass([$setup.bem(), { [$setup.bem("", "disabled")]: $props.item.disabled }]),
3453
+ disabled: $props.item.disabled,
3454
+ onClick: $setup.handleClick
3455
+ }, [
3456
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3457
+ $props.item.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
3458
+ key: 0,
3459
+ class: normalizeClass($setup.bem("icon"))
3460
+ }, {
3461
+ default: withCtx(() => [
3462
+ createVNode($setup["Icon"], {
3463
+ icon: $props.item.icon
3464
+ }, null, 8, ["icon"])
3465
+ ]),
3466
+ _: 1
3467
+ /* STABLE */
3468
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
3469
+ ]),
3470
+ createElementVNode(
3471
+ "span",
3472
+ {
3473
+ class: normalizeClass($setup.bem("content"))
3474
+ },
3475
+ [
3476
+ createElementVNode(
3477
+ "span",
3478
+ {
3479
+ class: normalizeClass($setup.bem("label"))
3480
+ },
3481
+ toDisplayString($props.item.label),
3482
+ 3
3483
+ /* TEXT, CLASS */
3484
+ ),
3485
+ $props.item.description ? (openBlock(), createElementBlock(
3486
+ "span",
3487
+ {
3488
+ key: 0,
3489
+ class: normalizeClass($setup.bem("description"))
3490
+ },
3491
+ toDisplayString($props.item.description),
3492
+ 3
3493
+ /* TEXT, CLASS */
3494
+ )) : createCommentVNode("v-if", true)
3495
+ ],
3496
+ 2
3497
+ /* CLASS */
3498
+ )
3499
+ ], 10, _hoisted_19);
3500
+ }
3501
+
3502
+ // src/components/suggestion/suggestion-item.vue
3503
+ suggestion_item_default.render = render27;
3504
+ suggestion_item_default.__file = "src/components/suggestion/suggestion-item.vue";
3505
+ var suggestion_item_default2 = suggestion_item_default;
3506
+
3507
+ // sfc-script:/Users/yishuai/develop/ai/markdown/packages/chat-vue/src/components/suggestion/suggestion.vue?type=script
3508
+ var suggestion_default = /* @__PURE__ */ defineComponent({
3509
+ __name: "suggestion",
3510
+ props: {
3511
+ items: { type: Array, required: true },
3512
+ vertical: { type: Boolean, required: false, default: false }
3513
+ },
3514
+ emits: ["select"],
3515
+ setup(__props, { expose: __expose, emit: __emit }) {
3516
+ __expose();
3517
+ const emit = __emit;
3518
+ const bem = createImBem("suggestion");
3519
+ const handleItemClick = (item) => {
3520
+ emit("select", item);
3521
+ };
3522
+ const __returned__ = { emit, bem, handleItemClick, SuggestionItemVue: suggestion_item_default2 };
3523
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3524
+ return __returned__;
3525
+ }
3526
+ });
3527
+ function render28(_ctx, _cache, $props, $setup, $data, $options) {
3528
+ return openBlock(), createElementBlock(
3529
+ "div",
3530
+ {
3531
+ class: normalizeClass([$setup.bem(), { [$setup.bem("", "vertical")]: $props.vertical }])
3532
+ },
3533
+ [
3534
+ (openBlock(true), createElementBlock(
3535
+ Fragment,
3536
+ null,
3537
+ renderList($props.items, (item, index) => {
3538
+ return openBlock(), createBlock($setup["SuggestionItemVue"], {
3539
+ key: item.id ?? index,
3540
+ item,
3541
+ onClick: $setup.handleItemClick
3542
+ }, {
3543
+ icon: withCtx(() => [
3544
+ renderSlot(_ctx.$slots, "icon", { item })
3545
+ ]),
3546
+ _: 2
3547
+ /* DYNAMIC */
3548
+ }, 1032, ["item"]);
3549
+ }),
3550
+ 128
3551
+ /* KEYED_FRAGMENT */
3552
+ ))
3553
+ ],
3554
+ 2
3555
+ /* CLASS */
3556
+ );
3557
+ }
3558
+
3559
+ // src/components/suggestion/suggestion.vue
3560
+ suggestion_default.render = render28;
3561
+ suggestion_default.__file = "src/components/suggestion/suggestion.vue";
3562
+ var suggestion_default2 = suggestion_default;
3563
+ var error_message_default = /* @__PURE__ */ defineComponent({
3564
+ __name: "error-message",
3565
+ props: {
3566
+ title: { type: String, required: false },
3567
+ message: { type: String, required: true },
3568
+ type: { type: String, required: false, default: "unknown" },
3569
+ retryable: { type: Boolean, required: false, default: false },
3570
+ retryText: { type: String, required: false, default: "\u91CD\u8BD5" }
3571
+ },
3572
+ emits: ["retry"],
3573
+ setup(__props, { expose: __expose, emit: __emit }) {
3574
+ __expose();
3575
+ const props = __props;
3576
+ const emit = __emit;
3577
+ const bem = createImBem("error-message");
3578
+ const iconMap = {
3579
+ "network": "mdi:wifi-off",
3580
+ "rate-limit": "mdi:clock-alert-outline",
3581
+ "server": "mdi:server-off",
3582
+ "auth": "mdi:account-alert-outline",
3583
+ "unknown": "mdi:alert-circle-outline"
3584
+ };
3585
+ const icon = computed(() => iconMap[props.type]);
3586
+ const defaultTitleMap = {
3587
+ "network": "\u7F51\u7EDC\u9519\u8BEF",
3588
+ "rate-limit": "\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41",
3589
+ "server": "\u670D\u52A1\u5668\u9519\u8BEF",
3590
+ "auth": "\u8BA4\u8BC1\u5931\u8D25",
3591
+ "unknown": "\u51FA\u9519\u4E86"
3592
+ };
3593
+ const displayTitle = computed(() => props.title || defaultTitleMap[props.type]);
3594
+ const handleRetry = () => {
3595
+ emit("retry");
3596
+ };
3597
+ const __returned__ = { props, emit, bem, iconMap, icon, defaultTitleMap, displayTitle, handleRetry, get Icon() {
3598
+ return Icon;
3599
+ }, SvgIcon: svg_icon_default2 };
3600
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3601
+ return __returned__;
3602
+ }
3603
+ });
3604
+ function render29(_ctx, _cache, $props, $setup, $data, $options) {
3605
+ return openBlock(), createElementBlock(
3606
+ "div",
3607
+ {
3608
+ class: normalizeClass([$setup.bem(), $setup.bem("", $props.type)])
3609
+ },
3610
+ [
3611
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3612
+ createVNode($setup["SvgIcon"], {
3613
+ class: normalizeClass($setup.bem("icon"))
3614
+ }, {
3615
+ default: withCtx(() => [
3616
+ createVNode($setup["Icon"], { icon: $setup.icon }, null, 8, ["icon"])
3617
+ ]),
3618
+ _: 1
3619
+ /* STABLE */
3620
+ }, 8, ["class"])
3621
+ ]),
3622
+ createElementVNode(
3623
+ "div",
3624
+ {
3625
+ class: normalizeClass($setup.bem("content"))
3626
+ },
3627
+ [
3628
+ createElementVNode(
3629
+ "div",
3630
+ {
3631
+ class: normalizeClass($setup.bem("title"))
3632
+ },
3633
+ toDisplayString($setup.displayTitle),
3634
+ 3
3635
+ /* TEXT, CLASS */
3636
+ ),
3637
+ createElementVNode(
3638
+ "div",
3639
+ {
3640
+ class: normalizeClass($setup.bem("message"))
3641
+ },
3642
+ toDisplayString($props.message),
3643
+ 3
3644
+ /* TEXT, CLASS */
3645
+ )
3646
+ ],
3647
+ 2
3648
+ /* CLASS */
3649
+ ),
3650
+ $props.retryable ? (openBlock(), createElementBlock(
3651
+ "button",
3652
+ {
3653
+ key: 0,
3654
+ type: "button",
3655
+ class: normalizeClass($setup.bem("retry")),
3656
+ onClick: $setup.handleRetry
3657
+ },
3658
+ [
3659
+ createVNode($setup["SvgIcon"], {
3660
+ class: normalizeClass($setup.bem("retry-icon"))
3661
+ }, {
3662
+ default: withCtx(() => [
3663
+ createVNode($setup["Icon"], { icon: "mdi:refresh" })
3664
+ ]),
3665
+ _: 1
3666
+ /* STABLE */
3667
+ }, 8, ["class"]),
3668
+ createTextVNode(
3669
+ " " + toDisplayString($props.retryText),
3670
+ 1
3671
+ /* TEXT */
3672
+ )
3673
+ ],
3674
+ 2
3675
+ /* CLASS */
3676
+ )) : createCommentVNode("v-if", true)
3677
+ ],
3678
+ 2
3679
+ /* CLASS */
3680
+ );
3681
+ }
3682
+
3683
+ // src/components/error-message/error-message.vue
3684
+ error_message_default.render = render29;
3685
+ error_message_default.__file = "src/components/error-message/error-message.vue";
3686
+ var error_message_default2 = error_message_default;
3687
+ var welcome_default = /* @__PURE__ */ defineComponent({
3688
+ __name: "welcome",
3689
+ props: {
3690
+ title: { type: String, required: false, default: "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F" },
3691
+ description: { type: String, required: false },
3692
+ icon: { type: String, required: false, default: "mdi:robot-happy-outline" },
3693
+ suggestions: { type: Array, required: false },
3694
+ hint: { type: String, required: false }
3695
+ },
3696
+ emits: ["select"],
3697
+ setup(__props, { expose: __expose, emit: __emit }) {
3698
+ __expose();
3699
+ const emit = __emit;
3700
+ const bem = createImBem("welcome");
3701
+ const handleSelect = (item) => {
3702
+ emit("select", item);
3703
+ };
3704
+ const __returned__ = { emit, bem, handleSelect, get Icon() {
3705
+ return Icon;
3706
+ }, SvgIcon: svg_icon_default2, get Suggestion() {
3707
+ return suggestion_default2;
3708
+ } };
3709
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3710
+ return __returned__;
3711
+ }
3712
+ });
3713
+ function render30(_ctx, _cache, $props, $setup, $data, $options) {
3714
+ return openBlock(), createElementBlock(
3715
+ "div",
3716
+ {
3717
+ class: normalizeClass($setup.bem())
3718
+ },
3719
+ [
3720
+ createElementVNode(
3721
+ "div",
3722
+ {
3723
+ class: normalizeClass($setup.bem("header"))
3724
+ },
3725
+ [
3726
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3727
+ $props.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
3728
+ key: 0,
3729
+ class: normalizeClass($setup.bem("icon"))
3730
+ }, {
3731
+ default: withCtx(() => [
3732
+ createVNode($setup["Icon"], { icon: $props.icon }, null, 8, ["icon"])
3733
+ ]),
3734
+ _: 1
3735
+ /* STABLE */
3736
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
3737
+ ]),
3738
+ createElementVNode(
3739
+ "h2",
3740
+ {
3741
+ class: normalizeClass($setup.bem("title"))
3742
+ },
3743
+ toDisplayString($props.title),
3744
+ 3
3745
+ /* TEXT, CLASS */
3746
+ ),
3747
+ $props.description ? (openBlock(), createElementBlock(
3748
+ "p",
3749
+ {
3750
+ key: 0,
3751
+ class: normalizeClass($setup.bem("description"))
3752
+ },
3753
+ toDisplayString($props.description),
3754
+ 3
3755
+ /* TEXT, CLASS */
3756
+ )) : createCommentVNode("v-if", true)
3757
+ ],
3758
+ 2
3759
+ /* CLASS */
3760
+ ),
3761
+ $props.suggestions?.length ? (openBlock(), createElementBlock(
3762
+ "div",
3763
+ {
3764
+ key: 0,
3765
+ class: normalizeClass($setup.bem("suggestions"))
3766
+ },
3767
+ [
3768
+ renderSlot(_ctx.$slots, "suggestions", { items: $props.suggestions }, () => [
3769
+ createVNode($setup["Suggestion"], {
3770
+ items: $props.suggestions,
3771
+ onSelect: $setup.handleSelect
3772
+ }, null, 8, ["items"])
3773
+ ])
3774
+ ],
3775
+ 2
3776
+ /* CLASS */
3777
+ )) : createCommentVNode("v-if", true),
3778
+ $props.hint || _ctx.$slots.hint ? (openBlock(), createElementBlock(
3779
+ "div",
3780
+ {
3781
+ key: 1,
3782
+ class: normalizeClass($setup.bem("hint"))
3783
+ },
3784
+ [
3785
+ renderSlot(_ctx.$slots, "hint", {}, () => [
3786
+ createTextVNode(
3787
+ toDisplayString($props.hint),
3788
+ 1
3789
+ /* TEXT */
3790
+ )
3791
+ ])
3792
+ ],
3793
+ 2
3794
+ /* CLASS */
3795
+ )) : createCommentVNode("v-if", true)
3796
+ ],
3797
+ 2
3798
+ /* CLASS */
3799
+ );
3800
+ }
3801
+
3802
+ // src/components/welcome/welcome.vue
3803
+ welcome_default.render = render30;
3804
+ welcome_default.__file = "src/components/welcome/welcome.vue";
3805
+ var welcome_default2 = welcome_default;
3806
+
3807
+ export { chain_of_thought_default2 as chain_of_thought_default, chain_of_thought_step_default2 as chain_of_thought_step_default, error_message_default2 as error_message_default, file_preview_default2 as file_preview_default, im_button_default2 as im_button_default, im_tooltip_default2 as im_tooltip_default, message_action_copy_default2 as message_action_copy_default, message_action_default2 as message_action_default, message_action_feedback_default2 as message_action_feedback_default, message_actions_default2 as message_actions_default, message_bubble_default2 as message_bubble_default, part_renderer_default2 as part_renderer_default, provideUIAdapter, reasoning_message_default2 as reasoning_message_default, sender_action_button_default2 as sender_action_button_default, sender_default2 as sender_default, sender_input_default2 as sender_input_default, sender_submit_button_default2 as sender_submit_button_default, source_reference_default2 as source_reference_default, suggestion_default2 as suggestion_default, suggestion_item_default2 as suggestion_item_default, svg_icon_default2 as svg_icon_default, text_message_default2 as text_message_default, tool_call_default2 as tool_call_default, useCollapsible, useCopyAction, useSender, useUIAdapter, welcome_default2 as welcome_default };
3808
+ //# sourceMappingURL=chunk-X3YI3YOK.js.map
3809
+ //# sourceMappingURL=chunk-X3YI3YOK.js.map