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

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