@blade-hq/agent-react 2612.0.0-beta.28 → 2612.0.0-beta.29
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/chat/AgentLoopBlock.d.ts +0 -2
- package/dist/chat/AssistantTurnBlock.d.ts +0 -8
- package/dist/chat/AttachmentPreviewDialog.d.ts +0 -1
- package/dist/chat/CurrentPlanPanel.d.ts +0 -3
- package/dist/chat/FileDeliveryCards.d.ts +0 -4
- package/dist/chat/FinalArtifactCards.d.ts +0 -1
- package/dist/chat/LiteMessageList.d.ts +1 -3
- package/dist/chat/MessageFileAttachmentList.d.ts +0 -5
- package/dist/chat/SessionReplayBar.d.ts +0 -1
- package/dist/chat/TextAttachmentPills.d.ts +0 -3
- package/dist/chat/TurnNavRail.d.ts +0 -3
- package/dist/chat/WorkflowRunBlock.d.ts +0 -2
- package/dist/chat/ai-elements/shimmer.d.ts +0 -4
- package/dist/chat/message-list-blocks.d.ts +0 -1
- package/dist/chat/runtime/actions.d.ts +1 -2
- package/dist/chat/runtime/background-task-dismissals.d.ts +0 -1
- package/dist/chat/runtime/composer-channels.d.ts +0 -3
- package/dist/chat/runtime/input-cache-reset.d.ts +0 -5
- package/dist/chat/runtime/session-source.d.ts +0 -5
- package/dist/chat/runtime/use-chat-actions.d.ts +0 -4
- package/dist/{chat-OCLOVB3H.css → chat-IHPRU35X.css} +5 -18
- package/dist/chat.css +5 -18
- package/dist/{chunk-66V4EOSO.js → chunk-M5NAFIU4.js} +340 -399
- package/dist/chunk-M5NAFIU4.js.map +1 -0
- package/dist/{chunk-PAZSK73V.js → chunk-PHWYZP6F.js} +3 -8
- package/dist/chunk-PHWYZP6F.js.map +1 -0
- package/dist/{chunk-PPREDKQ2.js → chunk-XTYNDVUV.js} +15 -3
- package/dist/chunk-XTYNDVUV.js.map +1 -0
- package/dist/components/ChatInput.d.ts +1 -15
- package/dist/components/LlmAdvancedSettings.d.ts +0 -1
- package/dist/components/PlanUpdateBlock.d.ts +0 -1
- package/dist/embed/blade-chat-element.d.ts +0 -8
- package/dist/embed/entry.d.ts +1 -13
- package/dist/hooks/use-message-pin.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/internal.js +4 -6
- package/dist/internal.js.map +1 -1
- package/dist/lib/message-shortcuts.d.ts +5 -0
- package/dist/rich-input/ConnectButton.d.ts +0 -2
- package/dist/rich-input/SkillStatusBar.d.ts +0 -6
- package/dist/rich-input/lib/reference-candidates.d.ts +0 -1
- package/dist/rich-input/voice/VoiceWaveform.d.ts +0 -3
- package/dist/rich-input.js +90 -110
- package/dist/rich-input.js.map +1 -1
- package/dist/style.css +16 -55
- package/dist/style.full.css +23 -77
- package/package.json +2 -2
- package/dist/chunk-66V4EOSO.js.map +0 -1
- package/dist/chunk-PAZSK73V.js.map +0 -1
- package/dist/chunk-PPREDKQ2.js.map +0 -1
|
@@ -87,9 +87,11 @@ import {
|
|
|
87
87
|
getToolStatusLabel,
|
|
88
88
|
getToolTone,
|
|
89
89
|
isPlanUpdateTool,
|
|
90
|
+
isQueueShortcut,
|
|
90
91
|
notifyChat,
|
|
91
92
|
parsePlanUpdate,
|
|
92
93
|
pluginRefsForSend,
|
|
94
|
+
queueShortcutLabel,
|
|
93
95
|
sendToSession,
|
|
94
96
|
useBladeClient,
|
|
95
97
|
useBladeHost,
|
|
@@ -112,7 +114,7 @@ import {
|
|
|
112
114
|
useSessionSource,
|
|
113
115
|
useSessionState,
|
|
114
116
|
useSingleSessionSource
|
|
115
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-XTYNDVUV.js";
|
|
116
118
|
import {
|
|
117
119
|
__export
|
|
118
120
|
} from "./chunk-PR4QN5HX.js";
|
|
@@ -576,276 +578,268 @@ function SessionQueuePanel({
|
|
|
576
578
|
next.splice(edge === "after" ? target + 1 : target, 0, sourceId);
|
|
577
579
|
onReorder(next);
|
|
578
580
|
};
|
|
579
|
-
return (
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
"\u5F85\u6267\u884C \xB7 ",
|
|
590
|
-
items.length
|
|
591
|
-
] }),
|
|
592
|
-
snapshot.paused && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
593
|
-
/* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--destructive))]", children: [
|
|
594
|
-
/* @__PURE__ */ jsx3(CirclePause, { size: 12 }),
|
|
595
|
-
pauseLabel
|
|
596
|
-
] }),
|
|
597
|
-
/* @__PURE__ */ jsx3(
|
|
598
|
-
"button",
|
|
599
|
-
{
|
|
600
|
-
type: "button",
|
|
601
|
-
onClick: onResume,
|
|
602
|
-
className: "h-6 rounded-md border border-[hsl(var(--border))] px-2 font-medium text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]",
|
|
603
|
-
children: "\u7EE7\u7EED\u6267\u884C"
|
|
604
|
-
}
|
|
605
|
-
)
|
|
581
|
+
return /* @__PURE__ */ jsx3("section", { part: "queue", className: cn("blade-chat-queue shrink-0 pt-2", rootClassName), "aria-label": "\u5F85\u6267\u884C\u6D88\u606F", children: /* @__PURE__ */ jsxs3("div", { className: cn("mx-auto", contentWidthClassName), children: [
|
|
582
|
+
snapshot.paused || collapsible ? /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
583
|
+
/* @__PURE__ */ jsxs3("span", { className: "font-medium", children: [
|
|
584
|
+
"\u5F85\u6267\u884C \xB7 ",
|
|
585
|
+
items.length
|
|
586
|
+
] }),
|
|
587
|
+
snapshot.paused && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
588
|
+
/* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--destructive))]", children: [
|
|
589
|
+
/* @__PURE__ */ jsx3(CirclePause, { size: 12 }),
|
|
590
|
+
pauseLabel
|
|
606
591
|
] }),
|
|
607
|
-
|
|
592
|
+
/* @__PURE__ */ jsx3(
|
|
608
593
|
"button",
|
|
609
594
|
{
|
|
610
595
|
type: "button",
|
|
611
|
-
onClick:
|
|
612
|
-
"
|
|
613
|
-
|
|
614
|
-
children: [
|
|
615
|
-
collapsed ? "\u5C55\u5F00" : "\u6298\u53E0",
|
|
616
|
-
/* @__PURE__ */ jsx3(ChevronDown, { size: 12, className: cn(!collapsed && "rotate-180") })
|
|
617
|
-
]
|
|
596
|
+
onClick: onResume,
|
|
597
|
+
className: "h-6 rounded-md border border-[hsl(var(--border))] px-2 font-medium text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]",
|
|
598
|
+
children: "\u7EE7\u7EED\u6267\u884C"
|
|
618
599
|
}
|
|
619
600
|
)
|
|
620
|
-
] }) : null,
|
|
621
|
-
notice && /* @__PURE__ */ jsxs3("div", { className: "blade-chat-queue-notice mt-2 flex items-start gap-1.5 text-xs text-[hsl(var(--destructive))]", children: [
|
|
622
|
-
/* @__PURE__ */ jsx3(CircleAlert, { size: 13, className: "mt-0.5 shrink-0" }),
|
|
623
|
-
/* @__PURE__ */ jsx3("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: notice })
|
|
624
|
-
] }),
|
|
625
|
-
detachedEdit && /* @__PURE__ */ jsxs3("div", { className: "mt-2 flex flex-col gap-2 text-xs", children: [
|
|
626
|
-
/* @__PURE__ */ jsx3("span", { children: "\u539F\u6D88\u606F\u5DF2\u53D8\u5316\uFF0C\u4FEE\u6539\u5185\u5BB9\u5DF2\u4FDD\u7559" }),
|
|
627
|
-
/* @__PURE__ */ jsx3(
|
|
628
|
-
"textarea",
|
|
629
|
-
{
|
|
630
|
-
"aria-label": "\u4FDD\u7559\u7684\u4FEE\u6539\u5185\u5BB9",
|
|
631
|
-
value: detachedEdit.text,
|
|
632
|
-
onChange: (event) => setEditing((current) => current ? { ...current, text: event.target.value } : current),
|
|
633
|
-
rows: 2,
|
|
634
|
-
className: "w-full rounded border border-[hsl(var(--border))] bg-transparent p-2"
|
|
635
|
-
}
|
|
636
|
-
),
|
|
637
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-2", children: [
|
|
638
|
-
/* @__PURE__ */ jsx3("button", { type: "button", className: "rounded border border-[hsl(var(--border))] px-2 py-1", disabled: requeueing, onClick: stopEdit, children: "\u653E\u5F03\u4FEE\u6539" }),
|
|
639
|
-
onRequeue && /* @__PURE__ */ jsx3("button", { type: "button", className: "rounded bg-[hsl(var(--primary))] px-2 py-1 text-[hsl(var(--primary-foreground))] disabled:opacity-40", disabled: requeueing || !detachedEdit.text.trim(), onClick: async () => {
|
|
640
|
-
if (requeuePending.current) return;
|
|
641
|
-
requeuePending.current = true;
|
|
642
|
-
setRequeueing(true);
|
|
643
|
-
const submitted = editing;
|
|
644
|
-
try {
|
|
645
|
-
if (await onRequeue(detachedEdit.text.trim())) {
|
|
646
|
-
setEditing((current) => current === submitted ? null : current);
|
|
647
|
-
}
|
|
648
|
-
} finally {
|
|
649
|
-
requeuePending.current = false;
|
|
650
|
-
setRequeueing(false);
|
|
651
|
-
}
|
|
652
|
-
}, children: "\u4F5C\u4E3A\u65B0\u6D88\u606F\u6392\u961F" })
|
|
653
|
-
] })
|
|
654
601
|
] }),
|
|
602
|
+
collapsible && /* @__PURE__ */ jsxs3(
|
|
603
|
+
"button",
|
|
604
|
+
{
|
|
605
|
+
type: "button",
|
|
606
|
+
onClick: () => setCollapsed((value) => !value),
|
|
607
|
+
"aria-expanded": !collapsed,
|
|
608
|
+
className: "ml-auto inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
|
|
609
|
+
children: [
|
|
610
|
+
collapsed ? "\u5C55\u5F00" : "\u6298\u53E0",
|
|
611
|
+
/* @__PURE__ */ jsx3(ChevronDown, { size: 12, className: cn(!collapsed && "rotate-180") })
|
|
612
|
+
]
|
|
613
|
+
}
|
|
614
|
+
)
|
|
615
|
+
] }) : null,
|
|
616
|
+
notice && /* @__PURE__ */ jsxs3("div", { className: "blade-chat-queue-notice mt-2 flex items-start gap-1.5 text-xs text-[hsl(var(--destructive))]", children: [
|
|
617
|
+
/* @__PURE__ */ jsx3(CircleAlert, { size: 13, className: "mt-0.5 shrink-0" }),
|
|
618
|
+
/* @__PURE__ */ jsx3("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: notice })
|
|
619
|
+
] }),
|
|
620
|
+
detachedEdit && /* @__PURE__ */ jsxs3("div", { className: "mt-2 flex flex-col gap-2 text-xs", children: [
|
|
621
|
+
/* @__PURE__ */ jsx3("span", { children: "\u539F\u6D88\u606F\u5DF2\u53D8\u5316\uFF0C\u4FEE\u6539\u5185\u5BB9\u5DF2\u4FDD\u7559" }),
|
|
655
622
|
/* @__PURE__ */ jsx3(
|
|
656
|
-
"
|
|
623
|
+
"textarea",
|
|
657
624
|
{
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
)
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
625
|
+
"aria-label": "\u4FDD\u7559\u7684\u4FEE\u6539\u5185\u5BB9",
|
|
626
|
+
value: detachedEdit.text,
|
|
627
|
+
onChange: (event) => setEditing((current) => current ? { ...current, text: event.target.value } : current),
|
|
628
|
+
rows: 2,
|
|
629
|
+
className: "w-full rounded border border-[hsl(var(--border))] bg-transparent p-2"
|
|
630
|
+
}
|
|
631
|
+
),
|
|
632
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-2", children: [
|
|
633
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "rounded border border-[hsl(var(--border))] px-2 py-1", disabled: requeueing, onClick: stopEdit, children: "\u653E\u5F03\u4FEE\u6539" }),
|
|
634
|
+
onRequeue && /* @__PURE__ */ jsx3("button", { type: "button", className: "rounded bg-[hsl(var(--primary))] px-2 py-1 text-[hsl(var(--primary-foreground))] disabled:opacity-40", disabled: requeueing || !detachedEdit.text.trim(), onClick: async () => {
|
|
635
|
+
if (requeuePending.current) return;
|
|
636
|
+
requeuePending.current = true;
|
|
637
|
+
setRequeueing(true);
|
|
638
|
+
const submitted = editing;
|
|
639
|
+
try {
|
|
640
|
+
if (await onRequeue(detachedEdit.text.trim())) {
|
|
641
|
+
setEditing((current) => current === submitted ? null : current);
|
|
642
|
+
}
|
|
643
|
+
} finally {
|
|
644
|
+
requeuePending.current = false;
|
|
645
|
+
setRequeueing(false);
|
|
646
|
+
}
|
|
647
|
+
}, children: "\u4F5C\u4E3A\u6392\u961F\u6D88\u606F\u53D1\u9001" })
|
|
648
|
+
] })
|
|
649
|
+
] }),
|
|
650
|
+
/* @__PURE__ */ jsx3(
|
|
651
|
+
"ul",
|
|
652
|
+
{
|
|
653
|
+
className: cn(
|
|
654
|
+
QUEUE_INSET_CLASS,
|
|
655
|
+
"flex max-h-56 flex-col overflow-y-auto rounded-t-[22px] border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-1.5 py-1.5",
|
|
656
|
+
!mergesWithInputBelow && "rounded-b-[22px]"
|
|
657
|
+
),
|
|
658
|
+
children: visibleItems.map((item) => {
|
|
659
|
+
const position2 = items.indexOf(item) + 1;
|
|
660
|
+
const pending = canEditQueuedMessage(item);
|
|
661
|
+
const busy = pendingItemId === item.id;
|
|
662
|
+
const isEditing = activeEdit?.id === item.id;
|
|
663
|
+
const pendingIndex = pendingIds.indexOf(item.id);
|
|
664
|
+
const statusLabel = item.status === "pending" ? null : queuedMessageStatusLabel(item.status);
|
|
665
|
+
const deliverable = canDeliver && canDeliverQueuedMessage(item);
|
|
666
|
+
return /* @__PURE__ */ jsx3(
|
|
667
|
+
"li",
|
|
668
|
+
{
|
|
669
|
+
draggable: pending && !busy && !isEditing,
|
|
670
|
+
onDragStart: (event) => {
|
|
671
|
+
draggingRef.current = item.id;
|
|
672
|
+
setDraggingId(item.id);
|
|
673
|
+
const text4 = event.currentTarget.querySelector("[data-queue-text]");
|
|
674
|
+
if (text4 && event.dataTransfer) {
|
|
675
|
+
const rect = text4.getBoundingClientRect();
|
|
676
|
+
event.dataTransfer.setDragImage(
|
|
677
|
+
text4,
|
|
678
|
+
event.clientX - rect.left,
|
|
679
|
+
event.clientY - rect.top
|
|
703
680
|
);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
onDragEnd: () => {
|
|
684
|
+
draggingRef.current = null;
|
|
685
|
+
dropRef.current = null;
|
|
686
|
+
setDraggingId(null);
|
|
687
|
+
setDropAt(null);
|
|
688
|
+
},
|
|
689
|
+
onDragOver: (event) => {
|
|
690
|
+
if (!pending) return;
|
|
691
|
+
event.preventDefault();
|
|
692
|
+
if (!draggingRef.current || draggingRef.current === item.id) return;
|
|
693
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
694
|
+
const edge = event.clientY > rect.top + rect.height / 2 ? "after" : "before";
|
|
695
|
+
dropRef.current = { id: item.id, edge };
|
|
696
|
+
setDropAt(
|
|
697
|
+
(current) => current?.id === item.id && current.edge === edge ? current : { id: item.id, edge }
|
|
698
|
+
);
|
|
699
|
+
},
|
|
700
|
+
onDragLeave: () => {
|
|
701
|
+
if (dropRef.current?.id === item.id) dropRef.current = null;
|
|
702
|
+
setDropAt((current) => current?.id === item.id ? null : current);
|
|
703
|
+
},
|
|
704
|
+
onDrop: (event) => {
|
|
705
|
+
event.preventDefault();
|
|
706
|
+
const landed = dropRef.current;
|
|
707
|
+
if (pending) handleDrop(item.id, landed?.id === item.id ? landed.edge : "before");
|
|
708
|
+
},
|
|
709
|
+
className: cn(
|
|
710
|
+
"blade-chat-queue-item group relative flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[11px]",
|
|
711
|
+
pending && !isEditing && "cursor-grab active:cursor-grabbing",
|
|
712
|
+
busy && "opacity-60",
|
|
713
|
+
draggingId === item.id && "opacity-40"
|
|
714
|
+
),
|
|
715
|
+
children: isEditing ? /* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
|
|
716
|
+
/* @__PURE__ */ jsx3(
|
|
717
|
+
"textarea",
|
|
718
|
+
{
|
|
719
|
+
value: activeEdit?.text ?? "",
|
|
720
|
+
onChange: (event) => setEditing(
|
|
721
|
+
(current) => current ? { ...current, text: event.target.value } : current
|
|
722
|
+
),
|
|
723
|
+
rows: 2,
|
|
724
|
+
"aria-label": `\u7F16\u8F91\u7B2C ${position2} \u6761\u6D88\u606F`,
|
|
725
|
+
className: "w-full resize-none rounded-md border border-[hsl(var(--border))] bg-transparent px-2 py-1.5 text-sm leading-5 text-[hsl(var(--foreground))] outline-none"
|
|
726
|
+
}
|
|
719
727
|
),
|
|
720
|
-
|
|
728
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-1.5", children: [
|
|
721
729
|
/* @__PURE__ */ jsx3(
|
|
722
|
-
"
|
|
730
|
+
"button",
|
|
723
731
|
{
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
rows: 2,
|
|
729
|
-
"aria-label": `\u7F16\u8F91\u7B2C ${position2} \u6761\u6D88\u606F`,
|
|
730
|
-
className: "w-full resize-none rounded-md border border-[hsl(var(--border))] bg-transparent px-2 py-1.5 text-sm leading-5 text-[hsl(var(--foreground))] outline-none"
|
|
732
|
+
type: "button",
|
|
733
|
+
onClick: stopEdit,
|
|
734
|
+
className: "h-7 rounded-md border border-[hsl(var(--border))] px-2 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
|
|
735
|
+
children: "\u53D6\u6D88"
|
|
731
736
|
}
|
|
732
737
|
),
|
|
733
|
-
/* @__PURE__ */
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
738
|
+
/* @__PURE__ */ jsx3(
|
|
739
|
+
"button",
|
|
740
|
+
{
|
|
741
|
+
type: "button",
|
|
742
|
+
onClick: () => commitEdit(item),
|
|
743
|
+
disabled: busy || !activeEdit?.text.trim(),
|
|
744
|
+
className: "h-7 rounded-md bg-[hsl(var(--primary))] px-2 text-xs font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:opacity-40",
|
|
745
|
+
children: "\u4FDD\u5B58"
|
|
746
|
+
}
|
|
747
|
+
)
|
|
748
|
+
] })
|
|
749
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
750
|
+
dropAt?.id === item.id ? /* @__PURE__ */ jsx3(
|
|
751
|
+
"span",
|
|
752
|
+
{
|
|
753
|
+
"aria-hidden": "true",
|
|
754
|
+
style: { background: "var(--resize-line-hover, hsl(var(--foreground) / 0.55))" },
|
|
755
|
+
className: cn(
|
|
756
|
+
"pointer-events-none absolute inset-x-1 h-[2px] rounded-full",
|
|
757
|
+
dropAt.edge === "before" ? "top-0" : "bottom-0"
|
|
752
758
|
)
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
759
|
+
}
|
|
760
|
+
) : null,
|
|
761
|
+
/* @__PURE__ */ jsx3(
|
|
762
|
+
"button",
|
|
763
|
+
{
|
|
764
|
+
type: "button",
|
|
765
|
+
disabled: !pending || busy,
|
|
766
|
+
"aria-label": `\u8C03\u6574\u7B2C ${position2} \u6761\u7684\u987A\u5E8F\uFF08\u62D6\u52A8\uFF0C\u6216\u6309 Alt+\u4E0A/\u4E0B\uFF09`,
|
|
767
|
+
title: "\u62D6\u52A8\u8C03\u6574\u987A\u5E8F\uFF08Alt+\u4E0A/\u4E0B \u4E5F\u884C\uFF09",
|
|
768
|
+
onKeyDown: (event) => {
|
|
769
|
+
if (!event.altKey) return;
|
|
770
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
771
|
+
event.preventDefault();
|
|
772
|
+
const delta = event.key === "ArrowUp" ? -1 : 1;
|
|
773
|
+
if (pendingIndex < 0) return;
|
|
774
|
+
if (delta < 0 && pendingIndex === 0) return;
|
|
775
|
+
if (delta > 0 && pendingIndex === pendingIds.length - 1) return;
|
|
776
|
+
onMove(item, delta);
|
|
777
|
+
},
|
|
778
|
+
className: "-ml-0.5 flex h-5 w-4 shrink-0 cursor-grab items-center justify-center rounded text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] active:cursor-grabbing disabled:cursor-default disabled:opacity-60 disabled:hover:bg-transparent",
|
|
779
|
+
children: /* @__PURE__ */ jsx3(Menu, { size: 14, "aria-hidden": "true" })
|
|
780
|
+
}
|
|
781
|
+
),
|
|
782
|
+
/* @__PURE__ */ jsx3(
|
|
783
|
+
"span",
|
|
784
|
+
{
|
|
785
|
+
"data-queue-text": true,
|
|
786
|
+
className: "min-w-0 flex-1 truncate pt-px text-[hsl(var(--foreground))]",
|
|
787
|
+
children: item.content
|
|
788
|
+
}
|
|
789
|
+
),
|
|
790
|
+
item.error ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 pt-1 text-[11px] text-[hsl(var(--destructive))]", children: item.error }) : busy ? /* @__PURE__ */ jsxs3("span", { className: "mt-0.5 inline-flex shrink-0 items-center gap-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
791
|
+
/* @__PURE__ */ jsx3(LoaderCircle, { size: 11, className: "animate-spin" }),
|
|
792
|
+
"\u5904\u7406\u4E2D"
|
|
793
|
+
] }) : statusLabel ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 pt-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: statusLabel }) : null,
|
|
794
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 items-center gap-0.5 opacity-0 [@media(hover:none)]:opacity-100 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", children: [
|
|
795
|
+
/* @__PURE__ */ jsxs3(
|
|
796
|
+
"button",
|
|
757
797
|
{
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
798
|
+
type: "button",
|
|
799
|
+
"aria-label": `\u7ACB\u523B\u53D1\u9001\u7B2C ${position2} \u6761`,
|
|
800
|
+
title: deliverable ? "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F" : "\u5F53\u524D\u6CA1\u6709\u53EF\u63A5\u6536\u8865\u5145\u7684\u4EFB\u52A1",
|
|
801
|
+
disabled: busy || !deliverable,
|
|
802
|
+
onClick: () => onDeliver(item),
|
|
803
|
+
className: LABEL_BUTTON,
|
|
804
|
+
children: [
|
|
805
|
+
/* @__PURE__ */ jsx3(Send, { size: 13, "aria-hidden": "true" }),
|
|
806
|
+
"\u7ACB\u523B\u53D1\u9001"
|
|
807
|
+
]
|
|
764
808
|
}
|
|
765
|
-
)
|
|
809
|
+
),
|
|
766
810
|
/* @__PURE__ */ jsx3(
|
|
767
811
|
"button",
|
|
768
812
|
{
|
|
769
813
|
type: "button",
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
event.preventDefault();
|
|
777
|
-
const delta = event.key === "ArrowUp" ? -1 : 1;
|
|
778
|
-
if (pendingIndex < 0) return;
|
|
779
|
-
if (delta < 0 && pendingIndex === 0) return;
|
|
780
|
-
if (delta > 0 && pendingIndex === pendingIds.length - 1) return;
|
|
781
|
-
onMove(item, delta);
|
|
782
|
-
},
|
|
783
|
-
className: "-ml-0.5 flex h-5 w-4 shrink-0 cursor-grab items-center justify-center rounded text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] active:cursor-grabbing disabled:cursor-default disabled:opacity-60 disabled:hover:bg-transparent",
|
|
784
|
-
children: /* @__PURE__ */ jsx3(Menu, { size: 14, "aria-hidden": "true" })
|
|
814
|
+
"aria-label": `\u7F16\u8F91\u7B2C ${position2} \u6761`,
|
|
815
|
+
title: "\u7F16\u8F91",
|
|
816
|
+
disabled: busy || !pending,
|
|
817
|
+
onClick: () => startEdit(item),
|
|
818
|
+
className: ICON_BUTTON,
|
|
819
|
+
children: /* @__PURE__ */ jsx3(Pencil, { size: 13, "aria-hidden": "true" })
|
|
785
820
|
}
|
|
786
821
|
),
|
|
787
822
|
/* @__PURE__ */ jsx3(
|
|
788
|
-
"
|
|
823
|
+
"button",
|
|
789
824
|
{
|
|
790
|
-
"
|
|
791
|
-
|
|
792
|
-
|
|
825
|
+
type: "button",
|
|
826
|
+
"aria-label": `\u5220\u9664\u7B2C ${position2} \u6761`,
|
|
827
|
+
title: "\u5220\u9664",
|
|
828
|
+
disabled: busy || !canCancelQueuedMessage(item),
|
|
829
|
+
onClick: () => onCancel(item),
|
|
830
|
+
className: ICON_BUTTON,
|
|
831
|
+
children: /* @__PURE__ */ jsx3(Trash2, { size: 13, "aria-hidden": "true" })
|
|
793
832
|
}
|
|
794
|
-
)
|
|
795
|
-
item.error ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 pt-1 text-[11px] text-[hsl(var(--destructive))]", children: item.error }) : busy ? /* @__PURE__ */ jsxs3("span", { className: "mt-0.5 inline-flex shrink-0 items-center gap-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
796
|
-
/* @__PURE__ */ jsx3(LoaderCircle, { size: 11, className: "animate-spin" }),
|
|
797
|
-
"\u5904\u7406\u4E2D"
|
|
798
|
-
] }) : statusLabel ? /* @__PURE__ */ jsx3("span", { className: "shrink-0 pt-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: statusLabel }) : null,
|
|
799
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 items-center gap-0.5 opacity-0 [@media(hover:none)]:opacity-100 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", children: [
|
|
800
|
-
/* @__PURE__ */ jsxs3(
|
|
801
|
-
"button",
|
|
802
|
-
{
|
|
803
|
-
type: "button",
|
|
804
|
-
"aria-label": `\u7ACB\u523B\u53D1\u9001\u7B2C ${position2} \u6761`,
|
|
805
|
-
title: deliverable ? "\u7ACB\u523B\u53D1\u9001" : "\u5F53\u524D\u6CA1\u6709\u53EF\u63A5\u6536\u8865\u5145\u7684\u4EFB\u52A1",
|
|
806
|
-
disabled: busy || !deliverable,
|
|
807
|
-
onClick: () => onDeliver(item),
|
|
808
|
-
className: LABEL_BUTTON,
|
|
809
|
-
children: [
|
|
810
|
-
/* @__PURE__ */ jsx3(Send, { size: 13, "aria-hidden": "true" }),
|
|
811
|
-
"\u7ACB\u523B\u53D1\u9001"
|
|
812
|
-
]
|
|
813
|
-
}
|
|
814
|
-
),
|
|
815
|
-
/* @__PURE__ */ jsx3(
|
|
816
|
-
"button",
|
|
817
|
-
{
|
|
818
|
-
type: "button",
|
|
819
|
-
"aria-label": `\u7F16\u8F91\u7B2C ${position2} \u6761`,
|
|
820
|
-
title: "\u7F16\u8F91",
|
|
821
|
-
disabled: busy || !pending,
|
|
822
|
-
onClick: () => startEdit(item),
|
|
823
|
-
className: ICON_BUTTON,
|
|
824
|
-
children: /* @__PURE__ */ jsx3(Pencil, { size: 13, "aria-hidden": "true" })
|
|
825
|
-
}
|
|
826
|
-
),
|
|
827
|
-
/* @__PURE__ */ jsx3(
|
|
828
|
-
"button",
|
|
829
|
-
{
|
|
830
|
-
type: "button",
|
|
831
|
-
"aria-label": `\u5220\u9664\u7B2C ${position2} \u6761`,
|
|
832
|
-
title: "\u5220\u9664",
|
|
833
|
-
disabled: busy || !canCancelQueuedMessage(item),
|
|
834
|
-
onClick: () => onCancel(item),
|
|
835
|
-
className: ICON_BUTTON,
|
|
836
|
-
children: /* @__PURE__ */ jsx3(Trash2, { size: 13, "aria-hidden": "true" })
|
|
837
|
-
}
|
|
838
|
-
)
|
|
839
|
-
] })
|
|
833
|
+
)
|
|
840
834
|
] })
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
);
|
|
835
|
+
] })
|
|
836
|
+
},
|
|
837
|
+
item.id
|
|
838
|
+
);
|
|
839
|
+
})
|
|
840
|
+
}
|
|
841
|
+
)
|
|
842
|
+
] }) });
|
|
849
843
|
}
|
|
850
844
|
|
|
851
845
|
// src/components/McpAppCard.tsx
|
|
@@ -26215,13 +26209,13 @@ function ChatInput({
|
|
|
26215
26209
|
const [isSending2, setIsSending] = useState6(false);
|
|
26216
26210
|
void queueKey;
|
|
26217
26211
|
const canSend = !isSending2 && (trimmed.length > 0 || hasAttachments) && (!isStreaming || queueWhileRunning && !hasAttachments && !isStopping);
|
|
26218
|
-
const handleSend = async () => {
|
|
26212
|
+
const handleSend = async (queueWhenRunning = false) => {
|
|
26219
26213
|
if (!canSend || sending.current) return;
|
|
26220
26214
|
sending.current = true;
|
|
26221
26215
|
setIsSending(true);
|
|
26222
26216
|
const submitted = value;
|
|
26223
26217
|
try {
|
|
26224
|
-
const accepted = await onSend(trimmed);
|
|
26218
|
+
const accepted = await onSend(trimmed, queueWhenRunning);
|
|
26225
26219
|
if (accepted === false) return;
|
|
26226
26220
|
if (latestValue.current === submitted) onValueChange("");
|
|
26227
26221
|
} finally {
|
|
@@ -26239,10 +26233,10 @@ function ChatInput({
|
|
|
26239
26233
|
keyCode: event.nativeEvent.keyCode
|
|
26240
26234
|
}, false)) {
|
|
26241
26235
|
event.preventDefault();
|
|
26242
|
-
void handleSend();
|
|
26236
|
+
void handleSend(isQueueShortcut(event));
|
|
26243
26237
|
}
|
|
26244
26238
|
};
|
|
26245
|
-
return /* @__PURE__ */
|
|
26239
|
+
return /* @__PURE__ */ jsxs7(
|
|
26246
26240
|
"div",
|
|
26247
26241
|
{
|
|
26248
26242
|
style: mergesWithPanelAbove ? { "--blade-chat-input-top-border": "0" } : void 0,
|
|
@@ -26254,55 +26248,61 @@ function ChatInput({
|
|
|
26254
26248
|
mergesWithPanelAbove && "pt-0",
|
|
26255
26249
|
className
|
|
26256
26250
|
),
|
|
26257
|
-
children:
|
|
26258
|
-
|
|
26259
|
-
|
|
26260
|
-
|
|
26261
|
-
|
|
26262
|
-
|
|
26263
|
-
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
children: [
|
|
26267
|
-
/* @__PURE__ */ jsx7(
|
|
26268
|
-
"textarea",
|
|
26269
|
-
{
|
|
26270
|
-
value,
|
|
26271
|
-
onChange: (event) => onValueChange(event.target.value),
|
|
26272
|
-
onKeyDown: handleKeyDown,
|
|
26273
|
-
onInput: (event) => {
|
|
26274
|
-
const el = event.currentTarget;
|
|
26275
|
-
el.style.height = "auto";
|
|
26276
|
-
el.style.height = `${Math.min(el.scrollHeight, 192)}px`;
|
|
26277
|
-
},
|
|
26278
|
-
rows: 1,
|
|
26279
|
-
placeholder,
|
|
26280
|
-
"aria-label": "\u804A\u5929\u8F93\u5165",
|
|
26281
|
-
part: "textarea",
|
|
26282
|
-
className: cn(
|
|
26283
|
-
"blade-chat-textarea max-h-48 min-h-[28px] flex-1 resize-none bg-transparent py-1 text-sm leading-6 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.6)]",
|
|
26284
|
-
textareaClassName
|
|
26285
|
-
)
|
|
26286
|
-
}
|
|
26251
|
+
children: [
|
|
26252
|
+
/* @__PURE__ */ jsxs7(
|
|
26253
|
+
"div",
|
|
26254
|
+
{
|
|
26255
|
+
part: "input-inner",
|
|
26256
|
+
className: cn(
|
|
26257
|
+
"blade-chat-input-inner mx-auto flex max-w-[748px] items-end gap-2 border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2",
|
|
26258
|
+
mergesWithPanelAbove ? "rounded-b-[22px]" : "rounded-2xl",
|
|
26259
|
+
innerClassName
|
|
26287
26260
|
),
|
|
26288
|
-
|
|
26289
|
-
|
|
26290
|
-
|
|
26291
|
-
|
|
26292
|
-
|
|
26293
|
-
|
|
26294
|
-
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26299
|
-
|
|
26300
|
-
|
|
26301
|
-
|
|
26302
|
-
|
|
26303
|
-
|
|
26304
|
-
|
|
26305
|
-
|
|
26261
|
+
children: [
|
|
26262
|
+
/* @__PURE__ */ jsx7(
|
|
26263
|
+
"textarea",
|
|
26264
|
+
{
|
|
26265
|
+
value,
|
|
26266
|
+
onChange: (event) => onValueChange(event.target.value),
|
|
26267
|
+
onKeyDown: handleKeyDown,
|
|
26268
|
+
onInput: (event) => {
|
|
26269
|
+
const el = event.currentTarget;
|
|
26270
|
+
el.style.height = "auto";
|
|
26271
|
+
el.style.height = `${Math.min(el.scrollHeight, 192)}px`;
|
|
26272
|
+
},
|
|
26273
|
+
rows: 1,
|
|
26274
|
+
placeholder,
|
|
26275
|
+
"aria-label": "\u804A\u5929\u8F93\u5165",
|
|
26276
|
+
part: "textarea",
|
|
26277
|
+
className: cn(
|
|
26278
|
+
"blade-chat-textarea max-h-48 min-h-[28px] flex-1 resize-none bg-transparent py-1 text-sm leading-6 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.6)]",
|
|
26279
|
+
textareaClassName
|
|
26280
|
+
)
|
|
26281
|
+
}
|
|
26282
|
+
),
|
|
26283
|
+
/* @__PURE__ */ jsx7("div", { part: "input-toolbar", className: cn("blade-chat-input-toolbar flex shrink-0 items-center gap-2", toolbarClassName), children: isStreaming ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
26284
|
+
queueWhileRunning ? /* @__PURE__ */ jsx7("button", { type: "button", onClick: () => void handleSend(), disabled: !canSend, "aria-label": "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F", title: "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] disabled:opacity-40", children: /* @__PURE__ */ jsx7(ArrowUp, { size: 15 }) }) : null,
|
|
26285
|
+
/* @__PURE__ */ jsx7("button", { type: "button", onClick: onStop, disabled: isStopping, "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] transition-opacity hover:opacity-90 disabled:opacity-60", children: isStopping ? /* @__PURE__ */ jsx7(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx7(Square, { size: 12, fill: "currentColor" }) })
|
|
26286
|
+
] }) : /* @__PURE__ */ jsx7(
|
|
26287
|
+
"button",
|
|
26288
|
+
{
|
|
26289
|
+
type: "button",
|
|
26290
|
+
onClick: () => void handleSend(),
|
|
26291
|
+
disabled: !canSend,
|
|
26292
|
+
"aria-label": "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
|
|
26293
|
+
title: "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
|
|
26294
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",
|
|
26295
|
+
children: /* @__PURE__ */ jsx7(ArrowUp, { size: 15 })
|
|
26296
|
+
}
|
|
26297
|
+
) })
|
|
26298
|
+
]
|
|
26299
|
+
}
|
|
26300
|
+
),
|
|
26301
|
+
trimmed && canSend && !hasAttachments && /* @__PURE__ */ jsxs7("div", { className: "mx-auto mt-1 max-w-[748px] text-right text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
26302
|
+
queueShortcutLabel(),
|
|
26303
|
+
" \xB7 \u6392\u961F\u6D88\u606F"
|
|
26304
|
+
] })
|
|
26305
|
+
]
|
|
26306
26306
|
}
|
|
26307
26307
|
);
|
|
26308
26308
|
}
|
|
@@ -26408,7 +26408,7 @@ ${content3}`);
|
|
|
26408
26408
|
{
|
|
26409
26409
|
value,
|
|
26410
26410
|
onValueChange: setValue,
|
|
26411
|
-
onSend: (text4) => onSend(text4 || refs.map((ref) => `@${ref.label}`).join(" "), { refs: pluginRefsForSend(refs, session?.getState().turns) }),
|
|
26411
|
+
onSend: (text4, queueWhenRunning) => onSend(text4 || refs.map((ref) => `@${ref.label}`).join(" "), { queueWhenRunning, refs: pluginRefsForSend(refs, session?.getState().turns) }),
|
|
26412
26412
|
hasAttachments: refs.length > 0,
|
|
26413
26413
|
onKeyDown: (event) => {
|
|
26414
26414
|
if (query === null || event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return;
|
|
@@ -35345,12 +35345,6 @@ function renderNode(node3, context, key) {
|
|
|
35345
35345
|
renderIntrinsic(
|
|
35346
35346
|
context,
|
|
35347
35347
|
"code",
|
|
35348
|
-
// 用字符偏移量而不是行号:增量解析里冻结前缀和尾部是分两次单独
|
|
35349
|
-
// 解析的(`incremental.ts` 的 `shiftPositions` 只搬移了 offset,
|
|
35350
|
-
// 没有跟着搬移 line/column),尾部重新解析出来的节点 line 永远从
|
|
35351
|
-
// 1 数起,冻结边界一推进这个值就会变,两个不同位置的代码块也
|
|
35352
|
-
// 可能撞上同一个相对行号——offset 全程是相对整篇输入的绝对值,
|
|
35353
|
-
// 才是跨帧稳定、真正唯一的标识。
|
|
35354
35348
|
{ className, "data-block-offset": code2.position?.start.offset },
|
|
35355
35349
|
"code",
|
|
35356
35350
|
`${code2.value}
|
|
@@ -35981,7 +35975,6 @@ function CodeBlockPre({ children, ...props }) {
|
|
|
35981
35975
|
className: cn(
|
|
35982
35976
|
"blade-chat-codeblock-body",
|
|
35983
35977
|
props.className,
|
|
35984
|
-
// 原型:13.5px/1.7 等宽、浅底;覆盖 prose 的继承字号与主题里手写的 pre 样式。
|
|
35985
35978
|
"m-0! overflow-x-auto! rounded-none! border-0! bg-[hsl(var(--muted))/0.25]! px-4! py-3.5! font-mono text-[13.5px]! leading-[1.7]! [&_code]:bg-transparent! [&_code]:p-0! [&_code]:font-mono [&_code]:text-[13.5px]! [&_code]:text-[hsl(var(--foreground))]"
|
|
35986
35979
|
),
|
|
35987
35980
|
children
|
|
@@ -38057,7 +38050,6 @@ function parseWebResults(result) {
|
|
|
38057
38050
|
const value = parseJsonValue(result);
|
|
38058
38051
|
const items = isPlainObject3(value) ? toRecordArray(value.results) : toRecordArray(value);
|
|
38059
38052
|
return items.map((item) => ({
|
|
38060
|
-
// text 是当前字段;description 只为读旧会话保留,那时的结果没有正文片段。
|
|
38061
38053
|
description: typeof item.text === "string" ? item.text : typeof item.description === "string" ? item.description : null,
|
|
38062
38054
|
publishedDate: typeof item.published_date === "string" ? item.published_date : null,
|
|
38063
38055
|
title: typeof item.title === "string" ? item.title : null,
|
|
@@ -38681,14 +38673,12 @@ function renderContent({
|
|
|
38681
38673
|
|
|
38682
38674
|
// src/chat/lib/preview-dispatch.ts
|
|
38683
38675
|
var IMAGE_EXTS = [
|
|
38684
|
-
// 静态
|
|
38685
38676
|
".png",
|
|
38686
38677
|
".jpg",
|
|
38687
38678
|
".jpeg",
|
|
38688
38679
|
".bmp",
|
|
38689
38680
|
".svg",
|
|
38690
38681
|
".heic",
|
|
38691
|
-
// 动图(<img> 原生播放)
|
|
38692
38682
|
".gif",
|
|
38693
38683
|
".webp",
|
|
38694
38684
|
".apng",
|
|
@@ -39116,32 +39106,25 @@ function UserMessageBubble({ message, className }) {
|
|
|
39116
39106
|
pluginPills,
|
|
39117
39107
|
topicAssetPills,
|
|
39118
39108
|
/* @__PURE__ */ jsx36(ContextAttachmentPills, { attachments: message.context_attachments }),
|
|
39119
|
-
trimmedClean &&
|
|
39120
|
-
(customBubble != null ? customBubble : /* @__PURE__ */ jsx36(
|
|
39109
|
+
trimmedClean && (customBubble != null ? customBubble : /* @__PURE__ */ jsx36(
|
|
39121
39110
|
"div",
|
|
39122
39111
|
{
|
|
39123
39112
|
part: "user-bubble",
|
|
39124
|
-
className:
|
|
39113
|
+
className: cn(
|
|
39114
|
+
"blade-chat-user-bubble max-w-full rounded-[24px] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-base leading-[1.7] transition-colors duration-200",
|
|
39115
|
+
isSending(message) ? "text-[hsl(var(--muted-foreground))]" : "text-[hsl(var(--user-msg-fg))]"
|
|
39116
|
+
),
|
|
39125
39117
|
children: /* @__PURE__ */ jsx36(
|
|
39126
39118
|
MarkdownContent,
|
|
39127
39119
|
{
|
|
39128
|
-
className: USER_MESSAGE_MARKDOWN_CLASS,
|
|
39120
|
+
className: cn(USER_MESSAGE_MARKDOWN_CLASS, "text-inherit [&_strong]:text-inherit [&_p]:text-inherit"),
|
|
39129
39121
|
controls: { code: true },
|
|
39130
39122
|
children: cleanText
|
|
39131
39123
|
}
|
|
39132
39124
|
)
|
|
39133
39125
|
}
|
|
39134
39126
|
)),
|
|
39135
|
-
trimmedClean &&
|
|
39136
|
-
/* @__PURE__ */ jsx36(LoaderCircle, { size: 12, className: "animate-spin", "aria-hidden": "true" }),
|
|
39137
|
-
/* @__PURE__ */ jsx36("span", { children: "\u53D1\u9001\u4E2D" })
|
|
39138
|
-
] }) : /* @__PURE__ */ jsx36(
|
|
39139
|
-
MessageActions,
|
|
39140
|
-
{
|
|
39141
|
-
content: cleanText,
|
|
39142
|
-
className: "opacity-0 [@media(hover:none)]:opacity-100 transition-opacity group-hover:opacity-100"
|
|
39143
|
-
}
|
|
39144
|
-
))
|
|
39127
|
+
trimmedClean && !isSending(message) && /* @__PURE__ */ jsx36(MessageActions, { content: cleanText, className: "opacity-0 transition-opacity group-hover:opacity-100 [@media(hover:none)]:opacity-100" })
|
|
39145
39128
|
] }) });
|
|
39146
39129
|
}
|
|
39147
39130
|
function ErrorMessageBlock({
|
|
@@ -39574,7 +39557,6 @@ function synthToolCall(loopName, info, desc) {
|
|
|
39574
39557
|
id: loopName,
|
|
39575
39558
|
name: "Agent",
|
|
39576
39559
|
arguments: JSON.stringify({ description: desc || info.description }),
|
|
39577
|
-
// error/cancelled/awaiting_answer 原样透传:失败的步骤卡不能渲染成绿色完成态
|
|
39578
39560
|
status: info.status === "running" ? "pending" : info.status === "error" || info.status === "cancelled" || info.status === "awaiting_answer" ? info.status : "done"
|
|
39579
39561
|
};
|
|
39580
39562
|
}
|
|
@@ -39819,8 +39801,7 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
|
|
|
39819
39801
|
/* @__PURE__ */ jsx38("summary", { className: "cursor-pointer select-none text-xs text-[hsl(var(--muted-foreground))]", children: "\u6700\u7EC8\u8F93\u51FA" }),
|
|
39820
39802
|
/* @__PURE__ */ jsx38("pre", { className: "mt-1.5 max-h-48 overflow-y-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]", children: finalOutput })
|
|
39821
39803
|
] }),
|
|
39822
|
-
status === "done" && hasStepContent &&
|
|
39823
|
-
/* @__PURE__ */ jsx38("div", { className: "py-0.5 text-center text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u23F9 \u6D41\u7A0B\u5230\u6B64\u7ED3\u675F" })
|
|
39804
|
+
status === "done" && hasStepContent && /* @__PURE__ */ jsx38("div", { className: "py-0.5 text-center text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u23F9 \u6D41\u7A0B\u5230\u6B64\u7ED3\u675F" })
|
|
39824
39805
|
] })
|
|
39825
39806
|
] });
|
|
39826
39807
|
}
|
|
@@ -40058,8 +40039,7 @@ function AssistantTurnBlockBase({
|
|
|
40058
40039
|
const allToolCalls = useMemo11(() => messages.flatMap((m2) => m2.tool_calls ?? []), [messages]);
|
|
40059
40040
|
const detailToolCalls = useMemo11(
|
|
40060
40041
|
() => allToolCalls.filter(
|
|
40061
|
-
(toolCall) => formatToolName(toolCall.name) !== "AskUserQuestion" && !isPlanUpdateTool(toolCall) &&
|
|
40062
|
-
!isWorkflowRunToolName2(toolCall.name)
|
|
40042
|
+
(toolCall) => formatToolName(toolCall.name) !== "AskUserQuestion" && !isPlanUpdateTool(toolCall) && !isWorkflowRunToolName2(toolCall.name)
|
|
40063
40043
|
),
|
|
40064
40044
|
[allToolCalls]
|
|
40065
40045
|
);
|
|
@@ -40151,8 +40131,7 @@ function AssistantTurnBlockBase({
|
|
|
40151
40131
|
() => finalMessage ? getOrderedMessageParts(
|
|
40152
40132
|
finalMessage,
|
|
40153
40133
|
(finalMessage.tool_calls ?? []).filter(
|
|
40154
|
-
(toolCall) => !isPlanUpdateTool(toolCall) && formatToolName(toolCall.name) !== "AskUserQuestion" &&
|
|
40155
|
-
!isWorkflowRunToolName2(toolCall.name)
|
|
40134
|
+
(toolCall) => !isPlanUpdateTool(toolCall) && formatToolName(toolCall.name) !== "AskUserQuestion" && !isWorkflowRunToolName2(toolCall.name)
|
|
40156
40135
|
)
|
|
40157
40136
|
) : [],
|
|
40158
40137
|
[finalMessage]
|
|
@@ -40175,8 +40154,6 @@ function AssistantTurnBlockBase({
|
|
|
40175
40154
|
const hasExecutionProcess = detailToolCalls.length > 0 || workflowRunToolCalls.length > 0 || persistentAskUserQuestions.length > 0 || messages.some((message) => Boolean(message.reasoning)) || resourceBlocks.length > 0;
|
|
40176
40155
|
const client = useOptionalBladeClient();
|
|
40177
40156
|
const executionDurationMs = getExecutionDurationMs({
|
|
40178
|
-
// 根消息的 duration 已覆盖等待子智能体的墙钟时间,不能再累计 turnMessages
|
|
40179
|
-
// 里收集到的子循环,否则嵌套和并行 Agent 都会重复计时。
|
|
40180
40157
|
messages,
|
|
40181
40158
|
isStreaming
|
|
40182
40159
|
});
|
|
@@ -40189,7 +40166,6 @@ function AssistantTurnBlockBase({
|
|
|
40189
40166
|
const liveExecutionDurationMs = isStreaming ? getExecutionDurationMs({
|
|
40190
40167
|
messages,
|
|
40191
40168
|
isStreaming,
|
|
40192
|
-
// Direct LLM mode has no Blade session and generates its own local timestamps.
|
|
40193
40169
|
now: sessionId ? getServerTime(client, clock) : Date.now()
|
|
40194
40170
|
}) : executionDurationMs;
|
|
40195
40171
|
const observedMemoryRefs = useMemo11(() => collectMemoryRefs(messages), [messages]);
|
|
@@ -40351,12 +40327,8 @@ function AssistantTurnBlockBase({
|
|
|
40351
40327
|
customization
|
|
40352
40328
|
}
|
|
40353
40329
|
),
|
|
40354
|
-
SHOW_FILE_DELIVERY_CARDS && level === 1 &&
|
|
40355
|
-
/* @__PURE__ */ jsx39(
|
|
40356
|
-
level === 1 && !isStreaming && finalMessageText ? (
|
|
40357
|
-
// 反馈行(原型):轮次底部的复制入口。
|
|
40358
|
-
/* @__PURE__ */ jsx39(MessageActions, { content: finalMessageText, className: "-mt-1.5" })
|
|
40359
|
-
) : null
|
|
40330
|
+
SHOW_FILE_DELIVERY_CARDS && level === 1 && /* @__PURE__ */ jsx39(FileDeliveryCards, { toolCalls: turnToolCalls, sessionId }),
|
|
40331
|
+
level === 1 && !isStreaming && finalMessageText ? /* @__PURE__ */ jsx39(MessageActions, { content: finalMessageText, className: "-mt-1.5" }) : null
|
|
40360
40332
|
]
|
|
40361
40333
|
}
|
|
40362
40334
|
);
|
|
@@ -40834,11 +40806,6 @@ function useMessagePin({
|
|
|
40834
40806
|
getSpacerHeight,
|
|
40835
40807
|
setSpacerHeight,
|
|
40836
40808
|
stopAutoScroll,
|
|
40837
|
-
// 不再内部调用(见下面 reposition 里的说明),但这是公开的 SDK hook 参数,
|
|
40838
|
-
// 删掉会让已经传这个 prop 的调用方在 TS 严格类型下编译不过——留着接口
|
|
40839
|
-
// 不动,只是这里不再用它。
|
|
40840
|
-
// biome-ignore lint/correctness/noUnusedVariables: 保留公开 API 形状
|
|
40841
|
-
scrollToBottom,
|
|
40842
40809
|
margin = DEFAULT_MARGIN_PX
|
|
40843
40810
|
}) {
|
|
40844
40811
|
const pinActiveRef = useRef17(false);
|
|
@@ -41189,7 +41156,6 @@ function buildMessageListBlocks({
|
|
|
41189
41156
|
}
|
|
41190
41157
|
],
|
|
41191
41158
|
key: pendingKey,
|
|
41192
|
-
// pending 的 ID 只在前端临时存在,不能进入虚拟器的持久 key。
|
|
41193
41159
|
persistentId: null,
|
|
41194
41160
|
anchorId: `chat-turn-${assistantTurnCount}`,
|
|
41195
41161
|
isStreaming: true,
|
|
@@ -41565,6 +41531,7 @@ function buildLiteRows({
|
|
|
41565
41531
|
type: "text",
|
|
41566
41532
|
key: block.message.render_id ?? block.key,
|
|
41567
41533
|
role,
|
|
41534
|
+
sending: role === "user" && block.message.status === "streaming",
|
|
41568
41535
|
text: text4,
|
|
41569
41536
|
entryIds: block.message.entry_id ? [block.message.entry_id] : []
|
|
41570
41537
|
};
|
|
@@ -41907,7 +41874,7 @@ function PlainTextMessage({
|
|
|
41907
41874
|
}
|
|
41908
41875
|
);
|
|
41909
41876
|
if (row.role === "user") {
|
|
41910
|
-
return /* @__PURE__ */ jsx42("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx42("div", { className:
|
|
41877
|
+
return /* @__PURE__ */ jsx42("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx42("div", { className: `max-w-[82%] rounded-[24px] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-base leading-[1.7] transition-colors duration-200 ${row.sending ? "text-[hsl(var(--muted-foreground))]" : "text-[hsl(var(--user-msg-fg))]"}`, children: markdown }) });
|
|
41911
41878
|
}
|
|
41912
41879
|
return /* @__PURE__ */ jsxs36(
|
|
41913
41880
|
"div",
|
|
@@ -46543,37 +46510,32 @@ function TurnNavRail({
|
|
|
46543
46510
|
]
|
|
46544
46511
|
}
|
|
46545
46512
|
) : loadingTurnId ? /* @__PURE__ */ jsx47("output", { className: "absolute right-full top-1/2 mr-2 -translate-y-1/2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]", children: "\u6B63\u5728\u5B9A\u4F4D\u5230\u8FD9\u6761\u53D1\u8A00\u2026" }) : null,
|
|
46546
|
-
panelOpen ? (
|
|
46547
|
-
|
|
46548
|
-
|
|
46549
|
-
|
|
46550
|
-
|
|
46551
|
-
|
|
46552
|
-
|
|
46553
|
-
|
|
46554
|
-
|
|
46555
|
-
|
|
46556
|
-
|
|
46557
|
-
|
|
46558
|
-
|
|
46559
|
-
|
|
46560
|
-
|
|
46561
|
-
|
|
46562
|
-
"
|
|
46563
|
-
|
|
46564
|
-
|
|
46565
|
-
|
|
46566
|
-
|
|
46567
|
-
|
|
46568
|
-
|
|
46569
|
-
|
|
46570
|
-
|
|
46571
|
-
|
|
46572
|
-
);
|
|
46573
|
-
})
|
|
46574
|
-
}
|
|
46575
|
-
) })
|
|
46576
|
-
) : null
|
|
46513
|
+
panelOpen ? /* @__PURE__ */ jsx47("div", { className: "absolute right-full top-1/2 -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx47(
|
|
46514
|
+
"div",
|
|
46515
|
+
{
|
|
46516
|
+
ref: listRef,
|
|
46517
|
+
className: "flex max-h-[min(28rem,60vh)] w-80 flex-col overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]",
|
|
46518
|
+
children: items.map((item, index2) => {
|
|
46519
|
+
const isActive = item.id === activeTurnId;
|
|
46520
|
+
const isHovered = item.id === hoveredTurnId;
|
|
46521
|
+
return /* @__PURE__ */ jsx47(
|
|
46522
|
+
"button",
|
|
46523
|
+
{
|
|
46524
|
+
type: "button",
|
|
46525
|
+
"data-turn-id": item.id,
|
|
46526
|
+
onClick: () => onSelectTurn(item.id),
|
|
46527
|
+
onMouseEnter: () => setHoveredTurnId(item.id),
|
|
46528
|
+
className: cn(
|
|
46529
|
+
"shrink-0 truncate px-3 py-1.5 text-left text-xs text-[hsl(var(--popover-foreground))] transition-colors",
|
|
46530
|
+
isHovered ? "bg-[hsl(var(--accent))]" : isActive ? "bg-[hsl(var(--accent)/0.5)]" : "hover:bg-[hsl(var(--accent))]"
|
|
46531
|
+
),
|
|
46532
|
+
children: item.title || `\u7B2C ${index2 + 1} \u8F6E`
|
|
46533
|
+
},
|
|
46534
|
+
item.id
|
|
46535
|
+
);
|
|
46536
|
+
})
|
|
46537
|
+
}
|
|
46538
|
+
) }) : null
|
|
46577
46539
|
] })
|
|
46578
46540
|
}
|
|
46579
46541
|
);
|
|
@@ -46764,10 +46726,6 @@ function MessageListBody({
|
|
|
46764
46726
|
const blocks = buildMessageListBlocks({
|
|
46765
46727
|
messages: messages.filter((message) => message.kind !== "compaction"),
|
|
46766
46728
|
agentLoopNames: agentLoopNameSet,
|
|
46767
|
-
// 服务端可能已经说完了(sessionIsStreaming 变 false),但打字机节流
|
|
46768
|
-
// 还没把最后这点内容追平——block.isStreaming 驱动一大批"完成态"展示
|
|
46769
|
-
// 逻辑(折叠/展开、思考过程是否显示等),提前关掉会出现"字还没打完,
|
|
46770
|
-
// 这堆状态已经按完成态收起来了"这种跟视觉进度对不上的观感。
|
|
46771
46729
|
sessionIsStreaming: sessionIsStreaming || isRevealingAny,
|
|
46772
46730
|
showContexts: false
|
|
46773
46731
|
});
|
|
@@ -46917,22 +46875,16 @@ function MessageListBody({
|
|
|
46917
46875
|
selectEntry: selectNavEntry
|
|
46918
46876
|
} = useTurnNavigation({
|
|
46919
46877
|
sessionId,
|
|
46920
|
-
// 目录只在最新一条用户发言变化时重拉:往上翻页补进更早的发言、助手继续输出都
|
|
46921
|
-
// 不改目录,却会把正在进行的定位误判成过期。窗口被整段替换是另一回事,见 rewriteKey。
|
|
46922
46878
|
reloadKey: latestUserSpeechEntryId(messages),
|
|
46923
46879
|
rewriteKey: historyRewriteRevision,
|
|
46924
46880
|
loadTurnIndex: isSharedSession ? void 0 : session ? () => session.loadTurnIndex() : void 0,
|
|
46925
46881
|
fallbackItems: sharedNavItems,
|
|
46926
|
-
// 会话实例还没建好时没有历史窗口可换,定位按失败处理
|
|
46927
46882
|
locateEntry: (entryId) => session?.locateEntry(entryId) ?? Promise.resolve(false),
|
|
46928
|
-
// 改选一条已加载的发言时不发定位请求,前一次在途的定位得在这里作废。
|
|
46929
46883
|
cancelPendingLocate: () => session?.cancelPendingLocate(),
|
|
46930
46884
|
getLoadedEntryElement: (entryId) => {
|
|
46931
46885
|
const root = containerRef.current;
|
|
46932
46886
|
return root ? findEntryAnchor(root, entryId) : null;
|
|
46933
46887
|
},
|
|
46934
|
-
// 已加载窗口里有这条发言就算"已加载",哪怕它的行还在虚拟前缀的挂载范围之外:
|
|
46935
|
-
// 那些发言该由宿主挂出来再滚,不该发定位请求(分享页更没有定位接口)。
|
|
46936
46888
|
isEntryLoaded: (entryId) => entryIdToBlockIndex.has(entryId),
|
|
46937
46889
|
revealEntry: (entryId) => {
|
|
46938
46890
|
const blockIndex = entryIdToBlockIndex.get(entryId);
|
|
@@ -46956,8 +46908,7 @@ function MessageListBody({
|
|
|
46956
46908
|
}, [activeTurnId, renderBlocks, turnIdToBlockIndex]);
|
|
46957
46909
|
const lastNavTurnId = turnNavItems.at(-1)?.id ?? null;
|
|
46958
46910
|
const layoutSignature = useMemo16(
|
|
46959
|
-
() => `${getMessagesMeasureSignature(messages)}|${postChatFollowup ? `${postChatFollowup.assistant_entry_id}:${postChatFollowup.recaption ?? ""}:${postChatFollowup.suggestions.join("")}` : ""}|${
|
|
46960
|
-
(postChatFollowup?.final_artifacts ?? []).map((artifact) => artifact.target).join(",")}|${[...resultFeedbackByEntry.values()].map((feedback) => `${feedback.assistant_entry_id}:${feedback.updated_at}`).join(",")}`,
|
|
46911
|
+
() => `${getMessagesMeasureSignature(messages)}|${postChatFollowup ? `${postChatFollowup.assistant_entry_id}:${postChatFollowup.recaption ?? ""}:${postChatFollowup.suggestions.join("")}` : ""}|${(postChatFollowup?.final_artifacts ?? []).map((artifact) => artifact.target).join(",")}|${[...resultFeedbackByEntry.values()].map((feedback) => `${feedback.assistant_entry_id}:${feedback.updated_at}`).join(",")}`,
|
|
46961
46912
|
[messages, postChatFollowup, resultFeedbackByEntry]
|
|
46962
46913
|
);
|
|
46963
46914
|
const followupTurnId = useMemo16(() => {
|
|
@@ -48050,10 +48001,7 @@ function useChatActions(sessionId) {
|
|
|
48050
48001
|
const [pendingQueueItemId, setPendingQueueItemId] = useState33(null);
|
|
48051
48002
|
const previousSessionIdRef = useRef28(sessionId);
|
|
48052
48003
|
const send = useCallback15(
|
|
48053
|
-
(msg, targetMode, askuserAnswer, options) => (
|
|
48054
|
-
// 等会话就绪再发:等待回答时要按最新状态把输入当作作答
|
|
48055
|
-
source.whenReady ? source.whenReady(sessionId, (ready) => sendToSession(ready, msg, targetMode, askuserAnswer, options)) : session ? sendToSession(session, msg, targetMode, askuserAnswer, options) : Promise.resolve(false)
|
|
48056
|
-
),
|
|
48004
|
+
(msg, targetMode, askuserAnswer, options) => source.whenReady ? source.whenReady(sessionId, (ready) => sendToSession(ready, msg, targetMode, askuserAnswer, options)) : session ? sendToSession(session, msg, targetMode, askuserAnswer, options) : Promise.resolve(false),
|
|
48057
48005
|
[session, sessionId, source]
|
|
48058
48006
|
);
|
|
48059
48007
|
const withQueue = useCallback15(
|
|
@@ -48380,8 +48328,7 @@ function ChatPanel({
|
|
|
48380
48328
|
[sendUserMessage]
|
|
48381
48329
|
);
|
|
48382
48330
|
const sendNewUserMessage = useCallback17(
|
|
48383
|
-
|
|
48384
|
-
(message, options) => sendUserMessage(message, mode, void 0, { ...options, queueWhenRunning: true }),
|
|
48331
|
+
(message, options) => sendUserMessage(message, mode, void 0, options),
|
|
48385
48332
|
[mode, sendUserMessage]
|
|
48386
48333
|
);
|
|
48387
48334
|
const answerQuestion = useCallback17(
|
|
@@ -48433,12 +48380,6 @@ function ChatPanel({
|
|
|
48433
48380
|
canShareSession,
|
|
48434
48381
|
planPanel: !lite ? /* @__PURE__ */ jsx50(CurrentPlanPanel, { sessionId, className: "border-b border-[hsl(var(--border))] px-4" }) : null,
|
|
48435
48382
|
maxWidthClassName: cn("max-w-3xl", classNames?.chatInputInner),
|
|
48436
|
-
// 队列面板此刻占位时,输入框上两角改直角,跟它拼成一条完整轮廓。
|
|
48437
|
-
// 用面板自己上报的状态,不在宿主侧复算。
|
|
48438
|
-
//
|
|
48439
|
-
// 必须真的**相邻**才算:`composerBanner`(走 statusBarAddon)渲染在
|
|
48440
|
-
// 面板与圆角框之间,两张卡片并不挨着,这时去掉圆角只会让输入框看起来
|
|
48441
|
-
// 缺了个角,却没有东西跟它对上。
|
|
48442
48383
|
mergesWithPanelAbove: queuePanelVisible && !composerBanner,
|
|
48443
48384
|
className: classNames?.chatInputRoot,
|
|
48444
48385
|
innerClassName: classNames?.chatInputInner,
|
|
@@ -49562,4 +49503,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
49562
49503
|
js-yaml/dist/js-yaml.mjs:
|
|
49563
49504
|
(*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
|
|
49564
49505
|
*/
|
|
49565
|
-
//# sourceMappingURL=chunk-
|
|
49506
|
+
//# sourceMappingURL=chunk-M5NAFIU4.js.map
|