@yourgpt/copilot-sdk 2.1.5-alpha.5 → 2.1.5-alpha.7
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/{ThreadManager-DK46fVl3.d.cts → ThreadManager-B12N-zpq.d.cts} +3 -3
- package/dist/{ThreadManager-D7KwT2FJ.d.ts → ThreadManager-BxGOeykx.d.ts} +3 -3
- package/dist/{chunk-KGYDGK3U.cjs → chunk-7GWEW2DU.cjs} +24 -8
- package/dist/chunk-7GWEW2DU.cjs.map +1 -0
- package/dist/{chunk-YLZCTR4O.js → chunk-J5D3AZF6.js} +24 -8
- package/dist/chunk-J5D3AZF6.js.map +1 -0
- package/dist/{chunk-5UGWLGFS.cjs → chunk-M66XAHSW.cjs} +84 -46
- package/dist/chunk-M66XAHSW.cjs.map +1 -0
- package/dist/{chunk-LHLVTGIP.cjs → chunk-NPBOKT63.cjs} +297 -96
- package/dist/chunk-NPBOKT63.cjs.map +1 -0
- package/dist/{chunk-DH6EO6NW.js → chunk-UZHGMDOK.js} +293 -92
- package/dist/chunk-UZHGMDOK.js.map +1 -0
- package/dist/{chunk-ZAOTYA5L.js → chunk-YHW6JZEF.js} +48 -11
- package/dist/chunk-YHW6JZEF.js.map +1 -0
- package/dist/core/index.cjs +72 -72
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/experimental/index.cjs +3 -3
- package/dist/experimental/index.js +2 -2
- package/dist/react/index.cjs +70 -66
- package/dist/react/index.d.cts +207 -5
- package/dist/react/index.d.ts +207 -5
- package/dist/react/index.js +3 -3
- package/dist/ui/index.cjs +1178 -228
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +119 -7
- package/dist/ui/index.d.ts +119 -7
- package/dist/ui/index.js +1173 -227
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5UGWLGFS.cjs.map +0 -1
- package/dist/chunk-DH6EO6NW.js.map +0 -1
- package/dist/chunk-KGYDGK3U.cjs.map +0 -1
- package/dist/chunk-LHLVTGIP.cjs.map +0 -1
- package/dist/chunk-YLZCTR4O.js.map +0 -1
- package/dist/chunk-ZAOTYA5L.js.map +0 -1
package/dist/ui/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useThreadManager } from '../chunk-
|
|
1
|
+
import { useThreadManager } from '../chunk-YHW6JZEF.js';
|
|
2
2
|
import { DEFAULT_MCP_UI_SANDBOX, parseMCPUIMessage } from '../chunk-G4SF2PNQ.js';
|
|
3
3
|
import { cn, Loader, TextShimmerLoader } from '../chunk-TXQ37MAO.js';
|
|
4
4
|
export { Loader, cn } from '../chunk-TXQ37MAO.js';
|
|
5
|
-
import { useCopilot } from '../chunk-
|
|
6
|
-
import { createServerAdapter } from '../chunk-
|
|
5
|
+
import { useCopilot } from '../chunk-UZHGMDOK.js';
|
|
6
|
+
import { createLocalStorageAdapter, createServerAdapter } from '../chunk-J5D3AZF6.js';
|
|
7
7
|
import '../chunk-EWVQWTNV.js';
|
|
8
8
|
import '../chunk-VNLLW3ZI.js';
|
|
9
9
|
import '../chunk-533K2Z7C.js';
|
|
@@ -19,7 +19,7 @@ import '../chunk-MNDGIW47.js';
|
|
|
19
19
|
import '../chunk-VD74IPKB.js';
|
|
20
20
|
import '../chunk-DGUM43GV.js';
|
|
21
21
|
import * as React19 from 'react';
|
|
22
|
-
import React19__default, { memo, createContext, useState, useRef, useId, useCallback, useMemo, useLayoutEffect, useContext, useEffect } from 'react';
|
|
22
|
+
import React19__default, { memo, createContext, useState, useRef, useId, useCallback, useMemo, useLayoutEffect, useContext, useReducer, useEffect } from 'react';
|
|
23
23
|
import { Streamdown } from 'streamdown';
|
|
24
24
|
import { code } from '@streamdown/code';
|
|
25
25
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -31,6 +31,7 @@ import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
|
31
31
|
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
32
32
|
import { Globe, ChevronUp, ChevronDown, ExternalLink } from 'lucide-react';
|
|
33
33
|
import { Popover as Popover$1 } from '@base-ui/react/popover';
|
|
34
|
+
import * as ReactDOM from 'react-dom';
|
|
34
35
|
|
|
35
36
|
var createHeading = (Tag) => {
|
|
36
37
|
const HeadingComponent = ({
|
|
@@ -3453,10 +3454,14 @@ function ThreadPicker({
|
|
|
3453
3454
|
newButtonClassName
|
|
3454
3455
|
}) {
|
|
3455
3456
|
const [isOpen, setIsOpen] = React19.useState(false);
|
|
3457
|
+
const [displayedThreads, setDisplayedThreads] = React19.useState(threads);
|
|
3458
|
+
React19.useEffect(() => {
|
|
3459
|
+
setDisplayedThreads(threads);
|
|
3460
|
+
}, [threads]);
|
|
3456
3461
|
const selectedThread = React19.useMemo(() => {
|
|
3457
3462
|
if (!value) return null;
|
|
3458
|
-
return
|
|
3459
|
-
}, [value,
|
|
3463
|
+
return displayedThreads.find((t) => t.id === value) ?? null;
|
|
3464
|
+
}, [value, displayedThreads]);
|
|
3460
3465
|
const handleSelect = (threadId) => {
|
|
3461
3466
|
onSelect?.(threadId);
|
|
3462
3467
|
setIsOpen(false);
|
|
@@ -3465,6 +3470,10 @@ function ThreadPicker({
|
|
|
3465
3470
|
onNewThread?.();
|
|
3466
3471
|
setIsOpen(false);
|
|
3467
3472
|
};
|
|
3473
|
+
const handleDelete = (threadId) => {
|
|
3474
|
+
setDisplayedThreads((prev) => prev.filter((t) => t.id !== threadId));
|
|
3475
|
+
onDeleteThread?.(threadId);
|
|
3476
|
+
};
|
|
3468
3477
|
return /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
3469
3478
|
/* @__PURE__ */ jsxs(
|
|
3470
3479
|
PopoverTrigger,
|
|
@@ -3517,7 +3526,7 @@ function ThreadPicker({
|
|
|
3517
3526
|
]
|
|
3518
3527
|
}
|
|
3519
3528
|
),
|
|
3520
|
-
|
|
3529
|
+
displayedThreads.length > 0 ? displayedThreads.map((thread) => /* @__PURE__ */ jsxs(
|
|
3521
3530
|
"div",
|
|
3522
3531
|
{
|
|
3523
3532
|
className: cn(
|
|
@@ -3553,7 +3562,7 @@ function ThreadPicker({
|
|
|
3553
3562
|
type: "button",
|
|
3554
3563
|
onClick: (e) => {
|
|
3555
3564
|
e.stopPropagation();
|
|
3556
|
-
|
|
3565
|
+
handleDelete(thread.id);
|
|
3557
3566
|
},
|
|
3558
3567
|
className: "flex-shrink-0 p-1 rounded opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-all focus:opacity-100 focus:outline-none",
|
|
3559
3568
|
"aria-label": "Delete thread",
|
|
@@ -4555,17 +4564,37 @@ function DefaultMessage({
|
|
|
4555
4564
|
)
|
|
4556
4565
|
] })
|
|
4557
4566
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4558
|
-
|
|
4559
|
-
/* @__PURE__ */
|
|
4560
|
-
|
|
4567
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
4568
|
+
/* @__PURE__ */ jsxs(
|
|
4569
|
+
"div",
|
|
4561
4570
|
{
|
|
4562
4571
|
className: cn(
|
|
4563
|
-
"csdk-message-user rounded-
|
|
4572
|
+
"csdk-message-user rounded-2xl overflow-hidden bg-primary text-primary-foreground",
|
|
4573
|
+
hasAttachments && "p-[3px]",
|
|
4574
|
+
hasAttachments && !message.content && "max-w-[260px]",
|
|
4575
|
+
hasAttachments && message.content && "max-w-[280px]",
|
|
4576
|
+
!hasAttachments && "",
|
|
4564
4577
|
userMessageClassName
|
|
4565
4578
|
),
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4579
|
+
children: [
|
|
4580
|
+
hasAttachments && /* @__PURE__ */ jsx(
|
|
4581
|
+
MessageMedia,
|
|
4582
|
+
{
|
|
4583
|
+
attachments: message.attachments,
|
|
4584
|
+
hasText: !!message.content,
|
|
4585
|
+
align: "end"
|
|
4586
|
+
}
|
|
4587
|
+
),
|
|
4588
|
+
message.content && /* @__PURE__ */ jsx(
|
|
4589
|
+
MessageContent,
|
|
4590
|
+
{
|
|
4591
|
+
className: cn("px-4 py-2"),
|
|
4592
|
+
markdown: true,
|
|
4593
|
+
size,
|
|
4594
|
+
children: message.content
|
|
4595
|
+
}
|
|
4596
|
+
)
|
|
4597
|
+
]
|
|
4569
4598
|
}
|
|
4570
4599
|
),
|
|
4571
4600
|
showEditBtn && /* @__PURE__ */ jsx(
|
|
@@ -4579,7 +4608,7 @@ function DefaultMessage({
|
|
|
4579
4608
|
"size-6 flex items-center justify-center rounded-full",
|
|
4580
4609
|
"text-muted-foreground bg-background border border-border shadow-sm",
|
|
4581
4610
|
"opacity-0 group-hover/user-msg:opacity-100 transition-opacity",
|
|
4582
|
-
"hover:text-foreground hover:bg-muted"
|
|
4611
|
+
"hover:text-foreground hover:bg-muted cursor-pointer"
|
|
4583
4612
|
),
|
|
4584
4613
|
children: /* @__PURE__ */ jsxs(
|
|
4585
4614
|
"svg",
|
|
@@ -4601,7 +4630,6 @@ function DefaultMessage({
|
|
|
4601
4630
|
}
|
|
4602
4631
|
)
|
|
4603
4632
|
] }),
|
|
4604
|
-
hasAttachments && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2 justify-end", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsx(AttachmentPreview, { attachment }, index)) }),
|
|
4605
4633
|
showBranchNav && /* @__PURE__ */ jsx(
|
|
4606
4634
|
BranchNavigator,
|
|
4607
4635
|
{
|
|
@@ -4873,7 +4901,14 @@ function DefaultMessage({
|
|
|
4873
4901
|
tool.id
|
|
4874
4902
|
);
|
|
4875
4903
|
}) }),
|
|
4876
|
-
message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: "
|
|
4904
|
+
message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: "csdk-assistant-attachments mt-2", children: /* @__PURE__ */ jsx(
|
|
4905
|
+
MessageMedia,
|
|
4906
|
+
{
|
|
4907
|
+
attachments: message.attachments,
|
|
4908
|
+
hasText: !!message.content,
|
|
4909
|
+
align: "start"
|
|
4910
|
+
}
|
|
4911
|
+
) }),
|
|
4877
4912
|
shouldShowSources && /* @__PURE__ */ jsx(
|
|
4878
4913
|
SourceGroup,
|
|
4879
4914
|
{
|
|
@@ -4900,83 +4935,379 @@ function DefaultMessage({
|
|
|
4900
4935
|
] })
|
|
4901
4936
|
] });
|
|
4902
4937
|
}
|
|
4903
|
-
function
|
|
4904
|
-
|
|
4905
|
-
if (attachment.
|
|
4906
|
-
return
|
|
4907
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: attachment.type }),
|
|
4908
|
-
/* @__PURE__ */ jsx("span", { children: attachment.filename || "Attachment" })
|
|
4909
|
-
] });
|
|
4910
|
-
}
|
|
4911
|
-
let src;
|
|
4912
|
-
if (attachment.url) {
|
|
4913
|
-
src = attachment.url;
|
|
4914
|
-
} else if (attachment.data) {
|
|
4915
|
-
src = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType};base64,${attachment.data}`;
|
|
4916
|
-
} else {
|
|
4917
|
-
return null;
|
|
4938
|
+
function getAttachmentSrc(attachment) {
|
|
4939
|
+
if (attachment.url) return attachment.url;
|
|
4940
|
+
if (attachment.data) {
|
|
4941
|
+
return attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType};base64,${attachment.data}`;
|
|
4918
4942
|
}
|
|
4943
|
+
return null;
|
|
4944
|
+
}
|
|
4945
|
+
function ImageLightbox({
|
|
4946
|
+
src,
|
|
4947
|
+
alt,
|
|
4948
|
+
onClose
|
|
4949
|
+
}) {
|
|
4950
|
+
const [closing, setClosing] = React19.useState(false);
|
|
4951
|
+
const backdropRef = React19.useRef(null);
|
|
4952
|
+
const handleClose = React19.useCallback(() => {
|
|
4953
|
+
setClosing(true);
|
|
4954
|
+
setTimeout(onClose, 180);
|
|
4955
|
+
}, [onClose]);
|
|
4956
|
+
React19.useEffect(() => {
|
|
4957
|
+
const handler = (e) => {
|
|
4958
|
+
if (e.key === "Escape") handleClose();
|
|
4959
|
+
};
|
|
4960
|
+
document.addEventListener("keydown", handler);
|
|
4961
|
+
return () => document.removeEventListener("keydown", handler);
|
|
4962
|
+
}, [handleClose]);
|
|
4963
|
+
React19.useEffect(() => {
|
|
4964
|
+
const prev = document.body.style.overflow;
|
|
4965
|
+
document.body.style.overflow = "hidden";
|
|
4966
|
+
return () => {
|
|
4967
|
+
document.body.style.overflow = prev;
|
|
4968
|
+
};
|
|
4969
|
+
}, []);
|
|
4970
|
+
const portal = /* @__PURE__ */ jsxs(
|
|
4971
|
+
"div",
|
|
4972
|
+
{
|
|
4973
|
+
ref: backdropRef,
|
|
4974
|
+
className: "csdk-lightbox csdk-lightbox-backdrop fixed inset-0 z-[9999] flex items-center justify-center cursor-zoom-out",
|
|
4975
|
+
onClick: handleClose,
|
|
4976
|
+
style: {
|
|
4977
|
+
animation: closing ? "csdk-lightbox-backdrop-out 180ms ease-in forwards" : "csdk-lightbox-backdrop-in 200ms ease-out forwards"
|
|
4978
|
+
},
|
|
4979
|
+
children: [
|
|
4980
|
+
/* @__PURE__ */ jsx(
|
|
4981
|
+
"div",
|
|
4982
|
+
{
|
|
4983
|
+
className: "csdk-lightbox-scrim absolute inset-0",
|
|
4984
|
+
style: {
|
|
4985
|
+
backgroundColor: "rgba(0, 0, 0, 0.88)",
|
|
4986
|
+
backdropFilter: "blur(12px)",
|
|
4987
|
+
WebkitBackdropFilter: "blur(12px)",
|
|
4988
|
+
animation: closing ? "csdk-lightbox-fade-out 180ms ease-in forwards" : "csdk-lightbox-fade-in 200ms ease-out forwards"
|
|
4989
|
+
}
|
|
4990
|
+
}
|
|
4991
|
+
),
|
|
4992
|
+
/* @__PURE__ */ jsxs(
|
|
4993
|
+
"div",
|
|
4994
|
+
{
|
|
4995
|
+
className: "csdk-lightbox-content relative z-10 max-w-[90vw] max-h-[90vh]",
|
|
4996
|
+
style: {
|
|
4997
|
+
animation: closing ? "csdk-lightbox-img-out 180ms ease-in forwards" : "csdk-lightbox-img-in 220ms cubic-bezier(0.22, 1, 0.36, 1) forwards"
|
|
4998
|
+
},
|
|
4999
|
+
onClick: (e) => e.stopPropagation(),
|
|
5000
|
+
children: [
|
|
5001
|
+
/* @__PURE__ */ jsx(
|
|
5002
|
+
"img",
|
|
5003
|
+
{
|
|
5004
|
+
src,
|
|
5005
|
+
alt,
|
|
5006
|
+
className: "csdk-lightbox-image max-w-full max-h-[90vh] object-contain rounded-xl",
|
|
5007
|
+
style: { boxShadow: "0 25px 50px -12px rgba(0,0,0,0.5)" },
|
|
5008
|
+
draggable: false
|
|
5009
|
+
}
|
|
5010
|
+
),
|
|
5011
|
+
/* @__PURE__ */ jsx(
|
|
5012
|
+
"button",
|
|
5013
|
+
{
|
|
5014
|
+
type: "button",
|
|
5015
|
+
className: "csdk-lightbox-close absolute -top-3 -right-3 size-8 flex items-center justify-center rounded-full shadow-lg transition-[background,transform] duration-150 cursor-pointer active:scale-95",
|
|
5016
|
+
style: { backgroundColor: "rgba(255,255,255,0.9)" },
|
|
5017
|
+
onMouseEnter: (e) => {
|
|
5018
|
+
e.currentTarget.style.backgroundColor = "rgba(255,255,255,1)";
|
|
5019
|
+
},
|
|
5020
|
+
onMouseLeave: (e) => {
|
|
5021
|
+
e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.9)";
|
|
5022
|
+
},
|
|
5023
|
+
onClick: handleClose,
|
|
5024
|
+
children: /* @__PURE__ */ jsxs(
|
|
5025
|
+
"svg",
|
|
5026
|
+
{
|
|
5027
|
+
className: "size-4",
|
|
5028
|
+
style: { color: "#333" },
|
|
5029
|
+
fill: "none",
|
|
5030
|
+
viewBox: "0 0 24 24",
|
|
5031
|
+
stroke: "currentColor",
|
|
5032
|
+
strokeWidth: 2.5,
|
|
5033
|
+
strokeLinecap: "round",
|
|
5034
|
+
strokeLinejoin: "round",
|
|
5035
|
+
children: [
|
|
5036
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
5037
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
5038
|
+
]
|
|
5039
|
+
}
|
|
5040
|
+
)
|
|
5041
|
+
}
|
|
5042
|
+
)
|
|
5043
|
+
]
|
|
5044
|
+
}
|
|
5045
|
+
),
|
|
5046
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
5047
|
+
@keyframes csdk-lightbox-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
5048
|
+
@keyframes csdk-lightbox-fade-out { from { opacity: 1; } to { opacity: 0; } }
|
|
5049
|
+
@keyframes csdk-lightbox-img-in { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } }
|
|
5050
|
+
@keyframes csdk-lightbox-img-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }
|
|
5051
|
+
@keyframes csdk-lightbox-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
|
|
5052
|
+
@keyframes csdk-lightbox-backdrop-out { from { opacity: 1; } to { opacity: 0; } }
|
|
5053
|
+
` })
|
|
5054
|
+
]
|
|
5055
|
+
}
|
|
5056
|
+
);
|
|
5057
|
+
return typeof document !== "undefined" ? ReactDOM.createPortal(portal, document.body) : null;
|
|
5058
|
+
}
|
|
5059
|
+
function ImageThumb({
|
|
5060
|
+
src,
|
|
5061
|
+
alt,
|
|
5062
|
+
className
|
|
5063
|
+
}) {
|
|
5064
|
+
const [expanded, setExpanded] = React19.useState(false);
|
|
4919
5065
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4920
5066
|
/* @__PURE__ */ jsx(
|
|
4921
5067
|
"button",
|
|
4922
5068
|
{
|
|
4923
5069
|
type: "button",
|
|
4924
5070
|
onClick: () => setExpanded(true),
|
|
4925
|
-
className:
|
|
5071
|
+
className: cn(
|
|
5072
|
+
"csdk-attachment-image relative overflow-hidden cursor-zoom-in",
|
|
5073
|
+
"transition-[opacity,transform] duration-150 hover:opacity-90 active:scale-[0.98]",
|
|
5074
|
+
className
|
|
5075
|
+
),
|
|
5076
|
+
style: { backgroundColor: "#000" },
|
|
4926
5077
|
children: /* @__PURE__ */ jsx(
|
|
4927
5078
|
"img",
|
|
4928
5079
|
{
|
|
4929
5080
|
src,
|
|
4930
|
-
alt
|
|
4931
|
-
className: "
|
|
5081
|
+
alt,
|
|
5082
|
+
className: "w-full h-full object-cover",
|
|
5083
|
+
loading: "lazy",
|
|
5084
|
+
draggable: false
|
|
4932
5085
|
}
|
|
4933
5086
|
)
|
|
4934
5087
|
}
|
|
4935
5088
|
),
|
|
4936
|
-
expanded && /* @__PURE__ */ jsx(
|
|
5089
|
+
expanded && /* @__PURE__ */ jsx(ImageLightbox, { src, alt, onClose: () => setExpanded(false) })
|
|
5090
|
+
] });
|
|
5091
|
+
}
|
|
5092
|
+
function FileCard({ attachment }) {
|
|
5093
|
+
const isPdfFile = isPdf(attachment);
|
|
5094
|
+
const isAudio = attachment.type === "audio";
|
|
5095
|
+
const isVideo = attachment.type === "video";
|
|
5096
|
+
const accent = isPdfFile ? { color: "#ef4444", bg: "rgba(239,68,68,0.12)" } : isAudio ? { color: "#10b981", bg: "rgba(16,185,129,0.12)" } : isVideo ? { color: "#8b5cf6", bg: "rgba(139,92,246,0.12)" } : { color: "#3b82f6", bg: "rgba(59,130,246,0.12)" };
|
|
5097
|
+
const label = isPdfFile ? "PDF" : attachment.mimeType?.split("/")[1]?.toUpperCase() || attachment.type?.toUpperCase() || "FILE";
|
|
5098
|
+
const filename = attachment.filename || "Attachment";
|
|
5099
|
+
const href = attachment.url || (attachment.data?.startsWith("data:") ? attachment.data : null);
|
|
5100
|
+
const cssClass = isPdfFile ? "csdk-attachment-pdf" : "csdk-attachment-file";
|
|
5101
|
+
return /* @__PURE__ */ jsxs(
|
|
5102
|
+
"a",
|
|
5103
|
+
{
|
|
5104
|
+
href: href ?? void 0,
|
|
5105
|
+
target: "_blank",
|
|
5106
|
+
rel: "noopener noreferrer",
|
|
5107
|
+
download: isPdfFile ? void 0 : attachment.filename,
|
|
5108
|
+
className: cn(
|
|
5109
|
+
cssClass,
|
|
5110
|
+
"flex items-center gap-2 rounded-lg min-w-0 w-full",
|
|
5111
|
+
"px-2 py-1.5 cursor-pointer transition-opacity duration-150 hover:opacity-80",
|
|
5112
|
+
"no-underline"
|
|
5113
|
+
),
|
|
5114
|
+
style: { backgroundColor: "rgba(255,255,255,0.92)", color: "#1a1a1a" },
|
|
5115
|
+
onClick: (e) => {
|
|
5116
|
+
if (!href) e.preventDefault();
|
|
5117
|
+
},
|
|
5118
|
+
children: [
|
|
5119
|
+
/* @__PURE__ */ jsx(
|
|
5120
|
+
"div",
|
|
5121
|
+
{
|
|
5122
|
+
className: "size-8 rounded-md flex items-center justify-center shrink-0",
|
|
5123
|
+
style: { backgroundColor: accent.bg },
|
|
5124
|
+
children: /* @__PURE__ */ jsx(
|
|
5125
|
+
"svg",
|
|
5126
|
+
{
|
|
5127
|
+
className: "size-4",
|
|
5128
|
+
viewBox: "0 0 24 24",
|
|
5129
|
+
fill: "none",
|
|
5130
|
+
stroke: accent.color,
|
|
5131
|
+
strokeWidth: 1.8,
|
|
5132
|
+
strokeLinecap: "round",
|
|
5133
|
+
strokeLinejoin: "round",
|
|
5134
|
+
children: isPdfFile || !isAudio && !isVideo ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5135
|
+
/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5136
|
+
/* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5137
|
+
] }) : isAudio ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5138
|
+
/* @__PURE__ */ jsx("path", { d: "M9 18V5l12-2v13" }),
|
|
5139
|
+
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "18", r: "3" }),
|
|
5140
|
+
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "16", r: "3" })
|
|
5141
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5142
|
+
/* @__PURE__ */ jsx("path", { d: "m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.934a.5.5 0 0 0-.777-.416L16 11" }),
|
|
5143
|
+
/* @__PURE__ */ jsx("rect", { width: "14", height: "12", x: "2", y: "6", rx: "2" })
|
|
5144
|
+
] })
|
|
5145
|
+
}
|
|
5146
|
+
)
|
|
5147
|
+
}
|
|
5148
|
+
),
|
|
5149
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
5150
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium truncate leading-tight", children: filename }),
|
|
5151
|
+
/* @__PURE__ */ jsx(
|
|
5152
|
+
"p",
|
|
5153
|
+
{
|
|
5154
|
+
className: "text-[9px] font-semibold uppercase tracking-wider leading-tight mt-0.5",
|
|
5155
|
+
style: { color: accent.color },
|
|
5156
|
+
children: label
|
|
5157
|
+
}
|
|
5158
|
+
)
|
|
5159
|
+
] }),
|
|
5160
|
+
href && /* @__PURE__ */ jsx(
|
|
5161
|
+
"div",
|
|
5162
|
+
{
|
|
5163
|
+
className: "size-6 rounded-md flex items-center justify-center shrink-0",
|
|
5164
|
+
style: { backgroundColor: "rgba(0,0,0,0.05)" },
|
|
5165
|
+
children: /* @__PURE__ */ jsxs(
|
|
5166
|
+
"svg",
|
|
5167
|
+
{
|
|
5168
|
+
className: "size-3",
|
|
5169
|
+
viewBox: "0 0 24 24",
|
|
5170
|
+
fill: "none",
|
|
5171
|
+
stroke: "currentColor",
|
|
5172
|
+
strokeWidth: 2.5,
|
|
5173
|
+
strokeLinecap: "round",
|
|
5174
|
+
strokeLinejoin: "round",
|
|
5175
|
+
style: { opacity: 0.35 },
|
|
5176
|
+
children: [
|
|
5177
|
+
/* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
5178
|
+
/* @__PURE__ */ jsx("polyline", { points: "7 10 12 15 17 10" }),
|
|
5179
|
+
/* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
|
|
5180
|
+
]
|
|
5181
|
+
}
|
|
5182
|
+
)
|
|
5183
|
+
}
|
|
5184
|
+
)
|
|
5185
|
+
]
|
|
5186
|
+
}
|
|
5187
|
+
);
|
|
5188
|
+
}
|
|
5189
|
+
function ImageGrid({
|
|
5190
|
+
images,
|
|
5191
|
+
bubbleRadius
|
|
5192
|
+
}) {
|
|
5193
|
+
const srcs = images.map((img) => getAttachmentSrc(img)).filter(Boolean);
|
|
5194
|
+
if (srcs.length === 0) return null;
|
|
5195
|
+
const innerRadius = bubbleRadius ? `calc(${bubbleRadius} - 2px)` : "0.875rem";
|
|
5196
|
+
if (srcs.length === 1) {
|
|
5197
|
+
return /* @__PURE__ */ jsx(
|
|
5198
|
+
"div",
|
|
5199
|
+
{
|
|
5200
|
+
className: "csdk-attachment-grid",
|
|
5201
|
+
style: { borderRadius: innerRadius, overflow: "hidden" },
|
|
5202
|
+
children: /* @__PURE__ */ jsx(
|
|
5203
|
+
ImageThumb,
|
|
5204
|
+
{
|
|
5205
|
+
src: srcs[0],
|
|
5206
|
+
alt: images[0].filename || "Image",
|
|
5207
|
+
className: "w-full"
|
|
5208
|
+
}
|
|
5209
|
+
)
|
|
5210
|
+
}
|
|
5211
|
+
);
|
|
5212
|
+
}
|
|
5213
|
+
if (srcs.length === 2) {
|
|
5214
|
+
return /* @__PURE__ */ jsx(
|
|
4937
5215
|
"div",
|
|
4938
5216
|
{
|
|
4939
|
-
className: "csdk-
|
|
4940
|
-
|
|
4941
|
-
children: /* @__PURE__ */
|
|
5217
|
+
className: "csdk-attachment-grid grid grid-cols-2 gap-[2px]",
|
|
5218
|
+
style: { borderRadius: innerRadius, overflow: "hidden" },
|
|
5219
|
+
children: srcs.map((src, i) => /* @__PURE__ */ jsx(
|
|
5220
|
+
ImageThumb,
|
|
5221
|
+
{
|
|
5222
|
+
src,
|
|
5223
|
+
alt: images[i].filename || "Image",
|
|
5224
|
+
className: "aspect-square"
|
|
5225
|
+
},
|
|
5226
|
+
i
|
|
5227
|
+
))
|
|
5228
|
+
}
|
|
5229
|
+
);
|
|
5230
|
+
}
|
|
5231
|
+
if (srcs.length === 3) {
|
|
5232
|
+
return /* @__PURE__ */ jsxs(
|
|
5233
|
+
"div",
|
|
5234
|
+
{
|
|
5235
|
+
className: "csdk-attachment-grid grid grid-cols-2 gap-[2px]",
|
|
5236
|
+
style: { borderRadius: innerRadius, overflow: "hidden" },
|
|
5237
|
+
children: [
|
|
4942
5238
|
/* @__PURE__ */ jsx(
|
|
4943
|
-
|
|
5239
|
+
ImageThumb,
|
|
4944
5240
|
{
|
|
4945
|
-
src,
|
|
4946
|
-
alt:
|
|
4947
|
-
className: "
|
|
5241
|
+
src: srcs[0],
|
|
5242
|
+
alt: images[0].filename || "Image",
|
|
5243
|
+
className: "col-span-2 max-h-[180px] min-h-[100px]"
|
|
4948
5244
|
}
|
|
4949
5245
|
),
|
|
4950
5246
|
/* @__PURE__ */ jsx(
|
|
4951
|
-
|
|
5247
|
+
ImageThumb,
|
|
4952
5248
|
{
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
viewBox: "0 0 24 24",
|
|
4965
|
-
stroke: "currentColor",
|
|
4966
|
-
strokeWidth: 2,
|
|
4967
|
-
children: /* @__PURE__ */ jsx(
|
|
4968
|
-
"path",
|
|
4969
|
-
{
|
|
4970
|
-
strokeLinecap: "round",
|
|
4971
|
-
strokeLinejoin: "round",
|
|
4972
|
-
d: "M6 18L18 6M6 6l12 12"
|
|
4973
|
-
}
|
|
4974
|
-
)
|
|
4975
|
-
}
|
|
4976
|
-
)
|
|
5249
|
+
src: srcs[1],
|
|
5250
|
+
alt: images[1].filename || "Image",
|
|
5251
|
+
className: "aspect-square"
|
|
5252
|
+
}
|
|
5253
|
+
),
|
|
5254
|
+
/* @__PURE__ */ jsx(
|
|
5255
|
+
ImageThumb,
|
|
5256
|
+
{
|
|
5257
|
+
src: srcs[2],
|
|
5258
|
+
alt: images[2].filename || "Image",
|
|
5259
|
+
className: "aspect-square"
|
|
4977
5260
|
}
|
|
4978
5261
|
)
|
|
4979
|
-
]
|
|
5262
|
+
]
|
|
5263
|
+
}
|
|
5264
|
+
);
|
|
5265
|
+
}
|
|
5266
|
+
const showOverlay = srcs.length > 4;
|
|
5267
|
+
const gridSrcs = srcs.slice(0, 4);
|
|
5268
|
+
return /* @__PURE__ */ jsx(
|
|
5269
|
+
"div",
|
|
5270
|
+
{
|
|
5271
|
+
className: "csdk-attachment-grid grid grid-cols-2 gap-[2px]",
|
|
5272
|
+
style: { borderRadius: innerRadius, overflow: "hidden" },
|
|
5273
|
+
children: gridSrcs.map((src, i) => /* @__PURE__ */ jsxs("div", { className: "relative aspect-square", children: [
|
|
5274
|
+
/* @__PURE__ */ jsx(
|
|
5275
|
+
ImageThumb,
|
|
5276
|
+
{
|
|
5277
|
+
src,
|
|
5278
|
+
alt: images[i].filename || "Image",
|
|
5279
|
+
className: "w-full h-full"
|
|
5280
|
+
}
|
|
5281
|
+
),
|
|
5282
|
+
i === 3 && showOverlay && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs("span", { className: "text-white text-lg font-semibold", children: [
|
|
5283
|
+
"+",
|
|
5284
|
+
srcs.length - 4
|
|
5285
|
+
] }) })
|
|
5286
|
+
] }, i))
|
|
5287
|
+
}
|
|
5288
|
+
);
|
|
5289
|
+
}
|
|
5290
|
+
function isPdf(a) {
|
|
5291
|
+
return a.mimeType === "application/pdf" || a.filename?.toLowerCase().endsWith(".pdf") === true;
|
|
5292
|
+
}
|
|
5293
|
+
function MessageMedia({
|
|
5294
|
+
attachments,
|
|
5295
|
+
hasText,
|
|
5296
|
+
align = "end"
|
|
5297
|
+
}) {
|
|
5298
|
+
const images = attachments.filter((a) => a.type === "image");
|
|
5299
|
+
const pdfs = attachments.filter((a) => isPdf(a));
|
|
5300
|
+
const files = attachments.filter((a) => a.type !== "image" && !isPdf(a));
|
|
5301
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5302
|
+
images.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("csdk-attachment-images", hasText ? "mb-0" : ""), children: /* @__PURE__ */ jsx(ImageGrid, { images, bubbleRadius: "0.5rem" }) }),
|
|
5303
|
+
(pdfs.length > 0 || files.length > 0) && /* @__PURE__ */ jsx(
|
|
5304
|
+
"div",
|
|
5305
|
+
{
|
|
5306
|
+
className: cn(
|
|
5307
|
+
"csdk-attachment-files flex flex-col gap-1",
|
|
5308
|
+
hasText || images.length > 0 ? "px-1.5 pb-1.5 pt-1" : "p-1.5"
|
|
5309
|
+
),
|
|
5310
|
+
children: [...pdfs, ...files].map((file, i) => /* @__PURE__ */ jsx(FileCard, { attachment: file }, i))
|
|
4980
5311
|
}
|
|
4981
5312
|
)
|
|
4982
5313
|
] });
|
|
@@ -5571,7 +5902,8 @@ function ChatComponent({
|
|
|
5571
5902
|
allowedFileTypes = DEFAULT_ALLOWED_TYPES2,
|
|
5572
5903
|
attachmentsEnabled = true,
|
|
5573
5904
|
attachmentsDisabledTooltip = "Attachments not supported by this model",
|
|
5574
|
-
|
|
5905
|
+
upload: uploadProp,
|
|
5906
|
+
processAttachment: deprecatedProcessAttachment,
|
|
5575
5907
|
// Suggestions
|
|
5576
5908
|
suggestions = [],
|
|
5577
5909
|
onSuggestionClick,
|
|
@@ -5670,8 +6002,34 @@ function ChatComponent({
|
|
|
5670
6002
|
]);
|
|
5671
6003
|
try {
|
|
5672
6004
|
let attachment;
|
|
5673
|
-
|
|
5674
|
-
|
|
6005
|
+
const uploader = uploadProp ?? deprecatedProcessAttachment;
|
|
6006
|
+
if (typeof uploader === "function") {
|
|
6007
|
+
attachment = await uploader(file);
|
|
6008
|
+
} else if (uploader) {
|
|
6009
|
+
const config = typeof uploader === "string" ? { url: uploader } : uploader;
|
|
6010
|
+
const extraHeaders = typeof config.headers === "function" ? config.headers() : config.headers;
|
|
6011
|
+
const extraBody = typeof config.body === "function" ? config.body() : config.body;
|
|
6012
|
+
const data = await fileToBase642(file);
|
|
6013
|
+
const res = await fetch(config.url, {
|
|
6014
|
+
method: "POST",
|
|
6015
|
+
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
6016
|
+
body: JSON.stringify({
|
|
6017
|
+
data,
|
|
6018
|
+
mimeType: file.type,
|
|
6019
|
+
filename: file.name,
|
|
6020
|
+
...extraBody
|
|
6021
|
+
})
|
|
6022
|
+
});
|
|
6023
|
+
if (!res.ok) throw new Error(`Upload failed: ${res.status}`);
|
|
6024
|
+
const result = await res.json();
|
|
6025
|
+
const url = result.url ?? result.data?.url;
|
|
6026
|
+
if (!url) throw new Error("Upload returned no URL");
|
|
6027
|
+
attachment = {
|
|
6028
|
+
type: getAttachmentType2(file.type),
|
|
6029
|
+
url,
|
|
6030
|
+
mimeType: file.type,
|
|
6031
|
+
filename: file.name
|
|
6032
|
+
};
|
|
5675
6033
|
} else {
|
|
5676
6034
|
const data = await fileToBase642(file);
|
|
5677
6035
|
attachment = {
|
|
@@ -5699,7 +6057,13 @@ function ChatComponent({
|
|
|
5699
6057
|
}
|
|
5700
6058
|
}
|
|
5701
6059
|
},
|
|
5702
|
-
[
|
|
6060
|
+
[
|
|
6061
|
+
attachmentsEnabled,
|
|
6062
|
+
maxFileSize,
|
|
6063
|
+
isFileTypeAllowed,
|
|
6064
|
+
uploadProp,
|
|
6065
|
+
deprecatedProcessAttachment
|
|
6066
|
+
]
|
|
5703
6067
|
);
|
|
5704
6068
|
const handleInputChange = useCallback(
|
|
5705
6069
|
(e) => {
|
|
@@ -5843,7 +6207,7 @@ function ChatComponent({
|
|
|
5843
6207
|
onDragLeave: handleDragLeave,
|
|
5844
6208
|
onDrop: handleDrop,
|
|
5845
6209
|
children: [
|
|
5846
|
-
isDragging && /* @__PURE__ */ jsx("div", { className: "csdk-dropzone-overlay absolute inset-0 z-50 bg-primary/10 border-2 border-dashed border-primary flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "text-primary font-medium text-lg", children: "Drop files here" }) }),
|
|
6210
|
+
isDragging && !renderInput && /* @__PURE__ */ jsx("div", { className: "csdk-dropzone-overlay absolute inset-0 z-50 bg-primary/10 border-2 border-dashed border-primary flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "text-primary font-medium text-lg", children: "Drop files here" }) }),
|
|
5847
6211
|
showHeader && (renderHeader ? renderHeader() : /* @__PURE__ */ jsx(
|
|
5848
6212
|
ChatHeader,
|
|
5849
6213
|
{
|
|
@@ -5877,7 +6241,7 @@ function ChatComponent({
|
|
|
5877
6241
|
attachmentsDisabledTooltip,
|
|
5878
6242
|
maxFileSize,
|
|
5879
6243
|
allowedFileTypes,
|
|
5880
|
-
processAttachment:
|
|
6244
|
+
processAttachment: typeof uploadProp === "function" ? uploadProp : deprecatedProcessAttachment
|
|
5881
6245
|
}
|
|
5882
6246
|
)
|
|
5883
6247
|
) : null,
|
|
@@ -6316,6 +6680,106 @@ function ToolExecutionMessage({
|
|
|
6316
6680
|
] })
|
|
6317
6681
|
] });
|
|
6318
6682
|
}
|
|
6683
|
+
var INITIAL_STATE = {
|
|
6684
|
+
phase: "idle",
|
|
6685
|
+
threadId: null,
|
|
6686
|
+
lastSnapshot: "",
|
|
6687
|
+
initialized: false
|
|
6688
|
+
};
|
|
6689
|
+
function threadReducer(state, action) {
|
|
6690
|
+
switch (action.type) {
|
|
6691
|
+
case "FIRST_RESPONSE_COMPLETE":
|
|
6692
|
+
if (state.phase !== "idle") return state;
|
|
6693
|
+
return { ...state, phase: "awaiting_server_id", initialized: true };
|
|
6694
|
+
case "SERVER_ID_RECEIVED":
|
|
6695
|
+
if (state.phase !== "awaiting_server_id") return state;
|
|
6696
|
+
return { ...state, phase: "creating" };
|
|
6697
|
+
case "CREATE_WITH_LOCAL_ID":
|
|
6698
|
+
if (state.phase !== "awaiting_server_id") return state;
|
|
6699
|
+
return { ...state, phase: "creating" };
|
|
6700
|
+
case "THREAD_CREATED":
|
|
6701
|
+
return {
|
|
6702
|
+
...state,
|
|
6703
|
+
phase: "active",
|
|
6704
|
+
threadId: action.threadId,
|
|
6705
|
+
lastSnapshot: action.snapshot,
|
|
6706
|
+
initialized: true
|
|
6707
|
+
};
|
|
6708
|
+
case "MESSAGES_SAVED":
|
|
6709
|
+
if (state.phase !== "active") return state;
|
|
6710
|
+
return { ...state, lastSnapshot: action.snapshot };
|
|
6711
|
+
case "START_SWITCH":
|
|
6712
|
+
if (state.phase !== "active" && state.phase !== "idle") return state;
|
|
6713
|
+
return { ...state, phase: "switching" };
|
|
6714
|
+
case "SWITCH_COMPLETE":
|
|
6715
|
+
return {
|
|
6716
|
+
...state,
|
|
6717
|
+
phase: "active",
|
|
6718
|
+
threadId: action.threadId,
|
|
6719
|
+
lastSnapshot: action.snapshot
|
|
6720
|
+
};
|
|
6721
|
+
case "NEW_THREAD":
|
|
6722
|
+
return {
|
|
6723
|
+
...INITIAL_STATE,
|
|
6724
|
+
initialized: true
|
|
6725
|
+
};
|
|
6726
|
+
case "RESTORE_START":
|
|
6727
|
+
if (state.initialized) return state;
|
|
6728
|
+
if (state.phase === "creating" || state.phase === "awaiting_server_id")
|
|
6729
|
+
return state;
|
|
6730
|
+
return { ...state, phase: "restoring" };
|
|
6731
|
+
case "RESTORE_COMPLETE":
|
|
6732
|
+
return {
|
|
6733
|
+
...state,
|
|
6734
|
+
phase: "active",
|
|
6735
|
+
threadId: action.threadId,
|
|
6736
|
+
lastSnapshot: action.snapshot,
|
|
6737
|
+
initialized: true
|
|
6738
|
+
};
|
|
6739
|
+
case "SKIP_RESTORE":
|
|
6740
|
+
return { ...state, initialized: true };
|
|
6741
|
+
default:
|
|
6742
|
+
return state;
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
function getMessageSnapshot(msgs) {
|
|
6746
|
+
return msgs.map((m) => {
|
|
6747
|
+
const preview = (m.content ?? "").slice(0, 20);
|
|
6748
|
+
return `${m.id}:${preview}:${m.content?.length ?? 0}`;
|
|
6749
|
+
}).join("|");
|
|
6750
|
+
}
|
|
6751
|
+
function convertToCore(msgs) {
|
|
6752
|
+
return msgs.map((m) => ({
|
|
6753
|
+
id: m.id,
|
|
6754
|
+
role: m.role,
|
|
6755
|
+
content: m.content,
|
|
6756
|
+
created_at: m.createdAt,
|
|
6757
|
+
tool_calls: m.toolCalls,
|
|
6758
|
+
tool_call_id: m.toolCallId,
|
|
6759
|
+
parent_id: m.parentId,
|
|
6760
|
+
children_ids: m.childrenIds,
|
|
6761
|
+
metadata: {
|
|
6762
|
+
...m.metadata,
|
|
6763
|
+
attachments: m.attachments,
|
|
6764
|
+
thinking: m.thinking
|
|
6765
|
+
}
|
|
6766
|
+
}));
|
|
6767
|
+
}
|
|
6768
|
+
function coreToUI(m) {
|
|
6769
|
+
return {
|
|
6770
|
+
id: m.id,
|
|
6771
|
+
role: m.role,
|
|
6772
|
+
content: m.content ?? "",
|
|
6773
|
+
createdAt: m.created_at ?? /* @__PURE__ */ new Date(),
|
|
6774
|
+
toolCalls: m.tool_calls,
|
|
6775
|
+
toolCallId: m.tool_call_id,
|
|
6776
|
+
parentId: m.parent_id,
|
|
6777
|
+
childrenIds: m.children_ids,
|
|
6778
|
+
attachments: m.metadata?.attachments,
|
|
6779
|
+
thinking: m.metadata?.thinking,
|
|
6780
|
+
metadata: m.metadata
|
|
6781
|
+
};
|
|
6782
|
+
}
|
|
6319
6783
|
function useInternalThreadManager(config = {}) {
|
|
6320
6784
|
const {
|
|
6321
6785
|
adapter,
|
|
@@ -6324,20 +6788,20 @@ function useInternalThreadManager(config = {}) {
|
|
|
6324
6788
|
onThreadChange,
|
|
6325
6789
|
enabled = true
|
|
6326
6790
|
} = config;
|
|
6327
|
-
const
|
|
6791
|
+
const [state, dispatch] = useReducer(threadReducer, INITIAL_STATE);
|
|
6792
|
+
const isLoadingRef = useRef(false);
|
|
6793
|
+
const threadManager = useThreadManager({
|
|
6328
6794
|
adapter,
|
|
6329
6795
|
saveDebounce,
|
|
6330
6796
|
autoRestoreLastThread
|
|
6331
|
-
};
|
|
6332
|
-
const threadManager = useThreadManager(threadManagerConfig);
|
|
6797
|
+
});
|
|
6333
6798
|
const {
|
|
6334
6799
|
currentThread,
|
|
6335
6800
|
currentThreadId,
|
|
6336
6801
|
createThread,
|
|
6337
6802
|
switchThread,
|
|
6338
6803
|
updateCurrentThread,
|
|
6339
|
-
clearCurrentThread
|
|
6340
|
-
refreshThreads
|
|
6804
|
+
clearCurrentThread
|
|
6341
6805
|
} = threadManager;
|
|
6342
6806
|
const {
|
|
6343
6807
|
messages,
|
|
@@ -6345,183 +6809,148 @@ function useInternalThreadManager(config = {}) {
|
|
|
6345
6809
|
status,
|
|
6346
6810
|
isLoading,
|
|
6347
6811
|
getAllMessages,
|
|
6348
|
-
switchBranch
|
|
6812
|
+
switchBranch,
|
|
6813
|
+
threadId: sdkThreadId,
|
|
6814
|
+
setActiveThread
|
|
6349
6815
|
} = useCopilot();
|
|
6350
|
-
const isLoadingMessagesRef = useRef(false);
|
|
6351
|
-
const savingToThreadRef = useRef(null);
|
|
6352
|
-
const lastSavedSnapshotRef = useRef("");
|
|
6353
|
-
const hasInitializedRef = useRef(false);
|
|
6354
|
-
const getMessageSnapshot = useCallback((msgs) => {
|
|
6355
|
-
return msgs.map((m) => {
|
|
6356
|
-
const contentPreview = (m.content ?? "").slice(0, 20);
|
|
6357
|
-
return `${m.id}:${contentPreview}:${m.content?.length ?? 0}`;
|
|
6358
|
-
}).join("|");
|
|
6359
|
-
}, []);
|
|
6360
|
-
const convertToCore = useCallback((msgs) => {
|
|
6361
|
-
return msgs.map((m) => ({
|
|
6362
|
-
id: m.id,
|
|
6363
|
-
role: m.role,
|
|
6364
|
-
content: m.content,
|
|
6365
|
-
created_at: m.createdAt,
|
|
6366
|
-
tool_calls: m.toolCalls,
|
|
6367
|
-
tool_call_id: m.toolCallId,
|
|
6368
|
-
parent_id: m.parentId,
|
|
6369
|
-
children_ids: m.childrenIds,
|
|
6370
|
-
// Preserve full metadata including citations, toolExecutions, etc.
|
|
6371
|
-
metadata: {
|
|
6372
|
-
...m.metadata,
|
|
6373
|
-
attachments: m.attachments,
|
|
6374
|
-
thinking: m.thinking
|
|
6375
|
-
}
|
|
6376
|
-
}));
|
|
6377
|
-
}, []);
|
|
6378
|
-
const handleSwitchThread = useCallback(
|
|
6379
|
-
async (threadId) => {
|
|
6380
|
-
isLoadingMessagesRef.current = true;
|
|
6381
|
-
const thread = await switchThread(threadId);
|
|
6382
|
-
if (thread?.messages) {
|
|
6383
|
-
const uiMessages = thread.messages.map((m) => ({
|
|
6384
|
-
id: m.id,
|
|
6385
|
-
role: m.role,
|
|
6386
|
-
content: m.content ?? "",
|
|
6387
|
-
createdAt: m.created_at ?? /* @__PURE__ */ new Date(),
|
|
6388
|
-
toolCalls: m.tool_calls,
|
|
6389
|
-
toolCallId: m.tool_call_id,
|
|
6390
|
-
parentId: m.parent_id,
|
|
6391
|
-
childrenIds: m.children_ids,
|
|
6392
|
-
attachments: m.metadata?.attachments,
|
|
6393
|
-
thinking: m.metadata?.thinking,
|
|
6394
|
-
// Preserve full metadata including citations, toolCallsHidden, toolExecutions, etc.
|
|
6395
|
-
metadata: m.metadata
|
|
6396
|
-
}));
|
|
6397
|
-
lastSavedSnapshotRef.current = getMessageSnapshot(uiMessages);
|
|
6398
|
-
savingToThreadRef.current = threadId;
|
|
6399
|
-
setMessages(uiMessages);
|
|
6400
|
-
if (thread.activeLeafId) {
|
|
6401
|
-
switchBranch(thread.activeLeafId);
|
|
6402
|
-
}
|
|
6403
|
-
} else {
|
|
6404
|
-
lastSavedSnapshotRef.current = "";
|
|
6405
|
-
savingToThreadRef.current = threadId;
|
|
6406
|
-
setMessages([]);
|
|
6407
|
-
}
|
|
6408
|
-
onThreadChange?.(threadId);
|
|
6409
|
-
requestAnimationFrame(() => {
|
|
6410
|
-
isLoadingMessagesRef.current = false;
|
|
6411
|
-
});
|
|
6412
|
-
},
|
|
6413
|
-
[
|
|
6414
|
-
switchThread,
|
|
6415
|
-
setMessages,
|
|
6416
|
-
switchBranch,
|
|
6417
|
-
getMessageSnapshot,
|
|
6418
|
-
onThreadChange
|
|
6419
|
-
]
|
|
6420
|
-
);
|
|
6421
|
-
const handleNewThread = useCallback(async () => {
|
|
6422
|
-
isLoadingMessagesRef.current = true;
|
|
6423
|
-
clearCurrentThread();
|
|
6424
|
-
lastSavedSnapshotRef.current = "";
|
|
6425
|
-
savingToThreadRef.current = null;
|
|
6426
|
-
setMessages([]);
|
|
6427
|
-
onThreadChange?.(null);
|
|
6428
|
-
requestAnimationFrame(() => {
|
|
6429
|
-
isLoadingMessagesRef.current = false;
|
|
6430
|
-
});
|
|
6431
|
-
}, [clearCurrentThread, setMessages, onThreadChange]);
|
|
6432
6816
|
useEffect(() => {
|
|
6433
|
-
if (!enabled) return;
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
}
|
|
6437
|
-
hasInitializedRef.current = true;
|
|
6438
|
-
isLoadingMessagesRef.current = true;
|
|
6817
|
+
if (!enabled || state.initialized || !currentThread) return;
|
|
6818
|
+
dispatch({ type: "RESTORE_START" });
|
|
6819
|
+
isLoadingRef.current = true;
|
|
6439
6820
|
if (currentThread.messages && currentThread.messages.length > 0) {
|
|
6440
|
-
const uiMessages = currentThread.messages.map(
|
|
6441
|
-
|
|
6442
|
-
role: m.role,
|
|
6443
|
-
content: m.content ?? "",
|
|
6444
|
-
createdAt: m.created_at ?? /* @__PURE__ */ new Date(),
|
|
6445
|
-
toolCalls: m.tool_calls,
|
|
6446
|
-
toolCallId: m.tool_call_id,
|
|
6447
|
-
parentId: m.parent_id,
|
|
6448
|
-
childrenIds: m.children_ids,
|
|
6449
|
-
attachments: m.metadata?.attachments,
|
|
6450
|
-
thinking: m.metadata?.thinking,
|
|
6451
|
-
// Preserve full metadata including citations, toolExecutions, etc.
|
|
6452
|
-
metadata: m.metadata
|
|
6453
|
-
}));
|
|
6454
|
-
lastSavedSnapshotRef.current = getMessageSnapshot(uiMessages);
|
|
6455
|
-
savingToThreadRef.current = currentThread.id;
|
|
6821
|
+
const uiMessages = currentThread.messages.map(coreToUI);
|
|
6822
|
+
const snapshot = getMessageSnapshot(uiMessages);
|
|
6456
6823
|
setMessages(uiMessages);
|
|
6457
|
-
if (currentThread.activeLeafId)
|
|
6458
|
-
|
|
6459
|
-
|
|
6824
|
+
if (currentThread.activeLeafId) switchBranch(currentThread.activeLeafId);
|
|
6825
|
+
onThreadChange?.(currentThread.id);
|
|
6826
|
+
dispatch({
|
|
6827
|
+
type: "RESTORE_COMPLETE",
|
|
6828
|
+
threadId: currentThread.id,
|
|
6829
|
+
snapshot
|
|
6830
|
+
});
|
|
6460
6831
|
} else {
|
|
6461
|
-
|
|
6462
|
-
|
|
6832
|
+
onThreadChange?.(currentThread.id);
|
|
6833
|
+
dispatch({
|
|
6834
|
+
type: "RESTORE_COMPLETE",
|
|
6835
|
+
threadId: currentThread.id,
|
|
6836
|
+
snapshot: ""
|
|
6837
|
+
});
|
|
6463
6838
|
}
|
|
6464
|
-
onThreadChange?.(currentThread.id);
|
|
6465
6839
|
requestAnimationFrame(() => {
|
|
6466
|
-
|
|
6840
|
+
isLoadingRef.current = false;
|
|
6467
6841
|
});
|
|
6468
6842
|
}, [
|
|
6469
6843
|
enabled,
|
|
6470
|
-
adapter,
|
|
6471
6844
|
currentThread,
|
|
6845
|
+
state.initialized,
|
|
6472
6846
|
setMessages,
|
|
6473
6847
|
switchBranch,
|
|
6474
|
-
getMessageSnapshot,
|
|
6475
6848
|
onThreadChange
|
|
6476
6849
|
]);
|
|
6477
6850
|
useEffect(() => {
|
|
6478
|
-
if (!enabled)
|
|
6479
|
-
|
|
6480
|
-
return;
|
|
6481
|
-
}
|
|
6482
|
-
if (status === "streaming" || status === "submitted") {
|
|
6851
|
+
if (!enabled) {
|
|
6852
|
+
dispatch({ type: "SKIP_RESTORE" });
|
|
6483
6853
|
return;
|
|
6484
6854
|
}
|
|
6485
|
-
if (
|
|
6486
|
-
|
|
6855
|
+
if (!autoRestoreLastThread && !state.initialized) {
|
|
6856
|
+
dispatch({ type: "SKIP_RESTORE" });
|
|
6487
6857
|
}
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6858
|
+
}, [enabled, autoRestoreLastThread, state.initialized]);
|
|
6859
|
+
useEffect(() => {
|
|
6860
|
+
if (!enabled) return;
|
|
6861
|
+
if (state.phase !== "idle") return;
|
|
6862
|
+
if (isLoadingRef.current) return;
|
|
6863
|
+
if (status === "streaming" || status === "submitted") return;
|
|
6864
|
+
if (messages.length === 0) return;
|
|
6865
|
+
if (currentThreadId) return;
|
|
6866
|
+
dispatch({ type: "FIRST_RESPONSE_COMPLETE" });
|
|
6867
|
+
}, [enabled, state.phase, status, messages.length, currentThreadId]);
|
|
6868
|
+
useEffect(() => {
|
|
6869
|
+
if (state.phase !== "awaiting_server_id") return;
|
|
6870
|
+
if (sdkThreadId) {
|
|
6871
|
+
dispatch({ type: "SERVER_ID_RECEIVED", threadId: sdkThreadId });
|
|
6872
|
+
} else {
|
|
6873
|
+
dispatch({ type: "CREATE_WITH_LOCAL_ID" });
|
|
6491
6874
|
}
|
|
6875
|
+
}, [state.phase, sdkThreadId]);
|
|
6876
|
+
useEffect(() => {
|
|
6877
|
+
if (state.phase !== "creating") return;
|
|
6878
|
+
const allUIMessages = getAllMessages();
|
|
6879
|
+
const coreMessages = convertToCore(
|
|
6880
|
+
allUIMessages.length > 0 ? allUIMessages : messages
|
|
6881
|
+
);
|
|
6882
|
+
const activeLeafId = messages[messages.length - 1]?.id;
|
|
6883
|
+
const snapshot = getMessageSnapshot(messages);
|
|
6884
|
+
createThread({
|
|
6885
|
+
id: sdkThreadId ?? void 0,
|
|
6886
|
+
messages: coreMessages,
|
|
6887
|
+
activeLeafId
|
|
6888
|
+
}).then((thread) => {
|
|
6889
|
+
dispatch({ type: "THREAD_CREATED", threadId: thread.id, snapshot });
|
|
6890
|
+
onThreadChange?.(thread.id);
|
|
6891
|
+
});
|
|
6892
|
+
}, [state.phase]);
|
|
6893
|
+
useEffect(() => {
|
|
6894
|
+
if (!enabled) return;
|
|
6895
|
+
if (state.phase !== "active") return;
|
|
6896
|
+
if (isLoadingRef.current) return;
|
|
6897
|
+
if (status === "streaming" || status === "submitted") return;
|
|
6898
|
+
if (messages.length === 0) return;
|
|
6899
|
+
const snapshot = getMessageSnapshot(messages);
|
|
6900
|
+
if (snapshot === state.lastSnapshot) return;
|
|
6901
|
+
if (state.threadId && state.threadId !== currentThreadId) return;
|
|
6492
6902
|
const allUIMessages = getAllMessages();
|
|
6493
6903
|
const coreMessages = convertToCore(
|
|
6494
6904
|
allUIMessages.length > 0 ? allUIMessages : messages
|
|
6495
6905
|
);
|
|
6496
6906
|
const activeLeafId = messages[messages.length - 1]?.id;
|
|
6497
|
-
if (!currentThreadId && !savingToThreadRef.current) {
|
|
6498
|
-
savingToThreadRef.current = "creating";
|
|
6499
|
-
createThread({ messages: coreMessages, activeLeafId }).then((thread) => {
|
|
6500
|
-
lastSavedSnapshotRef.current = currentSnapshot;
|
|
6501
|
-
savingToThreadRef.current = thread.id;
|
|
6502
|
-
onThreadChange?.(thread.id);
|
|
6503
|
-
});
|
|
6504
|
-
return;
|
|
6505
|
-
}
|
|
6506
|
-
if (savingToThreadRef.current && savingToThreadRef.current !== currentThreadId) {
|
|
6507
|
-
return;
|
|
6508
|
-
}
|
|
6509
6907
|
updateCurrentThread({ messages: coreMessages, activeLeafId });
|
|
6510
|
-
|
|
6908
|
+
dispatch({ type: "MESSAGES_SAVED", snapshot });
|
|
6511
6909
|
}, [
|
|
6512
6910
|
enabled,
|
|
6513
|
-
|
|
6911
|
+
state.phase,
|
|
6912
|
+
state.lastSnapshot,
|
|
6913
|
+
state.threadId,
|
|
6514
6914
|
messages,
|
|
6515
|
-
currentThreadId,
|
|
6516
6915
|
status,
|
|
6916
|
+
currentThreadId,
|
|
6517
6917
|
updateCurrentThread,
|
|
6518
|
-
|
|
6519
|
-
refreshThreads,
|
|
6520
|
-
getMessageSnapshot,
|
|
6521
|
-
convertToCore,
|
|
6522
|
-
getAllMessages,
|
|
6523
|
-
onThreadChange
|
|
6918
|
+
getAllMessages
|
|
6524
6919
|
]);
|
|
6920
|
+
const handleSwitchThread = useCallback(
|
|
6921
|
+
async (threadId) => {
|
|
6922
|
+
dispatch({ type: "START_SWITCH" });
|
|
6923
|
+
isLoadingRef.current = true;
|
|
6924
|
+
const thread = await switchThread(threadId);
|
|
6925
|
+
if (thread?.messages) {
|
|
6926
|
+
const uiMessages = thread.messages.map(coreToUI);
|
|
6927
|
+
const snapshot = getMessageSnapshot(uiMessages);
|
|
6928
|
+
setMessages(uiMessages);
|
|
6929
|
+
if (thread.activeLeafId) switchBranch(thread.activeLeafId);
|
|
6930
|
+
onThreadChange?.(threadId);
|
|
6931
|
+
dispatch({ type: "SWITCH_COMPLETE", threadId, snapshot });
|
|
6932
|
+
} else {
|
|
6933
|
+
setMessages([]);
|
|
6934
|
+
onThreadChange?.(threadId);
|
|
6935
|
+
dispatch({ type: "SWITCH_COMPLETE", threadId, snapshot: "" });
|
|
6936
|
+
}
|
|
6937
|
+
requestAnimationFrame(() => {
|
|
6938
|
+
isLoadingRef.current = false;
|
|
6939
|
+
});
|
|
6940
|
+
},
|
|
6941
|
+
[switchThread, setMessages, switchBranch, onThreadChange]
|
|
6942
|
+
);
|
|
6943
|
+
const handleNewThread = useCallback(async () => {
|
|
6944
|
+
isLoadingRef.current = true;
|
|
6945
|
+
clearCurrentThread();
|
|
6946
|
+
setMessages([]);
|
|
6947
|
+
setActiveThread(null);
|
|
6948
|
+
onThreadChange?.(null);
|
|
6949
|
+
dispatch({ type: "NEW_THREAD" });
|
|
6950
|
+
requestAnimationFrame(() => {
|
|
6951
|
+
isLoadingRef.current = false;
|
|
6952
|
+
});
|
|
6953
|
+
}, [clearCurrentThread, setMessages, setActiveThread, onThreadChange]);
|
|
6525
6954
|
const isBusy = isLoading || status === "streaming" || status === "submitted";
|
|
6526
6955
|
return {
|
|
6527
6956
|
threadManager,
|
|
@@ -6587,7 +7016,15 @@ function CopilotChatBase(props) {
|
|
|
6587
7016
|
allowEdit = false,
|
|
6588
7017
|
...chatProps
|
|
6589
7018
|
} = props;
|
|
7019
|
+
const localStorageKey = typeof persistence === "object" && "type" in persistence && persistence.type === "local" ? persistence.localStorageKey : void 0;
|
|
7020
|
+
const customAdapter = useMemo(
|
|
7021
|
+
() => localStorageKey ? createLocalStorageAdapter({ storageKey: localStorageKey }) : void 0,
|
|
7022
|
+
[localStorageKey]
|
|
7023
|
+
);
|
|
6590
7024
|
const persistenceConfig = parsePersistenceConfig(persistence, onThreadChange);
|
|
7025
|
+
if (persistenceConfig && customAdapter) {
|
|
7026
|
+
persistenceConfig.adapter = customAdapter;
|
|
7027
|
+
}
|
|
6591
7028
|
const threadManagerResult = useInternalThreadManager(
|
|
6592
7029
|
persistenceConfig ?? { autoRestoreLastThread: false, enabled: false }
|
|
6593
7030
|
);
|
|
@@ -6890,6 +7327,515 @@ function PoweredBy({ className, showLogo = true }) {
|
|
|
6890
7327
|
}
|
|
6891
7328
|
);
|
|
6892
7329
|
}
|
|
7330
|
+
var DEFAULT_MAX_FILES = 5;
|
|
7331
|
+
var DEFAULT_MAX_FILE_SIZE3 = 10 * 1024 * 1024;
|
|
7332
|
+
var DEFAULT_ALLOWED_TYPES3 = [
|
|
7333
|
+
"image/*",
|
|
7334
|
+
"application/pdf",
|
|
7335
|
+
"text/csv",
|
|
7336
|
+
"text/plain",
|
|
7337
|
+
"text/markdown",
|
|
7338
|
+
"application/json",
|
|
7339
|
+
".csv",
|
|
7340
|
+
".txt",
|
|
7341
|
+
".md",
|
|
7342
|
+
".json"
|
|
7343
|
+
];
|
|
7344
|
+
var TEXT_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
7345
|
+
"text/csv",
|
|
7346
|
+
"text/plain",
|
|
7347
|
+
"text/markdown",
|
|
7348
|
+
"text/x-markdown",
|
|
7349
|
+
"application/json",
|
|
7350
|
+
"application/csv"
|
|
7351
|
+
]);
|
|
7352
|
+
function isTextFile(file) {
|
|
7353
|
+
if (TEXT_MIME_TYPES.has(file.type)) return true;
|
|
7354
|
+
const ext = file.name.toLowerCase().split(".").pop();
|
|
7355
|
+
return ext === "csv" || ext === "txt" || ext === "md" || ext === "json";
|
|
7356
|
+
}
|
|
7357
|
+
function readFileAsText(file) {
|
|
7358
|
+
return new Promise((resolve, reject) => {
|
|
7359
|
+
const reader = new FileReader();
|
|
7360
|
+
reader.onload = () => resolve(reader.result);
|
|
7361
|
+
reader.onerror = () => reject(new Error("Failed to read file"));
|
|
7362
|
+
reader.readAsText(file);
|
|
7363
|
+
});
|
|
7364
|
+
}
|
|
7365
|
+
function generateId() {
|
|
7366
|
+
return `att_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
|
|
7367
|
+
}
|
|
7368
|
+
function getAttachmentType3(mimeType) {
|
|
7369
|
+
if (mimeType.startsWith("image/")) return "image";
|
|
7370
|
+
if (mimeType.startsWith("audio/")) return "audio";
|
|
7371
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
7372
|
+
return "file";
|
|
7373
|
+
}
|
|
7374
|
+
function isTypeAllowed(file, allowedTypes) {
|
|
7375
|
+
for (const type of allowedTypes) {
|
|
7376
|
+
if (type === file.type) return true;
|
|
7377
|
+
if (type.endsWith("/*") && file.type.startsWith(type.slice(0, -1)))
|
|
7378
|
+
return true;
|
|
7379
|
+
if (type.startsWith(".") && file.name.toLowerCase().endsWith(type))
|
|
7380
|
+
return true;
|
|
7381
|
+
}
|
|
7382
|
+
return false;
|
|
7383
|
+
}
|
|
7384
|
+
function fileToBase643(file) {
|
|
7385
|
+
return new Promise((resolve, reject) => {
|
|
7386
|
+
const reader = new FileReader();
|
|
7387
|
+
reader.onload = () => resolve(reader.result);
|
|
7388
|
+
reader.onerror = () => reject(new Error("Failed to read file"));
|
|
7389
|
+
reader.readAsDataURL(file);
|
|
7390
|
+
});
|
|
7391
|
+
}
|
|
7392
|
+
function createPreview(file) {
|
|
7393
|
+
if (file.type.startsWith("image/")) {
|
|
7394
|
+
return URL.createObjectURL(file);
|
|
7395
|
+
}
|
|
7396
|
+
return void 0;
|
|
7397
|
+
}
|
|
7398
|
+
function useAttachments(config = {}) {
|
|
7399
|
+
const {
|
|
7400
|
+
upload,
|
|
7401
|
+
maxFiles = DEFAULT_MAX_FILES,
|
|
7402
|
+
maxFileSize = DEFAULT_MAX_FILE_SIZE3,
|
|
7403
|
+
allowedFileTypes = DEFAULT_ALLOWED_TYPES3
|
|
7404
|
+
} = config;
|
|
7405
|
+
const [attachments, setAttachments] = useState([]);
|
|
7406
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
7407
|
+
const abortControllers = useRef(/* @__PURE__ */ new Map());
|
|
7408
|
+
const fileInputRef = useRef(null);
|
|
7409
|
+
const dragCounter = useRef(0);
|
|
7410
|
+
const uploadFile = useCallback(
|
|
7411
|
+
async (id, file) => {
|
|
7412
|
+
const updateProgress = (progress) => {
|
|
7413
|
+
setAttachments(
|
|
7414
|
+
(prev) => prev.map((a) => a.id === id ? { ...a, progress } : a)
|
|
7415
|
+
);
|
|
7416
|
+
};
|
|
7417
|
+
const markReady = (attachment) => {
|
|
7418
|
+
setAttachments(
|
|
7419
|
+
(prev) => prev.map(
|
|
7420
|
+
(a) => a.id === id ? { ...a, status: "ready", progress: 100, attachment } : a
|
|
7421
|
+
)
|
|
7422
|
+
);
|
|
7423
|
+
};
|
|
7424
|
+
const markError = (error) => {
|
|
7425
|
+
setAttachments(
|
|
7426
|
+
(prev) => prev.map(
|
|
7427
|
+
(a) => a.id === id ? { ...a, status: "error", error } : a
|
|
7428
|
+
)
|
|
7429
|
+
);
|
|
7430
|
+
};
|
|
7431
|
+
try {
|
|
7432
|
+
const controller = new AbortController();
|
|
7433
|
+
abortControllers.current.set(id, controller);
|
|
7434
|
+
let result;
|
|
7435
|
+
if (isTextFile(file)) {
|
|
7436
|
+
updateProgress(50);
|
|
7437
|
+
const textContent = await readFileAsText(file);
|
|
7438
|
+
result = {
|
|
7439
|
+
type: "file",
|
|
7440
|
+
data: textContent,
|
|
7441
|
+
mimeType: file.type || "text/plain",
|
|
7442
|
+
filename: file.name
|
|
7443
|
+
};
|
|
7444
|
+
markReady(result);
|
|
7445
|
+
return;
|
|
7446
|
+
}
|
|
7447
|
+
if (typeof upload === "function") {
|
|
7448
|
+
updateProgress(50);
|
|
7449
|
+
result = await upload(file);
|
|
7450
|
+
} else if (upload) {
|
|
7451
|
+
const uploadConfig = typeof upload === "string" ? { url: upload } : upload;
|
|
7452
|
+
const extraHeaders = typeof uploadConfig.headers === "function" ? uploadConfig.headers() : uploadConfig.headers;
|
|
7453
|
+
const extraBody = typeof uploadConfig.body === "function" ? uploadConfig.body() : uploadConfig.body;
|
|
7454
|
+
const base64 = await fileToBase643(file);
|
|
7455
|
+
updateProgress(30);
|
|
7456
|
+
const body = JSON.stringify({
|
|
7457
|
+
data: base64,
|
|
7458
|
+
mimeType: file.type,
|
|
7459
|
+
filename: file.name,
|
|
7460
|
+
...extraBody
|
|
7461
|
+
});
|
|
7462
|
+
const res = await fetch(uploadConfig.url, {
|
|
7463
|
+
method: "POST",
|
|
7464
|
+
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
7465
|
+
body,
|
|
7466
|
+
signal: controller.signal
|
|
7467
|
+
});
|
|
7468
|
+
updateProgress(90);
|
|
7469
|
+
if (!res.ok) throw new Error(`Upload failed: ${res.status}`);
|
|
7470
|
+
const json = await res.json();
|
|
7471
|
+
const url = json.url ?? json.data?.url;
|
|
7472
|
+
if (!url) throw new Error("Upload returned no URL");
|
|
7473
|
+
result = {
|
|
7474
|
+
type: getAttachmentType3(file.type),
|
|
7475
|
+
url,
|
|
7476
|
+
mimeType: file.type,
|
|
7477
|
+
filename: file.name
|
|
7478
|
+
};
|
|
7479
|
+
} else {
|
|
7480
|
+
updateProgress(50);
|
|
7481
|
+
const data = await fileToBase643(file);
|
|
7482
|
+
result = {
|
|
7483
|
+
type: getAttachmentType3(file.type),
|
|
7484
|
+
data,
|
|
7485
|
+
mimeType: file.type,
|
|
7486
|
+
filename: file.name
|
|
7487
|
+
};
|
|
7488
|
+
}
|
|
7489
|
+
markReady(result);
|
|
7490
|
+
} catch (err) {
|
|
7491
|
+
if (err?.name === "AbortError") return;
|
|
7492
|
+
markError(err?.message ?? "Upload failed");
|
|
7493
|
+
} finally {
|
|
7494
|
+
abortControllers.current.delete(id);
|
|
7495
|
+
}
|
|
7496
|
+
},
|
|
7497
|
+
[upload]
|
|
7498
|
+
);
|
|
7499
|
+
const addFiles = useCallback(
|
|
7500
|
+
(files) => {
|
|
7501
|
+
const fileArray = Array.from(files);
|
|
7502
|
+
const remaining = maxFiles - attachments.length;
|
|
7503
|
+
if (remaining <= 0) return;
|
|
7504
|
+
const toAdd = fileArray.slice(0, remaining);
|
|
7505
|
+
const newAttachments = [];
|
|
7506
|
+
for (const file of toAdd) {
|
|
7507
|
+
if (!isTypeAllowed(file, allowedFileTypes)) continue;
|
|
7508
|
+
if (file.size > maxFileSize) continue;
|
|
7509
|
+
const id = generateId();
|
|
7510
|
+
const preview = createPreview(file);
|
|
7511
|
+
newAttachments.push({
|
|
7512
|
+
id,
|
|
7513
|
+
file,
|
|
7514
|
+
preview,
|
|
7515
|
+
status: "uploading",
|
|
7516
|
+
progress: 0
|
|
7517
|
+
});
|
|
7518
|
+
}
|
|
7519
|
+
if (newAttachments.length === 0) return;
|
|
7520
|
+
setAttachments((prev) => [...prev, ...newAttachments]);
|
|
7521
|
+
for (const att of newAttachments) {
|
|
7522
|
+
uploadFile(att.id, att.file);
|
|
7523
|
+
}
|
|
7524
|
+
},
|
|
7525
|
+
[attachments.length, maxFiles, maxFileSize, allowedFileTypes, uploadFile]
|
|
7526
|
+
);
|
|
7527
|
+
const removeAttachment = useCallback((id) => {
|
|
7528
|
+
setAttachments((prev) => {
|
|
7529
|
+
const att = prev.find((a) => a.id === id);
|
|
7530
|
+
if (att?.preview) URL.revokeObjectURL(att.preview);
|
|
7531
|
+
return prev.filter((a) => a.id !== id);
|
|
7532
|
+
});
|
|
7533
|
+
const controller = abortControllers.current.get(id);
|
|
7534
|
+
if (controller) {
|
|
7535
|
+
controller.abort();
|
|
7536
|
+
abortControllers.current.delete(id);
|
|
7537
|
+
}
|
|
7538
|
+
}, []);
|
|
7539
|
+
const cancelUpload = useCallback(
|
|
7540
|
+
(id) => {
|
|
7541
|
+
removeAttachment(id);
|
|
7542
|
+
},
|
|
7543
|
+
[removeAttachment]
|
|
7544
|
+
);
|
|
7545
|
+
const retryUpload = useCallback(
|
|
7546
|
+
(id) => {
|
|
7547
|
+
setAttachments(
|
|
7548
|
+
(prev) => prev.map(
|
|
7549
|
+
(a) => a.id === id ? {
|
|
7550
|
+
...a,
|
|
7551
|
+
status: "uploading",
|
|
7552
|
+
progress: 0,
|
|
7553
|
+
error: void 0
|
|
7554
|
+
} : a
|
|
7555
|
+
)
|
|
7556
|
+
);
|
|
7557
|
+
const att = attachments.find((a) => a.id === id);
|
|
7558
|
+
if (att) uploadFile(id, att.file);
|
|
7559
|
+
},
|
|
7560
|
+
[attachments, uploadFile]
|
|
7561
|
+
);
|
|
7562
|
+
const clearAll = useCallback(() => {
|
|
7563
|
+
for (const att of attachments) {
|
|
7564
|
+
if (att.preview) URL.revokeObjectURL(att.preview);
|
|
7565
|
+
}
|
|
7566
|
+
for (const controller of abortControllers.current.values()) {
|
|
7567
|
+
controller.abort();
|
|
7568
|
+
}
|
|
7569
|
+
abortControllers.current.clear();
|
|
7570
|
+
setAttachments([]);
|
|
7571
|
+
}, [attachments]);
|
|
7572
|
+
const getReadyAttachments = useCallback(() => {
|
|
7573
|
+
return attachments.filter((a) => a.status === "ready" && a.attachment).map((a) => a.attachment);
|
|
7574
|
+
}, [attachments]);
|
|
7575
|
+
const hasAttachments = attachments.length > 0;
|
|
7576
|
+
const isUploading = attachments.some((a) => a.status === "uploading");
|
|
7577
|
+
const canSend = hasAttachments && attachments.some((a) => a.status === "ready") && !isUploading;
|
|
7578
|
+
const dragHandlers = useMemo(
|
|
7579
|
+
() => ({
|
|
7580
|
+
onDragEnter: (e) => {
|
|
7581
|
+
e.preventDefault();
|
|
7582
|
+
e.stopPropagation();
|
|
7583
|
+
dragCounter.current++;
|
|
7584
|
+
if (e.dataTransfer.types.includes("Files")) {
|
|
7585
|
+
setIsDragging(true);
|
|
7586
|
+
}
|
|
7587
|
+
},
|
|
7588
|
+
onDragOver: (e) => {
|
|
7589
|
+
e.preventDefault();
|
|
7590
|
+
e.stopPropagation();
|
|
7591
|
+
},
|
|
7592
|
+
onDragLeave: (e) => {
|
|
7593
|
+
e.preventDefault();
|
|
7594
|
+
e.stopPropagation();
|
|
7595
|
+
dragCounter.current--;
|
|
7596
|
+
if (dragCounter.current === 0) {
|
|
7597
|
+
setIsDragging(false);
|
|
7598
|
+
}
|
|
7599
|
+
},
|
|
7600
|
+
onDrop: (e) => {
|
|
7601
|
+
e.preventDefault();
|
|
7602
|
+
e.stopPropagation();
|
|
7603
|
+
dragCounter.current = 0;
|
|
7604
|
+
setIsDragging(false);
|
|
7605
|
+
if (e.dataTransfer.files?.length) {
|
|
7606
|
+
addFiles(e.dataTransfer.files);
|
|
7607
|
+
}
|
|
7608
|
+
}
|
|
7609
|
+
}),
|
|
7610
|
+
[addFiles]
|
|
7611
|
+
);
|
|
7612
|
+
const openFilePicker = useCallback(() => {
|
|
7613
|
+
fileInputRef.current?.click();
|
|
7614
|
+
}, []);
|
|
7615
|
+
const onFileInputChange = useCallback(
|
|
7616
|
+
(e) => {
|
|
7617
|
+
if (e.target.files?.length) {
|
|
7618
|
+
addFiles(e.target.files);
|
|
7619
|
+
}
|
|
7620
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
7621
|
+
},
|
|
7622
|
+
[addFiles]
|
|
7623
|
+
);
|
|
7624
|
+
return {
|
|
7625
|
+
attachments,
|
|
7626
|
+
isDragging,
|
|
7627
|
+
addFiles,
|
|
7628
|
+
removeAttachment,
|
|
7629
|
+
cancelUpload,
|
|
7630
|
+
retryUpload,
|
|
7631
|
+
clearAll,
|
|
7632
|
+
getReadyAttachments,
|
|
7633
|
+
hasAttachments,
|
|
7634
|
+
isUploading,
|
|
7635
|
+
canSend,
|
|
7636
|
+
dragHandlers,
|
|
7637
|
+
openFilePicker,
|
|
7638
|
+
fileInputRef,
|
|
7639
|
+
onFileInputChange
|
|
7640
|
+
};
|
|
7641
|
+
}
|
|
7642
|
+
var svgProps = {
|
|
7643
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
7644
|
+
viewBox: "0 0 24 24",
|
|
7645
|
+
fill: "none",
|
|
7646
|
+
stroke: "currentColor",
|
|
7647
|
+
strokeWidth: 2,
|
|
7648
|
+
strokeLinecap: "round",
|
|
7649
|
+
strokeLinejoin: "round"
|
|
7650
|
+
};
|
|
7651
|
+
function ImageIcon({ className }) {
|
|
7652
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7653
|
+
/* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
7654
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "2" }),
|
|
7655
|
+
/* @__PURE__ */ jsx("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
|
|
7656
|
+
] });
|
|
7657
|
+
}
|
|
7658
|
+
function FileTextIcon({ className }) {
|
|
7659
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7660
|
+
/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
7661
|
+
/* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
|
|
7662
|
+
/* @__PURE__ */ jsx("path", { d: "M10 9H8" }),
|
|
7663
|
+
/* @__PURE__ */ jsx("path", { d: "M16 13H8" }),
|
|
7664
|
+
/* @__PURE__ */ jsx("path", { d: "M16 17H8" })
|
|
7665
|
+
] });
|
|
7666
|
+
}
|
|
7667
|
+
function MusicIcon({ className }) {
|
|
7668
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7669
|
+
/* @__PURE__ */ jsx("path", { d: "M9 18V5l12-2v13" }),
|
|
7670
|
+
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "18", r: "3" }),
|
|
7671
|
+
/* @__PURE__ */ jsx("circle", { cx: "18", cy: "16", r: "3" })
|
|
7672
|
+
] });
|
|
7673
|
+
}
|
|
7674
|
+
function VideoIcon({ className }) {
|
|
7675
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7676
|
+
/* @__PURE__ */ jsx("path", { d: "m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.934a.5.5 0 0 0-.777-.416L16 11" }),
|
|
7677
|
+
/* @__PURE__ */ jsx("rect", { width: "14", height: "12", x: "2", y: "6", rx: "2" })
|
|
7678
|
+
] });
|
|
7679
|
+
}
|
|
7680
|
+
function XIcon3({ className }) {
|
|
7681
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7682
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
7683
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
7684
|
+
] });
|
|
7685
|
+
}
|
|
7686
|
+
function RefreshCwIcon({ className }) {
|
|
7687
|
+
return /* @__PURE__ */ jsxs("svg", { ...svgProps, className, children: [
|
|
7688
|
+
/* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
7689
|
+
/* @__PURE__ */ jsx("path", { d: "M21 3v5h-5" }),
|
|
7690
|
+
/* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
7691
|
+
/* @__PURE__ */ jsx("path", { d: "M8 16H3v5" })
|
|
7692
|
+
] });
|
|
7693
|
+
}
|
|
7694
|
+
function Loader2Icon({ className }) {
|
|
7695
|
+
return /* @__PURE__ */ jsx("svg", { ...svgProps, className, children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
|
|
7696
|
+
}
|
|
7697
|
+
function CheckIcon4({ className }) {
|
|
7698
|
+
return /* @__PURE__ */ jsx("svg", { ...svgProps, className, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
7699
|
+
}
|
|
7700
|
+
function FileTypeIcon({ mimeType }) {
|
|
7701
|
+
const cls = "size-3.5";
|
|
7702
|
+
if (mimeType.startsWith("image/")) return /* @__PURE__ */ jsx(ImageIcon, { className: cls });
|
|
7703
|
+
if (mimeType.startsWith("audio/")) return /* @__PURE__ */ jsx(MusicIcon, { className: cls });
|
|
7704
|
+
if (mimeType.startsWith("video/")) return /* @__PURE__ */ jsx(VideoIcon, { className: cls });
|
|
7705
|
+
return /* @__PURE__ */ jsx(FileTextIcon, { className: cls });
|
|
7706
|
+
}
|
|
7707
|
+
function StatusBadge2({ status }) {
|
|
7708
|
+
if (status === "uploading") {
|
|
7709
|
+
return /* @__PURE__ */ jsx(Loader2Icon, { className: "size-3 animate-spin text-blue-400" });
|
|
7710
|
+
}
|
|
7711
|
+
if (status === "ready") {
|
|
7712
|
+
return /* @__PURE__ */ jsx(CheckIcon4, { className: "size-3 text-emerald-400" });
|
|
7713
|
+
}
|
|
7714
|
+
return null;
|
|
7715
|
+
}
|
|
7716
|
+
function AttachmentCard({
|
|
7717
|
+
attachment,
|
|
7718
|
+
onRemove,
|
|
7719
|
+
onRetry
|
|
7720
|
+
}) {
|
|
7721
|
+
const { id, file, preview, status, progress, error } = attachment;
|
|
7722
|
+
const isError = status === "error";
|
|
7723
|
+
return /* @__PURE__ */ jsxs(
|
|
7724
|
+
"div",
|
|
7725
|
+
{
|
|
7726
|
+
className: `
|
|
7727
|
+
csdk-attachment-card group relative flex items-center gap-1.5
|
|
7728
|
+
rounded-lg border px-2 py-1.5 min-w-0 max-w-[160px]
|
|
7729
|
+
transition-colors duration-150
|
|
7730
|
+
${isError ? "border-red-500/30 bg-red-500/5" : "border-border/60 bg-muted/40 hover:bg-muted/60"}
|
|
7731
|
+
`,
|
|
7732
|
+
children: [
|
|
7733
|
+
/* @__PURE__ */ jsx("div", { className: "size-7 rounded shrink-0 overflow-hidden bg-muted/60 flex items-center justify-center", children: preview ? /* @__PURE__ */ jsx(
|
|
7734
|
+
"img",
|
|
7735
|
+
{
|
|
7736
|
+
src: preview,
|
|
7737
|
+
alt: file.name,
|
|
7738
|
+
className: "size-full object-cover"
|
|
7739
|
+
}
|
|
7740
|
+
) : /* @__PURE__ */ jsx(FileTypeIcon, { mimeType: file.type }) }),
|
|
7741
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
7742
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium truncate leading-tight text-foreground/80", children: file.name }),
|
|
7743
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 mt-0.5", children: isError ? /* @__PURE__ */ jsxs(
|
|
7744
|
+
"button",
|
|
7745
|
+
{
|
|
7746
|
+
onClick: () => onRetry(id),
|
|
7747
|
+
className: "flex items-center gap-0.5 text-[9px] text-red-400 hover:text-red-300 cursor-pointer",
|
|
7748
|
+
children: [
|
|
7749
|
+
/* @__PURE__ */ jsx(RefreshCwIcon, { className: "size-2.5" }),
|
|
7750
|
+
"Retry"
|
|
7751
|
+
]
|
|
7752
|
+
}
|
|
7753
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7754
|
+
/* @__PURE__ */ jsx(StatusBadge2, { status }),
|
|
7755
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground", children: status === "uploading" ? `${progress}%` : formatBytes(file.size) })
|
|
7756
|
+
] }) })
|
|
7757
|
+
] }),
|
|
7758
|
+
status === "uploading" && /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 h-[2px] rounded-b-lg overflow-hidden bg-muted/40", children: /* @__PURE__ */ jsx(
|
|
7759
|
+
"div",
|
|
7760
|
+
{
|
|
7761
|
+
className: "h-full bg-blue-500 transition-[width] duration-300 ease-out",
|
|
7762
|
+
style: { width: `${progress}%` }
|
|
7763
|
+
}
|
|
7764
|
+
) }),
|
|
7765
|
+
/* @__PURE__ */ jsx(
|
|
7766
|
+
"button",
|
|
7767
|
+
{
|
|
7768
|
+
onClick: () => onRemove(id),
|
|
7769
|
+
className: "\n size-4 rounded-full shrink-0 flex items-center justify-center\n text-muted-foreground/50 hover:text-foreground hover:bg-muted\n transition-colors cursor-pointer\n ",
|
|
7770
|
+
"aria-label": "Remove attachment",
|
|
7771
|
+
children: /* @__PURE__ */ jsx(XIcon3, { className: "size-2.5" })
|
|
7772
|
+
}
|
|
7773
|
+
)
|
|
7774
|
+
]
|
|
7775
|
+
}
|
|
7776
|
+
);
|
|
7777
|
+
}
|
|
7778
|
+
function formatBytes(bytes) {
|
|
7779
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
7780
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}KB`;
|
|
7781
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
7782
|
+
}
|
|
7783
|
+
function AttachmentStrip({
|
|
7784
|
+
attachments,
|
|
7785
|
+
onRemove,
|
|
7786
|
+
onRetry,
|
|
7787
|
+
className = ""
|
|
7788
|
+
}) {
|
|
7789
|
+
if (attachments.length === 0) return null;
|
|
7790
|
+
return /* @__PURE__ */ jsx(
|
|
7791
|
+
"div",
|
|
7792
|
+
{
|
|
7793
|
+
className: `csdk-attachment-strip flex gap-1.5 overflow-x-auto px-1 py-1.5 scrollbar-none ${className}`,
|
|
7794
|
+
children: attachments.map((att) => /* @__PURE__ */ jsx(
|
|
7795
|
+
AttachmentCard,
|
|
7796
|
+
{
|
|
7797
|
+
attachment: att,
|
|
7798
|
+
onRemove,
|
|
7799
|
+
onRetry
|
|
7800
|
+
},
|
|
7801
|
+
att.id
|
|
7802
|
+
))
|
|
7803
|
+
}
|
|
7804
|
+
);
|
|
7805
|
+
}
|
|
7806
|
+
var svgProps2 = {
|
|
7807
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
7808
|
+
viewBox: "0 0 24 24",
|
|
7809
|
+
fill: "none",
|
|
7810
|
+
stroke: "currentColor",
|
|
7811
|
+
strokeWidth: 2,
|
|
7812
|
+
strokeLinecap: "round",
|
|
7813
|
+
strokeLinejoin: "round"
|
|
7814
|
+
};
|
|
7815
|
+
function PaperclipIcon({ className }) {
|
|
7816
|
+
return /* @__PURE__ */ jsx("svg", { ...svgProps2, className, children: /* @__PURE__ */ jsx("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
7817
|
+
}
|
|
7818
|
+
function DropZoneOverlay({
|
|
7819
|
+
isDragging,
|
|
7820
|
+
className = ""
|
|
7821
|
+
}) {
|
|
7822
|
+
if (!isDragging) return null;
|
|
7823
|
+
return /* @__PURE__ */ jsx(
|
|
7824
|
+
"div",
|
|
7825
|
+
{
|
|
7826
|
+
className: `
|
|
7827
|
+
csdk-drop-zone absolute inset-0 z-50 flex items-center justify-center
|
|
7828
|
+
bg-background/80 backdrop-blur-sm border-2 border-dashed border-primary/40
|
|
7829
|
+
rounded-xl pointer-events-none
|
|
7830
|
+
${className}
|
|
7831
|
+
`,
|
|
7832
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-primary/70", children: [
|
|
7833
|
+
/* @__PURE__ */ jsx("div", { className: "size-10 rounded-xl bg-primary/10 flex items-center justify-center", children: /* @__PURE__ */ jsx(PaperclipIcon, { className: "size-5" }) }),
|
|
7834
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Drop files to attach" })
|
|
7835
|
+
] })
|
|
7836
|
+
}
|
|
7837
|
+
);
|
|
7838
|
+
}
|
|
6893
7839
|
|
|
6894
7840
|
// src/ui/index.ts
|
|
6895
7841
|
var ChatPrimitives = {
|
|
@@ -6923,6 +7869,6 @@ var ChatPrimitives = {
|
|
|
6923
7869
|
Loader
|
|
6924
7870
|
};
|
|
6925
7871
|
|
|
6926
|
-
export { AlertTriangleIcon, BotIcon, BranchNavigator, Button, CapabilityBadge, CapabilityList, Chat, ChatContainerContent, ChatContainerRoot, ChatContainerScrollAnchor, ChatPrimitives, ChatWelcome, CheckIcon, ChevronDownIcon2 as ChevronDownIcon, ChevronLeftIcon, ChevronUpIcon, CitationBadge, CitationSuperscript, CloseIcon, CodeBlock, CompactPermissionConfirmation, Confirmation, ConfirmationActions, ConfirmationApproved, ConfirmationMessage, ConfirmationPending, ConfirmationRejected, ConnectedChat, CopilotChat, CopilotUIProvider, CopyIcon, DEFAULT_PERMISSION_OPTIONS, DevLogger, FeedbackBar, FollowUpQuestions, InlineToolSteps, MCPUIFrame, MCPUIFrameList, Markdown, MessageAvatar, MessageContent, Message as MessagePrimitive, MessageWithCitations, ModelSelector, PermissionConfirmation, PoweredBy, PromptInput, PromptInputAction, PromptInputActions, PromptInputTextarea, Reasoning, ReasoningContent, ReasoningTrigger, RefreshIcon, ScrollButton, SearchAnswer, SearchResults, SearchResultsWithAnswer, SendIcon, SimpleConfirmation, SimpleModelSelector, SimpleReasoning, SimpleSource, Source, SourceContent, SourceGroup, SourcePill, SourceTrigger, SourcesBar, SourcesCollapsible, SourcesList, StopIcon, ThreadCard, ThreadList, ThreadPicker, ThumbsDownIcon2 as ThumbsDownIcon, ThumbsUpIcon2 as ThumbsUpIcon, ToolExecutionMessage, ToolStep, ToolSteps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserIcon, XIcon2 as XIcon, annotationsToCitations, parseFollowUps, resultsToCitations, useChatContainer, useCopilotChatContext, useCopilotUI };
|
|
7872
|
+
export { AlertTriangleIcon, AttachmentStrip, BotIcon, BranchNavigator, Button, CapabilityBadge, CapabilityList, Chat, ChatContainerContent, ChatContainerRoot, ChatContainerScrollAnchor, ChatPrimitives, ChatWelcome, CheckIcon, ChevronDownIcon2 as ChevronDownIcon, ChevronLeftIcon, ChevronUpIcon, CitationBadge, CitationSuperscript, CloseIcon, CodeBlock, CompactPermissionConfirmation, Confirmation, ConfirmationActions, ConfirmationApproved, ConfirmationMessage, ConfirmationPending, ConfirmationRejected, ConnectedChat, CopilotChat, CopilotUIProvider, CopyIcon, DEFAULT_PERMISSION_OPTIONS, DevLogger, DropZoneOverlay, FeedbackBar, FollowUpQuestions, InlineToolSteps, MCPUIFrame, MCPUIFrameList, Markdown, MessageAvatar, MessageContent, Message as MessagePrimitive, MessageWithCitations, ModelSelector, PermissionConfirmation, PoweredBy, PromptInput, PromptInputAction, PromptInputActions, PromptInputTextarea, Reasoning, ReasoningContent, ReasoningTrigger, RefreshIcon, ScrollButton, SearchAnswer, SearchResults, SearchResultsWithAnswer, SendIcon, SimpleConfirmation, SimpleModelSelector, SimpleReasoning, SimpleSource, Source, SourceContent, SourceGroup, SourcePill, SourceTrigger, SourcesBar, SourcesCollapsible, SourcesList, StopIcon, ThreadCard, ThreadList, ThreadPicker, ThumbsDownIcon2 as ThumbsDownIcon, ThumbsUpIcon2 as ThumbsUpIcon, ToolExecutionMessage, ToolStep, ToolSteps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserIcon, XIcon2 as XIcon, annotationsToCitations, parseFollowUps, resultsToCitations, useAttachments, useChatContainer, useCopilotChatContext, useCopilotUI };
|
|
6927
7873
|
//# sourceMappingURL=index.js.map
|
|
6928
7874
|
//# sourceMappingURL=index.js.map
|