@cadraos/sdk 0.1.12 → 0.1.13
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/index.cjs +423 -149
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +29 -3
- package/dist/chat/index.d.ts +29 -3
- package/dist/chat/index.js +423 -149
- package/dist/chat/index.js.map +1 -1
- package/package.json +15 -14
package/dist/chat/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var fetchEventSource = require('@microsoft/fetch-event-source');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var reactDom = require('react-dom');
|
|
6
7
|
var ReactMarkdown = require('react-markdown');
|
|
7
8
|
var remarkGfm = require('remark-gfm');
|
|
8
9
|
|
|
@@ -4032,6 +4033,24 @@ function useFileAttachments(options) {
|
|
|
4032
4033
|
console.log("[useFileAttachments] prepareForSubmit result:", aiUuids);
|
|
4033
4034
|
return aiUuids;
|
|
4034
4035
|
}, [onSubmitUpload, onError]);
|
|
4036
|
+
const addExternalFile = react.useCallback(
|
|
4037
|
+
(opts) => {
|
|
4038
|
+
const category = opts.category || (opts.mimeType.startsWith("image/") ? "image" : "document");
|
|
4039
|
+
const placeholderFile = new File([], opts.filename, { type: opts.mimeType });
|
|
4040
|
+
const newAttachment = {
|
|
4041
|
+
uuid: opts.uuid,
|
|
4042
|
+
file: placeholderFile,
|
|
4043
|
+
status: "ready",
|
|
4044
|
+
progress: 100,
|
|
4045
|
+
category,
|
|
4046
|
+
previewUrl: opts.previewUrl,
|
|
4047
|
+
hasThumbnail: category === "image",
|
|
4048
|
+
actualSize: opts.size
|
|
4049
|
+
};
|
|
4050
|
+
setFiles((prev) => [...prev, newAttachment]);
|
|
4051
|
+
},
|
|
4052
|
+
[]
|
|
4053
|
+
);
|
|
4035
4054
|
const clear = react.useCallback(() => {
|
|
4036
4055
|
for (const file of filesRef.current) {
|
|
4037
4056
|
if (file.previewUrl) {
|
|
@@ -4057,6 +4076,7 @@ function useFileAttachments(options) {
|
|
|
4057
4076
|
files,
|
|
4058
4077
|
dropZoneProps,
|
|
4059
4078
|
removeFile,
|
|
4079
|
+
addExternalFile,
|
|
4060
4080
|
getReadyUuids,
|
|
4061
4081
|
getReadyUrls,
|
|
4062
4082
|
prepareForSubmit,
|
|
@@ -5772,23 +5792,45 @@ function ImageLightbox({
|
|
|
5772
5792
|
}) {
|
|
5773
5793
|
const currentImage = images[currentIndex];
|
|
5774
5794
|
const hasMultiple = images.length > 1;
|
|
5795
|
+
const [container, setContainer] = react.useState(null);
|
|
5796
|
+
react.useEffect(() => {
|
|
5797
|
+
const el = document.createElement("div");
|
|
5798
|
+
el.id = "cadra-lightbox-root";
|
|
5799
|
+
el.style.position = "fixed";
|
|
5800
|
+
el.style.inset = "0";
|
|
5801
|
+
el.style.zIndex = "999999";
|
|
5802
|
+
el.style.pointerEvents = "auto";
|
|
5803
|
+
document.body.appendChild(el);
|
|
5804
|
+
setContainer(el);
|
|
5805
|
+
return () => {
|
|
5806
|
+
document.body.removeChild(el);
|
|
5807
|
+
};
|
|
5808
|
+
}, []);
|
|
5809
|
+
const onCloseRef = react.useRef(onClose);
|
|
5810
|
+
const onPrevRef = react.useRef(onPrev);
|
|
5811
|
+
const onNextRef = react.useRef(onNext);
|
|
5812
|
+
onCloseRef.current = onClose;
|
|
5813
|
+
onPrevRef.current = onPrev;
|
|
5814
|
+
onNextRef.current = onNext;
|
|
5775
5815
|
react.useEffect(() => {
|
|
5776
5816
|
function handleKeyDown(e) {
|
|
5777
5817
|
switch (e.key) {
|
|
5778
5818
|
case "Escape":
|
|
5779
|
-
|
|
5819
|
+
e.preventDefault();
|
|
5820
|
+
e.stopPropagation();
|
|
5821
|
+
onCloseRef.current();
|
|
5780
5822
|
break;
|
|
5781
5823
|
case "ArrowLeft":
|
|
5782
|
-
if (hasMultiple)
|
|
5824
|
+
if (hasMultiple) onPrevRef.current();
|
|
5783
5825
|
break;
|
|
5784
5826
|
case "ArrowRight":
|
|
5785
|
-
if (hasMultiple)
|
|
5827
|
+
if (hasMultiple) onNextRef.current();
|
|
5786
5828
|
break;
|
|
5787
5829
|
}
|
|
5788
5830
|
}
|
|
5789
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
5790
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5791
|
-
}, [
|
|
5831
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
5832
|
+
return () => document.removeEventListener("keydown", handleKeyDown, true);
|
|
5833
|
+
}, [hasMultiple]);
|
|
5792
5834
|
react.useEffect(() => {
|
|
5793
5835
|
const originalOverflow = document.body.style.overflow;
|
|
5794
5836
|
document.body.style.overflow = "hidden";
|
|
@@ -5796,97 +5838,143 @@ function ImageLightbox({
|
|
|
5796
5838
|
document.body.style.overflow = originalOverflow;
|
|
5797
5839
|
};
|
|
5798
5840
|
}, []);
|
|
5799
|
-
|
|
5841
|
+
react.useEffect(() => {
|
|
5842
|
+
if (!container) return;
|
|
5843
|
+
function handleClick(e) {
|
|
5844
|
+
const target = e.target;
|
|
5845
|
+
if (target.dataset.lightboxBackdrop === "true") {
|
|
5846
|
+
e.preventDefault();
|
|
5847
|
+
e.stopPropagation();
|
|
5848
|
+
onCloseRef.current();
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
container.addEventListener("click", handleClick, true);
|
|
5852
|
+
return () => container.removeEventListener("click", handleClick, true);
|
|
5853
|
+
}, [container]);
|
|
5854
|
+
const handleDownload = react.useCallback(async () => {
|
|
5800
5855
|
if (!currentImage) return;
|
|
5801
|
-
const
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
{
|
|
5814
|
-
|
|
5815
|
-
onClick: onClose,
|
|
5816
|
-
children: [
|
|
5817
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-between p-4 z-10", children: [
|
|
5818
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-white text-sm", children: hasMultiple && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5819
|
-
currentIndex + 1,
|
|
5820
|
-
" / ",
|
|
5821
|
-
images.length
|
|
5822
|
-
] }) }),
|
|
5823
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5824
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5825
|
-
"button",
|
|
5826
|
-
{
|
|
5827
|
-
type: "button",
|
|
5828
|
-
onClick: (e) => {
|
|
5829
|
-
e.stopPropagation();
|
|
5830
|
-
handleDownload();
|
|
5831
|
-
},
|
|
5832
|
-
className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors",
|
|
5833
|
-
"aria-label": "Download image",
|
|
5834
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, { className: "h-5 w-5" })
|
|
5835
|
-
}
|
|
5836
|
-
),
|
|
5837
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5838
|
-
"button",
|
|
5839
|
-
{
|
|
5840
|
-
type: "button",
|
|
5841
|
-
onClick: (e) => {
|
|
5842
|
-
e.stopPropagation();
|
|
5843
|
-
onClose();
|
|
5844
|
-
},
|
|
5845
|
-
className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors",
|
|
5846
|
-
"aria-label": "Close lightbox",
|
|
5847
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, { className: "h-5 w-5" })
|
|
5848
|
-
}
|
|
5849
|
-
)
|
|
5850
|
-
] })
|
|
5851
|
-
] }),
|
|
5852
|
-
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5853
|
-
"button",
|
|
5854
|
-
{
|
|
5855
|
-
type: "button",
|
|
5856
|
-
onClick: (e) => {
|
|
5857
|
-
e.stopPropagation();
|
|
5858
|
-
onPrev();
|
|
5859
|
-
},
|
|
5860
|
-
className: "absolute left-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors z-10",
|
|
5861
|
-
"aria-label": "Previous image",
|
|
5862
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "h-6 w-6" })
|
|
5863
|
-
}
|
|
5864
|
-
),
|
|
5865
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5866
|
-
"img",
|
|
5867
|
-
{
|
|
5868
|
-
src: currentImage.url,
|
|
5869
|
-
alt: currentImage.alt || `Image ${currentIndex + 1}`,
|
|
5870
|
-
className: "max-w-[90vw] max-h-[85vh] object-contain",
|
|
5871
|
-
onClick: (e) => e.stopPropagation()
|
|
5872
|
-
}
|
|
5873
|
-
),
|
|
5874
|
-
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5875
|
-
"button",
|
|
5876
|
-
{
|
|
5877
|
-
type: "button",
|
|
5878
|
-
onClick: (e) => {
|
|
5879
|
-
e.stopPropagation();
|
|
5880
|
-
onNext();
|
|
5881
|
-
},
|
|
5882
|
-
className: "absolute right-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors z-10",
|
|
5883
|
-
"aria-label": "Next image",
|
|
5884
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-6 w-6" })
|
|
5885
|
-
}
|
|
5886
|
-
),
|
|
5887
|
-
currentImage.alt && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 text-center z-10", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-sm bg-black/50 inline-block px-3 py-1 rounded-full", children: currentImage.alt }) })
|
|
5888
|
-
]
|
|
5856
|
+
const filename = currentImage.filename || `image-${currentIndex + 1}`;
|
|
5857
|
+
try {
|
|
5858
|
+
const response = await fetch(currentImage.url);
|
|
5859
|
+
const blob = await response.blob();
|
|
5860
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
5861
|
+
const link = document.createElement("a");
|
|
5862
|
+
link.href = blobUrl;
|
|
5863
|
+
link.download = filename;
|
|
5864
|
+
document.body.appendChild(link);
|
|
5865
|
+
link.click();
|
|
5866
|
+
document.body.removeChild(link);
|
|
5867
|
+
URL.revokeObjectURL(blobUrl);
|
|
5868
|
+
} catch {
|
|
5869
|
+
window.open(currentImage.url, "_blank");
|
|
5889
5870
|
}
|
|
5871
|
+
}, [currentImage, currentIndex]);
|
|
5872
|
+
const handleClose = react.useCallback(() => {
|
|
5873
|
+
onCloseRef.current();
|
|
5874
|
+
}, []);
|
|
5875
|
+
if (!currentImage || !container) return null;
|
|
5876
|
+
return reactDom.createPortal(
|
|
5877
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5878
|
+
"div",
|
|
5879
|
+
{
|
|
5880
|
+
"data-lightbox-backdrop": "true",
|
|
5881
|
+
className: `absolute inset-0 flex items-center justify-center bg-black/90 ${className || ""}`,
|
|
5882
|
+
style: { cursor: "zoom-out" },
|
|
5883
|
+
children: [
|
|
5884
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5885
|
+
"div",
|
|
5886
|
+
{
|
|
5887
|
+
className: "absolute top-0 left-0 right-0 flex items-center justify-between p-4",
|
|
5888
|
+
style: { zIndex: 10 },
|
|
5889
|
+
children: [
|
|
5890
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-white text-sm", children: hasMultiple && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5891
|
+
currentIndex + 1,
|
|
5892
|
+
" / ",
|
|
5893
|
+
images.length
|
|
5894
|
+
] }) }),
|
|
5895
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5896
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5897
|
+
"button",
|
|
5898
|
+
{
|
|
5899
|
+
type: "button",
|
|
5900
|
+
onClick: (e) => {
|
|
5901
|
+
e.stopPropagation();
|
|
5902
|
+
handleDownload();
|
|
5903
|
+
},
|
|
5904
|
+
className: "p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5905
|
+
style: { cursor: "pointer", pointerEvents: "auto" },
|
|
5906
|
+
"aria-label": "Download image",
|
|
5907
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, { className: "h-5 w-5" })
|
|
5908
|
+
}
|
|
5909
|
+
),
|
|
5910
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5911
|
+
"button",
|
|
5912
|
+
{
|
|
5913
|
+
type: "button",
|
|
5914
|
+
onClick: (e) => {
|
|
5915
|
+
e.stopPropagation();
|
|
5916
|
+
handleClose();
|
|
5917
|
+
},
|
|
5918
|
+
className: "p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5919
|
+
style: { cursor: "pointer", pointerEvents: "auto" },
|
|
5920
|
+
"aria-label": "Close lightbox",
|
|
5921
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, { className: "h-5 w-5" })
|
|
5922
|
+
}
|
|
5923
|
+
)
|
|
5924
|
+
] })
|
|
5925
|
+
]
|
|
5926
|
+
}
|
|
5927
|
+
),
|
|
5928
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5929
|
+
"button",
|
|
5930
|
+
{
|
|
5931
|
+
type: "button",
|
|
5932
|
+
onClick: (e) => {
|
|
5933
|
+
e.stopPropagation();
|
|
5934
|
+
onPrev();
|
|
5935
|
+
},
|
|
5936
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5937
|
+
style: { zIndex: 10, cursor: "pointer", pointerEvents: "auto" },
|
|
5938
|
+
"aria-label": "Previous image",
|
|
5939
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "h-6 w-6" })
|
|
5940
|
+
}
|
|
5941
|
+
),
|
|
5942
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5943
|
+
"img",
|
|
5944
|
+
{
|
|
5945
|
+
src: currentImage.url,
|
|
5946
|
+
alt: currentImage.alt || `Image ${currentIndex + 1}`,
|
|
5947
|
+
className: "max-w-[90vw] max-h-[85vh] object-contain select-none",
|
|
5948
|
+
style: { cursor: "default", pointerEvents: "auto" },
|
|
5949
|
+
draggable: false
|
|
5950
|
+
}
|
|
5951
|
+
),
|
|
5952
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5953
|
+
"button",
|
|
5954
|
+
{
|
|
5955
|
+
type: "button",
|
|
5956
|
+
onClick: (e) => {
|
|
5957
|
+
e.stopPropagation();
|
|
5958
|
+
onNext();
|
|
5959
|
+
},
|
|
5960
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5961
|
+
style: { zIndex: 10, cursor: "pointer", pointerEvents: "auto" },
|
|
5962
|
+
"aria-label": "Next image",
|
|
5963
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-6 w-6" })
|
|
5964
|
+
}
|
|
5965
|
+
),
|
|
5966
|
+
currentImage.alt && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5967
|
+
"div",
|
|
5968
|
+
{
|
|
5969
|
+
className: "absolute bottom-0 left-0 right-0 p-4 text-center",
|
|
5970
|
+
style: { zIndex: 10, pointerEvents: "none" },
|
|
5971
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-sm bg-black/50 inline-block px-3 py-1 rounded-full", children: currentImage.alt })
|
|
5972
|
+
}
|
|
5973
|
+
)
|
|
5974
|
+
]
|
|
5975
|
+
}
|
|
5976
|
+
),
|
|
5977
|
+
container
|
|
5890
5978
|
);
|
|
5891
5979
|
}
|
|
5892
5980
|
function cn7(...classes) {
|
|
@@ -5899,12 +5987,12 @@ function ImageWithLoading({ src, alt, className, onClick }) {
|
|
|
5899
5987
|
"div",
|
|
5900
5988
|
{
|
|
5901
5989
|
className: cn7(
|
|
5902
|
-
"relative overflow-hidden
|
|
5990
|
+
"relative overflow-hidden rounded-lg",
|
|
5903
5991
|
className
|
|
5904
5992
|
),
|
|
5905
5993
|
children: [
|
|
5906
|
-
!isLoaded && !hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 animate-pulse bg-gray-200 dark:bg-gray-700" }),
|
|
5907
|
-
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-gray-400 dark:text-gray-500 text-sm", children: "Failed to load" }),
|
|
5994
|
+
!isLoaded && !hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 animate-pulse bg-gray-200 dark:bg-gray-700 rounded-lg" }),
|
|
5995
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-gray-400 dark:text-gray-500 text-sm rounded-lg bg-gray-100 dark:bg-gray-800", children: "Failed to load" }),
|
|
5908
5996
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5909
5997
|
"img",
|
|
5910
5998
|
{
|
|
@@ -5912,7 +6000,7 @@ function ImageWithLoading({ src, alt, className, onClick }) {
|
|
|
5912
6000
|
alt,
|
|
5913
6001
|
loading: "lazy",
|
|
5914
6002
|
className: cn7(
|
|
5915
|
-
"w-full h-auto max-h-[
|
|
6003
|
+
"w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm transition-opacity duration-200",
|
|
5916
6004
|
isLoaded ? "opacity-100" : "opacity-0"
|
|
5917
6005
|
),
|
|
5918
6006
|
onLoad: () => setIsLoaded(true),
|
|
@@ -5969,7 +6057,7 @@ function ImageGallery({
|
|
|
5969
6057
|
{
|
|
5970
6058
|
type: "button",
|
|
5971
6059
|
onClick: () => handleImageClick(image, index),
|
|
5972
|
-
className: "block rounded-lg overflow-hidden
|
|
6060
|
+
className: "block rounded-lg overflow-hidden transition-transform hover:scale-[1.02] text-left",
|
|
5973
6061
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5974
6062
|
ImageWithLoading,
|
|
5975
6063
|
{
|
|
@@ -6180,7 +6268,8 @@ var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
6180
6268
|
"check_task_status",
|
|
6181
6269
|
"assign_task",
|
|
6182
6270
|
"update_plan",
|
|
6183
|
-
"check_delegations"
|
|
6271
|
+
"check_delegations",
|
|
6272
|
+
"activate_skill"
|
|
6184
6273
|
]);
|
|
6185
6274
|
function isInternalTool(toolName) {
|
|
6186
6275
|
if (!toolName) return false;
|
|
@@ -6199,6 +6288,15 @@ function cn10(...classes) {
|
|
|
6199
6288
|
}
|
|
6200
6289
|
function formatToolName(toolName) {
|
|
6201
6290
|
if (!toolName) return toolName;
|
|
6291
|
+
if (toolName.includes(".")) {
|
|
6292
|
+
const segments = toolName.split(".");
|
|
6293
|
+
const uniqueSegments = segments.filter(
|
|
6294
|
+
(seg, idx) => idx === 0 || seg.toLowerCase().trim() !== segments[idx - 1]?.toLowerCase().trim()
|
|
6295
|
+
);
|
|
6296
|
+
const bestSegment = uniqueSegments[uniqueSegments.length - 1]?.trim() || toolName;
|
|
6297
|
+
if (bestSegment.includes(" ")) return bestSegment;
|
|
6298
|
+
return formatToolName(bestSegment);
|
|
6299
|
+
}
|
|
6202
6300
|
const prefixesToRemove = [
|
|
6203
6301
|
"skills_api_",
|
|
6204
6302
|
"tools_api_",
|
|
@@ -6303,6 +6401,7 @@ function ToolCallEntry({
|
|
|
6303
6401
|
compact = false
|
|
6304
6402
|
}) {
|
|
6305
6403
|
const [isExpanded, setIsExpanded] = react.useState(false);
|
|
6404
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
6306
6405
|
const formattedName = react.useMemo(
|
|
6307
6406
|
() => formatToolName(toolCall.name),
|
|
6308
6407
|
[toolCall.name]
|
|
@@ -6311,6 +6410,14 @@ function ToolCallEntry({
|
|
|
6311
6410
|
() => toolCall.status === "completed" && toolCall.result ? extractImagesFromResult2(toolCall.result) : [],
|
|
6312
6411
|
[toolCall.status, toolCall.result]
|
|
6313
6412
|
);
|
|
6413
|
+
const lightboxImages = react.useMemo(
|
|
6414
|
+
() => resultImages.map((img) => ({
|
|
6415
|
+
url: img.url,
|
|
6416
|
+
alt: img.alt || img.prompt,
|
|
6417
|
+
filename: img.alt || img.prompt
|
|
6418
|
+
})),
|
|
6419
|
+
[resultImages]
|
|
6420
|
+
);
|
|
6314
6421
|
const hasImages = resultImages.length > 0;
|
|
6315
6422
|
const statusIcon = react.useMemo(() => {
|
|
6316
6423
|
switch (toolCall.status) {
|
|
@@ -6380,47 +6487,56 @@ function ToolCallEntry({
|
|
|
6380
6487
|
]
|
|
6381
6488
|
}
|
|
6382
6489
|
),
|
|
6383
|
-
hasImages && /* @__PURE__ */ jsxRuntime.
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6490
|
+
hasImages && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 pb-3", children: [
|
|
6491
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn10(
|
|
6492
|
+
"grid gap-3",
|
|
6493
|
+
resultImages.length === 1 ? "grid-cols-1 max-w-sm" : resultImages.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3"
|
|
6494
|
+
), children: resultImages.map((img, idx) => {
|
|
6495
|
+
const altText = img.alt || img.prompt || `Generated image ${idx + 1}`;
|
|
6496
|
+
const imageElement = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
|
|
6497
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6498
|
+
"img",
|
|
6499
|
+
{
|
|
6500
|
+
src: img.thumbnailUrl || img.url,
|
|
6501
|
+
alt: altText,
|
|
6502
|
+
className: "w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm",
|
|
6503
|
+
loading: "lazy"
|
|
6504
|
+
}
|
|
6505
|
+
),
|
|
6506
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-lg bg-black/0 group-hover:bg-black/10 dark:group-hover:bg-white/5 transition-colors" })
|
|
6507
|
+
] });
|
|
6401
6508
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6402
6509
|
"button",
|
|
6403
6510
|
{
|
|
6404
6511
|
type: "button",
|
|
6405
|
-
onClick: () =>
|
|
6406
|
-
|
|
6512
|
+
onClick: () => {
|
|
6513
|
+
if (onImageClick) {
|
|
6514
|
+
onImageClick({ url: img.url, alt: altText, filename: altText });
|
|
6515
|
+
} else {
|
|
6516
|
+
setLightboxIndex(idx);
|
|
6517
|
+
}
|
|
6518
|
+
},
|
|
6519
|
+
className: "block rounded-lg overflow-hidden cursor-pointer text-left transition-transform hover:scale-[1.02]",
|
|
6407
6520
|
children: imageElement
|
|
6408
6521
|
},
|
|
6409
6522
|
idx
|
|
6410
6523
|
);
|
|
6411
|
-
}
|
|
6412
|
-
|
|
6413
|
-
|
|
6524
|
+
}) }),
|
|
6525
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6526
|
+
ImageLightbox,
|
|
6414
6527
|
{
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6528
|
+
images: lightboxImages,
|
|
6529
|
+
currentIndex: lightboxIndex,
|
|
6530
|
+
onClose: () => setLightboxIndex(null),
|
|
6531
|
+
onPrev: () => setLightboxIndex(
|
|
6532
|
+
(prev) => prev !== null ? (prev - 1 + lightboxImages.length) % lightboxImages.length : null
|
|
6533
|
+
),
|
|
6534
|
+
onNext: () => setLightboxIndex(
|
|
6535
|
+
(prev) => prev !== null ? (prev + 1) % lightboxImages.length : null
|
|
6536
|
+
)
|
|
6537
|
+
}
|
|
6538
|
+
)
|
|
6539
|
+
] }),
|
|
6424
6540
|
isExpanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 px-3 py-2 space-y-2", children: [
|
|
6425
6541
|
toolCall.args && Object.keys(toolCall.args).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
6426
6542
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 mb-1", children: "Input" }),
|
|
@@ -6442,11 +6558,168 @@ function ToolCallEntry({
|
|
|
6442
6558
|
function cn11(...classes) {
|
|
6443
6559
|
return classes.filter(Boolean).join(" ");
|
|
6444
6560
|
}
|
|
6561
|
+
function normalizeToolNameForGrouping(name) {
|
|
6562
|
+
const lastSegment = name.includes(".") ? name.split(".").pop() : name;
|
|
6563
|
+
return lastSegment.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
6564
|
+
}
|
|
6565
|
+
function groupToolCalls(toolCalls) {
|
|
6566
|
+
const byNormalizedName = /* @__PURE__ */ new Map();
|
|
6567
|
+
const nameOrder = [];
|
|
6568
|
+
for (const tc of toolCalls) {
|
|
6569
|
+
const key = normalizeToolNameForGrouping(tc.name);
|
|
6570
|
+
if (!byNormalizedName.has(key)) {
|
|
6571
|
+
byNormalizedName.set(key, []);
|
|
6572
|
+
nameOrder.push(key);
|
|
6573
|
+
}
|
|
6574
|
+
byNormalizedName.get(key).push(tc);
|
|
6575
|
+
}
|
|
6576
|
+
const groups = [];
|
|
6577
|
+
for (const key of nameOrder) {
|
|
6578
|
+
const calls = byNormalizedName.get(key);
|
|
6579
|
+
if (calls.length === 1) {
|
|
6580
|
+
groups.push({ type: "single", toolCall: calls[0] });
|
|
6581
|
+
} else {
|
|
6582
|
+
groups.push({ type: "group", name: calls[0].name, toolCalls: calls });
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6585
|
+
return groups;
|
|
6586
|
+
}
|
|
6587
|
+
function ToolCallList({ toolCalls, toolCallVerbosity, onImageClick, renderToolCall }) {
|
|
6588
|
+
const visibleToolCalls = react.useMemo(() => {
|
|
6589
|
+
if (toolCallVerbosity !== "compact") return toolCalls;
|
|
6590
|
+
return toolCalls.filter((tc) => !isInternalTool(tc.name));
|
|
6591
|
+
}, [toolCalls, toolCallVerbosity]);
|
|
6592
|
+
const grouped = react.useMemo(() => groupToolCalls(visibleToolCalls), [visibleToolCalls]);
|
|
6593
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: grouped.map((group) => {
|
|
6594
|
+
if (group.type === "single") {
|
|
6595
|
+
const toolCall = group.toolCall;
|
|
6596
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6597
|
+
ToolCallEntry,
|
|
6598
|
+
{
|
|
6599
|
+
toolCall,
|
|
6600
|
+
onImageClick
|
|
6601
|
+
},
|
|
6602
|
+
toolCall.id
|
|
6603
|
+
);
|
|
6604
|
+
if (renderToolCall) {
|
|
6605
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(toolCall, defaultRender) }, toolCall.id);
|
|
6606
|
+
}
|
|
6607
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultRender() }, toolCall.id);
|
|
6608
|
+
}
|
|
6609
|
+
const completed = group.toolCalls.filter((tc) => tc.status === "completed" || tc.status === "failed");
|
|
6610
|
+
const running = group.toolCalls.filter((tc) => tc.status !== "completed" && tc.status !== "failed");
|
|
6611
|
+
const allImages = completed.flatMap(
|
|
6612
|
+
(tc) => tc.result ? extractImagesFromResult2(tc.result) : []
|
|
6613
|
+
);
|
|
6614
|
+
const hasImages = allImages.length > 0;
|
|
6615
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6616
|
+
running.length > 0 && running[0] && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6617
|
+
ToolCallEntry,
|
|
6618
|
+
{
|
|
6619
|
+
toolCall: {
|
|
6620
|
+
...running[0],
|
|
6621
|
+
name: running.length > 1 ? `${running[0].name} (${running.length})` : running[0].name
|
|
6622
|
+
},
|
|
6623
|
+
onImageClick
|
|
6624
|
+
},
|
|
6625
|
+
running[0].id
|
|
6626
|
+
),
|
|
6627
|
+
completed.length > 0 && hasImages && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6628
|
+
GroupedImageGallery,
|
|
6629
|
+
{
|
|
6630
|
+
images: allImages,
|
|
6631
|
+
completedCount: completed.length,
|
|
6632
|
+
onImageClick
|
|
6633
|
+
}
|
|
6634
|
+
),
|
|
6635
|
+
completed.length > 0 && !hasImages && completed.map((tc) => {
|
|
6636
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(ToolCallEntry, { toolCall: tc, onImageClick }, tc.id);
|
|
6637
|
+
if (renderToolCall) {
|
|
6638
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(tc, defaultRender) }, tc.id);
|
|
6639
|
+
}
|
|
6640
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultRender() }, tc.id);
|
|
6641
|
+
})
|
|
6642
|
+
] }, `group-${group.name}-${group.toolCalls[0]?.id}`);
|
|
6643
|
+
}) });
|
|
6644
|
+
}
|
|
6645
|
+
function GroupedImageGallery({
|
|
6646
|
+
images,
|
|
6647
|
+
completedCount,
|
|
6648
|
+
onImageClick
|
|
6649
|
+
}) {
|
|
6650
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
6651
|
+
const lightboxImages = react.useMemo(
|
|
6652
|
+
() => images.map((img) => ({
|
|
6653
|
+
url: img.url,
|
|
6654
|
+
alt: img.alt || img.prompt,
|
|
6655
|
+
filename: img.alt || img.prompt
|
|
6656
|
+
})),
|
|
6657
|
+
[images]
|
|
6658
|
+
);
|
|
6659
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6660
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400 px-1", children: [
|
|
6661
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-4 w-4 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4 text-green-500", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
|
|
6662
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6663
|
+
completedCount,
|
|
6664
|
+
" image",
|
|
6665
|
+
completedCount !== 1 ? "s" : "",
|
|
6666
|
+
" generated"
|
|
6667
|
+
] })
|
|
6668
|
+
] }),
|
|
6669
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn11(
|
|
6670
|
+
"grid gap-3",
|
|
6671
|
+
images.length === 1 ? "grid-cols-1 max-w-sm" : images.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3"
|
|
6672
|
+
), children: images.map((img, idx) => {
|
|
6673
|
+
const altText = img.alt || img.prompt || `Generated image ${idx + 1}`;
|
|
6674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6675
|
+
"button",
|
|
6676
|
+
{
|
|
6677
|
+
type: "button",
|
|
6678
|
+
onClick: () => {
|
|
6679
|
+
if (onImageClick) {
|
|
6680
|
+
onImageClick({ url: img.url, alt: altText, filename: altText });
|
|
6681
|
+
} else {
|
|
6682
|
+
setLightboxIndex(idx);
|
|
6683
|
+
}
|
|
6684
|
+
},
|
|
6685
|
+
className: "block rounded-lg overflow-hidden cursor-pointer text-left transition-transform hover:scale-[1.02] group",
|
|
6686
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
6687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6688
|
+
"img",
|
|
6689
|
+
{
|
|
6690
|
+
src: img.thumbnailUrl || img.url,
|
|
6691
|
+
alt: altText,
|
|
6692
|
+
className: "w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm",
|
|
6693
|
+
loading: "lazy"
|
|
6694
|
+
}
|
|
6695
|
+
),
|
|
6696
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-lg bg-black/0 group-hover:bg-black/10 dark:group-hover:bg-white/5 transition-colors" })
|
|
6697
|
+
] })
|
|
6698
|
+
},
|
|
6699
|
+
`${img.url}-${idx}`
|
|
6700
|
+
);
|
|
6701
|
+
}) }),
|
|
6702
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6703
|
+
ImageLightbox,
|
|
6704
|
+
{
|
|
6705
|
+
images: lightboxImages,
|
|
6706
|
+
currentIndex: lightboxIndex,
|
|
6707
|
+
onClose: () => setLightboxIndex(null),
|
|
6708
|
+
onPrev: () => setLightboxIndex(
|
|
6709
|
+
(prev) => prev !== null ? (prev - 1 + lightboxImages.length) % lightboxImages.length : null
|
|
6710
|
+
),
|
|
6711
|
+
onNext: () => setLightboxIndex(
|
|
6712
|
+
(prev) => prev !== null ? (prev + 1) % lightboxImages.length : null
|
|
6713
|
+
)
|
|
6714
|
+
}
|
|
6715
|
+
)
|
|
6716
|
+
] });
|
|
6717
|
+
}
|
|
6445
6718
|
function ChatMessage({
|
|
6446
6719
|
message,
|
|
6447
6720
|
enableMarkdown = true,
|
|
6448
6721
|
showToolCalls = true,
|
|
6449
|
-
toolCallVerbosity
|
|
6722
|
+
toolCallVerbosity = "compact",
|
|
6450
6723
|
className,
|
|
6451
6724
|
markdownComponents,
|
|
6452
6725
|
markdownUrlTransform,
|
|
@@ -6520,21 +6793,16 @@ function ChatMessage({
|
|
|
6520
6793
|
),
|
|
6521
6794
|
showThinking && message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlockList, { blocks: message.thinkingBlocks }),
|
|
6522
6795
|
showDelegation && message.delegationEvents && message.delegationEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(DelegationProgressList, { events: message.delegationEvents }),
|
|
6523
|
-
showToolCalls && message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
toolCall.id
|
|
6531
|
-
);
|
|
6532
|
-
if (renderToolCall) {
|
|
6533
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(toolCall, defaultRender) }, toolCall.id);
|
|
6796
|
+
showToolCalls && toolCallVerbosity !== "hidden" && message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6797
|
+
ToolCallList,
|
|
6798
|
+
{
|
|
6799
|
+
toolCalls: message.toolCalls,
|
|
6800
|
+
toolCallVerbosity,
|
|
6801
|
+
onImageClick,
|
|
6802
|
+
renderToolCall
|
|
6534
6803
|
}
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
showImages && message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6804
|
+
),
|
|
6805
|
+
showImages && !showToolCalls && message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6538
6806
|
ImageGallery,
|
|
6539
6807
|
{
|
|
6540
6808
|
images: message.images,
|
|
@@ -6746,7 +7014,8 @@ function AgentChat({
|
|
|
6746
7014
|
showImages = true,
|
|
6747
7015
|
pollingInterval,
|
|
6748
7016
|
pollingEnabled,
|
|
6749
|
-
onDelegation
|
|
7017
|
+
onDelegation,
|
|
7018
|
+
onAttachmentsReady
|
|
6750
7019
|
}) {
|
|
6751
7020
|
const {
|
|
6752
7021
|
messages,
|
|
@@ -6793,6 +7062,11 @@ function AgentChat({
|
|
|
6793
7062
|
console.error("[AgentChat] Attachment error:", msg);
|
|
6794
7063
|
}
|
|
6795
7064
|
});
|
|
7065
|
+
react.useEffect(() => {
|
|
7066
|
+
if (enableAttachments && onAttachmentsReady) {
|
|
7067
|
+
onAttachmentsReady({ addExternalFile: attachments.addExternalFile });
|
|
7068
|
+
}
|
|
7069
|
+
}, [enableAttachments, onAttachmentsReady, attachments.addExternalFile]);
|
|
6796
7070
|
const handleSend = react.useCallback(
|
|
6797
7071
|
async (content) => {
|
|
6798
7072
|
if (enableAttachments && attachments.hasReadyFiles) {
|