@mastra/playground-ui 2.0.1-alpha.1 → 2.0.1
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/components/ui/data-table.d.ts +5 -1
- package/dist/components/ui/resizable.d.ts +1 -1
- package/dist/components/ui/text.d.ts +1 -1
- package/dist/domains/workflows/context/workflow-run-context.d.ts +3 -1
- package/dist/domains/workflows/workflow/utils.d.ts +5 -4
- package/dist/domains/workflows/workflow/workflow-after-node.d.ts +6 -0
- package/dist/domains/workflows/workflow/workflow-loop-result-node.d.ts +6 -0
- package/dist/hooks/use-traces.d.ts +1 -1
- package/dist/hooks/use-workflows.d.ts +10 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.es.js +444 -1083
- package/dist/index.es.js.map +1 -1
- package/dist/lib/polls.d.ts +5 -1
- package/package.json +3 -3
- package/dist/chat-ui/chat-items.d.ts +0 -52
- package/dist/chat-ui/chat-message.d.ts +0 -30
- package/dist/chat-ui/chat.d.ts +0 -3
- package/dist/chat-ui/copy-button.d.ts +0 -7
- package/dist/chat-ui/file-preview.d.ts +0 -8
- package/dist/chat-ui/hooks/use-auto-scroll.d.ts +0 -7
- package/dist/chat-ui/hooks/use-autosize-textarea.d.ts +0 -8
- package/dist/chat-ui/hooks/use-copy-to-clipboard.d.ts +0 -10
- package/dist/chat-ui/markdown-renderer.d.ts +0 -88
- package/dist/chat-ui/markdown.d.ts +0 -4
- package/dist/chat-ui/message-input.d.ts +0 -22
- package/dist/chat-ui/message-list.d.ts +0 -11
- package/dist/chat-ui/prompt-suggestions.d.ts +0 -11
- package/dist/chat-ui/syntax-highlighter.d.ts +0 -1
- package/dist/chat-ui/types.d.ts +0 -14
- package/dist/chat-ui/typing-indicator.d.ts +0 -1
package/dist/index.es.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { MessagePrimitive, ActionBarPrimitive, BranchPickerPrimitive, ThreadPrimitive, ComposerPrimitive, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
|
|
3
|
+
import { CheckIcon, CopyIcon, ChevronLeftIcon, ChevronRightIcon, ArrowUp, Copy, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Braces, Clock1, ChevronDown, XIcon, Footprints, CircleCheck, CircleX, AlertCircleIcon, X, Plus, CalendarIcon, Check, Loader2 } from 'lucide-react';
|
|
2
4
|
import * as React from 'react';
|
|
3
|
-
import React__default, {
|
|
4
|
-
import { useSWRConfig } from 'swr';
|
|
5
|
-
import { MastraClient } from '@mastra/client-js';
|
|
6
|
-
import { Check, Copy, X, FileIcon, Paperclip, Square, ArrowUp, Dot, ArrowDown, CheckIcon, CopyIcon, ChevronLeftIcon, ChevronRightIcon, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Braces, Clock1, ChevronDown, XIcon, Footprints, AlertCircleIcon, Plus, CalendarIcon, Loader2 } from 'lucide-react';
|
|
5
|
+
import React__default, { forwardRef, memo, useState, useEffect, createContext, useContext, useRef, useMemo, useCallback, Fragment as Fragment$1 } from 'react';
|
|
7
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
8
|
-
import { omit } from 'remeda';
|
|
9
|
-
import { motion, AnimatePresence } from 'motion/react';
|
|
10
|
-
import Markdown from 'react-markdown';
|
|
11
|
-
import remarkGfm from 'remark-gfm';
|
|
12
|
-
import { MessagePrimitive, ActionBarPrimitive, BranchPickerPrimitive, ThreadPrimitive, ComposerPrimitive, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
|
|
13
7
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
14
8
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
15
9
|
import { unstable_memoizeMarkdownComponents, useIsMarkdownCodeBlock, MarkdownTextPrimitive } from '@assistant-ui/react-markdown';
|
|
16
10
|
import '@assistant-ui/react-markdown/styles/dot.css';
|
|
11
|
+
import remarkGfm from 'remark-gfm';
|
|
17
12
|
import { makePrismAsyncSyntaxHighlighter } from '@assistant-ui/react-syntax-highlighter';
|
|
18
13
|
import { coldarkDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
|
14
|
+
import { MastraClient } from '@mastra/client-js';
|
|
19
15
|
import { format, formatDistanceToNow, isValid } from 'date-fns';
|
|
20
16
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
21
17
|
import { toast } from 'sonner';
|
|
18
|
+
import { AnimatePresence } from 'motion/react';
|
|
22
19
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
23
20
|
import { jsonLanguage } from '@codemirror/lang-json';
|
|
24
21
|
import { tags } from '@lezer/highlight';
|
|
@@ -44,7 +41,7 @@ import { DayPicker } from 'react-day-picker';
|
|
|
44
41
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
45
42
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
46
43
|
import { v4 } from '@lukeed/uuid';
|
|
47
|
-
import { CodeBlock
|
|
44
|
+
import { CodeBlock } from 'react-code-block';
|
|
48
45
|
|
|
49
46
|
import './index.css';function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
50
47
|
|
|
@@ -2837,877 +2834,6 @@ const Button = React.forwardRef(
|
|
|
2837
2834
|
);
|
|
2838
2835
|
Button.displayName = "Button";
|
|
2839
2836
|
|
|
2840
|
-
function useCopyToClipboard$2({ text, copyMessage = "Copied to clipboard!" }) {
|
|
2841
|
-
const [isCopied, setIsCopied] = useState(false);
|
|
2842
|
-
const [error, setError] = useState("");
|
|
2843
|
-
const timeoutRef = useRef(null);
|
|
2844
|
-
const handleCopy = useCallback(() => {
|
|
2845
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
2846
|
-
setIsCopied(true);
|
|
2847
|
-
if (timeoutRef.current) {
|
|
2848
|
-
clearTimeout(timeoutRef.current);
|
|
2849
|
-
timeoutRef.current = null;
|
|
2850
|
-
}
|
|
2851
|
-
timeoutRef.current = setTimeout(() => {
|
|
2852
|
-
setIsCopied(false);
|
|
2853
|
-
}, 2e3);
|
|
2854
|
-
}).catch(() => {
|
|
2855
|
-
setError("Failed to copy to clipboard.");
|
|
2856
|
-
});
|
|
2857
|
-
}, [text, copyMessage]);
|
|
2858
|
-
return { isCopied, handleCopy, error };
|
|
2859
|
-
}
|
|
2860
|
-
|
|
2861
|
-
function CopyButton$1({ content, copyMessage, classname }) {
|
|
2862
|
-
const { isCopied, handleCopy } = useCopyToClipboard$2({
|
|
2863
|
-
text: content,
|
|
2864
|
-
copyMessage
|
|
2865
|
-
});
|
|
2866
|
-
return /* @__PURE__ */ jsxs("button", { className: cn("relative h-6 w-6", classname), "aria-label": "Copy to clipboard", onClick: handleCopy, children: [
|
|
2867
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(Check, { className: cn("h-4 w-4 transition-transform ease-in-out", isCopied ? "scale-100" : "scale-0") }) }),
|
|
2868
|
-
/* @__PURE__ */ jsx(Copy, { className: cn("h-4 w-4 transition-transform ease-in-out", isCopied ? "scale-0" : "scale-100") })
|
|
2869
|
-
] });
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
const ACTIVATION_THRESHOLD = 50;
|
|
2873
|
-
function useAutoScroll(dependencies) {
|
|
2874
|
-
const containerRef = useRef(null);
|
|
2875
|
-
const previousScrollTop = useRef(null);
|
|
2876
|
-
const [shouldAutoScroll, setShouldAutoScroll] = useState(true);
|
|
2877
|
-
const scrollToBottom = () => {
|
|
2878
|
-
if (containerRef.current) {
|
|
2879
|
-
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
2880
|
-
}
|
|
2881
|
-
};
|
|
2882
|
-
const handleScroll = () => {
|
|
2883
|
-
if (containerRef.current) {
|
|
2884
|
-
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
|
2885
|
-
const isScrollingUp = previousScrollTop.current ? scrollTop < previousScrollTop.current : false;
|
|
2886
|
-
if (isScrollingUp) {
|
|
2887
|
-
setShouldAutoScroll(false);
|
|
2888
|
-
} else {
|
|
2889
|
-
const isScrolledToBottom = Math.abs(scrollHeight - scrollTop - clientHeight) < ACTIVATION_THRESHOLD;
|
|
2890
|
-
setShouldAutoScroll(isScrolledToBottom);
|
|
2891
|
-
}
|
|
2892
|
-
previousScrollTop.current = scrollTop;
|
|
2893
|
-
}
|
|
2894
|
-
};
|
|
2895
|
-
const handleTouchStart = () => {
|
|
2896
|
-
setShouldAutoScroll(false);
|
|
2897
|
-
};
|
|
2898
|
-
useEffect(() => {
|
|
2899
|
-
if (containerRef.current) {
|
|
2900
|
-
previousScrollTop.current = containerRef.current.scrollTop;
|
|
2901
|
-
}
|
|
2902
|
-
}, []);
|
|
2903
|
-
useEffect(() => {
|
|
2904
|
-
if (shouldAutoScroll) {
|
|
2905
|
-
scrollToBottom();
|
|
2906
|
-
}
|
|
2907
|
-
}, dependencies);
|
|
2908
|
-
return {
|
|
2909
|
-
containerRef,
|
|
2910
|
-
scrollToBottom,
|
|
2911
|
-
handleScroll,
|
|
2912
|
-
shouldAutoScroll,
|
|
2913
|
-
handleTouchStart
|
|
2914
|
-
};
|
|
2915
|
-
}
|
|
2916
|
-
|
|
2917
|
-
const FilePreview = React__default.forwardRef((props, ref) => {
|
|
2918
|
-
if (props.file.type.startsWith("image/")) {
|
|
2919
|
-
return /* @__PURE__ */ jsx(ImageFilePreview, { ...props, ref });
|
|
2920
|
-
}
|
|
2921
|
-
if (props.file.type.startsWith("text/") || props.file.name.endsWith(".txt") || props.file.name.endsWith(".md")) {
|
|
2922
|
-
return /* @__PURE__ */ jsx(TextFilePreview, { ...props, ref });
|
|
2923
|
-
}
|
|
2924
|
-
return /* @__PURE__ */ jsx(GenericFilePreview, { ...props, ref });
|
|
2925
|
-
});
|
|
2926
|
-
FilePreview.displayName = "FilePreview";
|
|
2927
|
-
const ImageFilePreview = React__default.forwardRef(({ file, onRemove }, ref) => {
|
|
2928
|
-
return /* @__PURE__ */ jsxs(
|
|
2929
|
-
motion.div,
|
|
2930
|
-
{
|
|
2931
|
-
ref,
|
|
2932
|
-
className: "relative flex max-w-[200px] rounded-md border p-1.5 pr-2 text-xs",
|
|
2933
|
-
layout: true,
|
|
2934
|
-
initial: { opacity: 0, y: "100%" },
|
|
2935
|
-
animate: { opacity: 1, y: 0 },
|
|
2936
|
-
exit: { opacity: 0, y: "100%" },
|
|
2937
|
-
children: [
|
|
2938
|
-
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center space-x-2", children: [
|
|
2939
|
-
/* @__PURE__ */ jsx(
|
|
2940
|
-
"img",
|
|
2941
|
-
{
|
|
2942
|
-
alt: `Attachment ${file.name}`,
|
|
2943
|
-
className: "bg-muted grid h-10 w-10 shrink-0 place-items-center rounded-sm border object-cover",
|
|
2944
|
-
src: URL.createObjectURL(file)
|
|
2945
|
-
}
|
|
2946
|
-
),
|
|
2947
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground w-full truncate", children: file.name })
|
|
2948
|
-
] }),
|
|
2949
|
-
onRemove ? /* @__PURE__ */ jsx(
|
|
2950
|
-
"button",
|
|
2951
|
-
{
|
|
2952
|
-
className: "bg-background absolute -right-2 -top-2 flex h-4 w-4 items-center justify-center rounded-full border",
|
|
2953
|
-
type: "button",
|
|
2954
|
-
onClick: onRemove,
|
|
2955
|
-
"aria-label": "Remove attachment",
|
|
2956
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-2.5 w-2.5" })
|
|
2957
|
-
}
|
|
2958
|
-
) : null
|
|
2959
|
-
]
|
|
2960
|
-
}
|
|
2961
|
-
);
|
|
2962
|
-
});
|
|
2963
|
-
ImageFilePreview.displayName = "ImageFilePreview";
|
|
2964
|
-
const TextFilePreview = React__default.forwardRef(({ file, onRemove }, ref) => {
|
|
2965
|
-
const [preview, setPreview] = React__default.useState("");
|
|
2966
|
-
useEffect(() => {
|
|
2967
|
-
const reader = new FileReader();
|
|
2968
|
-
reader.onload = (e) => {
|
|
2969
|
-
const text = e.target?.result;
|
|
2970
|
-
setPreview(text.slice(0, 50) + (text.length > 50 ? "..." : ""));
|
|
2971
|
-
};
|
|
2972
|
-
reader.readAsText(file);
|
|
2973
|
-
}, [file]);
|
|
2974
|
-
return /* @__PURE__ */ jsxs(
|
|
2975
|
-
motion.div,
|
|
2976
|
-
{
|
|
2977
|
-
ref,
|
|
2978
|
-
className: "relative flex max-w-[200px] rounded-md border p-1.5 pr-2 text-xs",
|
|
2979
|
-
layout: true,
|
|
2980
|
-
initial: { opacity: 0, y: "100%" },
|
|
2981
|
-
animate: { opacity: 1, y: 0 },
|
|
2982
|
-
exit: { opacity: 0, y: "100%" },
|
|
2983
|
-
children: [
|
|
2984
|
-
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center space-x-2", children: [
|
|
2985
|
-
/* @__PURE__ */ jsx("div", { className: "bg-muted grid h-10 w-10 shrink-0 place-items-center rounded-sm border p-0.5", children: /* @__PURE__ */ jsx("div", { className: "text-muted-foreground h-full w-full overflow-hidden text-[6px] leading-none", children: preview || "Loading..." }) }),
|
|
2986
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground w-full truncate", children: file.name })
|
|
2987
|
-
] }),
|
|
2988
|
-
onRemove ? /* @__PURE__ */ jsx(
|
|
2989
|
-
"button",
|
|
2990
|
-
{
|
|
2991
|
-
className: "bg-background absolute -right-2 -top-2 flex h-4 w-4 items-center justify-center rounded-full border",
|
|
2992
|
-
type: "button",
|
|
2993
|
-
onClick: onRemove,
|
|
2994
|
-
"aria-label": "Remove attachment",
|
|
2995
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-2.5 w-2.5" })
|
|
2996
|
-
}
|
|
2997
|
-
) : null
|
|
2998
|
-
]
|
|
2999
|
-
}
|
|
3000
|
-
);
|
|
3001
|
-
});
|
|
3002
|
-
TextFilePreview.displayName = "TextFilePreview";
|
|
3003
|
-
const GenericFilePreview = React__default.forwardRef(({ file, onRemove }, ref) => {
|
|
3004
|
-
return /* @__PURE__ */ jsxs(
|
|
3005
|
-
motion.div,
|
|
3006
|
-
{
|
|
3007
|
-
ref,
|
|
3008
|
-
className: "relative flex max-w-[200px] rounded-md border p-1.5 pr-2 text-xs",
|
|
3009
|
-
layout: true,
|
|
3010
|
-
initial: { opacity: 0, y: "100%" },
|
|
3011
|
-
animate: { opacity: 1, y: 0 },
|
|
3012
|
-
exit: { opacity: 0, y: "100%" },
|
|
3013
|
-
children: [
|
|
3014
|
-
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center space-x-2", children: [
|
|
3015
|
-
/* @__PURE__ */ jsx("div", { className: "bg-muted grid h-10 w-10 shrink-0 place-items-center rounded-sm border", children: /* @__PURE__ */ jsx(FileIcon, { className: "text-foreground h-6 w-6" }) }),
|
|
3016
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground w-full truncate", children: file.name })
|
|
3017
|
-
] }),
|
|
3018
|
-
onRemove ? /* @__PURE__ */ jsx(
|
|
3019
|
-
"button",
|
|
3020
|
-
{
|
|
3021
|
-
className: "bg-background absolute -right-2 -top-2 flex h-4 w-4 items-center justify-center rounded-full border",
|
|
3022
|
-
type: "button",
|
|
3023
|
-
onClick: onRemove,
|
|
3024
|
-
"aria-label": "Remove attachment",
|
|
3025
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-2.5 w-2.5" })
|
|
3026
|
-
}
|
|
3027
|
-
) : null
|
|
3028
|
-
]
|
|
3029
|
-
}
|
|
3030
|
-
);
|
|
3031
|
-
});
|
|
3032
|
-
GenericFilePreview.displayName = "GenericFilePreview";
|
|
3033
|
-
|
|
3034
|
-
function useAutosizeTextArea({
|
|
3035
|
-
ref,
|
|
3036
|
-
maxHeight = Number.MAX_SAFE_INTEGER,
|
|
3037
|
-
borderWidth = 0,
|
|
3038
|
-
dependencies
|
|
3039
|
-
}) {
|
|
3040
|
-
const originalHeight = useRef(null);
|
|
3041
|
-
useLayoutEffect(() => {
|
|
3042
|
-
if (!ref.current) return;
|
|
3043
|
-
const currentRef = ref.current;
|
|
3044
|
-
const borderAdjustment = borderWidth * 2;
|
|
3045
|
-
if (originalHeight.current === null) {
|
|
3046
|
-
originalHeight.current = currentRef.scrollHeight - borderAdjustment;
|
|
3047
|
-
}
|
|
3048
|
-
currentRef.style.removeProperty("height");
|
|
3049
|
-
const scrollHeight = currentRef.scrollHeight;
|
|
3050
|
-
const clampedToMax = Math.min(scrollHeight, maxHeight);
|
|
3051
|
-
const clampedToMin = Math.max(clampedToMax, originalHeight.current);
|
|
3052
|
-
currentRef.style.height = `${clampedToMin + borderAdjustment}px`;
|
|
3053
|
-
}, [maxHeight, ref, ...dependencies]);
|
|
3054
|
-
}
|
|
3055
|
-
|
|
3056
|
-
function MessageInput({
|
|
3057
|
-
placeholder = "Ask AI...",
|
|
3058
|
-
className,
|
|
3059
|
-
onKeyDown: onKeyDownProp,
|
|
3060
|
-
submitOnEnter = true,
|
|
3061
|
-
stop,
|
|
3062
|
-
isGenerating,
|
|
3063
|
-
...props
|
|
3064
|
-
}) {
|
|
3065
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
3066
|
-
const addFiles = (files) => {
|
|
3067
|
-
if (props.allowAttachments) {
|
|
3068
|
-
props.setFiles((currentFiles) => {
|
|
3069
|
-
if (currentFiles === null) {
|
|
3070
|
-
return files;
|
|
3071
|
-
}
|
|
3072
|
-
if (files === null) {
|
|
3073
|
-
return currentFiles;
|
|
3074
|
-
}
|
|
3075
|
-
return [...currentFiles, ...files];
|
|
3076
|
-
});
|
|
3077
|
-
}
|
|
3078
|
-
};
|
|
3079
|
-
const onDragOver = (event) => {
|
|
3080
|
-
if (props.allowAttachments !== true) return;
|
|
3081
|
-
event.preventDefault();
|
|
3082
|
-
setIsDragging(true);
|
|
3083
|
-
};
|
|
3084
|
-
const onDragLeave = (event) => {
|
|
3085
|
-
if (props.allowAttachments !== true) return;
|
|
3086
|
-
event.preventDefault();
|
|
3087
|
-
setIsDragging(false);
|
|
3088
|
-
};
|
|
3089
|
-
const onDrop = (event) => {
|
|
3090
|
-
setIsDragging(false);
|
|
3091
|
-
if (props.allowAttachments !== true) return;
|
|
3092
|
-
event.preventDefault();
|
|
3093
|
-
const dataTransfer = event.dataTransfer;
|
|
3094
|
-
if (dataTransfer.files.length) {
|
|
3095
|
-
addFiles(Array.from(dataTransfer.files));
|
|
3096
|
-
}
|
|
3097
|
-
};
|
|
3098
|
-
const onPaste = (event) => {
|
|
3099
|
-
const items = event.clipboardData?.items;
|
|
3100
|
-
if (!items) return;
|
|
3101
|
-
const files = Array.from(items).map((item) => item.getAsFile()).filter((file) => file !== null);
|
|
3102
|
-
if (props.allowAttachments && files.length > 0) {
|
|
3103
|
-
addFiles(files);
|
|
3104
|
-
}
|
|
3105
|
-
};
|
|
3106
|
-
const onKeyDown = (event) => {
|
|
3107
|
-
if (submitOnEnter && event.key === "Enter" && !event.shiftKey) {
|
|
3108
|
-
event.preventDefault();
|
|
3109
|
-
event.currentTarget.form?.requestSubmit();
|
|
3110
|
-
}
|
|
3111
|
-
onKeyDownProp?.(event);
|
|
3112
|
-
};
|
|
3113
|
-
const textAreaRef = useRef(null);
|
|
3114
|
-
const showFileList = props.allowAttachments && props.files && props.files.length > 0;
|
|
3115
|
-
useAutosizeTextArea({
|
|
3116
|
-
ref: textAreaRef,
|
|
3117
|
-
maxHeight: 240,
|
|
3118
|
-
borderWidth: 1,
|
|
3119
|
-
dependencies: [props.value, showFileList]
|
|
3120
|
-
});
|
|
3121
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative mx-auto flex w-full", onDragOver, onDragLeave, onDrop, children: [
|
|
3122
|
-
/* @__PURE__ */ jsx(
|
|
3123
|
-
"textarea",
|
|
3124
|
-
{
|
|
3125
|
-
"aria-label": "Write your prompt here",
|
|
3126
|
-
placeholder,
|
|
3127
|
-
ref: textAreaRef,
|
|
3128
|
-
onPaste,
|
|
3129
|
-
onKeyDown,
|
|
3130
|
-
className: cn(
|
|
3131
|
-
"ring-offset-background placeholder:text-muted-foreground focus-visible:border-primary h-[98px] w-full grow resize-none rounded-2xl border-[0.5px] border-[#424242] bg-[#141414] p-3 pr-24 text-sm shadow-[0px_2px_8.1px_0px_rgba(0,0,0,0.20);] transition-[border] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
3132
|
-
showFileList && "pb-16",
|
|
3133
|
-
className
|
|
3134
|
-
),
|
|
3135
|
-
...props.allowAttachments ? omit(props, ["allowAttachments", "files", "setFiles"]) : omit(props, ["allowAttachments"])
|
|
3136
|
-
}
|
|
3137
|
-
),
|
|
3138
|
-
props.allowAttachments && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-3 bottom-0 overflow-x-scroll py-3", children: /* @__PURE__ */ jsx("div", { className: "flex space-x-3", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "popLayout", children: props.files?.map((file) => {
|
|
3139
|
-
return /* @__PURE__ */ jsx(
|
|
3140
|
-
FilePreview,
|
|
3141
|
-
{
|
|
3142
|
-
file,
|
|
3143
|
-
onRemove: () => {
|
|
3144
|
-
props.setFiles((files) => {
|
|
3145
|
-
if (!files) return null;
|
|
3146
|
-
const filtered = Array.from(files).filter((f) => f !== file);
|
|
3147
|
-
if (filtered.length === 0) return null;
|
|
3148
|
-
return filtered;
|
|
3149
|
-
});
|
|
3150
|
-
}
|
|
3151
|
-
},
|
|
3152
|
-
file.name + String(file.lastModified)
|
|
3153
|
-
);
|
|
3154
|
-
}) }) }) }),
|
|
3155
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-3 right-3 flex gap-2", children: [
|
|
3156
|
-
props.allowAttachments && /* @__PURE__ */ jsx(
|
|
3157
|
-
Button,
|
|
3158
|
-
{
|
|
3159
|
-
type: "button",
|
|
3160
|
-
size: "icon",
|
|
3161
|
-
variant: "outline",
|
|
3162
|
-
className: "h-8 w-8",
|
|
3163
|
-
"aria-label": "Attach a file",
|
|
3164
|
-
onClick: async () => {
|
|
3165
|
-
const files = await showFileUploadDialog();
|
|
3166
|
-
addFiles(files);
|
|
3167
|
-
},
|
|
3168
|
-
children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
|
|
3169
|
-
}
|
|
3170
|
-
),
|
|
3171
|
-
isGenerating && stop ? /* @__PURE__ */ jsx(Button, { type: "button", size: "icon", className: "h-8 w-8", "aria-label": "Stop generating", onClick: stop, children: /* @__PURE__ */ jsx(Square, { className: "h-3 w-3 animate-pulse", fill: "currentColor" }) }) : /* @__PURE__ */ jsx(
|
|
3172
|
-
Button,
|
|
3173
|
-
{
|
|
3174
|
-
type: "submit",
|
|
3175
|
-
variant: "secondary",
|
|
3176
|
-
size: "icon",
|
|
3177
|
-
className: "mt-0 h-8 w-8 rounded-full transition-opacity",
|
|
3178
|
-
"aria-label": "Send message",
|
|
3179
|
-
disabled: props.value === "" || isGenerating,
|
|
3180
|
-
children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-6 w-6" })
|
|
3181
|
-
}
|
|
3182
|
-
)
|
|
3183
|
-
] }),
|
|
3184
|
-
props.allowAttachments && /* @__PURE__ */ jsx(FileUploadOverlay, { isDragging })
|
|
3185
|
-
] });
|
|
3186
|
-
}
|
|
3187
|
-
MessageInput.displayName = "MessageInput";
|
|
3188
|
-
function FileUploadOverlay({ isDragging }) {
|
|
3189
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: isDragging && /* @__PURE__ */ jsxs(
|
|
3190
|
-
motion.div,
|
|
3191
|
-
{
|
|
3192
|
-
className: "border-border bg-background text-muted-foreground pointer-events-none absolute inset-0 flex items-center justify-center space-x-2 rounded-xl border border-dashed text-sm",
|
|
3193
|
-
initial: { opacity: 0 },
|
|
3194
|
-
animate: { opacity: 1 },
|
|
3195
|
-
exit: { opacity: 0 },
|
|
3196
|
-
transition: { duration: 0.2 },
|
|
3197
|
-
"aria-hidden": true,
|
|
3198
|
-
children: [
|
|
3199
|
-
/* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" }),
|
|
3200
|
-
/* @__PURE__ */ jsx("span", { children: "Drop your files here to attach them." })
|
|
3201
|
-
]
|
|
3202
|
-
}
|
|
3203
|
-
) });
|
|
3204
|
-
}
|
|
3205
|
-
function showFileUploadDialog() {
|
|
3206
|
-
const input = document.createElement("input");
|
|
3207
|
-
input.type = "file";
|
|
3208
|
-
input.multiple = true;
|
|
3209
|
-
input.accept = "*/*";
|
|
3210
|
-
input.click();
|
|
3211
|
-
return new Promise((resolve) => {
|
|
3212
|
-
input.onchange = (e) => {
|
|
3213
|
-
const files = e.currentTarget.files;
|
|
3214
|
-
if (files) {
|
|
3215
|
-
resolve(Array.from(files));
|
|
3216
|
-
return;
|
|
3217
|
-
}
|
|
3218
|
-
resolve(null);
|
|
3219
|
-
};
|
|
3220
|
-
});
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3223
|
-
async function highlight(code, language) {
|
|
3224
|
-
const { codeToTokens, bundledLanguages } = await import('shiki');
|
|
3225
|
-
if (!(language in bundledLanguages)) return null;
|
|
3226
|
-
const { tokens } = await codeToTokens(code, {
|
|
3227
|
-
lang: language,
|
|
3228
|
-
defaultColor: false,
|
|
3229
|
-
themes: {
|
|
3230
|
-
light: "github-light",
|
|
3231
|
-
dark: "github-dark"
|
|
3232
|
-
}
|
|
3233
|
-
});
|
|
3234
|
-
return tokens;
|
|
3235
|
-
}
|
|
3236
|
-
|
|
3237
|
-
function MarkdownRenderer({ children }) {
|
|
3238
|
-
const processedText = children?.replace(/\\n/g, "\n");
|
|
3239
|
-
return /* @__PURE__ */ jsx(Markdown, { remarkPlugins: [remarkGfm], components: COMPONENTS, className: "space-y-3", children: processedText });
|
|
3240
|
-
}
|
|
3241
|
-
const HighlightedPre = React__default.memo(({ children, language, ...props }) => {
|
|
3242
|
-
const [tokens, setTokens] = useState([]);
|
|
3243
|
-
useEffect(() => {
|
|
3244
|
-
highlight(children, language).then((tokens2) => {
|
|
3245
|
-
if (tokens2) setTokens(tokens2);
|
|
3246
|
-
});
|
|
3247
|
-
}, [children, language]);
|
|
3248
|
-
if (!tokens.length) {
|
|
3249
|
-
return /* @__PURE__ */ jsx("pre", { ...props, children });
|
|
3250
|
-
}
|
|
3251
|
-
return /* @__PURE__ */ jsx("pre", { ...props, children: /* @__PURE__ */ jsx("code", { children: tokens.map((line, lineIndex) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3252
|
-
/* @__PURE__ */ jsx("span", { children: line.map((token, tokenIndex) => {
|
|
3253
|
-
const style = typeof token.htmlStyle === "string" ? void 0 : token.htmlStyle;
|
|
3254
|
-
return /* @__PURE__ */ jsx(
|
|
3255
|
-
"span",
|
|
3256
|
-
{
|
|
3257
|
-
className: "text-shiki-light bg-shiki-light-bg dark:text-shiki-dark dark:bg-shiki-dark-bg",
|
|
3258
|
-
style,
|
|
3259
|
-
children: token.content
|
|
3260
|
-
},
|
|
3261
|
-
tokenIndex
|
|
3262
|
-
);
|
|
3263
|
-
}) }, lineIndex),
|
|
3264
|
-
lineIndex !== tokens.length - 1 && "\n"
|
|
3265
|
-
] })) }) });
|
|
3266
|
-
});
|
|
3267
|
-
HighlightedPre.displayName = "HighlightedCode";
|
|
3268
|
-
const CodeBlock = ({ children, className, language, ...restProps }) => {
|
|
3269
|
-
const code = typeof children === "string" ? children : childrenTakeAllStringContents(children);
|
|
3270
|
-
const preClass = cn(
|
|
3271
|
-
"overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]",
|
|
3272
|
-
className
|
|
3273
|
-
);
|
|
3274
|
-
return /* @__PURE__ */ jsxs("div", { className: "group/code relative mb-4", children: [
|
|
3275
|
-
/* @__PURE__ */ jsx(
|
|
3276
|
-
Suspense,
|
|
3277
|
-
{
|
|
3278
|
-
fallback: /* @__PURE__ */ jsx("pre", { className: preClass, ...restProps, children }),
|
|
3279
|
-
children: /* @__PURE__ */ jsx(HighlightedPre, { language, className: preClass, children: code })
|
|
3280
|
-
}
|
|
3281
|
-
),
|
|
3282
|
-
/* @__PURE__ */ jsx("div", { className: "invisible absolute right-2 top-2 flex space-x-1 rounded-lg p-1 opacity-0 transition-all duration-200 group-hover/code:visible group-hover/code:opacity-100", children: /* @__PURE__ */ jsx(CopyButton$1, { content: code, copyMessage: "Copied code to clipboard" }) })
|
|
3283
|
-
] });
|
|
3284
|
-
};
|
|
3285
|
-
function childrenTakeAllStringContents(element) {
|
|
3286
|
-
if (typeof element === "string") {
|
|
3287
|
-
return element;
|
|
3288
|
-
}
|
|
3289
|
-
if (element && typeof element === "object" && "props" in element) {
|
|
3290
|
-
const el = element;
|
|
3291
|
-
const children = el.props.children;
|
|
3292
|
-
if (Array.isArray(children)) {
|
|
3293
|
-
return children.map((child) => childrenTakeAllStringContents(child)).join("");
|
|
3294
|
-
} else {
|
|
3295
|
-
return childrenTakeAllStringContents(children);
|
|
3296
|
-
}
|
|
3297
|
-
}
|
|
3298
|
-
return "";
|
|
3299
|
-
}
|
|
3300
|
-
const COMPONENTS = {
|
|
3301
|
-
h1: withClass("h1", "text-2xl font-semibold"),
|
|
3302
|
-
h2: withClass("h2", "font-semibold text-xl"),
|
|
3303
|
-
h3: withClass("h3", "font-semibold text-lg"),
|
|
3304
|
-
h4: withClass("h4", "font-semibold text-base"),
|
|
3305
|
-
h5: withClass("h5", "font-medium"),
|
|
3306
|
-
strong: withClass("strong", "font-semibold"),
|
|
3307
|
-
a: withClass("a", "text-primary underline underline-offset-2"),
|
|
3308
|
-
blockquote: withClass("blockquote", "border-l-2 border-primary pl-4"),
|
|
3309
|
-
code: ({ children, className, ...rest }) => {
|
|
3310
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
3311
|
-
return match ? /* @__PURE__ */ jsx(CodeBlock, { className, language: match[1], ...rest, children }) : /* @__PURE__ */ jsx(
|
|
3312
|
-
"code",
|
|
3313
|
-
{
|
|
3314
|
-
className: cn(
|
|
3315
|
-
"[:not(pre)>&]:bg-background/50 font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5"
|
|
3316
|
-
),
|
|
3317
|
-
...rest,
|
|
3318
|
-
children
|
|
3319
|
-
}
|
|
3320
|
-
);
|
|
3321
|
-
},
|
|
3322
|
-
pre: ({ children }) => children,
|
|
3323
|
-
ol: withClass("ol", "list-decimal space-y-2 pl-6"),
|
|
3324
|
-
ul: withClass("ul", "list-disc space-y-2 pl-6"),
|
|
3325
|
-
li: withClass("li", "my-1.5"),
|
|
3326
|
-
table: withClass("table", "w-full border-collapse overflow-y-auto rounded-md border border-foreground/20"),
|
|
3327
|
-
th: withClass(
|
|
3328
|
-
"th",
|
|
3329
|
-
"border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
|
3330
|
-
),
|
|
3331
|
-
td: withClass(
|
|
3332
|
-
"td",
|
|
3333
|
-
"border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
|
3334
|
-
),
|
|
3335
|
-
tr: withClass("tr", "m-0 border-t p-0 even:bg-muted"),
|
|
3336
|
-
p: withClass("p", "whitespace-pre-wrap leading-relaxed"),
|
|
3337
|
-
hr: withClass("hr", "border-foreground/20")
|
|
3338
|
-
};
|
|
3339
|
-
function withClass(Tag, classes) {
|
|
3340
|
-
const Component = ({ node, ...props }) => /* @__PURE__ */ jsx(Tag, { className: classes, ...props });
|
|
3341
|
-
Component.displayName = Tag;
|
|
3342
|
-
return Component;
|
|
3343
|
-
}
|
|
3344
|
-
|
|
3345
|
-
const chatBubbleVariants = cva("group/message relative break-words rounded-xl px-3 py-2 text-sm sm:max-w-[70%]", {
|
|
3346
|
-
variants: {
|
|
3347
|
-
isUser: {
|
|
3348
|
-
true: "bg-primary text-primary-foreground",
|
|
3349
|
-
false: "bg-muted text-foreground"
|
|
3350
|
-
},
|
|
3351
|
-
isError: {
|
|
3352
|
-
true: "bg-red-100 dark:bg-red-900/20",
|
|
3353
|
-
false: ""
|
|
3354
|
-
},
|
|
3355
|
-
animation: {
|
|
3356
|
-
none: "",
|
|
3357
|
-
slide: "duration-300 animate-in fade-in-0",
|
|
3358
|
-
scale: "duration-300 animate-in fade-in-0 zoom-in-75",
|
|
3359
|
-
fade: "duration-500 animate-in fade-in-0"
|
|
3360
|
-
}
|
|
3361
|
-
},
|
|
3362
|
-
compoundVariants: [
|
|
3363
|
-
{
|
|
3364
|
-
isUser: true,
|
|
3365
|
-
animation: "slide",
|
|
3366
|
-
class: "slide-in-from-right"
|
|
3367
|
-
},
|
|
3368
|
-
{
|
|
3369
|
-
isUser: false,
|
|
3370
|
-
animation: "slide",
|
|
3371
|
-
class: "slide-in-from-left"
|
|
3372
|
-
},
|
|
3373
|
-
{
|
|
3374
|
-
isUser: true,
|
|
3375
|
-
animation: "scale",
|
|
3376
|
-
class: "origin-bottom-right"
|
|
3377
|
-
},
|
|
3378
|
-
{
|
|
3379
|
-
isUser: false,
|
|
3380
|
-
animation: "scale",
|
|
3381
|
-
class: "origin-bottom-left"
|
|
3382
|
-
}
|
|
3383
|
-
]
|
|
3384
|
-
});
|
|
3385
|
-
const ChatMessage = ({
|
|
3386
|
-
role,
|
|
3387
|
-
content,
|
|
3388
|
-
createdAt,
|
|
3389
|
-
showTimeStamp = false,
|
|
3390
|
-
animation = "scale",
|
|
3391
|
-
actions,
|
|
3392
|
-
className,
|
|
3393
|
-
experimental_attachments,
|
|
3394
|
-
isError = false
|
|
3395
|
-
}) => {
|
|
3396
|
-
const isUser = role === "user";
|
|
3397
|
-
const files = useMemo(() => {
|
|
3398
|
-
return experimental_attachments?.map((attachment) => {
|
|
3399
|
-
const dataArray = dataUrlToUint8Array(attachment.url);
|
|
3400
|
-
const file = new File([dataArray], attachment.name ?? "Unknown");
|
|
3401
|
-
return file;
|
|
3402
|
-
});
|
|
3403
|
-
}, [experimental_attachments]);
|
|
3404
|
-
const formattedTime = createdAt?.toLocaleTimeString("en-US", {
|
|
3405
|
-
hour: "2-digit",
|
|
3406
|
-
minute: "2-digit"
|
|
3407
|
-
});
|
|
3408
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", isUser ? "items-end" : "items-start"), children: [
|
|
3409
|
-
files ? /* @__PURE__ */ jsx("div", { className: "mb-1 flex flex-wrap gap-2", children: files.map((file, index) => {
|
|
3410
|
-
return /* @__PURE__ */ jsx(FilePreview, { file }, index);
|
|
3411
|
-
}) }) : null,
|
|
3412
|
-
/* @__PURE__ */ jsxs("div", { className: cn(chatBubbleVariants({ isUser, isError, animation: "none" }), className), children: [
|
|
3413
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(MarkdownRenderer, { children: content }) }),
|
|
3414
|
-
role === "assistant" && actions ? /* @__PURE__ */ jsx("div", { className: "bg-background text-foreground absolute -bottom-4 right-2 flex space-x-1 rounded-lg border p-1 opacity-0 transition-opacity group-hover/message:opacity-100", children: actions }) : null
|
|
3415
|
-
] }),
|
|
3416
|
-
showTimeStamp && createdAt ? /* @__PURE__ */ jsx(
|
|
3417
|
-
"time",
|
|
3418
|
-
{
|
|
3419
|
-
dateTime: createdAt.toISOString(),
|
|
3420
|
-
className: cn(
|
|
3421
|
-
"mt-1 block px-1 text-xs opacity-50",
|
|
3422
|
-
animation !== "none" && "animate-in fade-in-0 duration-500"
|
|
3423
|
-
),
|
|
3424
|
-
children: formattedTime
|
|
3425
|
-
}
|
|
3426
|
-
) : null
|
|
3427
|
-
] });
|
|
3428
|
-
};
|
|
3429
|
-
function dataUrlToUint8Array(data) {
|
|
3430
|
-
const base64 = data.split(",")[1];
|
|
3431
|
-
const buf = Buffer.from(base64 ?? "", "base64");
|
|
3432
|
-
return new Uint8Array(buf);
|
|
3433
|
-
}
|
|
3434
|
-
|
|
3435
|
-
function TypingIndicator() {
|
|
3436
|
-
return /* @__PURE__ */ jsx("div", { className: "justify-left flex space-x-1", children: /* @__PURE__ */ jsx("div", { className: "bg-muted flex items-center gap-1 rounded-lg px-2 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2.5", children: [
|
|
3437
|
-
/* @__PURE__ */ jsx(Dot, { className: "animate-typing-dot-bounce h-5 w-5" }),
|
|
3438
|
-
/* @__PURE__ */ jsx(Dot, { className: "animate-typing-dot-bounce h-5 w-5 delay-200" }),
|
|
3439
|
-
/* @__PURE__ */ jsx(Dot, { className: "animate-typing-dot-bounce h-5 w-5 delay-500" })
|
|
3440
|
-
] }) }) });
|
|
3441
|
-
}
|
|
3442
|
-
|
|
3443
|
-
function MessageList({ messages, showTimeStamps = true, isTyping = false, messageOptions }) {
|
|
3444
|
-
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-3xl space-y-4 px-3 pt-3", children: [
|
|
3445
|
-
messages.map((message, index) => {
|
|
3446
|
-
const additionalOptions = typeof messageOptions === "function" ? messageOptions(message) : messageOptions;
|
|
3447
|
-
if (message.role === "assistant" && !message.content.trim()) {
|
|
3448
|
-
return null;
|
|
3449
|
-
}
|
|
3450
|
-
return /* @__PURE__ */ jsx(ChatMessage, { showTimeStamp: showTimeStamps, ...message, ...additionalOptions }, index);
|
|
3451
|
-
}),
|
|
3452
|
-
isTyping && /* @__PURE__ */ jsx(TypingIndicator, {})
|
|
3453
|
-
] });
|
|
3454
|
-
}
|
|
3455
|
-
|
|
3456
|
-
function PromptSuggestions({ append, suggestions, memoryIsPresent }) {
|
|
3457
|
-
return /* @__PURE__ */ jsx("div", { className: "flex gap-6 text-sm", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx(
|
|
3458
|
-
"button",
|
|
3459
|
-
{
|
|
3460
|
-
type: "button",
|
|
3461
|
-
onClick: () => append({ role: "user", content: suggestion }),
|
|
3462
|
-
className: "h-max rounded-[0.4rem] bg-[#141414] p-4 py-[0.6rem]",
|
|
3463
|
-
children: /* @__PURE__ */ jsx(
|
|
3464
|
-
"span",
|
|
3465
|
-
{
|
|
3466
|
-
className: cn("text-[#939393] transition-colors hover:text-white", memoryIsPresent ? "text-xs" : "text-sm"),
|
|
3467
|
-
children: suggestion
|
|
3468
|
-
}
|
|
3469
|
-
)
|
|
3470
|
-
},
|
|
3471
|
-
suggestion
|
|
3472
|
-
)) });
|
|
3473
|
-
}
|
|
3474
|
-
|
|
3475
|
-
function ChatMessages({
|
|
3476
|
-
messages,
|
|
3477
|
-
children
|
|
3478
|
-
}) {
|
|
3479
|
-
const { scrollToBottom, shouldAutoScroll } = useAutoScroll([messages]);
|
|
3480
|
-
return /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-scroll pb-4", children: [
|
|
3481
|
-
children,
|
|
3482
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-1 items-end justify-end [grid-column:1/1] [grid-row:1/1]", children: !shouldAutoScroll && /* @__PURE__ */ jsx("div", { className: "sticky bottom-0 left-0 flex w-full justify-end", children: /* @__PURE__ */ jsx(
|
|
3483
|
-
Button,
|
|
3484
|
-
{
|
|
3485
|
-
onClick: scrollToBottom,
|
|
3486
|
-
className: "animate-in fade-in-0 slide-in-from-bottom-1 h-8 w-8 rounded-full ease-in-out",
|
|
3487
|
-
size: "icon",
|
|
3488
|
-
variant: "ghost",
|
|
3489
|
-
children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-4 w-4" })
|
|
3490
|
-
}
|
|
3491
|
-
) }) })
|
|
3492
|
-
] });
|
|
3493
|
-
}
|
|
3494
|
-
const ChatContainer = forwardRef(
|
|
3495
|
-
({ className, ...props }, ref) => {
|
|
3496
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), ...props });
|
|
3497
|
-
}
|
|
3498
|
-
);
|
|
3499
|
-
ChatContainer.displayName = "ChatContainer";
|
|
3500
|
-
const ChatForm = forwardRef(
|
|
3501
|
-
({ children, handleSubmit, isPending, className }, ref) => {
|
|
3502
|
-
const [files, setFiles] = useState(null);
|
|
3503
|
-
const onSubmit = (event) => {
|
|
3504
|
-
if (isPending) {
|
|
3505
|
-
event.preventDefault();
|
|
3506
|
-
return;
|
|
3507
|
-
}
|
|
3508
|
-
if (!files) {
|
|
3509
|
-
handleSubmit(event);
|
|
3510
|
-
return;
|
|
3511
|
-
}
|
|
3512
|
-
const fileList = createFileList(files);
|
|
3513
|
-
handleSubmit(event, { experimental_attachments: fileList });
|
|
3514
|
-
setFiles(null);
|
|
3515
|
-
};
|
|
3516
|
-
return /* @__PURE__ */ jsx("form", { ref, onSubmit, className, children: children({ files, setFiles }) });
|
|
3517
|
-
}
|
|
3518
|
-
);
|
|
3519
|
-
ChatForm.displayName = "ChatForm";
|
|
3520
|
-
function createFileList(files) {
|
|
3521
|
-
const dataTransfer = new DataTransfer();
|
|
3522
|
-
for (const file of Array.from(files)) {
|
|
3523
|
-
dataTransfer.items.add(file);
|
|
3524
|
-
}
|
|
3525
|
-
return dataTransfer.files;
|
|
3526
|
-
}
|
|
3527
|
-
|
|
3528
|
-
function Chat({ agentId, initialMessages = [], agentName, threadId, memory, buildUrl }) {
|
|
3529
|
-
const [messages, setMessages] = useState(initialMessages);
|
|
3530
|
-
const [input, setInput] = useState("");
|
|
3531
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
3532
|
-
const { mutate } = useSWRConfig();
|
|
3533
|
-
const { containerRef, handleScroll, handleTouchStart } = useAutoScroll([messages]);
|
|
3534
|
-
useEffect(() => {
|
|
3535
|
-
setMessages(initialMessages);
|
|
3536
|
-
}, [initialMessages]);
|
|
3537
|
-
const handleInputChange = useCallback((e) => {
|
|
3538
|
-
setInput(e.target.value);
|
|
3539
|
-
}, []);
|
|
3540
|
-
const handleSubmit = useCallback(
|
|
3541
|
-
async (event) => {
|
|
3542
|
-
event?.preventDefault?.();
|
|
3543
|
-
if (!input.trim() || isLoading) return;
|
|
3544
|
-
const userMessage = input;
|
|
3545
|
-
setInput("");
|
|
3546
|
-
setIsLoading(true);
|
|
3547
|
-
const newUserMessage = {
|
|
3548
|
-
id: Date.now().toString(),
|
|
3549
|
-
role: "user",
|
|
3550
|
-
content: userMessage
|
|
3551
|
-
};
|
|
3552
|
-
const newAssistantMessage = {
|
|
3553
|
-
id: (Date.now() + 1).toString(),
|
|
3554
|
-
role: "assistant",
|
|
3555
|
-
content: ""
|
|
3556
|
-
};
|
|
3557
|
-
setMessages((prev) => [...prev, newUserMessage, newAssistantMessage]);
|
|
3558
|
-
const newThreadId = threadId ? threadId : crypto.randomUUID();
|
|
3559
|
-
try {
|
|
3560
|
-
const client = new MastraClient({
|
|
3561
|
-
baseUrl: buildUrl || ""
|
|
3562
|
-
});
|
|
3563
|
-
const response = await client.getAgent(agentId).stream({
|
|
3564
|
-
messages: [userMessage],
|
|
3565
|
-
threadId: newThreadId,
|
|
3566
|
-
resourceId: agentId
|
|
3567
|
-
});
|
|
3568
|
-
if (!response.body) return;
|
|
3569
|
-
if (response.status !== 200) {
|
|
3570
|
-
const error = await response.json();
|
|
3571
|
-
setMessages((prev) => [
|
|
3572
|
-
...prev.slice(0, -1),
|
|
3573
|
-
{
|
|
3574
|
-
...prev[prev.length - 1],
|
|
3575
|
-
content: error.error,
|
|
3576
|
-
isError: true
|
|
3577
|
-
}
|
|
3578
|
-
]);
|
|
3579
|
-
return;
|
|
3580
|
-
}
|
|
3581
|
-
await mutate(`${buildUrl}/api/memory/threads?resourceid=${agentId}`);
|
|
3582
|
-
const reader = response.body.getReader();
|
|
3583
|
-
const decoder = new TextDecoder();
|
|
3584
|
-
let buffer = "";
|
|
3585
|
-
let assistantMessage = "";
|
|
3586
|
-
while (true) {
|
|
3587
|
-
const { done, value } = await reader.read();
|
|
3588
|
-
if (done) {
|
|
3589
|
-
break;
|
|
3590
|
-
}
|
|
3591
|
-
const chunk = decoder.decode(value);
|
|
3592
|
-
buffer += chunk;
|
|
3593
|
-
if (buffer?.toLocaleLowerCase()?.includes("an error occurred")) {
|
|
3594
|
-
setMessages((prev) => [
|
|
3595
|
-
...prev.slice(0, -1),
|
|
3596
|
-
{
|
|
3597
|
-
...prev[prev.length - 1],
|
|
3598
|
-
content: "An error occurred while processing your request.",
|
|
3599
|
-
isError: true
|
|
3600
|
-
}
|
|
3601
|
-
]);
|
|
3602
|
-
return;
|
|
3603
|
-
}
|
|
3604
|
-
const matches = buffer.matchAll(/0:"([^"]*)"/g);
|
|
3605
|
-
for (const match of matches) {
|
|
3606
|
-
const content = match[1];
|
|
3607
|
-
assistantMessage += content;
|
|
3608
|
-
setMessages((prev) => [...prev.slice(0, -1), { ...prev[prev.length - 1], content: assistantMessage }]);
|
|
3609
|
-
}
|
|
3610
|
-
buffer = "";
|
|
3611
|
-
}
|
|
3612
|
-
} catch (error) {
|
|
3613
|
-
console.error("Error:", error);
|
|
3614
|
-
setMessages((prev) => [
|
|
3615
|
-
...prev.slice(0, -1),
|
|
3616
|
-
{
|
|
3617
|
-
...prev[prev.length - 1],
|
|
3618
|
-
content: "An error occurred while processing your request.",
|
|
3619
|
-
isError: true
|
|
3620
|
-
}
|
|
3621
|
-
]);
|
|
3622
|
-
} finally {
|
|
3623
|
-
setIsLoading(false);
|
|
3624
|
-
}
|
|
3625
|
-
},
|
|
3626
|
-
[input, isLoading, buildUrl, agentId, threadId, mutate]
|
|
3627
|
-
);
|
|
3628
|
-
const lastMessage = messages.at(-1);
|
|
3629
|
-
const isEmpty = messages.length === 0;
|
|
3630
|
-
const isTyping = isLoading && lastMessage?.role === "assistant" && !lastMessage?.content.trim();
|
|
3631
|
-
const append = useCallback(
|
|
3632
|
-
(message) => {
|
|
3633
|
-
setInput(message.content);
|
|
3634
|
-
handleSubmit();
|
|
3635
|
-
},
|
|
3636
|
-
[handleSubmit]
|
|
3637
|
-
);
|
|
3638
|
-
const suggestions = ["What capabilities do you have?", "How can you help me?", "Tell me about yourself"];
|
|
3639
|
-
return /* @__PURE__ */ jsxs(ChatContainer, { className: "relative flex h-full w-full flex-col overflow-y-clip pb-9", children: [
|
|
3640
|
-
/* @__PURE__ */ jsx(
|
|
3641
|
-
"div",
|
|
3642
|
-
{
|
|
3643
|
-
ref: containerRef,
|
|
3644
|
-
onScroll: handleScroll,
|
|
3645
|
-
onTouchStart: handleTouchStart,
|
|
3646
|
-
className: "h-full overflow-y-clip bg-transparent pb-[calc(98px+2rem)]",
|
|
3647
|
-
children: /* @__PURE__ */ jsx(ChatMessages, { messages, children: /* @__PURE__ */ jsx(MessageList, { messages, isTyping }) })
|
|
3648
|
-
}
|
|
3649
|
-
),
|
|
3650
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-8 left-1/2 flex w-full max-w-3xl -translate-x-1/2 flex-col gap-2 bg-[#0f0f0f] pb-3", children: [
|
|
3651
|
-
isEmpty ? /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-2xl", children: /* @__PURE__ */ jsx(
|
|
3652
|
-
PromptSuggestions,
|
|
3653
|
-
{
|
|
3654
|
-
memoryIsPresent: memory,
|
|
3655
|
-
label: `Chat with ${agentName}`,
|
|
3656
|
-
append,
|
|
3657
|
-
suggestions
|
|
3658
|
-
}
|
|
3659
|
-
) }) : null,
|
|
3660
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ChatForm, { isPending: isLoading || isTyping, handleSubmit, children: ({ files, setFiles }) => /* @__PURE__ */ jsx(
|
|
3661
|
-
MessageInput,
|
|
3662
|
-
{
|
|
3663
|
-
value: input,
|
|
3664
|
-
onChange: handleInputChange,
|
|
3665
|
-
files,
|
|
3666
|
-
setFiles,
|
|
3667
|
-
isGenerating: isLoading,
|
|
3668
|
-
placeholder: `Enter your message...`
|
|
3669
|
-
}
|
|
3670
|
-
) }) }),
|
|
3671
|
-
!memory && /* @__PURE__ */ jsxs("div", { className: "text-mastra-el-5 flex items-center gap-1 text-sm", children: [
|
|
3672
|
-
/* @__PURE__ */ jsxs(
|
|
3673
|
-
"svg",
|
|
3674
|
-
{
|
|
3675
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3676
|
-
width: "14",
|
|
3677
|
-
height: "14",
|
|
3678
|
-
viewBox: "0 0 24 24",
|
|
3679
|
-
fill: "none",
|
|
3680
|
-
stroke: "currentColor",
|
|
3681
|
-
strokeWidth: "2",
|
|
3682
|
-
strokeLinecap: "round",
|
|
3683
|
-
strokeLinejoin: "round",
|
|
3684
|
-
className: "text-purple-400",
|
|
3685
|
-
children: [
|
|
3686
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
3687
|
-
/* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
|
|
3688
|
-
/* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
|
|
3689
|
-
]
|
|
3690
|
-
}
|
|
3691
|
-
),
|
|
3692
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-300/60", children: [
|
|
3693
|
-
"Agent will not remember previous messages. To enable memory for agent see",
|
|
3694
|
-
" ",
|
|
3695
|
-
/* @__PURE__ */ jsx(
|
|
3696
|
-
"a",
|
|
3697
|
-
{
|
|
3698
|
-
href: "https://mastra.ai/docs/agents/01-agent-memory",
|
|
3699
|
-
target: "_blank",
|
|
3700
|
-
rel: "noopener",
|
|
3701
|
-
className: "text-gray-300/60 underline hover:text-gray-100",
|
|
3702
|
-
children: "docs."
|
|
3703
|
-
}
|
|
3704
|
-
)
|
|
3705
|
-
] })
|
|
3706
|
-
] })
|
|
3707
|
-
] })
|
|
3708
|
-
] });
|
|
3709
|
-
}
|
|
3710
|
-
|
|
3711
2837
|
const TooltipProvider = TooltipPrimitive.Provider;
|
|
3712
2838
|
const Tooltip = TooltipPrimitive.Root;
|
|
3713
2839
|
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
@@ -4378,7 +3504,7 @@ function MastraRuntimeProvider({
|
|
|
4378
3504
|
refreshThreadList?.();
|
|
4379
3505
|
}
|
|
4380
3506
|
} catch (error) {
|
|
4381
|
-
console.error("Error
|
|
3507
|
+
console.error("Error occurred in MastraRuntimeProvider", error);
|
|
4382
3508
|
setIsRunning(false);
|
|
4383
3509
|
}
|
|
4384
3510
|
};
|
|
@@ -4523,7 +3649,7 @@ const Table = React.forwardRef(
|
|
|
4523
3649
|
);
|
|
4524
3650
|
Table.displayName = "Table";
|
|
4525
3651
|
const TableHeader = React.forwardRef(
|
|
4526
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
3652
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b-[0.5px]", className), ...props })
|
|
4527
3653
|
);
|
|
4528
3654
|
TableHeader.displayName = "TableHeader";
|
|
4529
3655
|
const TableBody = React.forwardRef(
|
|
@@ -4842,29 +3968,112 @@ function EvalTable({ evals, isCIMode = false }) {
|
|
|
4842
3968
|
evals: [evaluation]
|
|
4843
3969
|
});
|
|
4844
3970
|
}
|
|
4845
|
-
return groups2;
|
|
4846
|
-
}, []);
|
|
4847
|
-
if (searchTerm) {
|
|
4848
|
-
groups = groups.filter(
|
|
4849
|
-
(group) => group.metricName.toLowerCase().includes(searchTerm.toLowerCase()) || group.evals.some(
|
|
4850
|
-
(metric) => metric.input?.toLowerCase().includes(searchTerm.toLowerCase()) || metric.output?.toLowerCase().includes(searchTerm.toLowerCase()) || metric.instructions?.toLowerCase().includes(searchTerm.toLowerCase())
|
|
4851
|
-
)
|
|
4852
|
-
);
|
|
4853
|
-
}
|
|
4854
|
-
groups.sort((a, b) => {
|
|
4855
|
-
const direction = sortConfig.direction === "asc" ? 1 : -1;
|
|
4856
|
-
switch (sortConfig.field) {
|
|
4857
|
-
case "metricName":
|
|
4858
|
-
return direction * a.metricName.localeCompare(b.metricName);
|
|
4859
|
-
case "averageScore":
|
|
4860
|
-
return direction * (a.averageScore - b.averageScore);
|
|
4861
|
-
default:
|
|
4862
|
-
return 0;
|
|
3971
|
+
return groups2;
|
|
3972
|
+
}, []);
|
|
3973
|
+
if (searchTerm) {
|
|
3974
|
+
groups = groups.filter(
|
|
3975
|
+
(group) => group.metricName.toLowerCase().includes(searchTerm.toLowerCase()) || group.evals.some(
|
|
3976
|
+
(metric) => metric.input?.toLowerCase().includes(searchTerm.toLowerCase()) || metric.output?.toLowerCase().includes(searchTerm.toLowerCase()) || metric.instructions?.toLowerCase().includes(searchTerm.toLowerCase())
|
|
3977
|
+
)
|
|
3978
|
+
);
|
|
3979
|
+
}
|
|
3980
|
+
groups.sort((a, b) => {
|
|
3981
|
+
const direction = sortConfig.direction === "asc" ? 1 : -1;
|
|
3982
|
+
switch (sortConfig.field) {
|
|
3983
|
+
case "metricName":
|
|
3984
|
+
return direction * a.metricName.localeCompare(b.metricName);
|
|
3985
|
+
case "averageScore":
|
|
3986
|
+
return direction * (a.averageScore - b.averageScore);
|
|
3987
|
+
default:
|
|
3988
|
+
return 0;
|
|
3989
|
+
}
|
|
3990
|
+
});
|
|
3991
|
+
return groups;
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
|
|
3995
|
+
const useResizeColumn = ({
|
|
3996
|
+
defaultWidth,
|
|
3997
|
+
minimumWidth,
|
|
3998
|
+
maximumWidth,
|
|
3999
|
+
setCurrentWidth
|
|
4000
|
+
}) => {
|
|
4001
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
4002
|
+
const [sidebarWidth, setSidebarWidth] = useState(defaultWidth);
|
|
4003
|
+
const containerRef = useRef(null);
|
|
4004
|
+
const dragStartXRef = useRef(0);
|
|
4005
|
+
const initialWidthRef = useRef(0);
|
|
4006
|
+
const handleMouseDown = (e) => {
|
|
4007
|
+
e.preventDefault();
|
|
4008
|
+
setIsDragging(true);
|
|
4009
|
+
dragStartXRef.current = e.clientX;
|
|
4010
|
+
initialWidthRef.current = sidebarWidth;
|
|
4011
|
+
};
|
|
4012
|
+
useEffect(() => {
|
|
4013
|
+
setSidebarWidth(defaultWidth);
|
|
4014
|
+
setCurrentWidth?.(defaultWidth);
|
|
4015
|
+
}, [defaultWidth]);
|
|
4016
|
+
useEffect(() => {
|
|
4017
|
+
const handleMouseMove = (e) => {
|
|
4018
|
+
if (!isDragging || !containerRef.current) return;
|
|
4019
|
+
const containerWidth = containerRef.current.offsetWidth;
|
|
4020
|
+
const deltaX = dragStartXRef.current - e.clientX;
|
|
4021
|
+
const deltaPercentage = deltaX / containerWidth * 100;
|
|
4022
|
+
const newWidth = Math.min(Math.max(initialWidthRef.current + deltaPercentage, minimumWidth), maximumWidth);
|
|
4023
|
+
setSidebarWidth(newWidth);
|
|
4024
|
+
setCurrentWidth?.(newWidth);
|
|
4025
|
+
};
|
|
4026
|
+
const handleMouseUp = () => {
|
|
4027
|
+
setIsDragging(false);
|
|
4028
|
+
};
|
|
4029
|
+
if (isDragging) {
|
|
4030
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
4031
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
4032
|
+
}
|
|
4033
|
+
return () => {
|
|
4034
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
4035
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
4036
|
+
};
|
|
4037
|
+
}, [isDragging]);
|
|
4038
|
+
return { sidebarWidth, isDragging, handleMouseDown, containerRef };
|
|
4039
|
+
};
|
|
4040
|
+
|
|
4041
|
+
const MastraResizablePanel = ({
|
|
4042
|
+
children,
|
|
4043
|
+
defaultWidth,
|
|
4044
|
+
minimumWidth,
|
|
4045
|
+
maximumWidth,
|
|
4046
|
+
className,
|
|
4047
|
+
disabled = false,
|
|
4048
|
+
setCurrentWidth,
|
|
4049
|
+
dividerPosition = "left"
|
|
4050
|
+
}) => {
|
|
4051
|
+
const { sidebarWidth, isDragging, handleMouseDown, containerRef } = useResizeColumn({
|
|
4052
|
+
defaultWidth: disabled ? 100 : defaultWidth,
|
|
4053
|
+
minimumWidth,
|
|
4054
|
+
maximumWidth,
|
|
4055
|
+
setCurrentWidth
|
|
4056
|
+
});
|
|
4057
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full h-full relative", className), ref: containerRef, style: { width: `${sidebarWidth}%` }, children: [
|
|
4058
|
+
!disabled && dividerPosition === "left" ? /* @__PURE__ */ jsx(
|
|
4059
|
+
"div",
|
|
4060
|
+
{
|
|
4061
|
+
className: `w-1 bg-mastra-bg-1 bg-[#121212] h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 -left-1 -right-1 z-10
|
|
4062
|
+
${isDragging ? "bg-mastra-border-2 bg-[#424242] w-1.5 cursor- col-resize" : ""}`,
|
|
4063
|
+
onMouseDown: handleMouseDown
|
|
4064
|
+
}
|
|
4065
|
+
) : null,
|
|
4066
|
+
children,
|
|
4067
|
+
!disabled && dividerPosition === "right" ? /* @__PURE__ */ jsx(
|
|
4068
|
+
"div",
|
|
4069
|
+
{
|
|
4070
|
+
className: `w-1 bg-mastra-bg-1 bg-[#121212] h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 -left-1 -right-1 z-10
|
|
4071
|
+
${isDragging ? "bg-mastra-border-2 bg-[#424242] w-1.5 cursor- col-resize" : ""}`,
|
|
4072
|
+
onMouseDown: handleMouseDown
|
|
4863
4073
|
}
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
}
|
|
4074
|
+
) : null
|
|
4075
|
+
] });
|
|
4076
|
+
};
|
|
4868
4077
|
|
|
4869
4078
|
const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(ScrollAreaPrimitive.Root, { ref, className: cn("relative overflow-hidden", className), ...props, children: [
|
|
4870
4079
|
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
@@ -5044,11 +4253,18 @@ const allowedAiSpanAttributes = [
|
|
|
5044
4253
|
];
|
|
5045
4254
|
|
|
5046
4255
|
function Traces({ traces }) {
|
|
5047
|
-
const {
|
|
5048
|
-
const
|
|
4256
|
+
const { trace: currentTrace } = useContext(TraceContext);
|
|
4257
|
+
const [prevTracesId, setPrevTracesId] = useState(/* @__PURE__ */ new Set());
|
|
5049
4258
|
useEffect(() => {
|
|
5050
|
-
|
|
4259
|
+
if (!prevTracesId.size && traces) {
|
|
4260
|
+
setPrevTracesId(new Set(traces.map((trace) => trace.traceId)));
|
|
4261
|
+
}
|
|
5051
4262
|
}, [traces]);
|
|
4263
|
+
const isNew = (traceId) => {
|
|
4264
|
+
if (!prevTracesId.size) return false;
|
|
4265
|
+
return !prevTracesId.has(traceId);
|
|
4266
|
+
};
|
|
4267
|
+
const currentTraceParentSpan = currentTrace?.find((span) => span.parentSpanId === void 0) || currentTrace?.[0];
|
|
5052
4268
|
return /* @__PURE__ */ jsx("div", { className: "h-full w-[calc(100%_-_400px)]", children: /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
5053
4269
|
/* @__PURE__ */ jsx(TableHeader, { className: "sticky top-0 z-10 bg-[#0F0F0F]", style: { outline: "1px solid 0_0%_20.4%" }, children: /* @__PURE__ */ jsxs(TableRow, { className: "border-gray-6 border-b-[0.1px] text-[0.8125rem]", children: [
|
|
5054
4270
|
/* @__PURE__ */ jsx(TableHead, { className: "text-mastra-el-3 h-10", children: "Trace" }),
|
|
@@ -5062,9 +4278,13 @@ function Traces({ traces }) {
|
|
|
5062
4278
|
/* @__PURE__ */ jsx(TableBody, { className: "border-b border-gray-6", children: !traces.length ? /* @__PURE__ */ jsx(TableRow, { className: "border-b-gray-6 border-b-[0.1px] text-[0.8125rem]", children: /* @__PURE__ */ jsx(TableCell, { colSpan: 4, className: "h-24 text-center", children: "No traces found" }) }) : traces.map((trace, index) => /* @__PURE__ */ jsxs(
|
|
5063
4279
|
TableRow,
|
|
5064
4280
|
{
|
|
5065
|
-
className: cn(
|
|
5066
|
-
"
|
|
5067
|
-
|
|
4281
|
+
className: cn(
|
|
4282
|
+
"border-b-gray-6 border-b-[0.1px] text-[0.8125rem]",
|
|
4283
|
+
isNew(trace.traceId) ? "animate-fade-in" : "not-new",
|
|
4284
|
+
{
|
|
4285
|
+
"bg-muted/50": currentTraceParentSpan?.traceId === trace.traceId
|
|
4286
|
+
}
|
|
4287
|
+
),
|
|
5068
4288
|
children: [
|
|
5069
4289
|
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
5070
4290
|
TraceButton,
|
|
@@ -5459,7 +4679,8 @@ function usePolling({
|
|
|
5459
4679
|
enabled = false,
|
|
5460
4680
|
onSuccess,
|
|
5461
4681
|
onError,
|
|
5462
|
-
shouldContinue = () => true
|
|
4682
|
+
shouldContinue = () => true,
|
|
4683
|
+
restartPolling = false
|
|
5463
4684
|
}) {
|
|
5464
4685
|
const [isPolling, setIsPolling] = useState(enabled);
|
|
5465
4686
|
const [error, setError] = useState(null);
|
|
@@ -5468,6 +4689,7 @@ function usePolling({
|
|
|
5468
4689
|
const [firstCallLoading, setFirstCallLoading] = useState(false);
|
|
5469
4690
|
const timeoutRef = useRef(null);
|
|
5470
4691
|
const mountedRef = useRef(true);
|
|
4692
|
+
const [restart, setRestart] = useState(restartPolling);
|
|
5471
4693
|
const cleanup = useCallback(() => {
|
|
5472
4694
|
console.log("cleanup");
|
|
5473
4695
|
if (timeoutRef.current) {
|
|
@@ -5486,17 +4708,15 @@ function usePolling({
|
|
|
5486
4708
|
setError(null);
|
|
5487
4709
|
}, []);
|
|
5488
4710
|
const executePoll = useCallback(
|
|
5489
|
-
async (
|
|
4711
|
+
async (refetch2 = true) => {
|
|
5490
4712
|
if (!mountedRef.current) return;
|
|
5491
4713
|
setIsLoading(true);
|
|
5492
|
-
setFirstCallLoading(fistCall);
|
|
5493
4714
|
try {
|
|
5494
4715
|
const result = await fetchFn();
|
|
5495
4716
|
setData(result);
|
|
5496
4717
|
setError(null);
|
|
5497
4718
|
onSuccess?.(result);
|
|
5498
|
-
|
|
5499
|
-
if (shouldContinue(result)) {
|
|
4719
|
+
if (shouldContinue(result) && refetch2) {
|
|
5500
4720
|
timeoutRef.current = setTimeout(executePoll, interval);
|
|
5501
4721
|
} else {
|
|
5502
4722
|
stopPolling();
|
|
@@ -5515,6 +4735,18 @@ function usePolling({
|
|
|
5515
4735
|
},
|
|
5516
4736
|
[fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
|
|
5517
4737
|
);
|
|
4738
|
+
const refetch = useCallback(
|
|
4739
|
+
(withPolling = false) => {
|
|
4740
|
+
console.log("refetch", { withPolling });
|
|
4741
|
+
if (withPolling) {
|
|
4742
|
+
setIsPolling(true);
|
|
4743
|
+
} else {
|
|
4744
|
+
executePoll(false);
|
|
4745
|
+
}
|
|
4746
|
+
setError(null);
|
|
4747
|
+
},
|
|
4748
|
+
[executePoll]
|
|
4749
|
+
);
|
|
5518
4750
|
useEffect(() => {
|
|
5519
4751
|
mountedRef.current = true;
|
|
5520
4752
|
if (enabled && isPolling) {
|
|
@@ -5526,6 +4758,16 @@ function usePolling({
|
|
|
5526
4758
|
cleanup();
|
|
5527
4759
|
};
|
|
5528
4760
|
}, [enabled, isPolling, executePoll, cleanup]);
|
|
4761
|
+
useEffect(() => {
|
|
4762
|
+
setRestart(restartPolling);
|
|
4763
|
+
}, [restartPolling]);
|
|
4764
|
+
useEffect(() => {
|
|
4765
|
+
if (restart && !isPolling) {
|
|
4766
|
+
setIsPolling(true);
|
|
4767
|
+
executePoll();
|
|
4768
|
+
setRestart(false);
|
|
4769
|
+
}
|
|
4770
|
+
}, [restart]);
|
|
5529
4771
|
return {
|
|
5530
4772
|
isPolling,
|
|
5531
4773
|
isLoading,
|
|
@@ -5533,15 +4775,19 @@ function usePolling({
|
|
|
5533
4775
|
data,
|
|
5534
4776
|
startPolling,
|
|
5535
4777
|
stopPolling,
|
|
5536
|
-
firstCallLoading
|
|
4778
|
+
firstCallLoading,
|
|
4779
|
+
refetch
|
|
5537
4780
|
};
|
|
5538
4781
|
}
|
|
5539
4782
|
|
|
5540
4783
|
const useTraces = (componentName, baseUrl, isWorkflow = false) => {
|
|
5541
|
-
const [traces, setTraces] = useState(
|
|
5542
|
-
const client =
|
|
5543
|
-
|
|
5544
|
-
|
|
4784
|
+
const [traces, setTraces] = useState([]);
|
|
4785
|
+
const client = useMemo(
|
|
4786
|
+
() => new MastraClient({
|
|
4787
|
+
baseUrl: baseUrl || ""
|
|
4788
|
+
}),
|
|
4789
|
+
[baseUrl]
|
|
4790
|
+
);
|
|
5545
4791
|
const fetchFn = useCallback(async () => {
|
|
5546
4792
|
try {
|
|
5547
4793
|
const res = await client.getTelemetry({
|
|
@@ -5557,7 +4803,7 @@ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
|
|
|
5557
4803
|
} catch (error2) {
|
|
5558
4804
|
throw error2;
|
|
5559
4805
|
}
|
|
5560
|
-
}, [componentName]);
|
|
4806
|
+
}, [client, componentName, isWorkflow]);
|
|
5561
4807
|
const onSuccess = useCallback((newTraces) => {
|
|
5562
4808
|
if (newTraces.length > 0) {
|
|
5563
4809
|
setTraces(() => newTraces);
|
|
@@ -5566,8 +4812,8 @@ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
|
|
|
5566
4812
|
const onError = useCallback((error2) => {
|
|
5567
4813
|
toast.error(error2.message);
|
|
5568
4814
|
}, []);
|
|
5569
|
-
const shouldContinue = useCallback(() => {
|
|
5570
|
-
return
|
|
4815
|
+
const shouldContinue = useCallback((result) => {
|
|
4816
|
+
return result.length > 0;
|
|
5571
4817
|
}, []);
|
|
5572
4818
|
const { firstCallLoading, error } = usePolling({
|
|
5573
4819
|
fetchFn,
|
|
@@ -5580,89 +4826,6 @@ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
|
|
|
5580
4826
|
return { traces, firstCallLoading, error };
|
|
5581
4827
|
};
|
|
5582
4828
|
|
|
5583
|
-
const useResizeColumn = ({
|
|
5584
|
-
defaultWidth,
|
|
5585
|
-
minimumWidth,
|
|
5586
|
-
maximumWidth,
|
|
5587
|
-
setCurrentWidth
|
|
5588
|
-
}) => {
|
|
5589
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
5590
|
-
const [sidebarWidth, setSidebarWidth] = useState(defaultWidth);
|
|
5591
|
-
const containerRef = useRef(null);
|
|
5592
|
-
const dragStartXRef = useRef(0);
|
|
5593
|
-
const initialWidthRef = useRef(0);
|
|
5594
|
-
const handleMouseDown = (e) => {
|
|
5595
|
-
e.preventDefault();
|
|
5596
|
-
setIsDragging(true);
|
|
5597
|
-
dragStartXRef.current = e.clientX;
|
|
5598
|
-
initialWidthRef.current = sidebarWidth;
|
|
5599
|
-
};
|
|
5600
|
-
useEffect(() => {
|
|
5601
|
-
setSidebarWidth(defaultWidth);
|
|
5602
|
-
setCurrentWidth?.(defaultWidth);
|
|
5603
|
-
}, [defaultWidth]);
|
|
5604
|
-
useEffect(() => {
|
|
5605
|
-
const handleMouseMove = (e) => {
|
|
5606
|
-
if (!isDragging || !containerRef.current) return;
|
|
5607
|
-
const containerWidth = containerRef.current.offsetWidth;
|
|
5608
|
-
const deltaX = dragStartXRef.current - e.clientX;
|
|
5609
|
-
const deltaPercentage = deltaX / containerWidth * 100;
|
|
5610
|
-
const newWidth = Math.min(Math.max(initialWidthRef.current + deltaPercentage, minimumWidth), maximumWidth);
|
|
5611
|
-
setSidebarWidth(newWidth);
|
|
5612
|
-
setCurrentWidth?.(newWidth);
|
|
5613
|
-
};
|
|
5614
|
-
const handleMouseUp = () => {
|
|
5615
|
-
setIsDragging(false);
|
|
5616
|
-
};
|
|
5617
|
-
if (isDragging) {
|
|
5618
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
5619
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
5620
|
-
}
|
|
5621
|
-
return () => {
|
|
5622
|
-
window.removeEventListener("mousemove", handleMouseMove);
|
|
5623
|
-
window.removeEventListener("mouseup", handleMouseUp);
|
|
5624
|
-
};
|
|
5625
|
-
}, [isDragging]);
|
|
5626
|
-
return { sidebarWidth, isDragging, handleMouseDown, containerRef };
|
|
5627
|
-
};
|
|
5628
|
-
|
|
5629
|
-
const MastraResizablePanel = ({
|
|
5630
|
-
children,
|
|
5631
|
-
defaultWidth,
|
|
5632
|
-
minimumWidth,
|
|
5633
|
-
maximumWidth,
|
|
5634
|
-
className,
|
|
5635
|
-
disabled = false,
|
|
5636
|
-
setCurrentWidth,
|
|
5637
|
-
dividerPosition = "left"
|
|
5638
|
-
}) => {
|
|
5639
|
-
const { sidebarWidth, isDragging, handleMouseDown, containerRef } = useResizeColumn({
|
|
5640
|
-
defaultWidth: disabled ? 100 : defaultWidth,
|
|
5641
|
-
minimumWidth,
|
|
5642
|
-
maximumWidth,
|
|
5643
|
-
setCurrentWidth
|
|
5644
|
-
});
|
|
5645
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("w-full h-full relative", className), ref: containerRef, style: { width: `${sidebarWidth}%` }, children: [
|
|
5646
|
-
!disabled && dividerPosition === "left" ? /* @__PURE__ */ jsx(
|
|
5647
|
-
"div",
|
|
5648
|
-
{
|
|
5649
|
-
className: `w-1 bg-mastra-bg-1 bg-[#121212] h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 -left-1 -right-1 z-10
|
|
5650
|
-
${isDragging ? "bg-mastra-border-2 bg-[#424242] w-1.5 cursor- col-resize" : ""}`,
|
|
5651
|
-
onMouseDown: handleMouseDown
|
|
5652
|
-
}
|
|
5653
|
-
) : null,
|
|
5654
|
-
children,
|
|
5655
|
-
!disabled && dividerPosition === "right" ? /* @__PURE__ */ jsx(
|
|
5656
|
-
"div",
|
|
5657
|
-
{
|
|
5658
|
-
className: `w-1 bg-mastra-bg-1 bg-[#121212] h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 -left-1 -right-1 z-10
|
|
5659
|
-
${isDragging ? "bg-mastra-border-2 bg-[#424242] w-1.5 cursor- col-resize" : ""}`,
|
|
5660
|
-
onMouseDown: handleMouseDown
|
|
5661
|
-
}
|
|
5662
|
-
) : null
|
|
5663
|
-
] });
|
|
5664
|
-
};
|
|
5665
|
-
|
|
5666
4829
|
function AgentTraces({
|
|
5667
4830
|
agentName,
|
|
5668
4831
|
baseUrl,
|
|
@@ -5813,7 +4976,8 @@ const DataTable = ({
|
|
|
5813
4976
|
emptyStateHeight,
|
|
5814
4977
|
getRowId,
|
|
5815
4978
|
selectedRowId,
|
|
5816
|
-
isLoading
|
|
4979
|
+
isLoading,
|
|
4980
|
+
emptyText
|
|
5817
4981
|
}) => {
|
|
5818
4982
|
const [sorting, setSorting] = useState([]);
|
|
5819
4983
|
const [{ pageIndex, pageSize }, setPagination] = useState({
|
|
@@ -5888,7 +5052,10 @@ const DataTable = ({
|
|
|
5888
5052
|
},
|
|
5889
5053
|
cell.id
|
|
5890
5054
|
))
|
|
5891
|
-
] }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */
|
|
5055
|
+
] }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsxs(TableCell, { colSpan: columns.length, className: cn("h-24 text-center", emptyStateHeight), children: [
|
|
5056
|
+
"No ",
|
|
5057
|
+
emptyText || "results"
|
|
5058
|
+
] }) }) })
|
|
5892
5059
|
] }) }),
|
|
5893
5060
|
pagination && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center justify-between px-2", children: [
|
|
5894
5061
|
/* @__PURE__ */ jsxs("div", { className: "text-muted-foreground text-sm", children: [
|
|
@@ -5918,6 +5085,7 @@ const AgentsTable = ({
|
|
|
5918
5085
|
return /* @__PURE__ */ jsx(
|
|
5919
5086
|
DataTable,
|
|
5920
5087
|
{
|
|
5088
|
+
emptyText: "Agents",
|
|
5921
5089
|
title,
|
|
5922
5090
|
isLoading,
|
|
5923
5091
|
withoutBorder: true,
|
|
@@ -5925,7 +5093,7 @@ const AgentsTable = ({
|
|
|
5925
5093
|
icon: /* @__PURE__ */ jsx(AgentIcon, { className: "h-4 w-4" }),
|
|
5926
5094
|
columns,
|
|
5927
5095
|
data: agentsList,
|
|
5928
|
-
className: "border-t-0
|
|
5096
|
+
className: "!border-t-0 border-[0.5px] border-x-0"
|
|
5929
5097
|
}
|
|
5930
5098
|
);
|
|
5931
5099
|
};
|
|
@@ -6082,16 +5250,26 @@ const useExecuteWorkflow = (baseUrl) => {
|
|
|
6082
5250
|
setIsExecutingWorkflow(false);
|
|
6083
5251
|
}
|
|
6084
5252
|
};
|
|
6085
|
-
const createWorkflowRun = async ({ workflowId,
|
|
5253
|
+
const createWorkflowRun = async ({ workflowId, prevRunId }) => {
|
|
6086
5254
|
try {
|
|
6087
|
-
const
|
|
6088
|
-
|
|
5255
|
+
const workflow = client.getWorkflow(workflowId);
|
|
5256
|
+
const { runId: newRunId } = await workflow.createRun({ runId: prevRunId });
|
|
5257
|
+
return { runId: newRunId };
|
|
6089
5258
|
} catch (error) {
|
|
6090
5259
|
console.error("Error creating workflow run:", error);
|
|
6091
5260
|
throw error;
|
|
6092
5261
|
}
|
|
6093
5262
|
};
|
|
6094
|
-
|
|
5263
|
+
const startWorkflowRun = async ({ workflowId, runId, input }) => {
|
|
5264
|
+
try {
|
|
5265
|
+
const workflow = client.getWorkflow(workflowId);
|
|
5266
|
+
await workflow.start({ runId, triggerData: input || {} });
|
|
5267
|
+
} catch (error) {
|
|
5268
|
+
console.error("Error starting workflow run:", error);
|
|
5269
|
+
throw error;
|
|
5270
|
+
}
|
|
5271
|
+
};
|
|
5272
|
+
return { executeWorkflow, startWorkflowRun, createWorkflowRun, isExecutingWorkflow };
|
|
6095
5273
|
};
|
|
6096
5274
|
const useWatchWorkflow = (baseUrl) => {
|
|
6097
5275
|
const [isWatchingWorkflow, setIsWatchingWorkflow] = useState(false);
|
|
@@ -6102,13 +5280,10 @@ const useWatchWorkflow = (baseUrl) => {
|
|
|
6102
5280
|
const client = new MastraClient({
|
|
6103
5281
|
baseUrl
|
|
6104
5282
|
});
|
|
6105
|
-
const
|
|
6106
|
-
|
|
6107
|
-
throw new Error("Error watching workflow");
|
|
6108
|
-
}
|
|
6109
|
-
for await (const record of watchSubscription) {
|
|
5283
|
+
const workflow = client.getWorkflow(workflowId);
|
|
5284
|
+
workflow.watch({ runId }, (record) => {
|
|
6110
5285
|
setWatchResult(record);
|
|
6111
|
-
}
|
|
5286
|
+
});
|
|
6112
5287
|
} catch (error) {
|
|
6113
5288
|
console.error("Error watching workflow:", error);
|
|
6114
5289
|
throw error;
|
|
@@ -6181,6 +5356,9 @@ function extractConditions(group, type) {
|
|
|
6181
5356
|
recurse({ ...subGroup }, "or");
|
|
6182
5357
|
}
|
|
6183
5358
|
}
|
|
5359
|
+
if ("not" in group2) {
|
|
5360
|
+
recurse({ ...group2.not }, "not");
|
|
5361
|
+
}
|
|
6184
5362
|
}
|
|
6185
5363
|
}
|
|
6186
5364
|
recurse(group);
|
|
@@ -6230,19 +5408,21 @@ const contructNodesAndEdges = ({
|
|
|
6230
5408
|
}
|
|
6231
5409
|
let nodes = [];
|
|
6232
5410
|
let edges = [];
|
|
5411
|
+
let allSteps = [];
|
|
6233
5412
|
for (const [_index, _step] of initial.entries()) {
|
|
6234
5413
|
const step = _step.step;
|
|
6235
5414
|
const stepId = step.id;
|
|
6236
5415
|
const steps = [_step, ...stepsList?.[stepId] || []]?.reduce((acc, step2, i) => {
|
|
6237
|
-
|
|
5416
|
+
let newStep = {
|
|
6238
5417
|
...step2.step,
|
|
6239
5418
|
label: step2.step.id,
|
|
5419
|
+
originalId: step2.step.id,
|
|
6240
5420
|
type: "default-node",
|
|
6241
5421
|
id: nodes.some((node) => node.id === step2.step.id) ? `${step2.step.id}-${i}` : step2.step.id
|
|
6242
5422
|
};
|
|
6243
5423
|
let conditionType = "when";
|
|
6244
5424
|
if (step2.config?.serializedWhen) {
|
|
6245
|
-
conditionType = step2.step.id
|
|
5425
|
+
conditionType = step2.step.id?.endsWith("_if") ? "if" : step2.step.id?.endsWith("_else") ? "else" : "when";
|
|
6246
5426
|
const conditions = extractConditions(step2.config.serializedWhen, conditionType);
|
|
6247
5427
|
const conditionStep = {
|
|
6248
5428
|
id: crypto.randomUUID(),
|
|
@@ -6252,11 +5432,20 @@ const contructNodesAndEdges = ({
|
|
|
6252
5432
|
};
|
|
6253
5433
|
acc.push(conditionStep);
|
|
6254
5434
|
}
|
|
6255
|
-
if (conditionType === "
|
|
6256
|
-
|
|
5435
|
+
if (conditionType === "if" || conditionType === "else") {
|
|
5436
|
+
newStep = {
|
|
5437
|
+
...newStep,
|
|
5438
|
+
label: conditionType === "if" ? "start if" : "start else"
|
|
5439
|
+
};
|
|
6257
5440
|
}
|
|
5441
|
+
newStep = {
|
|
5442
|
+
...newStep,
|
|
5443
|
+
label: step2.config?.loopLabel || newStep.label
|
|
5444
|
+
};
|
|
5445
|
+
acc.push(newStep);
|
|
6258
5446
|
return acc;
|
|
6259
5447
|
}, []);
|
|
5448
|
+
allSteps = [...allSteps, ...steps];
|
|
6260
5449
|
const newNodes = [...steps].map((step2, index) => {
|
|
6261
5450
|
const subscriberGraph = stepSubscriberGraph?.[step2.id];
|
|
6262
5451
|
return {
|
|
@@ -6289,21 +5478,26 @@ const contructNodesAndEdges = ({
|
|
|
6289
5478
|
}
|
|
6290
5479
|
for (const [connectingStepId, stepInfoGraph] of Object.entries(stepSubscriberGraph)) {
|
|
6291
5480
|
const { initial: initial2, ...stepsList2 } = stepInfoGraph;
|
|
5481
|
+
let untilOrWhileConditionId;
|
|
5482
|
+
const loopResultSteps = [];
|
|
5483
|
+
let finishedLoopStep;
|
|
5484
|
+
let otherLoopStep;
|
|
6292
5485
|
if (initial2.length) {
|
|
6293
5486
|
for (const [_index, _step] of initial2.entries()) {
|
|
6294
5487
|
const step = _step.step;
|
|
6295
5488
|
const stepId = step.id;
|
|
6296
|
-
const originalSteps = [_step, ...stepsList2?.[stepId] || []]?.map((step2) => step2.step);
|
|
6297
5489
|
const steps = [_step, ...stepsList2?.[stepId] || []]?.reduce((acc, step2, i) => {
|
|
6298
|
-
|
|
5490
|
+
let newStep = {
|
|
6299
5491
|
...step2.step,
|
|
5492
|
+
originalId: step2.step.id,
|
|
6300
5493
|
label: step2.step.id,
|
|
6301
5494
|
type: "default-node",
|
|
6302
5495
|
id: nodes.some((node) => node.id === step2.step.id) ? `${step2.step.id}-${i}` : step2.step.id
|
|
6303
5496
|
};
|
|
6304
5497
|
let conditionType = "when";
|
|
6305
|
-
|
|
6306
|
-
|
|
5498
|
+
const isFinishedLoop = step2.config?.loopLabel?.endsWith("loop finished");
|
|
5499
|
+
if (step2.config?.serializedWhen && !isFinishedLoop) {
|
|
5500
|
+
conditionType = step2.step.id?.endsWith("_if") ? "if" : step2.step.id?.endsWith("_else") ? "else" : step2.config?.loopType ?? "when";
|
|
6307
5501
|
const conditions = extractConditions(step2.config.serializedWhen, conditionType);
|
|
6308
5502
|
const conditionStep = {
|
|
6309
5503
|
id: crypto.randomUUID(),
|
|
@@ -6311,15 +5505,67 @@ const contructNodesAndEdges = ({
|
|
|
6311
5505
|
type: "condition-node",
|
|
6312
5506
|
isLarge: (conditions?.length > 1 || conditions.some(({ fnString }) => !!fnString)) && conditionType !== "else"
|
|
6313
5507
|
};
|
|
5508
|
+
if (conditionType === "until" || conditionType === "while") {
|
|
5509
|
+
untilOrWhileConditionId = conditionStep.id;
|
|
5510
|
+
}
|
|
6314
5511
|
acc.push(conditionStep);
|
|
6315
5512
|
}
|
|
6316
|
-
if (
|
|
6317
|
-
|
|
5513
|
+
if (isFinishedLoop) {
|
|
5514
|
+
const loopResultStep = {
|
|
5515
|
+
id: crypto.randomUUID(),
|
|
5516
|
+
type: "loop-result-node",
|
|
5517
|
+
loopType: "finished",
|
|
5518
|
+
loopResult: step2.config.loopType === "until" ? true : false
|
|
5519
|
+
};
|
|
5520
|
+
loopResultSteps.push(loopResultStep);
|
|
5521
|
+
acc.push(loopResultStep);
|
|
5522
|
+
}
|
|
5523
|
+
if (!isFinishedLoop && step2.config?.loopType) {
|
|
5524
|
+
const loopResultStep = {
|
|
5525
|
+
id: crypto.randomUUID(),
|
|
5526
|
+
type: "loop-result-node",
|
|
5527
|
+
loopType: step2.config.loopType,
|
|
5528
|
+
loopResult: step2.config.loopType === "until" ? false : true
|
|
5529
|
+
};
|
|
5530
|
+
loopResultSteps.push(loopResultStep);
|
|
5531
|
+
acc.push(loopResultStep);
|
|
5532
|
+
}
|
|
5533
|
+
if (conditionType === "if" || conditionType === "else") {
|
|
5534
|
+
newStep = {
|
|
5535
|
+
...newStep,
|
|
5536
|
+
label: conditionType === "if" ? "start if" : "start else"
|
|
5537
|
+
};
|
|
6318
5538
|
}
|
|
5539
|
+
if (step2.config.loopType) {
|
|
5540
|
+
if (isFinishedLoop) {
|
|
5541
|
+
finishedLoopStep = newStep;
|
|
5542
|
+
} else {
|
|
5543
|
+
otherLoopStep = newStep;
|
|
5544
|
+
}
|
|
5545
|
+
}
|
|
5546
|
+
newStep = {
|
|
5547
|
+
...newStep,
|
|
5548
|
+
loopType: isFinishedLoop ? "finished" : step2.config.loopType,
|
|
5549
|
+
label: step2.config?.loopLabel || newStep.label
|
|
5550
|
+
};
|
|
5551
|
+
acc.push(newStep);
|
|
6319
5552
|
return acc;
|
|
6320
5553
|
}, []);
|
|
6321
|
-
|
|
5554
|
+
let afterStep = [];
|
|
5555
|
+
let afterStepStepList = connectingStepId?.includes("&&") ? connectingStepId.split("&&") : [];
|
|
5556
|
+
if (connectingStepId?.includes("&&")) {
|
|
5557
|
+
afterStep = [
|
|
5558
|
+
{
|
|
5559
|
+
id: connectingStepId,
|
|
5560
|
+
label: connectingStepId,
|
|
5561
|
+
type: "after-node",
|
|
5562
|
+
steps: afterStepStepList
|
|
5563
|
+
}
|
|
5564
|
+
];
|
|
5565
|
+
}
|
|
5566
|
+
const newNodes = [...steps, ...afterStep].map((step2, index) => {
|
|
6322
5567
|
const subscriberGraph = stepSubscriberGraph?.[step2.id];
|
|
5568
|
+
const withBottomHandle = step2.originalId === connectingStepId || subscriberGraph;
|
|
6323
5569
|
return {
|
|
6324
5570
|
id: step2.id,
|
|
6325
5571
|
position: { x: _index * 300 + 300, y: index * 100 + 100 },
|
|
@@ -6328,19 +5574,37 @@ const contructNodesAndEdges = ({
|
|
|
6328
5574
|
conditions: step2.conditions,
|
|
6329
5575
|
label: step2.label,
|
|
6330
5576
|
description: step2.description,
|
|
6331
|
-
|
|
5577
|
+
result: step2.loopResult,
|
|
5578
|
+
loopType: step2.loopType,
|
|
5579
|
+
steps: step2.steps,
|
|
5580
|
+
withoutBottomHandle: withBottomHandle ? false : index === steps.length - 1,
|
|
6332
5581
|
isLarge: step2.isLarge
|
|
6333
5582
|
}
|
|
6334
5583
|
};
|
|
6335
5584
|
});
|
|
6336
|
-
nodes = [...nodes, ...newNodes]
|
|
5585
|
+
nodes = [...nodes, ...newNodes].map((node) => ({
|
|
5586
|
+
...node,
|
|
5587
|
+
data: {
|
|
5588
|
+
...node.data,
|
|
5589
|
+
withoutBottomHandle: afterStepStepList.includes(node.id) ? false : node.data.withoutBottomHandle
|
|
5590
|
+
}
|
|
5591
|
+
}));
|
|
6337
5592
|
const edgeSteps = [...steps].slice(0, -1);
|
|
5593
|
+
const afterEdges = afterStepStepList.map((step2) => ({
|
|
5594
|
+
id: `e${step2}-${connectingStepId}`,
|
|
5595
|
+
source: step2,
|
|
5596
|
+
target: connectingStepId,
|
|
5597
|
+
...defaultEdgeOptions
|
|
5598
|
+
}));
|
|
5599
|
+
const finishedLoopResult = loopResultSteps?.find((step2) => step2.loopType === "finished");
|
|
6338
5600
|
const newEdges = edgeSteps.map((step2, index) => ({
|
|
6339
5601
|
id: `e${step2.id}-${steps[index + 1].id}`,
|
|
6340
5602
|
source: step2.id,
|
|
6341
5603
|
target: steps[index + 1].id,
|
|
5604
|
+
remove: finishedLoopResult?.id === steps[index + 1].id,
|
|
5605
|
+
//remove if target is a finished loop result
|
|
6342
5606
|
...defaultEdgeOptions
|
|
6343
|
-
}));
|
|
5607
|
+
}))?.filter((edge) => !edge.remove);
|
|
6344
5608
|
const firstEdgeStep = steps[0];
|
|
6345
5609
|
const lastEdgeStep = steps[steps.length - 1];
|
|
6346
5610
|
const connectingEdge = connectingStepId === firstEdgeStep.id ? [] : [
|
|
@@ -6348,10 +5612,11 @@ const contructNodesAndEdges = ({
|
|
|
6348
5612
|
id: `e${connectingStepId}-${firstEdgeStep.id}`,
|
|
6349
5613
|
source: connectingStepId,
|
|
6350
5614
|
target: firstEdgeStep.id,
|
|
5615
|
+
remove: finishedLoopResult?.id === firstEdgeStep.id,
|
|
6351
5616
|
...defaultEdgeOptions
|
|
6352
5617
|
}
|
|
6353
|
-
];
|
|
6354
|
-
const lastEdge =
|
|
5618
|
+
]?.filter((edge) => !edge.remove);
|
|
5619
|
+
const lastEdge = lastEdgeStep.originalId === connectingStepId ? [
|
|
6355
5620
|
{
|
|
6356
5621
|
id: `e${lastEdgeStep.id}-${connectingStepId}`,
|
|
6357
5622
|
source: lastEdgeStep.id,
|
|
@@ -6359,7 +5624,31 @@ const contructNodesAndEdges = ({
|
|
|
6359
5624
|
...defaultEdgeOptions
|
|
6360
5625
|
}
|
|
6361
5626
|
] : [];
|
|
6362
|
-
edges = [...edges, ...connectingEdge, ...newEdges, ...lastEdge];
|
|
5627
|
+
edges = [...edges, ...afterEdges, ...connectingEdge, ...newEdges, ...lastEdge];
|
|
5628
|
+
allSteps = [...allSteps, ...steps];
|
|
5629
|
+
}
|
|
5630
|
+
if (untilOrWhileConditionId && loopResultSteps.length && finishedLoopStep && otherLoopStep) {
|
|
5631
|
+
const loopResultStepsEdges = loopResultSteps.map((step) => ({
|
|
5632
|
+
id: `e${untilOrWhileConditionId}-${step.id}`,
|
|
5633
|
+
source: untilOrWhileConditionId,
|
|
5634
|
+
target: step.id,
|
|
5635
|
+
...defaultEdgeOptions
|
|
5636
|
+
}));
|
|
5637
|
+
const finishedLoopResult = loopResultSteps?.find((res) => res.loopType === "finished");
|
|
5638
|
+
const otherLoopResult = loopResultSteps?.find((res) => res.loopType !== "finished");
|
|
5639
|
+
const otherLoopEdge = {
|
|
5640
|
+
id: `e${otherLoopResult?.id}-${otherLoopStep?.id}`,
|
|
5641
|
+
source: otherLoopResult?.id,
|
|
5642
|
+
target: otherLoopStep.id,
|
|
5643
|
+
...defaultEdgeOptions
|
|
5644
|
+
};
|
|
5645
|
+
const finishedLoopEdge = {
|
|
5646
|
+
id: `e${finishedLoopResult?.id}-${finishedLoopStep?.id}`,
|
|
5647
|
+
source: finishedLoopResult?.id,
|
|
5648
|
+
target: finishedLoopStep.id,
|
|
5649
|
+
...defaultEdgeOptions
|
|
5650
|
+
};
|
|
5651
|
+
edges = [...edges, ...loopResultStepsEdges, otherLoopEdge, finishedLoopEdge];
|
|
6363
5652
|
}
|
|
6364
5653
|
}
|
|
6365
5654
|
}
|
|
@@ -6427,7 +5716,7 @@ function WorkflowConditionNode({ data }) {
|
|
|
6427
5716
|
size: "xs",
|
|
6428
5717
|
weight: "medium",
|
|
6429
5718
|
className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
|
|
6430
|
-
children: type
|
|
5719
|
+
children: type?.toUpperCase()
|
|
6431
5720
|
}
|
|
6432
5721
|
),
|
|
6433
5722
|
isCollapsible && /* @__PURE__ */ jsx(
|
|
@@ -6488,14 +5777,72 @@ function WorkflowDefaultNode({ data }) {
|
|
|
6488
5777
|
] });
|
|
6489
5778
|
}
|
|
6490
5779
|
|
|
5780
|
+
function WorkflowAfterNode({ data }) {
|
|
5781
|
+
const { steps } = data;
|
|
5782
|
+
const [open, setOpen] = useState(true);
|
|
5783
|
+
return /* @__PURE__ */ jsxs(
|
|
5784
|
+
Collapsible,
|
|
5785
|
+
{
|
|
5786
|
+
open,
|
|
5787
|
+
onOpenChange: setOpen,
|
|
5788
|
+
className: cn("bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2"),
|
|
5789
|
+
children: [
|
|
5790
|
+
/* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
|
|
5791
|
+
/* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
|
|
5792
|
+
/* @__PURE__ */ jsx(
|
|
5793
|
+
Text,
|
|
5794
|
+
{
|
|
5795
|
+
size: "xs",
|
|
5796
|
+
weight: "medium",
|
|
5797
|
+
className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
|
|
5798
|
+
children: "AFTER"
|
|
5799
|
+
}
|
|
5800
|
+
),
|
|
5801
|
+
/* @__PURE__ */ jsx(
|
|
5802
|
+
ChevronDown,
|
|
5803
|
+
{
|
|
5804
|
+
className: cn("w-4 h-4 transition-transform", {
|
|
5805
|
+
"transform rotate-180": open
|
|
5806
|
+
})
|
|
5807
|
+
}
|
|
5808
|
+
)
|
|
5809
|
+
] }),
|
|
5810
|
+
/* @__PURE__ */ jsx(CollapsibleContent, { className: "flex flex-col gap-2", children: steps.map((step) => /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-[6px] rounded-sm p-2", children: [
|
|
5811
|
+
/* @__PURE__ */ jsx(Footprints, { className: "text-current w-4 h-4" }),
|
|
5812
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: step })
|
|
5813
|
+
] }, step)) }),
|
|
5814
|
+
/* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
|
|
5815
|
+
]
|
|
5816
|
+
}
|
|
5817
|
+
);
|
|
5818
|
+
}
|
|
5819
|
+
|
|
5820
|
+
function WorkflowLoopResultNode({ data }) {
|
|
5821
|
+
const { result } = data;
|
|
5822
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("bg-mastra-bg-8 rounded-md w-[274px]"), children: [
|
|
5823
|
+
/* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
|
|
5824
|
+
/* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-[6px] rounded-sm p-2", children: [
|
|
5825
|
+
result ? /* @__PURE__ */ jsx(CircleCheck, { className: "text-current w-4 h-4" }) : /* @__PURE__ */ jsx(CircleX, { className: "text-current w-4 h-4" }),
|
|
5826
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: String(result) })
|
|
5827
|
+
] }) }),
|
|
5828
|
+
/* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
|
|
5829
|
+
] });
|
|
5830
|
+
}
|
|
5831
|
+
|
|
6491
5832
|
function WorkflowGraphInner({ workflow }) {
|
|
6492
|
-
const { nodes: initialNodes, edges: initialEdges } = contructNodesAndEdges(
|
|
5833
|
+
const { nodes: initialNodes, edges: initialEdges } = contructNodesAndEdges({
|
|
5834
|
+
stepGraph: workflow.serializedStepGraph,
|
|
5835
|
+
stepSubscriberGraph: workflow.serializedStepSubscriberGraph
|
|
5836
|
+
});
|
|
6493
5837
|
const [nodes, _, onNodesChange] = useNodesState(initialNodes);
|
|
6494
5838
|
const [edges] = useEdgesState(initialEdges);
|
|
6495
5839
|
const nodeTypes = {
|
|
6496
5840
|
"default-node": WorkflowDefaultNode,
|
|
6497
|
-
"condition-node": WorkflowConditionNode
|
|
5841
|
+
"condition-node": WorkflowConditionNode,
|
|
5842
|
+
"after-node": WorkflowAfterNode,
|
|
5843
|
+
"loop-result-node": WorkflowLoopResultNode
|
|
6498
5844
|
};
|
|
5845
|
+
console.log("nodes===>", nodes);
|
|
6499
5846
|
return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxs(
|
|
6500
5847
|
ReactFlow,
|
|
6501
5848
|
{
|
|
@@ -6574,6 +5921,7 @@ const WorkflowsTable = ({
|
|
|
6574
5921
|
return /* @__PURE__ */ jsx(
|
|
6575
5922
|
DataTable,
|
|
6576
5923
|
{
|
|
5924
|
+
emptyText: "Workflows",
|
|
6577
5925
|
title,
|
|
6578
5926
|
withoutBorder: true,
|
|
6579
5927
|
withoutRadius: true,
|
|
@@ -7836,15 +7184,15 @@ function CodeBlockDemo({
|
|
|
7836
7184
|
filename,
|
|
7837
7185
|
className
|
|
7838
7186
|
}) {
|
|
7839
|
-
return /* @__PURE__ */ jsxs(CodeBlock
|
|
7187
|
+
return /* @__PURE__ */ jsxs(CodeBlock, { code, language, theme: themes.oneDark, children: [
|
|
7840
7188
|
filename ? /* @__PURE__ */ jsx("div", { className: "absolute w-full px-6 py-2 pl-4 text-sm rounded bg-mastra-bg-2 text-mastra-el-6/50", children: filename }) : null,
|
|
7841
7189
|
/* @__PURE__ */ jsx(
|
|
7842
|
-
CodeBlock
|
|
7190
|
+
CodeBlock.Code,
|
|
7843
7191
|
{
|
|
7844
7192
|
className: cn("bg-transparent h-full p-6 rounded-xl whitespace-pre-wrap", filename ? "pt-10" : "", className),
|
|
7845
7193
|
children: /* @__PURE__ */ jsx("div", { className: "table-row", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
7846
|
-
/* @__PURE__ */ jsx(CodeBlock
|
|
7847
|
-
/* @__PURE__ */ jsx(CodeBlock
|
|
7194
|
+
/* @__PURE__ */ jsx(CodeBlock.LineNumber, { className: "table-cell pr-4 text-sm text-right select-none text-gray-500/50" }),
|
|
7195
|
+
/* @__PURE__ */ jsx(CodeBlock.LineContent, { className: "flex", children: /* @__PURE__ */ jsx(CodeBlock.Token, { className: "font-mono text-sm mastra-token" }) })
|
|
7848
7196
|
] }) })
|
|
7849
7197
|
}
|
|
7850
7198
|
)
|
|
@@ -7923,7 +7271,7 @@ function WorkflowTrigger({
|
|
|
7923
7271
|
}) {
|
|
7924
7272
|
const { result, setResult, payload, setPayload } = useContext(WorkflowRunContext);
|
|
7925
7273
|
const { isLoading, workflow } = useWorkflow(workflowId, baseUrl);
|
|
7926
|
-
const { createWorkflowRun } = useExecuteWorkflow(baseUrl);
|
|
7274
|
+
const { createWorkflowRun, startWorkflowRun } = useExecuteWorkflow(baseUrl);
|
|
7927
7275
|
const { watchWorkflow, watchResult, isWatchingWorkflow } = useWatchWorkflow(baseUrl);
|
|
7928
7276
|
const { resumeWorkflow, isResumingWorkflow } = useResumeWorkflow(baseUrl);
|
|
7929
7277
|
const [suspendedSteps, setSuspendedSteps] = useState([]);
|
|
@@ -7934,9 +7282,10 @@ function WorkflowTrigger({
|
|
|
7934
7282
|
if (!workflow) return;
|
|
7935
7283
|
setIsRunning(true);
|
|
7936
7284
|
setResult(null);
|
|
7937
|
-
const { runId } = await createWorkflowRun({ workflowId
|
|
7285
|
+
const { runId } = await createWorkflowRun({ workflowId });
|
|
7938
7286
|
setRunId?.(runId);
|
|
7939
7287
|
watchWorkflow({ workflowId, runId });
|
|
7288
|
+
startWorkflowRun({ workflowId, runId, input: data });
|
|
7940
7289
|
} catch (err) {
|
|
7941
7290
|
setIsRunning(false);
|
|
7942
7291
|
toast.error("Error executing workflow");
|
|
@@ -7944,14 +7293,15 @@ function WorkflowTrigger({
|
|
|
7944
7293
|
};
|
|
7945
7294
|
const handleResumeWorkflow = async (step) => {
|
|
7946
7295
|
if (!workflow) return;
|
|
7947
|
-
const { stepId, runId, context } = step;
|
|
7948
|
-
|
|
7296
|
+
const { stepId, runId: prevRunId, context } = step;
|
|
7297
|
+
const { runId } = await createWorkflowRun({ workflowId, prevRunId });
|
|
7298
|
+
watchWorkflow({ workflowId, runId });
|
|
7299
|
+
await resumeWorkflow({
|
|
7949
7300
|
stepId,
|
|
7950
7301
|
runId,
|
|
7951
7302
|
context,
|
|
7952
7303
|
workflowId
|
|
7953
7304
|
});
|
|
7954
|
-
watchWorkflow({ workflowId, runId });
|
|
7955
7305
|
};
|
|
7956
7306
|
const watchResultToUse = result ?? watchResult;
|
|
7957
7307
|
const workflowActivePaths = watchResultToUse?.activePaths ?? [];
|
|
@@ -7962,7 +7312,8 @@ function WorkflowTrigger({
|
|
|
7962
7312
|
if (!watchResultToUse?.activePaths || !result?.runId) return;
|
|
7963
7313
|
const suspended = watchResultToUse.activePaths.filter((path) => watchResultToUse.context?.steps?.[path.stepId]?.status === "suspended").map((path) => ({
|
|
7964
7314
|
stepId: path.stepId,
|
|
7965
|
-
runId: result.runId
|
|
7315
|
+
runId: result.runId,
|
|
7316
|
+
suspendPayload: watchResultToUse.context?.steps?.[path.stepId]?.suspendPayload
|
|
7966
7317
|
}));
|
|
7967
7318
|
setSuspendedSteps(suspended);
|
|
7968
7319
|
}, [watchResultToUse, result]);
|
|
@@ -7980,13 +7331,13 @@ function WorkflowTrigger({
|
|
|
7980
7331
|
if (!workflow) return null;
|
|
7981
7332
|
if (!triggerSchema) {
|
|
7982
7333
|
return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs w-full", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
7983
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-4
|
|
7334
|
+
/* @__PURE__ */ jsx("div", { className: "px-4 space-y-4", children: /* @__PURE__ */ jsx(Button, { className: "w-full", disabled: isRunning, onClick: () => handleExecuteWorkflow(null), children: isRunning ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin" }) : "Trigger" }) }),
|
|
7984
7335
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
7985
|
-
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3
|
|
7336
|
+
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Output" }),
|
|
7986
7337
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsx(
|
|
7987
7338
|
CopyButton,
|
|
7988
7339
|
{
|
|
7989
|
-
classname: "absolute z-40
|
|
7340
|
+
classname: "absolute z-40 w-8 h-8 p-0 transition-opacity duration-150 ease-in-out opacity-0 top-4 right-4 group-hover:opacity-100",
|
|
7990
7341
|
content: JSON.stringify(result ?? {}, null, 2)
|
|
7991
7342
|
}
|
|
7992
7343
|
) }),
|
|
@@ -8002,30 +7353,13 @@ function WorkflowTrigger({
|
|
|
8002
7353
|
] }) });
|
|
8003
7354
|
}
|
|
8004
7355
|
const zodInputSchema = resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema)));
|
|
7356
|
+
const isSuspendedSteps = suspendedSteps.length > 0;
|
|
8005
7357
|
return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs w-full", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
8006
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
8007
|
-
suspendedSteps.length > 0 ? suspendedSteps?.map((step) => /* @__PURE__ */ jsxs("div", { className: "px-4", children: [
|
|
8008
|
-
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
|
|
8009
|
-
/* @__PURE__ */ jsx(
|
|
8010
|
-
DynamicForm,
|
|
8011
|
-
{
|
|
8012
|
-
schema: z$1.record(z$1.string(), z$1.any()),
|
|
8013
|
-
isSubmitLoading: isResumingWorkflow,
|
|
8014
|
-
submitButtonLabel: "Resume",
|
|
8015
|
-
onSubmit: (data) => {
|
|
8016
|
-
handleResumeWorkflow({
|
|
8017
|
-
stepId: step.stepId,
|
|
8018
|
-
runId: step.runId,
|
|
8019
|
-
context: data
|
|
8020
|
-
});
|
|
8021
|
-
}
|
|
8022
|
-
}
|
|
8023
|
-
)
|
|
8024
|
-
] })) : /* @__PURE__ */ jsx(Fragment, {}),
|
|
7358
|
+
!isSuspendedSteps && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
8025
7359
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
8026
|
-
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3
|
|
7360
|
+
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Input" }),
|
|
8027
7361
|
isResumingWorkflow ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
8028
|
-
/* @__PURE__ */ jsx(Loader2, { className: "
|
|
7362
|
+
/* @__PURE__ */ jsx(Loader2, { className: "w-3 h-3 animate-spin text-mastra-el-accent" }),
|
|
8029
7363
|
" Resuming workflow"
|
|
8030
7364
|
] }) : /* @__PURE__ */ jsx(Fragment, {})
|
|
8031
7365
|
] }),
|
|
@@ -8034,7 +7368,7 @@ function WorkflowTrigger({
|
|
|
8034
7368
|
{
|
|
8035
7369
|
schema: zodInputSchema,
|
|
8036
7370
|
defaultValues: payload,
|
|
8037
|
-
isSubmitLoading:
|
|
7371
|
+
isSubmitLoading: isWatchingWorkflow,
|
|
8038
7372
|
onSubmit: (data) => {
|
|
8039
7373
|
setPayload(data);
|
|
8040
7374
|
handleExecuteWorkflow(data);
|
|
@@ -8042,12 +7376,12 @@ function WorkflowTrigger({
|
|
|
8042
7376
|
}
|
|
8043
7377
|
)
|
|
8044
7378
|
] }),
|
|
8045
|
-
workflowActivePaths.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col
|
|
8046
|
-
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3
|
|
7379
|
+
workflowActivePaths.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
7380
|
+
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Status" }),
|
|
8047
7381
|
/* @__PURE__ */ jsx("div", { className: "px-4", children: workflowActivePaths?.map((activePath, idx) => {
|
|
8048
|
-
return /* @__PURE__ */ jsx("div", { className: "flex flex-col mt-2
|
|
7382
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col mt-2 overflow-hidden border", children: activePath?.stepPath?.map((sp, idx2) => {
|
|
8049
7383
|
const status = activePath?.status === "completed" ? "Completed" : sp === activePath?.stepId ? activePath?.status.charAt(0).toUpperCase() + activePath?.status.slice(1) : "Completed";
|
|
8050
|
-
const statusIcon = status === "Completed" ? /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }) : /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-yellow-500 animate-pulse
|
|
7384
|
+
const statusIcon = status === "Completed" ? /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }) : /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-yellow-500 rounded-full animate-pulse" });
|
|
8051
7385
|
return /* @__PURE__ */ jsxs(
|
|
8052
7386
|
"div",
|
|
8053
7387
|
{
|
|
@@ -8069,12 +7403,39 @@ function WorkflowTrigger({
|
|
|
8069
7403
|
}) }, idx);
|
|
8070
7404
|
}) })
|
|
8071
7405
|
] }),
|
|
8072
|
-
|
|
8073
|
-
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3
|
|
7406
|
+
isSuspendedSteps && suspendedSteps?.map((step) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
|
|
7407
|
+
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
|
|
7408
|
+
step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
7409
|
+
CodeBlockDemo,
|
|
7410
|
+
{
|
|
7411
|
+
className: "w-[300px] overflow-x-auto",
|
|
7412
|
+
code: JSON.stringify(step.suspendPayload, null, 2),
|
|
7413
|
+
language: "json"
|
|
7414
|
+
}
|
|
7415
|
+
) }),
|
|
7416
|
+
/* @__PURE__ */ jsx(
|
|
7417
|
+
DynamicForm,
|
|
7418
|
+
{
|
|
7419
|
+
schema: z$1.record(z$1.string(), z$1.any()),
|
|
7420
|
+
isSubmitLoading: isResumingWorkflow,
|
|
7421
|
+
submitButtonLabel: "Resume",
|
|
7422
|
+
onSubmit: (data) => {
|
|
7423
|
+
handleResumeWorkflow({
|
|
7424
|
+
stepId: step.stepId,
|
|
7425
|
+
runId: step.runId,
|
|
7426
|
+
suspendPayload: step.suspendPayload,
|
|
7427
|
+
context: data
|
|
7428
|
+
});
|
|
7429
|
+
}
|
|
7430
|
+
}
|
|
7431
|
+
)
|
|
7432
|
+
] })),
|
|
7433
|
+
result && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
7434
|
+
/* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Output" }),
|
|
8074
7435
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsx(
|
|
8075
7436
|
CopyButton,
|
|
8076
7437
|
{
|
|
8077
|
-
classname: "absolute z-40
|
|
7438
|
+
classname: "absolute z-40 w-8 h-8 p-0 transition-opacity duration-150 ease-in-out opacity-0 top-4 right-4 group-hover:opacity-100",
|
|
8078
7439
|
content: JSON.stringify(result, null, 2)
|
|
8079
7440
|
}
|
|
8080
7441
|
) }),
|
|
@@ -8090,5 +7451,5 @@ function WorkflowTrigger({
|
|
|
8090
7451
|
] }) });
|
|
8091
7452
|
}
|
|
8092
7453
|
|
|
8093
|
-
export { AgentChat, AgentEvals, AgentTraces, AgentsTable,
|
|
7454
|
+
export { AgentChat, AgentEvals, AgentTraces, AgentsTable, MastraResizablePanel, WorkflowGraph, WorkflowRunContext, WorkflowRunProvider, WorkflowTraces, WorkflowTrigger, WorkflowsTable };
|
|
8094
7455
|
//# sourceMappingURL=index.es.js.map
|