@incremark/chat-vue 0.4.0-alpha.1 → 0.4.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,3867 @@
1
- import { provideUIAdapter } from './chunk-X3YI3YOK.js';
2
- export { chain_of_thought_default as ChainOfThought, chain_of_thought_step_default as ChainOfThoughtStep, error_message_default as ErrorMessage, file_preview_default as FilePreview, im_button_default as ImButton, im_tooltip_default as ImTooltip, message_action_default as MessageAction, message_action_copy_default as MessageActionCopy, message_action_feedback_default as MessageActionFeedback, message_actions_default as MessageActions, message_bubble_default as MessageBubble, part_renderer_default as PartRenderer, reasoning_message_default as ReasoningMessage, sender_default as Sender, sender_action_button_default as SenderActionButton, sender_input_default as SenderInput, sender_submit_button_default as SenderSubmitButton, source_reference_default as SourceReference, suggestion_default as Suggestion, suggestion_item_default as SuggestionItem, svg_icon_default as SvgIcon, text_message_default as TextMessage, tool_call_default as ToolCall, welcome_default as Welcome, provideUIAdapter, useCollapsible, useCopyAction, useSender, useUIAdapter } from './chunk-X3YI3YOK.js';
3
- import { defineComponent, renderSlot } from 'vue';
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, useTemplateRef, 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, AutoScrollContainer } 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';
4
14
 
15
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/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/towardsphd/tp-full/incremark/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/towardsphd/tp-full/incremark/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/towardsphd/tp-full/incremark/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/towardsphd/tp-full/incremark/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/towardsphd/tp-full/incremark/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
+ fillTheme: { type: String, required: false, default: "default" },
1978
+ loading: { type: Boolean, required: false, default: false },
1979
+ streaming: { type: Boolean, required: false, default: false }
1980
+ },
1981
+ setup(__props, { expose: __expose }) {
1982
+ __expose();
1983
+ const props = __props;
1984
+ const bem = createImBem("message-bubble");
1985
+ const rootClass = computed(() => [
1986
+ bem(),
1987
+ bem("", props.placement),
1988
+ bem("", props.width),
1989
+ props.loading && bem("", "loading"),
1990
+ props.streaming && bem("", "streaming")
1991
+ ]);
1992
+ const contentClass = computed(() => [
1993
+ bem("content"),
1994
+ bem("content", props.variant),
1995
+ bem("content", props.shape),
1996
+ props.fillTheme !== "default" && bem("content", props.fillTheme)
1997
+ ]);
1998
+ const __returned__ = { props, bem, rootClass, contentClass };
1999
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2000
+ return __returned__;
2001
+ }
2002
+ });
2003
+ function render13(_ctx, _cache, $props, $setup, $data, $options) {
2004
+ return openBlock(), createElementBlock(
2005
+ "div",
2006
+ {
2007
+ class: normalizeClass($setup.rootClass)
2008
+ },
2009
+ [
2010
+ createCommentVNode(" \u5934\u50CF\u63D2\u69FD "),
2011
+ _ctx.$slots.avatar ? (openBlock(), createElementBlock(
2012
+ "div",
2013
+ {
2014
+ key: 0,
2015
+ class: normalizeClass($setup.bem("avatar"))
2016
+ },
2017
+ [
2018
+ renderSlot(_ctx.$slots, "avatar")
2019
+ ],
2020
+ 2
2021
+ /* CLASS */
2022
+ )) : createCommentVNode("v-if", true),
2023
+ createCommentVNode(" \u4E3B\u4F53\u533A\u57DF "),
2024
+ createElementVNode(
2025
+ "div",
2026
+ {
2027
+ class: normalizeClass($setup.bem("main"))
2028
+ },
2029
+ [
2030
+ createCommentVNode(" \u5934\u90E8\u63D2\u69FD "),
2031
+ _ctx.$slots.header ? (openBlock(), createElementBlock(
2032
+ "div",
2033
+ {
2034
+ key: 0,
2035
+ class: normalizeClass($setup.bem("header"))
2036
+ },
2037
+ [
2038
+ renderSlot(_ctx.$slots, "header")
2039
+ ],
2040
+ 2
2041
+ /* CLASS */
2042
+ )) : createCommentVNode("v-if", true),
2043
+ createCommentVNode(" \u5185\u5BB9\u533A\u57DF "),
2044
+ createElementVNode(
2045
+ "div",
2046
+ {
2047
+ class: normalizeClass($setup.contentClass)
2048
+ },
2049
+ [
2050
+ renderSlot(_ctx.$slots, "default")
2051
+ ],
2052
+ 2
2053
+ /* CLASS */
2054
+ ),
2055
+ createCommentVNode(" \u5E95\u90E8\u63D2\u69FD "),
2056
+ _ctx.$slots.footer ? (openBlock(), createElementBlock(
2057
+ "div",
2058
+ {
2059
+ key: 1,
2060
+ class: normalizeClass($setup.bem("footer"))
2061
+ },
2062
+ [
2063
+ renderSlot(_ctx.$slots, "footer")
2064
+ ],
2065
+ 2
2066
+ /* CLASS */
2067
+ )) : createCommentVNode("v-if", true)
2068
+ ],
2069
+ 2
2070
+ /* CLASS */
2071
+ )
2072
+ ],
2073
+ 2
2074
+ /* CLASS */
2075
+ );
2076
+ }
2077
+
2078
+ // src/components/message-bubble/message-bubble.vue
2079
+ message_bubble_default.render = render13;
2080
+ message_bubble_default.__file = "src/components/message-bubble/message-bubble.vue";
2081
+ var message_bubble_default2 = message_bubble_default;
2082
+ var action_button_default = /* @__PURE__ */ defineComponent({
2083
+ __name: "action-button",
2084
+ props: {
2085
+ ariaLabel: { type: String, required: false },
2086
+ intent: { type: String, required: false, default: "action" },
2087
+ size: { type: String, required: false, default: "sm" },
2088
+ square: { type: Boolean, required: false, default: false },
2089
+ circle: { type: Boolean, required: false, default: false },
2090
+ disabled: { type: Boolean, required: false, default: false },
2091
+ loading: { type: Boolean, required: false, default: false },
2092
+ active: { type: Boolean, required: false, default: false }
2093
+ },
2094
+ emits: ["click"],
2095
+ setup(__props, { expose: __expose, emit: __emit }) {
2096
+ __expose();
2097
+ const props = __props;
2098
+ const emit = __emit;
2099
+ const { Button } = useUIAdapter();
2100
+ const buttonProps = computed(() => {
2101
+ const intentMap = {
2102
+ action: { variant: "ghost", color: "neutral" },
2103
+ primary: { variant: "solid", color: "primary" },
2104
+ secondary: { variant: "outline", color: "neutral" },
2105
+ danger: { variant: "solid", color: "error" }
2106
+ };
2107
+ const { variant, color } = intentMap[props.intent] || intentMap.action;
2108
+ return {
2109
+ variant,
2110
+ color,
2111
+ size: props.size,
2112
+ square: props.square,
2113
+ circle: props.circle,
2114
+ disabled: props.disabled,
2115
+ loading: props.loading,
2116
+ active: props.active,
2117
+ // 传递原始 options,供自定义 adapter 使用
2118
+ options: {
2119
+ intent: props.intent,
2120
+ size: props.size,
2121
+ square: props.square,
2122
+ circle: props.circle,
2123
+ disabled: props.disabled,
2124
+ loading: props.loading,
2125
+ active: props.active
2126
+ }
2127
+ };
2128
+ });
2129
+ const handleClick = (event) => {
2130
+ if (!props.disabled && !props.loading) {
2131
+ emit("click", event);
2132
+ }
2133
+ };
2134
+ const __returned__ = { props, emit, Button, buttonProps, handleClick };
2135
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2136
+ return __returned__;
2137
+ }
2138
+ });
2139
+ function render14(_ctx, _cache, $props, $setup, $data, $options) {
2140
+ return openBlock(), createBlock(resolveDynamicComponent($setup.Button), mergeProps($setup.buttonProps, {
2141
+ "aria-label": $props.ariaLabel,
2142
+ "aria-pressed": $setup.props.active,
2143
+ onClick: $setup.handleClick
2144
+ }), {
2145
+ icon: withCtx(() => [
2146
+ renderSlot(_ctx.$slots, "icon")
2147
+ ]),
2148
+ default: withCtx(() => [
2149
+ renderSlot(_ctx.$slots, "default")
2150
+ ]),
2151
+ _: 3
2152
+ /* FORWARDED */
2153
+ }, 16, ["aria-label", "aria-pressed"]);
2154
+ }
2155
+
2156
+ // src/components/base/action-button/action-button.vue
2157
+ action_button_default.render = render14;
2158
+ action_button_default.__file = "src/components/base/action-button/action-button.vue";
2159
+ var action_button_default2 = action_button_default;
2160
+
2161
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/packages/chat-vue/src/components/message-actions/message-action.vue?type=script
2162
+ var message_action_default = /* @__PURE__ */ defineComponent({
2163
+ __name: "message-action",
2164
+ props: {
2165
+ icon: { type: null, required: false },
2166
+ tooltip: { type: String, required: false },
2167
+ label: { type: String, required: false },
2168
+ loading: { type: Boolean, required: false, default: false },
2169
+ disabled: { type: Boolean, required: false, default: false }
2170
+ },
2171
+ emits: ["click"],
2172
+ setup(__props, { expose: __expose, emit: __emit }) {
2173
+ __expose();
2174
+ const props = __props;
2175
+ const emit = __emit;
2176
+ const bem = createImBem("message-action");
2177
+ const { Tooltip } = useUIAdapter();
2178
+ const rootClass = computed(() => [
2179
+ bem(),
2180
+ props.loading && bem("", "loading"),
2181
+ props.disabled && bem("", "disabled")
2182
+ ]);
2183
+ const handleClick = (event) => {
2184
+ if (!props.disabled && !props.loading) {
2185
+ emit("click", event);
2186
+ }
2187
+ };
2188
+ const __returned__ = { props, emit, bem, Tooltip, rootClass, handleClick, get ActionButton() {
2189
+ return action_button_default2;
2190
+ }, get SvgIcon() {
2191
+ return svg_icon_default2;
2192
+ } };
2193
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2194
+ return __returned__;
2195
+ }
2196
+ });
2197
+ function render15(_ctx, _cache, $props, $setup, $data, $options) {
2198
+ return openBlock(), createBlock(resolveDynamicComponent($setup.Tooltip), { content: $props.tooltip }, {
2199
+ default: withCtx(() => [
2200
+ createVNode($setup["ActionButton"], {
2201
+ class: normalizeClass($setup.rootClass),
2202
+ intent: "action",
2203
+ size: "sm",
2204
+ square: "",
2205
+ disabled: $props.disabled,
2206
+ loading: $props.loading,
2207
+ "aria-label": $props.label || $props.tooltip,
2208
+ onClick: $setup.handleClick
2209
+ }, {
2210
+ default: withCtx(() => [
2211
+ renderSlot(_ctx.$slots, "default", {}, () => [
2212
+ $props.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
2213
+ key: 0,
2214
+ class: normalizeClass($setup.bem("icon"))
2215
+ }, {
2216
+ default: withCtx(() => [
2217
+ (openBlock(), createBlock(resolveDynamicComponent($props.icon)))
2218
+ ]),
2219
+ _: 1
2220
+ /* STABLE */
2221
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
2222
+ ])
2223
+ ]),
2224
+ _: 3
2225
+ /* FORWARDED */
2226
+ }, 8, ["class", "disabled", "loading", "aria-label"])
2227
+ ]),
2228
+ _: 3
2229
+ /* FORWARDED */
2230
+ }, 8, ["content"]);
2231
+ }
2232
+
2233
+ // src/components/message-actions/message-action.vue
2234
+ message_action_default.render = render15;
2235
+ message_action_default.__file = "src/components/message-actions/message-action.vue";
2236
+ var message_action_default2 = message_action_default;
2237
+ function useCopyAction(text, options = {}) {
2238
+ const { resetDelay = 2e3 } = options;
2239
+ const copied = ref(false);
2240
+ const copy = async () => {
2241
+ try {
2242
+ await navigator.clipboard.writeText(text.value);
2243
+ copied.value = true;
2244
+ setTimeout(() => {
2245
+ copied.value = false;
2246
+ }, resetDelay);
2247
+ } catch (err) {
2248
+ console.error("Failed to copy text:", err);
2249
+ }
2250
+ };
2251
+ return { copied, copy };
2252
+ }
2253
+
2254
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/packages/chat-vue/src/components/message-actions/message-action-copy.vue?type=script
2255
+ var message_action_copy_default = /* @__PURE__ */ defineComponent({
2256
+ __name: "message-action-copy",
2257
+ props: {
2258
+ text: { type: String, required: true },
2259
+ copiedTooltip: { type: String, required: false, default: "\u5DF2\u590D\u5236" },
2260
+ tooltip: { type: String, required: false, default: "\u590D\u5236" }
2261
+ },
2262
+ setup(__props, { expose: __expose }) {
2263
+ __expose();
2264
+ const props = __props;
2265
+ const { icons } = useUIAdapter();
2266
+ const { copied, copy } = useCopyAction(toRef(props, "text"));
2267
+ const defaultCopyIcon = h(Icon, { icon: "ph:copy" });
2268
+ const defaultCheckIcon = h(Icon, { icon: "ph:check" });
2269
+ const currentIcon = computed(() => {
2270
+ if (copied.value) {
2271
+ return icons?.check || defaultCheckIcon;
2272
+ }
2273
+ return icons?.copy || defaultCopyIcon;
2274
+ });
2275
+ const currentTooltip = computed(() => {
2276
+ return copied.value ? props.copiedTooltip : props.tooltip;
2277
+ });
2278
+ const __returned__ = { props, icons, copied, copy, defaultCopyIcon, defaultCheckIcon, currentIcon, currentTooltip, MessageAction: message_action_default2 };
2279
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2280
+ return __returned__;
2281
+ }
2282
+ });
2283
+ function render16(_ctx, _cache, $props, $setup, $data, $options) {
2284
+ return openBlock(), createBlock($setup["MessageAction"], {
2285
+ icon: $setup.currentIcon,
2286
+ tooltip: $setup.currentTooltip,
2287
+ label: $setup.currentTooltip,
2288
+ onClick: $setup.copy
2289
+ }, null, 8, ["icon", "tooltip", "label", "onClick"]);
2290
+ }
2291
+
2292
+ // src/components/message-actions/message-action-copy.vue
2293
+ message_action_copy_default.render = render16;
2294
+ message_action_copy_default.__file = "src/components/message-actions/message-action-copy.vue";
2295
+ var message_action_copy_default2 = message_action_copy_default;
2296
+ var message_action_feedback_default = /* @__PURE__ */ defineComponent({
2297
+ __name: "message-action-feedback",
2298
+ props: {
2299
+ value: { type: String, required: false, default: "default" },
2300
+ likeTooltip: { type: String, required: false, default: "\u6709\u5E2E\u52A9" },
2301
+ dislikeTooltip: { type: String, required: false, default: "\u6CA1\u5E2E\u52A9" }
2302
+ },
2303
+ emits: ["update:value", "change"],
2304
+ setup(__props, { expose: __expose, emit: __emit }) {
2305
+ __expose();
2306
+ const props = __props;
2307
+ const emit = __emit;
2308
+ const bem = createImBem("message-action-feedback");
2309
+ const { icons } = useUIAdapter();
2310
+ const defaultThumbUp = h(Icon, { icon: "ph:thumbs-up" });
2311
+ const defaultThumbUpFill = h(Icon, { icon: "ph:thumbs-up-fill" });
2312
+ const defaultThumbDown = h(Icon, { icon: "ph:thumbs-down" });
2313
+ const defaultThumbDownFill = h(Icon, { icon: "ph:thumbs-down-fill" });
2314
+ const likeIcon = computed(() => {
2315
+ if (props.value === "like") {
2316
+ return icons?.thumbUpFilled || defaultThumbUpFill;
2317
+ }
2318
+ return icons?.thumbUp || defaultThumbUp;
2319
+ });
2320
+ const dislikeIcon = computed(() => {
2321
+ if (props.value === "dislike") {
2322
+ return icons?.thumbDownFilled || defaultThumbDownFill;
2323
+ }
2324
+ return icons?.thumbDown || defaultThumbDown;
2325
+ });
2326
+ const handleLike = () => {
2327
+ const newValue = props.value === "like" ? "default" : "like";
2328
+ emit("update:value", newValue);
2329
+ emit("change", newValue);
2330
+ };
2331
+ const handleDislike = () => {
2332
+ const newValue = props.value === "dislike" ? "default" : "dislike";
2333
+ emit("update:value", newValue);
2334
+ emit("change", newValue);
2335
+ };
2336
+ const showLike = computed(() => props.value === "default" || props.value === "like");
2337
+ const showDislike = computed(() => props.value === "default" || props.value === "dislike");
2338
+ const __returned__ = { props, emit, bem, icons, defaultThumbUp, defaultThumbUpFill, defaultThumbDown, defaultThumbDownFill, likeIcon, dislikeIcon, handleLike, handleDislike, showLike, showDislike, MessageAction: message_action_default2 };
2339
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2340
+ return __returned__;
2341
+ }
2342
+ });
2343
+ function render17(_ctx, _cache, $props, $setup, $data, $options) {
2344
+ return openBlock(), createElementBlock(
2345
+ "span",
2346
+ {
2347
+ class: normalizeClass($setup.bem())
2348
+ },
2349
+ [
2350
+ $setup.showLike ? (openBlock(), createBlock($setup["MessageAction"], {
2351
+ key: 0,
2352
+ icon: $setup.likeIcon,
2353
+ tooltip: $props.likeTooltip,
2354
+ label: $props.likeTooltip,
2355
+ class: normalizeClass([$setup.bem("like"), $props.value === "like" && $setup.bem("like", "active")]),
2356
+ onClick: $setup.handleLike
2357
+ }, null, 8, ["icon", "tooltip", "label", "class"])) : createCommentVNode("v-if", true),
2358
+ $setup.showDislike ? (openBlock(), createBlock($setup["MessageAction"], {
2359
+ key: 1,
2360
+ icon: $setup.dislikeIcon,
2361
+ tooltip: $props.dislikeTooltip,
2362
+ label: $props.dislikeTooltip,
2363
+ class: normalizeClass([$setup.bem("dislike"), $props.value === "dislike" && $setup.bem("dislike", "active")]),
2364
+ onClick: $setup.handleDislike
2365
+ }, null, 8, ["icon", "tooltip", "label", "class"])) : createCommentVNode("v-if", true)
2366
+ ],
2367
+ 2
2368
+ /* CLASS */
2369
+ );
2370
+ }
2371
+
2372
+ // src/components/message-actions/message-action-feedback.vue
2373
+ message_action_feedback_default.render = render17;
2374
+ message_action_feedback_default.__file = "src/components/message-actions/message-action-feedback.vue";
2375
+ var message_action_feedback_default2 = message_action_feedback_default;
2376
+ var im_dropdown_default = /* @__PURE__ */ defineComponent({
2377
+ __name: "im-dropdown",
2378
+ props: {
2379
+ items: { type: Array, required: true },
2380
+ placement: { type: null, required: false, default: "bottom-start" },
2381
+ offset: { type: Number, required: false, default: 4 },
2382
+ disabled: { type: Boolean, required: false, default: false },
2383
+ to: { type: [String, Function], required: false, skipCheck: true, default: "body" },
2384
+ teleportDisabled: { type: Boolean, required: false, default: false }
2385
+ },
2386
+ emits: ["select"],
2387
+ setup(__props, { expose: __expose, emit: __emit }) {
2388
+ __expose();
2389
+ const props = __props;
2390
+ const emit = __emit;
2391
+ const bem = createImBem("dropdown");
2392
+ const visible = ref(false);
2393
+ const handleSelect = (item) => {
2394
+ if (item.disabled || item.divider) return;
2395
+ emit("select", item);
2396
+ visible.value = false;
2397
+ };
2398
+ const __returned__ = { props, emit, bem, visible, handleSelect, get ImPopover() {
2399
+ return im_popover_default2;
2400
+ }, get SvgIcon() {
2401
+ return svg_icon_default2;
2402
+ } };
2403
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2404
+ return __returned__;
2405
+ }
2406
+ });
2407
+ var _hoisted_17 = ["onClick"];
2408
+ function render18(_ctx, _cache, $props, $setup, $data, $options) {
2409
+ return openBlock(), createBlock($setup["ImPopover"], {
2410
+ visible: $setup.visible,
2411
+ "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => $setup.visible = $event),
2412
+ trigger: "click",
2413
+ placement: $props.placement,
2414
+ offset: $props.offset,
2415
+ disabled: $props.disabled,
2416
+ to: $props.to,
2417
+ "teleport-disabled": $props.teleportDisabled
2418
+ }, {
2419
+ content: withCtx(() => [
2420
+ createElementVNode(
2421
+ "div",
2422
+ {
2423
+ class: normalizeClass($setup.bem("menu"))
2424
+ },
2425
+ [
2426
+ (openBlock(true), createElementBlock(
2427
+ Fragment,
2428
+ null,
2429
+ renderList($props.items, (item) => {
2430
+ return openBlock(), createElementBlock(
2431
+ Fragment,
2432
+ {
2433
+ key: item.key
2434
+ },
2435
+ [
2436
+ item.divider ? (openBlock(), createElementBlock(
2437
+ "div",
2438
+ {
2439
+ key: 0,
2440
+ class: normalizeClass($setup.bem("divider"))
2441
+ },
2442
+ null,
2443
+ 2
2444
+ /* CLASS */
2445
+ )) : (openBlock(), createElementBlock("div", {
2446
+ key: 1,
2447
+ class: normalizeClass([$setup.bem("item"), { [$setup.bem("item", "disabled")]: item.disabled }]),
2448
+ onClick: ($event) => $setup.handleSelect(item)
2449
+ }, [
2450
+ item.icon ? (openBlock(), createElementBlock(
2451
+ "span",
2452
+ {
2453
+ key: 0,
2454
+ class: normalizeClass($setup.bem("icon"))
2455
+ },
2456
+ [
2457
+ createVNode(
2458
+ $setup["SvgIcon"],
2459
+ null,
2460
+ {
2461
+ default: withCtx(() => [
2462
+ (openBlock(), createBlock(resolveDynamicComponent(item.icon)))
2463
+ ]),
2464
+ _: 2
2465
+ /* DYNAMIC */
2466
+ },
2467
+ 1024
2468
+ /* DYNAMIC_SLOTS */
2469
+ )
2470
+ ],
2471
+ 2
2472
+ /* CLASS */
2473
+ )) : createCommentVNode("v-if", true),
2474
+ createElementVNode(
2475
+ "span",
2476
+ {
2477
+ class: normalizeClass($setup.bem("label"))
2478
+ },
2479
+ toDisplayString(item.label),
2480
+ 3
2481
+ /* TEXT, CLASS */
2482
+ )
2483
+ ], 10, _hoisted_17))
2484
+ ],
2485
+ 64
2486
+ /* STABLE_FRAGMENT */
2487
+ );
2488
+ }),
2489
+ 128
2490
+ /* KEYED_FRAGMENT */
2491
+ ))
2492
+ ],
2493
+ 2
2494
+ /* CLASS */
2495
+ )
2496
+ ]),
2497
+ default: withCtx(() => [
2498
+ renderSlot(_ctx.$slots, "default")
2499
+ ]),
2500
+ _: 3
2501
+ /* FORWARDED */
2502
+ }, 8, ["visible", "placement", "offset", "disabled", "to", "teleport-disabled"]);
2503
+ }
2504
+
2505
+ // src/components/base/im-dropdown/im-dropdown.vue
2506
+ im_dropdown_default.render = render18;
2507
+ im_dropdown_default.__file = "src/components/base/im-dropdown/im-dropdown.vue";
2508
+ var im_dropdown_default2 = im_dropdown_default;
2509
+ var message_action_more_default = /* @__PURE__ */ defineComponent({
2510
+ __name: "message-action-more",
2511
+ props: {
2512
+ items: { type: Array, required: true },
2513
+ tooltip: { type: String, required: false, default: "\u66F4\u591A" }
2514
+ },
2515
+ emits: ["select"],
2516
+ setup(__props, { expose: __expose, emit: __emit }) {
2517
+ __expose();
2518
+ const props = __props;
2519
+ const emit = __emit;
2520
+ const bem = createImBem("message-action-more");
2521
+ const { Tooltip } = useUIAdapter();
2522
+ const defaultMoreIcon = h(Icon, { icon: "ph:dots-three" });
2523
+ const dropdownItems = computed(() => {
2524
+ return props.items.map((item) => ({
2525
+ key: item.key,
2526
+ label: item.label,
2527
+ icon: item.icon,
2528
+ disabled: item.disabled,
2529
+ divider: item.divider
2530
+ }));
2531
+ });
2532
+ const handleSelect = (dropdownItem) => {
2533
+ const item = props.items.find((i) => i.key === dropdownItem.key);
2534
+ if (item) {
2535
+ emit("select", item);
2536
+ }
2537
+ };
2538
+ const __returned__ = { props, emit, bem, Tooltip, defaultMoreIcon, dropdownItems, handleSelect, get ImDropdown() {
2539
+ return im_dropdown_default2;
2540
+ }, get ActionButton() {
2541
+ return action_button_default2;
2542
+ }, get SvgIcon() {
2543
+ return svg_icon_default2;
2544
+ } };
2545
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2546
+ return __returned__;
2547
+ }
2548
+ });
2549
+ function render19(_ctx, _cache, $props, $setup, $data, $options) {
2550
+ return openBlock(), createBlock($setup["ImDropdown"], {
2551
+ items: $setup.dropdownItems,
2552
+ placement: "bottom-end",
2553
+ onSelect: $setup.handleSelect
2554
+ }, {
2555
+ default: withCtx(() => [
2556
+ (openBlock(), createBlock(resolveDynamicComponent($setup.Tooltip), { content: $props.tooltip }, {
2557
+ default: withCtx(() => [
2558
+ createVNode($setup["ActionButton"], {
2559
+ class: normalizeClass($setup.bem()),
2560
+ intent: "action",
2561
+ size: "sm",
2562
+ square: "",
2563
+ "aria-label": $props.tooltip
2564
+ }, {
2565
+ default: withCtx(() => [
2566
+ createVNode($setup["SvgIcon"], {
2567
+ class: normalizeClass($setup.bem("icon"))
2568
+ }, {
2569
+ default: withCtx(() => [
2570
+ (openBlock(), createBlock(resolveDynamicComponent($setup.defaultMoreIcon)))
2571
+ ]),
2572
+ _: 1
2573
+ /* STABLE */
2574
+ }, 8, ["class"])
2575
+ ]),
2576
+ _: 1
2577
+ /* STABLE */
2578
+ }, 8, ["class", "aria-label"])
2579
+ ]),
2580
+ _: 1
2581
+ /* STABLE */
2582
+ }, 8, ["content"]))
2583
+ ]),
2584
+ _: 1
2585
+ /* STABLE */
2586
+ }, 8, ["items"]);
2587
+ }
2588
+
2589
+ // src/components/message-actions/message-action-more.vue
2590
+ message_action_more_default.render = render19;
2591
+ message_action_more_default.__file = "src/components/message-actions/message-action-more.vue";
2592
+ var message_action_more_default2 = message_action_more_default;
2593
+
2594
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/packages/chat-vue/src/components/message-actions/message-actions.vue?type=script
2595
+ var message_actions_default = /* @__PURE__ */ defineComponent({
2596
+ __name: "message-actions",
2597
+ props: {
2598
+ variant: { type: String, required: false, default: "borderless" },
2599
+ actions: { type: Array, required: false },
2600
+ maxVisible: { type: Number, required: false, default: Infinity },
2601
+ feedbackValue: { type: String, required: false }
2602
+ },
2603
+ emits: ["action", "update:feedbackValue"],
2604
+ setup(__props, { expose: __expose, emit: __emit }) {
2605
+ __expose();
2606
+ const props = __props;
2607
+ const emit = __emit;
2608
+ const slots = useSlots();
2609
+ const bem = createImBem("message-actions");
2610
+ const rootClass = computed(() => [
2611
+ bem(),
2612
+ bem("", props.variant)
2613
+ ]);
2614
+ const useConfigMode = computed(() => {
2615
+ return props.actions && props.actions.length > 0 && !slots.default;
2616
+ });
2617
+ const visibleActions = computed(() => {
2618
+ if (!props.actions) return [];
2619
+ return props.actions.slice(0, props.maxVisible);
2620
+ });
2621
+ const moreActions = computed(() => {
2622
+ if (!props.actions || props.actions.length <= props.maxVisible) return [];
2623
+ return props.actions.slice(props.maxVisible).map((item) => ({
2624
+ key: item.key,
2625
+ label: item.label || item.tooltip || item.key,
2626
+ icon: item.icon,
2627
+ disabled: item.disabled
2628
+ }));
2629
+ });
2630
+ const handleAction = (item) => {
2631
+ if (item.handler) {
2632
+ item.handler();
2633
+ }
2634
+ emit("action", item);
2635
+ };
2636
+ const handleMoreSelect = (moreItem) => {
2637
+ const item = props.actions?.find((a) => a.key === moreItem.key);
2638
+ if (item) {
2639
+ handleAction(item);
2640
+ }
2641
+ };
2642
+ const handleFeedbackChange = (value) => {
2643
+ emit("update:feedbackValue", value);
2644
+ };
2645
+ 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 };
2646
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2647
+ return __returned__;
2648
+ }
2649
+ });
2650
+ function render20(_ctx, _cache, $props, $setup, $data, $options) {
2651
+ return openBlock(), createElementBlock(
2652
+ "div",
2653
+ {
2654
+ class: normalizeClass($setup.rootClass)
2655
+ },
2656
+ [
2657
+ createCommentVNode(" \u914D\u7F6E\u65B9\u5F0F "),
2658
+ $setup.useConfigMode ? (openBlock(), createElementBlock(
2659
+ Fragment,
2660
+ { key: 0 },
2661
+ [
2662
+ (openBlock(true), createElementBlock(
2663
+ Fragment,
2664
+ null,
2665
+ renderList($setup.visibleActions, (item) => {
2666
+ return openBlock(), createElementBlock(
2667
+ Fragment,
2668
+ {
2669
+ key: item.key
2670
+ },
2671
+ [
2672
+ createCommentVNode(" \u590D\u5236\u7C7B\u578B "),
2673
+ item.type === "copy" && item.copyText ? (openBlock(), createBlock($setup["MessageActionCopy"], {
2674
+ key: 0,
2675
+ text: item.copyText,
2676
+ tooltip: item.tooltip
2677
+ }, null, 8, ["text", "tooltip"])) : item.type === "feedback" ? (openBlock(), createElementBlock(
2678
+ Fragment,
2679
+ { key: 1 },
2680
+ [
2681
+ createCommentVNode(" \u53CD\u9988\u7C7B\u578B "),
2682
+ createVNode($setup["MessageActionFeedback"], {
2683
+ value: $props.feedbackValue,
2684
+ "onUpdate:value": $setup.handleFeedbackChange
2685
+ }, null, 8, ["value"])
2686
+ ],
2687
+ 2112
2688
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2689
+ )) : (openBlock(), createElementBlock(
2690
+ Fragment,
2691
+ { key: 2 },
2692
+ [
2693
+ createCommentVNode(" \u81EA\u5B9A\u4E49\u7C7B\u578B "),
2694
+ createVNode($setup["MessageAction"], {
2695
+ icon: item.icon,
2696
+ tooltip: item.tooltip,
2697
+ disabled: item.disabled,
2698
+ onClick: ($event) => $setup.handleAction(item)
2699
+ }, null, 8, ["icon", "tooltip", "disabled", "onClick"])
2700
+ ],
2701
+ 2112
2702
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2703
+ ))
2704
+ ],
2705
+ 64
2706
+ /* STABLE_FRAGMENT */
2707
+ );
2708
+ }),
2709
+ 128
2710
+ /* KEYED_FRAGMENT */
2711
+ )),
2712
+ createCommentVNode(" \u66F4\u591A\u64CD\u4F5C "),
2713
+ $setup.moreActions.length > 0 ? (openBlock(), createBlock($setup["MessageActionMore"], {
2714
+ key: 0,
2715
+ items: $setup.moreActions,
2716
+ onSelect: $setup.handleMoreSelect
2717
+ }, null, 8, ["items"])) : createCommentVNode("v-if", true)
2718
+ ],
2719
+ 64
2720
+ /* STABLE_FRAGMENT */
2721
+ )) : (openBlock(), createElementBlock(
2722
+ Fragment,
2723
+ { key: 1 },
2724
+ [
2725
+ createCommentVNode(" slot \u65B9\u5F0F "),
2726
+ renderSlot(_ctx.$slots, "default")
2727
+ ],
2728
+ 2112
2729
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
2730
+ ))
2731
+ ],
2732
+ 2
2733
+ /* CLASS */
2734
+ );
2735
+ }
2736
+
2737
+ // src/components/message-actions/message-actions.vue
2738
+ message_actions_default.render = render20;
2739
+ message_actions_default.__file = "src/components/message-actions/message-actions.vue";
2740
+ var message_actions_default2 = message_actions_default;
2741
+ var defaultPlaceholder = "Type something...";
2742
+ var sender_input_default = /* @__PURE__ */ defineComponent({
2743
+ __name: "sender-input",
2744
+ props: /* @__PURE__ */ mergeModels({
2745
+ placeholder: { type: String, required: false, default: defaultPlaceholder },
2746
+ disabled: { type: Boolean, required: false, default: false },
2747
+ bordered: { type: Boolean, required: false, default: false },
2748
+ maxHeight: { type: [String, Number], required: false },
2749
+ submitType: { type: String, required: false, default: "enter" },
2750
+ extensions: { type: Array, required: false, default: () => [] }
2751
+ }, {
2752
+ "modelValue": { type: String, ...{ default: "" } },
2753
+ "modelModifiers": {}
2754
+ }),
2755
+ emits: /* @__PURE__ */ mergeModels(["focus", "blur", "change", "paste", "pasteFile", "submit"], ["update:modelValue"]),
2756
+ setup(__props, { expose: __expose, emit: __emit }) {
2757
+ const props = __props;
2758
+ const emit = __emit;
2759
+ const modelValue = useModel(__props, "modelValue");
2760
+ const bem = createImBem("sender-input");
2761
+ const modelValueChangeByEditor = ref(false);
2762
+ const setContentByModelValue = ref(false);
2763
+ const handleKeyDown = (event) => {
2764
+ if (props.disabled) return false;
2765
+ const isEnter = event.key === "Enter";
2766
+ const hasShift = event.shiftKey;
2767
+ const hasMeta = event.metaKey || event.ctrlKey;
2768
+ if (!isEnter) return false;
2769
+ if (hasMeta) {
2770
+ event.preventDefault();
2771
+ emit("submit");
2772
+ return true;
2773
+ }
2774
+ if (props.submitType === "enter" && !hasShift) {
2775
+ event.preventDefault();
2776
+ emit("submit");
2777
+ return true;
2778
+ } else if (props.submitType === "shiftEnter" && hasShift) {
2779
+ event.preventDefault();
2780
+ emit("submit");
2781
+ return true;
2782
+ }
2783
+ return false;
2784
+ };
2785
+ const editor = useEditor({
2786
+ editorProps: {
2787
+ editable: () => !props.disabled,
2788
+ attributes: {
2789
+ class: bem("editor")
2790
+ },
2791
+ handleKeyDown: (_view, event) => {
2792
+ return handleKeyDown(event);
2793
+ },
2794
+ handlePaste: (_view, event) => {
2795
+ const files = Array.from(event.clipboardData?.files || []);
2796
+ if (files.length > 0) {
2797
+ emit("pasteFile", files);
2798
+ return true;
2799
+ }
2800
+ return false;
2801
+ }
2802
+ },
2803
+ content: modelValue.value,
2804
+ extensions: [
2805
+ Markdown,
2806
+ Document,
2807
+ Paragraph.configure(),
2808
+ Text,
2809
+ Placeholder.configure({
2810
+ placeholder: () => props.placeholder || defaultPlaceholder,
2811
+ showOnlyWhenEditable: false
2812
+ }),
2813
+ UndoRedo,
2814
+ ...props.extensions || []
2815
+ ],
2816
+ onFocus: (options) => {
2817
+ emit("focus", options.event);
2818
+ },
2819
+ onBlur: (options) => {
2820
+ emit("blur", options.event);
2821
+ },
2822
+ onUpdate: (options) => {
2823
+ if (setContentByModelValue.value) {
2824
+ setContentByModelValue.value = false;
2825
+ return;
2826
+ }
2827
+ const markdownContent = options.editor.getMarkdown().trim();
2828
+ if (markdownContent === modelValue.value) {
2829
+ return;
2830
+ }
2831
+ modelValueChangeByEditor.value = true;
2832
+ modelValue.value = markdownContent;
2833
+ }
2834
+ });
2835
+ watch(() => props.placeholder, (newPlaceholder) => {
2836
+ const newPlaceholderValue = newPlaceholder || defaultPlaceholder;
2837
+ editor.value?.commands.setMeta("placeholder", newPlaceholderValue);
2838
+ });
2839
+ watch(modelValue, (newVal) => {
2840
+ if (modelValueChangeByEditor.value) {
2841
+ modelValueChangeByEditor.value = false;
2842
+ return;
2843
+ }
2844
+ const newContent = newVal ?? "";
2845
+ setContentByModelValue.value = true;
2846
+ editor.value?.commands.setContent(newContent);
2847
+ });
2848
+ watch(() => props.disabled, (newDisable) => {
2849
+ editor.value?.setEditable(!newDisable);
2850
+ });
2851
+ const maxHeightValue = computed(() => {
2852
+ if (!props.maxHeight) return void 0;
2853
+ return typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight;
2854
+ });
2855
+ const handleClick = () => {
2856
+ nextTick(() => {
2857
+ if (editor.value?.isEditable && !editor.value.isFocused) {
2858
+ editor.value?.commands.focus();
2859
+ }
2860
+ });
2861
+ };
2862
+ const focus = () => {
2863
+ editor.value?.commands.focus();
2864
+ };
2865
+ const blur = () => {
2866
+ editor.value?.commands.blur();
2867
+ };
2868
+ const clear = () => {
2869
+ editor.value?.commands.clearContent();
2870
+ modelValue.value = "";
2871
+ };
2872
+ const insert = (text) => {
2873
+ editor.value?.commands.insertContent(text);
2874
+ };
2875
+ const getEditor = () => editor.value;
2876
+ __expose({
2877
+ focus,
2878
+ blur,
2879
+ clear,
2880
+ insert,
2881
+ getEditor
2882
+ });
2883
+ const __returned__ = { defaultPlaceholder, props, emit, modelValue, bem, modelValueChangeByEditor, setContentByModelValue, handleKeyDown, editor, maxHeightValue, handleClick, focus, blur, clear, insert, getEditor, get EditorContent() {
2884
+ return EditorContent;
2885
+ } };
2886
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2887
+ return __returned__;
2888
+ }
2889
+ });
2890
+ function render21(_ctx, _cache, $props, $setup, $data, $options) {
2891
+ return openBlock(), createBlock($setup["EditorContent"], {
2892
+ class: normalizeClass($setup.bem("", {
2893
+ bordered: $setup.props.bordered,
2894
+ disabled: $setup.props.disabled
2895
+ })),
2896
+ style: normalizeStyle({
2897
+ "--im-sender-input-max-height": $setup.maxHeightValue
2898
+ }),
2899
+ editor: $setup.editor,
2900
+ onClick: $setup.handleClick
2901
+ }, null, 8, ["class", "style", "editor"]);
2902
+ }
2903
+
2904
+ // src/components/sender-input/sender-input.vue
2905
+ sender_input_default.render = render21;
2906
+ sender_input_default.__file = "src/components/sender-input/sender-input.vue";
2907
+ var sender_input_default2 = sender_input_default;
2908
+ var sender_submit_button_default = /* @__PURE__ */ defineComponent({
2909
+ __name: "sender-submit-button",
2910
+ props: {
2911
+ disabled: { type: Boolean, required: false, default: false },
2912
+ loading: { type: Boolean, required: false, default: false }
2913
+ },
2914
+ emits: ["click"],
2915
+ setup(__props, { expose: __expose, emit: __emit }) {
2916
+ __expose();
2917
+ const props = __props;
2918
+ const emit = __emit;
2919
+ const bem = createImBem("sender-submit-button");
2920
+ const buttonColor = computed(() => props.loading ? "neutral" : "primary");
2921
+ const isDisabled = computed(() => props.disabled && !props.loading);
2922
+ const handleClick = (event) => {
2923
+ if (!props.loading && props.disabled) {
2924
+ return;
2925
+ }
2926
+ emit("click", event);
2927
+ };
2928
+ const __returned__ = { props, emit, bem, buttonColor, isDisabled, handleClick, get Icon() {
2929
+ return Icon;
2930
+ }, ImButton: im_button_default2, SvgIcon: svg_icon_default2 };
2931
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2932
+ return __returned__;
2933
+ }
2934
+ });
2935
+ function render22(_ctx, _cache, $props, $setup, $data, $options) {
2936
+ return openBlock(), createBlock($setup["ImButton"], {
2937
+ class: normalizeClass($setup.bem("", { loading: $setup.props.loading })),
2938
+ variant: "solid",
2939
+ color: $setup.buttonColor,
2940
+ size: "sm",
2941
+ square: "",
2942
+ disabled: $setup.isDisabled,
2943
+ "aria-label": $setup.props.loading ? "\u505C\u6B62" : "\u53D1\u9001",
2944
+ onClick: $setup.handleClick
2945
+ }, {
2946
+ default: withCtx(() => [
2947
+ renderSlot(_ctx.$slots, "default", {}, () => [
2948
+ createVNode($setup["SvgIcon"], {
2949
+ class: normalizeClass($setup.bem("icon"))
2950
+ }, {
2951
+ default: withCtx(() => [
2952
+ createVNode($setup["Icon"], {
2953
+ icon: $setup.props.loading ? "mdi:stop" : "mdi:arrow-up"
2954
+ }, null, 8, ["icon"])
2955
+ ]),
2956
+ _: 1
2957
+ /* STABLE */
2958
+ }, 8, ["class"])
2959
+ ])
2960
+ ]),
2961
+ _: 3
2962
+ /* FORWARDED */
2963
+ }, 8, ["class", "color", "disabled", "aria-label"]);
2964
+ }
2965
+
2966
+ // src/components/sender/components/sender-submit-button.vue
2967
+ sender_submit_button_default.render = render22;
2968
+ sender_submit_button_default.__file = "src/components/sender/components/sender-submit-button.vue";
2969
+ var sender_submit_button_default2 = sender_submit_button_default;
2970
+ var attachmentId = 0;
2971
+ function isFileTypeAccepted(file, accept) {
2972
+ if (!accept) return true;
2973
+ const acceptTypes = accept.split(",").map((t) => t.trim());
2974
+ return acceptTypes.some((type) => {
2975
+ if (type.startsWith(".")) {
2976
+ return file.name.toLowerCase().endsWith(type.toLowerCase());
2977
+ } else if (type.endsWith("/*")) {
2978
+ const baseType = type.slice(0, -2);
2979
+ return file.type.startsWith(baseType);
2980
+ } else {
2981
+ return file.type === type;
2982
+ }
2983
+ });
2984
+ }
2985
+ function useSender(options) {
2986
+ const { props, emit, modelValue, attachments, inputRef } = options;
2987
+ const canSubmit = computed(() => {
2988
+ const hasContent = modelValue.value.trim().length > 0;
2989
+ const hasAttachments = attachments.value.length > 0;
2990
+ return !props.disabled && !props.loading && (hasContent || hasAttachments);
2991
+ });
2992
+ const submit = () => {
2993
+ if (!canSubmit.value) return;
2994
+ const message = {
2995
+ content: modelValue.value.trim(),
2996
+ attachments: attachments.value.length > 0 ? [...attachments.value] : void 0
2997
+ };
2998
+ emit("submit", message);
2999
+ if (props.clearOnSubmit !== false) {
3000
+ modelValue.value = "";
3001
+ attachments.value = [];
3002
+ inputRef.value?.clear();
3003
+ }
3004
+ };
3005
+ const cancel = () => {
3006
+ emit("cancel");
3007
+ };
3008
+ const focus = () => {
3009
+ inputRef.value?.focus();
3010
+ };
3011
+ const blur = () => {
3012
+ inputRef.value?.blur();
3013
+ };
3014
+ const clear = () => {
3015
+ modelValue.value = "";
3016
+ attachments.value = [];
3017
+ inputRef.value?.clear();
3018
+ };
3019
+ const addFiles = (files) => {
3020
+ for (const file of files) {
3021
+ if (!isFileTypeAccepted(file, props.accept)) {
3022
+ emit("fileError", { type: "type", file, message: `\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ${file.type || file.name}` });
3023
+ continue;
3024
+ }
3025
+ if (props.maxSize && file.size > props.maxSize) {
3026
+ emit("fileError", { type: "size", file, message: `\u6587\u4EF6\u8FC7\u5927: ${file.name}` });
3027
+ continue;
3028
+ }
3029
+ if (props.maxFiles && attachments.value.length >= props.maxFiles) {
3030
+ emit("fileError", { type: "count", file, message: `\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 ${props.maxFiles} \u4E2A\u6587\u4EF6` });
3031
+ break;
3032
+ }
3033
+ const attachment = {
3034
+ id: `attachment-${++attachmentId}`,
3035
+ name: file.name,
3036
+ size: file.size,
3037
+ type: file.type,
3038
+ url: URL.createObjectURL(file),
3039
+ file
3040
+ };
3041
+ attachments.value.push(attachment);
3042
+ }
3043
+ };
3044
+ const removeAttachment = (id) => {
3045
+ const index = attachments.value.findIndex((a) => a.id === id);
3046
+ if (index !== -1) {
3047
+ const attachment = attachments.value[index];
3048
+ if (attachment.url?.startsWith("blob:")) {
3049
+ URL.revokeObjectURL(attachment.url);
3050
+ }
3051
+ attachments.value.splice(index, 1);
3052
+ }
3053
+ };
3054
+ return {
3055
+ canSubmit,
3056
+ submit,
3057
+ cancel,
3058
+ focus,
3059
+ blur,
3060
+ clear,
3061
+ addFiles,
3062
+ removeAttachment
3063
+ };
3064
+ }
3065
+
3066
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/packages/chat-vue/src/components/sender/sender.vue?type=script
3067
+ var sender_default = /* @__PURE__ */ defineComponent({
3068
+ __name: "sender",
3069
+ props: /* @__PURE__ */ mergeModels({
3070
+ modelValue: { type: String, required: false },
3071
+ attachments: { type: Array, required: false },
3072
+ placeholder: { type: String, required: false, default: "Type something..." },
3073
+ disabled: { type: Boolean, required: false, default: false },
3074
+ bordered: { type: Boolean, required: false, default: true },
3075
+ loading: { type: Boolean, required: false, default: false },
3076
+ maxHeight: { type: [String, Number], required: false },
3077
+ submitType: { type: String, required: false, default: "enter" },
3078
+ extensions: { type: Array, required: false },
3079
+ clearOnSubmit: { type: Boolean, required: false, default: true },
3080
+ accept: { type: String, required: false },
3081
+ maxFiles: { type: Number, required: false },
3082
+ maxSize: { type: Number, required: false }
3083
+ }, {
3084
+ "modelValue": { type: String, ...{ default: "" } },
3085
+ "modelModifiers": {},
3086
+ "attachments": { type: Array, ...{ default: () => [] } },
3087
+ "attachmentsModifiers": {}
3088
+ }),
3089
+ emits: /* @__PURE__ */ mergeModels(["submit", "cancel", "fileError"], ["update:modelValue", "update:attachments"]),
3090
+ setup(__props, { expose: __expose, emit: __emit }) {
3091
+ const props = __props;
3092
+ const emit = __emit;
3093
+ const modelValue = useModel(__props, "modelValue");
3094
+ const attachments = useModel(__props, "attachments");
3095
+ const bem = createImBem("sender");
3096
+ const inputRef = ref();
3097
+ const {
3098
+ canSubmit,
3099
+ submit,
3100
+ cancel,
3101
+ focus,
3102
+ blur,
3103
+ clear,
3104
+ addFiles,
3105
+ removeAttachment
3106
+ } = useSender({
3107
+ props,
3108
+ emit,
3109
+ modelValue,
3110
+ attachments,
3111
+ inputRef
3112
+ });
3113
+ const handleInputSubmit = () => {
3114
+ submit();
3115
+ };
3116
+ const handleSubmitClick = () => {
3117
+ if (props.loading) {
3118
+ cancel();
3119
+ } else {
3120
+ submit();
3121
+ }
3122
+ };
3123
+ const handlePasteFile = (files) => {
3124
+ addFiles(files);
3125
+ };
3126
+ const fileConfig = computed(() => ({
3127
+ accept: props.accept,
3128
+ maxFiles: props.maxFiles,
3129
+ maxSize: props.maxSize
3130
+ }));
3131
+ provide("sender", {
3132
+ value: modelValue,
3133
+ attachments,
3134
+ disabled: toRef(props, "disabled"),
3135
+ loading: toRef(props, "loading"),
3136
+ canSubmit,
3137
+ submit,
3138
+ cancel,
3139
+ addFiles,
3140
+ removeAttachment,
3141
+ fileConfig: fileConfig.value
3142
+ });
3143
+ const getEditor = () => inputRef.value?.getEditor();
3144
+ __expose({
3145
+ focus,
3146
+ blur,
3147
+ clear,
3148
+ submit,
3149
+ addFiles,
3150
+ removeAttachment,
3151
+ getEditor
3152
+ });
3153
+ const __returned__ = { props, emit, modelValue, attachments, bem, inputRef, canSubmit, submit, cancel, focus, blur, clear, addFiles, removeAttachment, handleInputSubmit, handleSubmitClick, handlePasteFile, fileConfig, getEditor, get SenderInput() {
3154
+ return sender_input_default2;
3155
+ }, SenderSubmitButton: sender_submit_button_default2 };
3156
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3157
+ return __returned__;
3158
+ }
3159
+ });
3160
+ function render23(_ctx, _cache, $props, $setup, $data, $options) {
3161
+ return openBlock(), createElementBlock(
3162
+ "div",
3163
+ {
3164
+ class: normalizeClass($setup.bem())
3165
+ },
3166
+ [
3167
+ createCommentVNode(" Header \u63D2\u69FD "),
3168
+ renderSlot(_ctx.$slots, "header"),
3169
+ createCommentVNode(" \u4E3B\u4F53\u5185\u5BB9\u533A "),
3170
+ createElementVNode(
3171
+ "div",
3172
+ {
3173
+ class: normalizeClass($setup.bem("box", {
3174
+ bordered: $setup.props.bordered,
3175
+ disabled: $setup.props.disabled
3176
+ }))
3177
+ },
3178
+ [
3179
+ createCommentVNode(" \u9644\u4EF6\u533A\u57DF\u63D2\u69FD "),
3180
+ renderSlot(_ctx.$slots, "attachments", {
3181
+ attachments: $setup.attachments,
3182
+ remove: $setup.removeAttachment
3183
+ }),
3184
+ createCommentVNode(" \u8F93\u5165\u6846 "),
3185
+ createVNode($setup["SenderInput"], {
3186
+ ref: "inputRef",
3187
+ modelValue: $setup.modelValue,
3188
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.modelValue = $event),
3189
+ class: normalizeClass($setup.bem("input")),
3190
+ placeholder: $setup.props.placeholder,
3191
+ disabled: $setup.props.disabled || $setup.props.loading,
3192
+ "max-height": $setup.props.maxHeight,
3193
+ "submit-type": $setup.props.submitType,
3194
+ extensions: $setup.props.extensions,
3195
+ onSubmit: $setup.handleInputSubmit,
3196
+ onPasteFile: $setup.handlePasteFile
3197
+ }, null, 8, ["modelValue", "class", "placeholder", "disabled", "max-height", "submit-type", "extensions"]),
3198
+ createCommentVNode(" \u5DE5\u5177\u680F "),
3199
+ createElementVNode(
3200
+ "div",
3201
+ {
3202
+ class: normalizeClass($setup.bem("toolbar"))
3203
+ },
3204
+ [
3205
+ createCommentVNode(" \u5DE6\u4FA7\u64CD\u4F5C\u533A "),
3206
+ createElementVNode(
3207
+ "div",
3208
+ {
3209
+ class: normalizeClass($setup.bem("prefix"))
3210
+ },
3211
+ [
3212
+ renderSlot(_ctx.$slots, "prefix")
3213
+ ],
3214
+ 2
3215
+ /* CLASS */
3216
+ ),
3217
+ createCommentVNode(" \u53F3\u4FA7\u64CD\u4F5C\u533A "),
3218
+ createElementVNode(
3219
+ "div",
3220
+ {
3221
+ class: normalizeClass($setup.bem("suffix"))
3222
+ },
3223
+ [
3224
+ renderSlot(_ctx.$slots, "suffix"),
3225
+ createCommentVNode(" \u9ED8\u8BA4\u53D1\u9001\u6309\u94AE "),
3226
+ createVNode($setup["SenderSubmitButton"], {
3227
+ disabled: !$setup.canSubmit,
3228
+ loading: $setup.props.loading,
3229
+ onClick: $setup.handleSubmitClick
3230
+ }, null, 8, ["disabled", "loading"])
3231
+ ],
3232
+ 2
3233
+ /* CLASS */
3234
+ )
3235
+ ],
3236
+ 2
3237
+ /* CLASS */
3238
+ )
3239
+ ],
3240
+ 2
3241
+ /* CLASS */
3242
+ ),
3243
+ createCommentVNode(" Footer \u63D2\u69FD "),
3244
+ renderSlot(_ctx.$slots, "footer")
3245
+ ],
3246
+ 2
3247
+ /* CLASS */
3248
+ );
3249
+ }
3250
+
3251
+ // src/components/sender/sender.vue
3252
+ sender_default.render = render23;
3253
+ sender_default.__file = "src/components/sender/sender.vue";
3254
+ var sender_default2 = sender_default;
3255
+ var sender_action_button_default = /* @__PURE__ */ defineComponent({
3256
+ __name: "sender-action-button",
3257
+ props: {
3258
+ disabled: { type: Boolean, required: false, default: false },
3259
+ active: { type: Boolean, required: false, default: false },
3260
+ square: { type: Boolean, required: false, default: false },
3261
+ ariaLabel: { type: String, required: false }
3262
+ },
3263
+ emits: ["click"],
3264
+ setup(__props, { expose: __expose, emit: __emit }) {
3265
+ __expose();
3266
+ const props = __props;
3267
+ const emit = __emit;
3268
+ const bem = createImBem("sender-action-button");
3269
+ const handleClick = (event) => {
3270
+ if (!props.disabled) {
3271
+ emit("click", event);
3272
+ }
3273
+ };
3274
+ const __returned__ = { props, emit, bem, handleClick, ActionButton: action_button_default2 };
3275
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3276
+ return __returned__;
3277
+ }
3278
+ });
3279
+ function render24(_ctx, _cache, $props, $setup, $data, $options) {
3280
+ return openBlock(), createBlock($setup["ActionButton"], {
3281
+ class: normalizeClass([$setup.bem("", { active: $setup.props.active })]),
3282
+ intent: "action",
3283
+ size: "sm",
3284
+ square: $setup.props.square,
3285
+ disabled: $setup.props.disabled,
3286
+ "aria-label": $setup.props.ariaLabel,
3287
+ onClick: $setup.handleClick
3288
+ }, {
3289
+ icon: withCtx(() => [
3290
+ renderSlot(_ctx.$slots, "icon")
3291
+ ]),
3292
+ default: withCtx(() => [
3293
+ renderSlot(_ctx.$slots, "default")
3294
+ ]),
3295
+ _: 3
3296
+ /* FORWARDED */
3297
+ }, 8, ["class", "square", "disabled", "aria-label"]);
3298
+ }
3299
+
3300
+ // src/components/sender/components/sender-action-button.vue
3301
+ sender_action_button_default.render = render24;
3302
+ sender_action_button_default.__file = "src/components/sender/components/sender-action-button.vue";
3303
+ var sender_action_button_default2 = sender_action_button_default;
3304
+ var sender_file_button_default = /* @__PURE__ */ defineComponent({
3305
+ __name: "sender-file-button",
3306
+ props: {
3307
+ accept: { type: String, required: false },
3308
+ multiple: { type: Boolean, required: false },
3309
+ ariaLabel: { type: String, required: false }
3310
+ },
3311
+ setup(__props, { expose: __expose }) {
3312
+ __expose();
3313
+ const props = __props;
3314
+ const sender = inject("sender");
3315
+ const inputRef = ref();
3316
+ const handleClick = () => {
3317
+ inputRef.value?.click();
3318
+ };
3319
+ const handleChange = (event) => {
3320
+ const input = event.target;
3321
+ const files = Array.from(input.files || []);
3322
+ if (files.length > 0) {
3323
+ sender?.addFiles(files);
3324
+ }
3325
+ input.value = "";
3326
+ };
3327
+ const acceptValue = props.accept ?? sender?.fileConfig.accept;
3328
+ const __returned__ = { props, sender, inputRef, handleClick, handleChange, acceptValue, get Icon() {
3329
+ return Icon;
3330
+ }, get SvgIcon() {
3331
+ return svg_icon_default2;
3332
+ }, SenderActionButton: sender_action_button_default2 };
3333
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3334
+ return __returned__;
3335
+ }
3336
+ });
3337
+ var _hoisted_18 = ["accept", "multiple"];
3338
+ function render25(_ctx, _cache, $props, $setup, $data, $options) {
3339
+ return openBlock(), createElementBlock(
3340
+ Fragment,
3341
+ null,
3342
+ [
3343
+ createVNode($setup["SenderActionButton"], {
3344
+ square: "",
3345
+ "aria-label": $props.ariaLabel || "\u6DFB\u52A0\u6587\u4EF6",
3346
+ disabled: $setup.sender?.disabled.value,
3347
+ onClick: $setup.handleClick
3348
+ }, {
3349
+ icon: withCtx(() => [
3350
+ createVNode($setup["SvgIcon"], null, {
3351
+ default: withCtx(() => [
3352
+ createVNode($setup["Icon"], { icon: "mdi:attachment" })
3353
+ ]),
3354
+ _: 1
3355
+ /* STABLE */
3356
+ })
3357
+ ]),
3358
+ _: 1
3359
+ /* STABLE */
3360
+ }, 8, ["aria-label", "disabled"]),
3361
+ createElementVNode("input", {
3362
+ ref: "inputRef",
3363
+ type: "file",
3364
+ accept: $setup.acceptValue,
3365
+ multiple: $props.multiple !== false,
3366
+ style: { "display": "none" },
3367
+ onChange: $setup.handleChange
3368
+ }, null, 40, _hoisted_18)
3369
+ ],
3370
+ 64
3371
+ /* STABLE_FRAGMENT */
3372
+ );
3373
+ }
3374
+
3375
+ // src/components/sender/components/sender-file-button.vue
3376
+ sender_file_button_default.render = render25;
3377
+ sender_file_button_default.__file = "src/components/sender/components/sender-file-button.vue";
3378
+ var sender_file_button_default2 = sender_file_button_default;
3379
+ var sender_attachments_default = /* @__PURE__ */ defineComponent({
3380
+ __name: "sender-attachments",
3381
+ props: {
3382
+ attachments: { type: Array, required: true }
3383
+ },
3384
+ emits: ["remove"],
3385
+ setup(__props, { expose: __expose, emit: __emit }) {
3386
+ __expose();
3387
+ const emit = __emit;
3388
+ const bem = createImBem("sender-attachments");
3389
+ const handleRemove = (id) => {
3390
+ emit("remove", id);
3391
+ };
3392
+ const __returned__ = { emit, bem, handleRemove, get FilePreview() {
3393
+ return file_preview_default2;
3394
+ } };
3395
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3396
+ return __returned__;
3397
+ }
3398
+ });
3399
+ function render26(_ctx, _cache, $props, $setup, $data, $options) {
3400
+ return $props.attachments.length > 0 ? (openBlock(), createElementBlock(
3401
+ "div",
3402
+ {
3403
+ key: 0,
3404
+ class: normalizeClass($setup.bem())
3405
+ },
3406
+ [
3407
+ (openBlock(true), createElementBlock(
3408
+ Fragment,
3409
+ null,
3410
+ renderList($props.attachments, (attachment) => {
3411
+ return openBlock(), createBlock($setup["FilePreview"], {
3412
+ key: attachment.id,
3413
+ file: {
3414
+ name: attachment.name,
3415
+ type: attachment.type,
3416
+ size: attachment.size,
3417
+ url: attachment.url
3418
+ },
3419
+ compact: "",
3420
+ removable: "",
3421
+ onRemove: ($event) => $setup.handleRemove(attachment.id)
3422
+ }, null, 8, ["file", "onRemove"]);
3423
+ }),
3424
+ 128
3425
+ /* KEYED_FRAGMENT */
3426
+ ))
3427
+ ],
3428
+ 2
3429
+ /* CLASS */
3430
+ )) : createCommentVNode("v-if", true);
3431
+ }
3432
+
3433
+ // src/components/sender/components/sender-attachments.vue
3434
+ sender_attachments_default.render = render26;
3435
+ sender_attachments_default.__file = "src/components/sender/components/sender-attachments.vue";
3436
+ var sender_attachments_default2 = sender_attachments_default;
3437
+ var suggestion_item_default = /* @__PURE__ */ defineComponent({
3438
+ __name: "suggestion-item",
3439
+ props: {
3440
+ item: { type: Object, required: true }
3441
+ },
3442
+ emits: ["click"],
3443
+ setup(__props, { expose: __expose, emit: __emit }) {
3444
+ __expose();
3445
+ const props = __props;
3446
+ const emit = __emit;
3447
+ const bem = createImBem("suggestion-item");
3448
+ const handleClick = () => {
3449
+ if (!props.item.disabled) {
3450
+ emit("click", props.item);
3451
+ }
3452
+ };
3453
+ const __returned__ = { props, emit, bem, handleClick, get Icon() {
3454
+ return Icon;
3455
+ }, SvgIcon: svg_icon_default2 };
3456
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3457
+ return __returned__;
3458
+ }
3459
+ });
3460
+ var _hoisted_19 = ["disabled"];
3461
+ function render27(_ctx, _cache, $props, $setup, $data, $options) {
3462
+ return openBlock(), createElementBlock("button", {
3463
+ type: "button",
3464
+ class: normalizeClass([$setup.bem(), { [$setup.bem("", "disabled")]: $props.item.disabled }]),
3465
+ disabled: $props.item.disabled,
3466
+ onClick: $setup.handleClick
3467
+ }, [
3468
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3469
+ $props.item.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
3470
+ key: 0,
3471
+ class: normalizeClass($setup.bem("icon"))
3472
+ }, {
3473
+ default: withCtx(() => [
3474
+ createVNode($setup["Icon"], {
3475
+ icon: $props.item.icon
3476
+ }, null, 8, ["icon"])
3477
+ ]),
3478
+ _: 1
3479
+ /* STABLE */
3480
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
3481
+ ]),
3482
+ createElementVNode(
3483
+ "span",
3484
+ {
3485
+ class: normalizeClass($setup.bem("content"))
3486
+ },
3487
+ [
3488
+ createElementVNode(
3489
+ "span",
3490
+ {
3491
+ class: normalizeClass($setup.bem("label"))
3492
+ },
3493
+ toDisplayString($props.item.label),
3494
+ 3
3495
+ /* TEXT, CLASS */
3496
+ ),
3497
+ $props.item.description ? (openBlock(), createElementBlock(
3498
+ "span",
3499
+ {
3500
+ key: 0,
3501
+ class: normalizeClass($setup.bem("description"))
3502
+ },
3503
+ toDisplayString($props.item.description),
3504
+ 3
3505
+ /* TEXT, CLASS */
3506
+ )) : createCommentVNode("v-if", true)
3507
+ ],
3508
+ 2
3509
+ /* CLASS */
3510
+ )
3511
+ ], 10, _hoisted_19);
3512
+ }
3513
+
3514
+ // src/components/suggestion/suggestion-item.vue
3515
+ suggestion_item_default.render = render27;
3516
+ suggestion_item_default.__file = "src/components/suggestion/suggestion-item.vue";
3517
+ var suggestion_item_default2 = suggestion_item_default;
3518
+
3519
+ // sfc-script:/Users/yishuai/develop/towardsphd/tp-full/incremark/packages/chat-vue/src/components/suggestion/suggestion.vue?type=script
3520
+ var suggestion_default = /* @__PURE__ */ defineComponent({
3521
+ __name: "suggestion",
3522
+ props: {
3523
+ items: { type: Array, required: true },
3524
+ vertical: { type: Boolean, required: false, default: false }
3525
+ },
3526
+ emits: ["select"],
3527
+ setup(__props, { expose: __expose, emit: __emit }) {
3528
+ __expose();
3529
+ const emit = __emit;
3530
+ const bem = createImBem("suggestion");
3531
+ const handleItemClick = (item) => {
3532
+ emit("select", item);
3533
+ };
3534
+ const __returned__ = { emit, bem, handleItemClick, SuggestionItemVue: suggestion_item_default2 };
3535
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3536
+ return __returned__;
3537
+ }
3538
+ });
3539
+ function render28(_ctx, _cache, $props, $setup, $data, $options) {
3540
+ return openBlock(), createElementBlock(
3541
+ "div",
3542
+ {
3543
+ class: normalizeClass([$setup.bem(), { [$setup.bem("", "vertical")]: $props.vertical }])
3544
+ },
3545
+ [
3546
+ (openBlock(true), createElementBlock(
3547
+ Fragment,
3548
+ null,
3549
+ renderList($props.items, (item, index) => {
3550
+ return openBlock(), createBlock($setup["SuggestionItemVue"], {
3551
+ key: item.id ?? index,
3552
+ item,
3553
+ onClick: $setup.handleItemClick
3554
+ }, {
3555
+ icon: withCtx(() => [
3556
+ renderSlot(_ctx.$slots, "icon", { item })
3557
+ ]),
3558
+ _: 2
3559
+ /* DYNAMIC */
3560
+ }, 1032, ["item"]);
3561
+ }),
3562
+ 128
3563
+ /* KEYED_FRAGMENT */
3564
+ ))
3565
+ ],
3566
+ 2
3567
+ /* CLASS */
3568
+ );
3569
+ }
3570
+
3571
+ // src/components/suggestion/suggestion.vue
3572
+ suggestion_default.render = render28;
3573
+ suggestion_default.__file = "src/components/suggestion/suggestion.vue";
3574
+ var suggestion_default2 = suggestion_default;
3575
+ var error_message_default = /* @__PURE__ */ defineComponent({
3576
+ __name: "error-message",
3577
+ props: {
3578
+ title: { type: String, required: false },
3579
+ message: { type: String, required: true },
3580
+ type: { type: String, required: false, default: "unknown" },
3581
+ retryable: { type: Boolean, required: false, default: false },
3582
+ retryText: { type: String, required: false, default: "\u91CD\u8BD5" }
3583
+ },
3584
+ emits: ["retry"],
3585
+ setup(__props, { expose: __expose, emit: __emit }) {
3586
+ __expose();
3587
+ const props = __props;
3588
+ const emit = __emit;
3589
+ const bem = createImBem("error-message");
3590
+ const iconMap = {
3591
+ "network": "mdi:wifi-off",
3592
+ "rate-limit": "mdi:clock-alert-outline",
3593
+ "server": "mdi:server-off",
3594
+ "auth": "mdi:account-alert-outline",
3595
+ "unknown": "mdi:alert-circle-outline"
3596
+ };
3597
+ const icon = computed(() => iconMap[props.type]);
3598
+ const defaultTitleMap = {
3599
+ "network": "\u7F51\u7EDC\u9519\u8BEF",
3600
+ "rate-limit": "\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41",
3601
+ "server": "\u670D\u52A1\u5668\u9519\u8BEF",
3602
+ "auth": "\u8BA4\u8BC1\u5931\u8D25",
3603
+ "unknown": "\u51FA\u9519\u4E86"
3604
+ };
3605
+ const displayTitle = computed(() => props.title || defaultTitleMap[props.type]);
3606
+ const handleRetry = () => {
3607
+ emit("retry");
3608
+ };
3609
+ const __returned__ = { props, emit, bem, iconMap, icon, defaultTitleMap, displayTitle, handleRetry, get Icon() {
3610
+ return Icon;
3611
+ }, SvgIcon: svg_icon_default2 };
3612
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3613
+ return __returned__;
3614
+ }
3615
+ });
3616
+ function render29(_ctx, _cache, $props, $setup, $data, $options) {
3617
+ return openBlock(), createElementBlock(
3618
+ "div",
3619
+ {
3620
+ class: normalizeClass([$setup.bem(), $setup.bem("", $props.type)])
3621
+ },
3622
+ [
3623
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3624
+ createVNode($setup["SvgIcon"], {
3625
+ class: normalizeClass($setup.bem("icon"))
3626
+ }, {
3627
+ default: withCtx(() => [
3628
+ createVNode($setup["Icon"], { icon: $setup.icon }, null, 8, ["icon"])
3629
+ ]),
3630
+ _: 1
3631
+ /* STABLE */
3632
+ }, 8, ["class"])
3633
+ ]),
3634
+ createElementVNode(
3635
+ "div",
3636
+ {
3637
+ class: normalizeClass($setup.bem("content"))
3638
+ },
3639
+ [
3640
+ createElementVNode(
3641
+ "div",
3642
+ {
3643
+ class: normalizeClass($setup.bem("title"))
3644
+ },
3645
+ toDisplayString($setup.displayTitle),
3646
+ 3
3647
+ /* TEXT, CLASS */
3648
+ ),
3649
+ createElementVNode(
3650
+ "div",
3651
+ {
3652
+ class: normalizeClass($setup.bem("message"))
3653
+ },
3654
+ toDisplayString($props.message),
3655
+ 3
3656
+ /* TEXT, CLASS */
3657
+ )
3658
+ ],
3659
+ 2
3660
+ /* CLASS */
3661
+ ),
3662
+ $props.retryable ? (openBlock(), createElementBlock(
3663
+ "button",
3664
+ {
3665
+ key: 0,
3666
+ type: "button",
3667
+ class: normalizeClass($setup.bem("retry")),
3668
+ onClick: $setup.handleRetry
3669
+ },
3670
+ [
3671
+ createVNode($setup["SvgIcon"], {
3672
+ class: normalizeClass($setup.bem("retry-icon"))
3673
+ }, {
3674
+ default: withCtx(() => [
3675
+ createVNode($setup["Icon"], { icon: "mdi:refresh" })
3676
+ ]),
3677
+ _: 1
3678
+ /* STABLE */
3679
+ }, 8, ["class"]),
3680
+ createTextVNode(
3681
+ " " + toDisplayString($props.retryText),
3682
+ 1
3683
+ /* TEXT */
3684
+ )
3685
+ ],
3686
+ 2
3687
+ /* CLASS */
3688
+ )) : createCommentVNode("v-if", true)
3689
+ ],
3690
+ 2
3691
+ /* CLASS */
3692
+ );
3693
+ }
3694
+
3695
+ // src/components/error-message/error-message.vue
3696
+ error_message_default.render = render29;
3697
+ error_message_default.__file = "src/components/error-message/error-message.vue";
3698
+ var error_message_default2 = error_message_default;
3699
+ var welcome_default = /* @__PURE__ */ defineComponent({
3700
+ __name: "welcome",
3701
+ props: {
3702
+ title: { type: String, required: false, default: "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F" },
3703
+ description: { type: String, required: false },
3704
+ icon: { type: String, required: false, default: "mdi:robot-happy-outline" },
3705
+ suggestions: { type: Array, required: false },
3706
+ hint: { type: String, required: false }
3707
+ },
3708
+ emits: ["select"],
3709
+ setup(__props, { expose: __expose, emit: __emit }) {
3710
+ __expose();
3711
+ const emit = __emit;
3712
+ const bem = createImBem("welcome");
3713
+ const handleSelect = (item) => {
3714
+ emit("select", item);
3715
+ };
3716
+ const __returned__ = { emit, bem, handleSelect, get Icon() {
3717
+ return Icon;
3718
+ }, SvgIcon: svg_icon_default2, get Suggestion() {
3719
+ return suggestion_default2;
3720
+ } };
3721
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3722
+ return __returned__;
3723
+ }
3724
+ });
3725
+ function render30(_ctx, _cache, $props, $setup, $data, $options) {
3726
+ return openBlock(), createElementBlock(
3727
+ "div",
3728
+ {
3729
+ class: normalizeClass($setup.bem())
3730
+ },
3731
+ [
3732
+ createElementVNode(
3733
+ "div",
3734
+ {
3735
+ class: normalizeClass($setup.bem("header"))
3736
+ },
3737
+ [
3738
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3739
+ $props.icon ? (openBlock(), createBlock($setup["SvgIcon"], {
3740
+ key: 0,
3741
+ class: normalizeClass($setup.bem("icon"))
3742
+ }, {
3743
+ default: withCtx(() => [
3744
+ createVNode($setup["Icon"], { icon: $props.icon }, null, 8, ["icon"])
3745
+ ]),
3746
+ _: 1
3747
+ /* STABLE */
3748
+ }, 8, ["class"])) : createCommentVNode("v-if", true)
3749
+ ]),
3750
+ createElementVNode(
3751
+ "h2",
3752
+ {
3753
+ class: normalizeClass($setup.bem("title"))
3754
+ },
3755
+ toDisplayString($props.title),
3756
+ 3
3757
+ /* TEXT, CLASS */
3758
+ ),
3759
+ $props.description ? (openBlock(), createElementBlock(
3760
+ "p",
3761
+ {
3762
+ key: 0,
3763
+ class: normalizeClass($setup.bem("description"))
3764
+ },
3765
+ toDisplayString($props.description),
3766
+ 3
3767
+ /* TEXT, CLASS */
3768
+ )) : createCommentVNode("v-if", true)
3769
+ ],
3770
+ 2
3771
+ /* CLASS */
3772
+ ),
3773
+ $props.suggestions?.length ? (openBlock(), createElementBlock(
3774
+ "div",
3775
+ {
3776
+ key: 0,
3777
+ class: normalizeClass($setup.bem("suggestions"))
3778
+ },
3779
+ [
3780
+ renderSlot(_ctx.$slots, "suggestions", { items: $props.suggestions }, () => [
3781
+ createVNode($setup["Suggestion"], {
3782
+ items: $props.suggestions,
3783
+ onSelect: $setup.handleSelect
3784
+ }, null, 8, ["items"])
3785
+ ])
3786
+ ],
3787
+ 2
3788
+ /* CLASS */
3789
+ )) : createCommentVNode("v-if", true),
3790
+ $props.hint || _ctx.$slots.hint ? (openBlock(), createElementBlock(
3791
+ "div",
3792
+ {
3793
+ key: 1,
3794
+ class: normalizeClass($setup.bem("hint"))
3795
+ },
3796
+ [
3797
+ renderSlot(_ctx.$slots, "hint", {}, () => [
3798
+ createTextVNode(
3799
+ toDisplayString($props.hint),
3800
+ 1
3801
+ /* TEXT */
3802
+ )
3803
+ ])
3804
+ ],
3805
+ 2
3806
+ /* CLASS */
3807
+ )) : createCommentVNode("v-if", true)
3808
+ ],
3809
+ 2
3810
+ /* CLASS */
3811
+ );
3812
+ }
3813
+
3814
+ // src/components/welcome/welcome.vue
3815
+ welcome_default.render = render30;
3816
+ welcome_default.__file = "src/components/welcome/welcome.vue";
3817
+ var welcome_default2 = welcome_default;
3818
+ var message_list_default = /* @__PURE__ */ defineComponent({
3819
+ __name: "message-list",
3820
+ props: {
3821
+ autoScroll: { type: Boolean, required: false, default: true },
3822
+ autoScrollThreshold: { type: Number, required: false, default: 50 },
3823
+ scrollBehavior: { type: null, required: false, default: "instant" }
3824
+ },
3825
+ setup(__props, { expose: __expose }) {
3826
+ const bem = createImBem("message-list");
3827
+ const containerRef = useTemplateRef("container");
3828
+ function scrollToBottom() {
3829
+ containerRef.value?.scrollToBottom();
3830
+ }
3831
+ function isUserScrolledUp() {
3832
+ return containerRef.value?.isUserScrolledUp() ?? false;
3833
+ }
3834
+ __expose({
3835
+ scrollToBottom,
3836
+ isUserScrolledUp
3837
+ });
3838
+ const __returned__ = { bem, containerRef, scrollToBottom, isUserScrolledUp, get AutoScrollContainer() {
3839
+ return AutoScrollContainer;
3840
+ } };
3841
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3842
+ return __returned__;
3843
+ }
3844
+ });
3845
+ function render31(_ctx, _cache, $props, $setup, $data, $options) {
3846
+ return openBlock(), createBlock($setup["AutoScrollContainer"], {
3847
+ ref: "container",
3848
+ enabled: $props.autoScroll,
3849
+ threshold: $props.autoScrollThreshold,
3850
+ behavior: $props.scrollBehavior,
3851
+ class: normalizeClass($setup.bem())
3852
+ }, {
3853
+ default: withCtx(() => [
3854
+ renderSlot(_ctx.$slots, "default")
3855
+ ]),
3856
+ _: 3
3857
+ /* FORWARDED */
3858
+ }, 8, ["enabled", "threshold", "behavior", "class"]);
3859
+ }
3860
+
3861
+ // src/components/message-list/message-list.vue
3862
+ message_list_default.render = render31;
3863
+ message_list_default.__file = "src/components/message-list/message-list.vue";
3864
+ var message_list_default2 = message_list_default;
5
3865
  var ChatProvider_default = /* @__PURE__ */ defineComponent({
6
3866
  __name: "ChatProvider",
7
3867
  props: {
@@ -16,15 +3876,15 @@ var ChatProvider_default = /* @__PURE__ */ defineComponent({
16
3876
  return __returned__;
17
3877
  }
18
3878
  });
19
- function render(_ctx, _cache, $props, $setup, $data, $options) {
3879
+ function render32(_ctx, _cache, $props, $setup, $data, $options) {
20
3880
  return renderSlot(_ctx.$slots, "default");
21
3881
  }
22
3882
 
23
3883
  // src/provider/ChatProvider.vue
24
- ChatProvider_default.render = render;
3884
+ ChatProvider_default.render = render32;
25
3885
  ChatProvider_default.__file = "src/provider/ChatProvider.vue";
26
3886
  var ChatProvider_default2 = ChatProvider_default;
27
3887
 
28
- export { ChatProvider_default2 as ChatProvider };
3888
+ export { chain_of_thought_default2 as ChainOfThought, chain_of_thought_step_default2 as ChainOfThoughtStep, ChatProvider_default2 as ChatProvider, error_message_default2 as ErrorMessage, file_preview_default2 as FilePreview, im_button_default2 as ImButton, im_dropdown_default2 as ImDropdown, im_tooltip_default2 as ImTooltip, message_action_default2 as MessageAction, message_action_copy_default2 as MessageActionCopy, message_action_feedback_default2 as MessageActionFeedback, message_actions_default2 as MessageActions, message_bubble_default2 as MessageBubble, message_list_default2 as MessageList, part_renderer_default2 as PartRenderer, reasoning_message_default2 as ReasoningMessage, sender_default2 as Sender, sender_action_button_default2 as SenderActionButton, sender_attachments_default2 as SenderAttachments, sender_file_button_default2 as SenderFileButton, sender_input_default2 as SenderInput, sender_submit_button_default2 as SenderSubmitButton, source_reference_default2 as SourceReference, suggestion_default2 as Suggestion, suggestion_item_default2 as SuggestionItem, svg_icon_default2 as SvgIcon, text_message_default2 as TextMessage, tool_call_default2 as ToolCall, welcome_default2 as Welcome, provideUIAdapter, useCollapsible, useCopyAction, useSender, useUIAdapter };
29
3889
  //# sourceMappingURL=index.js.map
30
3890
  //# sourceMappingURL=index.js.map