@mastra/playground-ui 5.1.7-alpha.1 → 5.1.7-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { createContext, useContext, forwardRef, useState, useEffect, memo, useRef, useCallback, useMemo, Suspense, Fragment as Fragment$1, useId } from 'react';
4
4
  import { MastraClient } from '@mastra/client-js';
5
5
  import { useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, ComposerPrimitive, useAttachment, AttachmentPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, FileText, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Network, PauseIcon, Loader2, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon, Plus, Minus, Maximize } from 'lucide-react';
6
+ import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, FileText, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Network, PauseIcon, Loader2, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon } from 'lucide-react';
7
7
  import { Slot } from '@radix-ui/react-slot';
8
8
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
9
  import { TooltipProvider as TooltipProvider$1 } from '@radix-ui/react-tooltip';
@@ -29,13 +29,18 @@ import { AnimatePresence } from 'motion/react';
29
29
  import { C as Colors } from './colors-CBG_Mm7P.js';
30
30
  import { processDataStream } from '@ai-sdk/ui-utils';
31
31
  import Markdown from 'react-markdown';
32
- import { useDebouncedCallback } from 'use-debounce';
33
- import { MarkerType, Handle, Position, useNodesState, useEdgesState, ReactFlow, Controls, MiniMap, Background, BackgroundVariant, ReactFlowProvider, useViewport, useReactFlow, Panel } from '@xyflow/react';
32
+ import { MarkerType, Handle, Position, useViewport, useReactFlow, Panel, useNodesState, useEdgesState, ReactFlow, MiniMap, Background, BackgroundVariant, ReactFlowProvider, Controls } from '@xyflow/react';
34
33
  import '@xyflow/react/dist/style.css';
35
34
  import Dagre from '@dagrejs/dagre';
36
35
  import { Highlight, themes } from 'prism-react-renderer';
37
36
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
38
37
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
38
+ import * as SliderPrimitive from '@radix-ui/react-slider';
39
+ import { useDebouncedCallback } from 'use-debounce';
40
+ import { v4 } from '@lukeed/uuid';
41
+ import prettier from 'prettier';
42
+ import prettierPluginBabel from 'prettier/plugins/babel';
43
+ import prettierPluginEstree from 'prettier/plugins/estree';
39
44
  import jsonSchemaToZod from 'json-schema-to-zod';
40
45
  import { parse } from 'superjson';
41
46
  import z$1, { z, ZodObject } from 'zod';
@@ -44,11 +49,9 @@ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
44
49
  import { DayPicker } from 'react-day-picker';
45
50
  import * as PopoverPrimitive from '@radix-ui/react-popover';
46
51
  import * as SelectPrimitive from '@radix-ui/react-select';
47
- import { v4 } from '@lukeed/uuid';
48
52
  import { ZodProvider, getFieldConfigInZodStack, getDefaultValueInZodStack } from '@autoform/zod';
49
53
  import * as LabelPrimitive from '@radix-ui/react-label';
50
54
  import { CodeBlock as CodeBlock$1 } from 'react-code-block';
51
- import * as SliderPrimitive from '@radix-ui/react-slider';
52
55
  import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
53
56
 
54
57
  import './index.css';const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
@@ -4364,10 +4367,10 @@ const AssistantMessage = ({
4364
4367
  }
4365
4368
  }
4366
4369
  ) }),
4367
- /* @__PURE__ */ jsx("div", { className: "h-6 pt-1", children: !isSolelyToolCall && /* @__PURE__ */ jsx(AssistantActionBar, {}) })
4370
+ /* @__PURE__ */ jsx("div", { className: "h-6 pt-1", children: !isSolelyToolCall && /* @__PURE__ */ jsx(AssistantActionBar$1, {}) })
4368
4371
  ] });
4369
4372
  };
4370
- const AssistantActionBar = () => {
4373
+ const AssistantActionBar$1 = () => {
4371
4374
  return /* @__PURE__ */ jsx(
4372
4375
  ActionBarPrimitive.Root,
4373
4376
  {
@@ -4645,28 +4648,28 @@ const Thread = ({ ToolFallback, agentName, hasMemory, showFileSupport }) => {
4645
4648
  const WrappedAssistantMessage = (props) => {
4646
4649
  return /* @__PURE__ */ jsx(AssistantMessage, { ...props, ToolFallback });
4647
4650
  };
4648
- return /* @__PURE__ */ jsxs(ThreadWrapper, { children: [
4651
+ return /* @__PURE__ */ jsxs(ThreadWrapper$1, { children: [
4649
4652
  /* @__PURE__ */ jsxs(ThreadPrimitive.Viewport, { ref: areaRef, autoScroll: false, className: "overflow-y-scroll scroll-smooth h-full", children: [
4650
- /* @__PURE__ */ jsx(ThreadWelcome, { agentName }),
4653
+ /* @__PURE__ */ jsx(ThreadWelcome$1, { agentName }),
4651
4654
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto px-4 pb-7", children: /* @__PURE__ */ jsx(
4652
4655
  ThreadPrimitive.Messages,
4653
4656
  {
4654
4657
  components: {
4655
4658
  UserMessage,
4656
- EditComposer,
4659
+ EditComposer: EditComposer$1,
4657
4660
  AssistantMessage: WrappedAssistantMessage
4658
4661
  }
4659
4662
  }
4660
4663
  ) }),
4661
4664
  /* @__PURE__ */ jsx(ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsx("div", {}) })
4662
4665
  ] }),
4663
- /* @__PURE__ */ jsx(Composer, { hasMemory, showFileSupport })
4666
+ /* @__PURE__ */ jsx(Composer$1, { hasMemory, showFileSupport })
4664
4667
  ] });
4665
4668
  };
4666
- const ThreadWrapper = ({ children }) => {
4669
+ const ThreadWrapper$1 = ({ children }) => {
4667
4670
  return /* @__PURE__ */ jsx(ThreadPrimitive.Root, { className: "grid grid-rows-[1fr_auto] h-full overflow-y-auto", children });
4668
4671
  };
4669
- const ThreadWelcome = ({ agentName }) => {
4672
+ const ThreadWelcome$1 = ({ agentName }) => {
4670
4673
  const safeAgentName = agentName ?? "";
4671
4674
  const words = safeAgentName.split(" ") ?? [];
4672
4675
  let initials = "A";
@@ -4682,7 +4685,7 @@ const ThreadWelcome = ({ agentName }) => {
4682
4685
  /* @__PURE__ */ jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
4683
4686
  ] }) });
4684
4687
  };
4685
- const Composer = ({ hasMemory, showFileSupport }) => {
4688
+ const Composer$1 = ({ hasMemory, showFileSupport }) => {
4686
4689
  return /* @__PURE__ */ jsxs("div", { className: "mx-4", children: [
4687
4690
  /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
4688
4691
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto px-2 py-3", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
@@ -4698,8 +4701,8 @@ const Composer = ({ hasMemory, showFileSupport }) => {
4698
4701
  }
4699
4702
  ) }),
4700
4703
  /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
4701
- /* @__PURE__ */ jsx(SpeechInput, {}),
4702
- /* @__PURE__ */ jsx(ComposerAction, { showFileSupport })
4704
+ /* @__PURE__ */ jsx(SpeechInput$1, {}),
4705
+ /* @__PURE__ */ jsx(ComposerAction$1, { showFileSupport })
4703
4706
  ] })
4704
4707
  ] })
4705
4708
  ] }),
@@ -4709,7 +4712,7 @@ const Composer = ({ hasMemory, showFileSupport }) => {
4709
4712
  ] })
4710
4713
  ] });
4711
4714
  };
4712
- const SpeechInput = () => {
4715
+ const SpeechInput$1 = () => {
4713
4716
  const composerRuntime = useComposerRuntime();
4714
4717
  const { start, stop, isListening, transcript } = useSpeechRecognition();
4715
4718
  useEffect(() => {
@@ -4724,11 +4727,11 @@ const SpeechInput = () => {
4724
4727
  variant: "ghost",
4725
4728
  className: "rounded-full",
4726
4729
  onClick: () => isListening ? stop() : start(),
4727
- children: isListening ? /* @__PURE__ */ jsx(CircleStopIcon, {}) : /* @__PURE__ */ jsx(Mic, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" })
4730
+ children: isListening ? /* @__PURE__ */ jsx(CircleStopIcon$1, {}) : /* @__PURE__ */ jsx(Mic, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" })
4728
4731
  }
4729
4732
  );
4730
4733
  };
4731
- const ComposerAction = ({ showFileSupport }) => {
4734
+ const ComposerAction$1 = ({ showFileSupport }) => {
4732
4735
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4733
4736
  showFileSupport && /* @__PURE__ */ jsx(ComposerPrimitive.AddAttachment, { asChild: true, children: /* @__PURE__ */ jsx(TooltipIconButton, { tooltip: "Add attachment", variant: "ghost", className: "rounded-full", children: /* @__PURE__ */ jsx(PlusIcon, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" }) }) }),
4734
4737
  /* @__PURE__ */ jsx(ThreadPrimitive.If, { running: false, children: /* @__PURE__ */ jsx(ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsx(
@@ -4740,10 +4743,10 @@ const ComposerAction = ({ showFileSupport }) => {
4740
4743
  children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" })
4741
4744
  }
4742
4745
  ) }) }),
4743
- /* @__PURE__ */ jsx(ThreadPrimitive.If, { running: true, children: /* @__PURE__ */ jsx(ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsx(TooltipIconButton, { tooltip: "Cancel", variant: "default", children: /* @__PURE__ */ jsx(CircleStopIcon, {}) }) }) })
4746
+ /* @__PURE__ */ jsx(ThreadPrimitive.If, { running: true, children: /* @__PURE__ */ jsx(ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsx(TooltipIconButton, { tooltip: "Cancel", variant: "default", children: /* @__PURE__ */ jsx(CircleStopIcon$1, {}) }) }) })
4744
4747
  ] });
4745
4748
  };
4746
- const EditComposer = () => {
4749
+ const EditComposer$1 = () => {
4747
4750
  return /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
4748
4751
  /* @__PURE__ */ jsx(ComposerPrimitive.Input, {}),
4749
4752
  /* @__PURE__ */ jsxs("div", { children: [
@@ -4752,7 +4755,7 @@ const EditComposer = () => {
4752
4755
  ] })
4753
4756
  ] });
4754
4757
  };
4755
- const CircleStopIcon = () => {
4758
+ const CircleStopIcon$1 = () => {
4756
4759
  return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", width: "16", height: "16", children: /* @__PURE__ */ jsx("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" }) });
4757
4760
  };
4758
4761
 
@@ -4827,7 +4830,7 @@ class PDFAttachmentAdapter {
4827
4830
  }
4828
4831
  }
4829
4832
 
4830
- const convertMessage$1 = (message) => {
4833
+ const convertMessage$2 = (message) => {
4831
4834
  return message;
4832
4835
  };
4833
4836
  const convertToAIAttachments = async (attachments) => {
@@ -5166,7 +5169,7 @@ function MastraRuntimeProvider({
5166
5169
  const runtime = useExternalStoreRuntime({
5167
5170
  isRunning,
5168
5171
  messages,
5169
- convertMessage: convertMessage$1,
5172
+ convertMessage: convertMessage$2,
5170
5173
  onNew,
5171
5174
  adapters: {
5172
5175
  attachments: new CompositeAttachmentAdapter([
@@ -6475,7 +6478,7 @@ function AgentTracesInner({ className, traces, error }) {
6475
6478
  ] });
6476
6479
  }
6477
6480
 
6478
- const convertMessage = (message) => {
6481
+ const convertMessage$1 = (message) => {
6479
6482
  return message;
6480
6483
  };
6481
6484
  function MastraNetworkRuntimeProvider({
@@ -6640,7 +6643,7 @@ function MastraNetworkRuntimeProvider({
6640
6643
  const runtime = useExternalStoreRuntime({
6641
6644
  isRunning,
6642
6645
  messages,
6643
- convertMessage,
6646
+ convertMessage: convertMessage$1,
6644
6647
  onNew
6645
6648
  });
6646
6649
  return /* @__PURE__ */ jsxs(AssistantRuntimeProvider, { runtime, children: [
@@ -6879,190 +6882,95 @@ const NetworkChat = ({ agentId, memory }) => {
6879
6882
  return /* @__PURE__ */ jsx(MastraNetworkRuntimeProvider, { agentId, memory, modelSettings, children: /* @__PURE__ */ jsx(Thread, { ToolFallback }) });
6880
6883
  };
6881
6884
 
6882
- function WorkflowTraces({ traces, error, runId, stepName }) {
6883
- return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(WorkflowTracesInner, { traces, error, runId, stepName }) });
6885
+ const VNextNetworkChatContext = createContext(void 0);
6886
+ const VNextNetworkChatProvider = ({ children, networkId }) => {
6887
+ const [state, setState] = useState({});
6888
+ const handleStep = (uuid, record) => {
6889
+ const id = record?.type === "finish" ? "finish" : record.type === "start" ? "start" : record.payload?.id;
6890
+ if (id.includes("mapping_")) return;
6891
+ setState((prevState) => {
6892
+ const current = prevState[uuid];
6893
+ const currentMetadata = current?.steps?.[id]?.metadata;
6894
+ let startTime = currentMetadata?.startTime;
6895
+ let endTime = currentMetadata?.endTime;
6896
+ if (record.type === "step-start") {
6897
+ startTime = Date.now();
6898
+ }
6899
+ if (record.type === "step-finish") {
6900
+ endTime = Date.now();
6901
+ }
6902
+ return {
6903
+ ...prevState,
6904
+ [uuid]: {
6905
+ ...current,
6906
+ runId: current?.runId || record?.payload?.runId,
6907
+ executionSteps: current?.steps?.[id] ? current?.executionSteps : [...current?.executionSteps || [], id],
6908
+ steps: {
6909
+ ...current?.steps,
6910
+ [id]: {
6911
+ ...current?.steps?.[id] || {},
6912
+ [record.type]: record.payload,
6913
+ metadata: {
6914
+ startTime,
6915
+ endTime
6916
+ }
6917
+ }
6918
+ }
6919
+ }
6920
+ };
6921
+ });
6922
+ };
6923
+ return /* @__PURE__ */ jsx(VNextNetworkChatContext.Provider, { value: { state, handleStep, setState }, children });
6924
+ };
6925
+ const useVNextNetworkChat = () => {
6926
+ const context = useContext(VNextNetworkChatContext);
6927
+ if (context === void 0) {
6928
+ throw new Error("useVNextNetworkChat must be used within a VNextNetworkChatProvider");
6929
+ }
6930
+ return context;
6931
+ };
6932
+
6933
+ function Spinner({ color = "#fff", className }) {
6934
+ return /* @__PURE__ */ jsx(
6935
+ "svg",
6936
+ {
6937
+ className: cn("animate-spin duration-700", className),
6938
+ xmlns: "http://www.w3.org/2000/svg",
6939
+ width: "24",
6940
+ height: "24",
6941
+ viewBox: "0 0 24 24",
6942
+ fill: "none",
6943
+ stroke: "currentColor",
6944
+ strokeWidth: "2",
6945
+ strokeLinecap: "round",
6946
+ strokeLinejoin: "round",
6947
+ children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
6948
+ }
6949
+ );
6884
6950
  }
6885
- function WorkflowTracesInner({ traces, error, runId, stepName }) {
6886
- const hasRunRef = useRef(false);
6887
- const [sidebarWidth, setSidebarWidth] = useState(100);
6888
- const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
6951
+
6952
+ const Clock = ({ startedAt, endedAt }) => {
6953
+ const [time, setTime] = useState(startedAt);
6889
6954
  useEffect(() => {
6890
- if (hasRunRef.current) return;
6891
- if (!runId || !stepName) return;
6892
- const matchingTrace = traces.find((trace) => trace.runId === runId);
6893
- if (!matchingTrace) return;
6894
- const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
6895
- if (!matchingSpan) return;
6896
- setTrace(matchingTrace.trace);
6897
- setSpan(matchingSpan);
6898
- setIsOpen(true);
6899
- hasRunRef.current = true;
6900
- }, [runId, traces, setTrace]);
6901
- return /* @__PURE__ */ jsxs("main", { className: "h-full relative overflow-hidden flex", children: [
6902
- /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsx(TracesTable, { traces, error }) }),
6903
- open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
6955
+ const interval = setInterval(() => {
6956
+ setTime(Date.now());
6957
+ }, 100);
6958
+ return () => clearInterval(interval);
6959
+ }, [startedAt]);
6960
+ const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
6961
+ return /* @__PURE__ */ jsxs("span", { className: "text-xs text-icon3", children: [
6962
+ toSigFigs(timeDiff, 3),
6963
+ "ms"
6904
6964
  ] });
6905
- }
6965
+ };
6906
6966
 
6907
6967
  function Skeleton({ className, ...props }) {
6908
6968
  return /* @__PURE__ */ jsx("div", { className: cn("animate-pulse rounded-md bg-muted/50", className), ...props });
6909
6969
  }
6910
6970
 
6911
- const useLegacyWorkflow = (workflowId) => {
6912
- const [legacyWorkflow, setLegacyWorkflow] = useState(null);
6913
- const [isLoading, setIsLoading] = useState(true);
6914
- const client = useMastraClient();
6915
- useEffect(() => {
6916
- const fetchWorkflow = async () => {
6917
- setIsLoading(true);
6918
- try {
6919
- if (!workflowId) {
6920
- setLegacyWorkflow(null);
6921
- setIsLoading(false);
6922
- return;
6923
- }
6924
- const res = await client.getLegacyWorkflow(workflowId).details();
6925
- if (!res) {
6926
- setLegacyWorkflow(null);
6927
- console.error("Error fetching legacy workflow");
6928
- toast.error("Error fetching legacy workflow");
6929
- return;
6930
- }
6931
- const steps = res.steps;
6932
- const stepsWithWorkflow = await Promise.all(
6933
- Object.values(steps)?.map(async (step) => {
6934
- if (!step.workflowId) return step;
6935
- const wFlow = await client.getLegacyWorkflow(step.workflowId).details();
6936
- if (!wFlow) return step;
6937
- return { ...step, stepGraph: wFlow.stepGraph, stepSubscriberGraph: wFlow.stepSubscriberGraph };
6938
- })
6939
- );
6940
- const _steps = stepsWithWorkflow.reduce((acc, b) => {
6941
- return { ...acc, [b.id]: b };
6942
- }, {});
6943
- setLegacyWorkflow({ ...res, steps: _steps });
6944
- } catch (error) {
6945
- setLegacyWorkflow(null);
6946
- console.error("Error fetching legacy workflow", error);
6947
- toast.error("Error fetching legacy workflow");
6948
- } finally {
6949
- setIsLoading(false);
6950
- }
6951
- };
6952
- fetchWorkflow();
6953
- }, [workflowId]);
6954
- return { legacyWorkflow, isLoading };
6955
- };
6956
- const useExecuteWorkflow = () => {
6957
- const client = useMastraClient();
6958
- const createLegacyWorkflowRun = async ({ workflowId, prevRunId }) => {
6959
- try {
6960
- const workflow = client.getLegacyWorkflow(workflowId);
6961
- const { runId: newRunId } = await workflow.createRun({ runId: prevRunId });
6962
- return { runId: newRunId };
6963
- } catch (error) {
6964
- console.error("Error creating workflow run:", error);
6965
- throw error;
6966
- }
6967
- };
6968
- const startLegacyWorkflowRun = async ({
6969
- workflowId,
6970
- runId,
6971
- input
6972
- }) => {
6973
- try {
6974
- const workflow = client.getLegacyWorkflow(workflowId);
6975
- await workflow.start({ runId, triggerData: input || {} });
6976
- } catch (error) {
6977
- console.error("Error starting workflow run:", error);
6978
- throw error;
6979
- }
6980
- };
6981
- return {
6982
- startLegacyWorkflowRun,
6983
- createLegacyWorkflowRun
6984
- };
6985
- };
6986
- const useWatchWorkflow = () => {
6987
- const [isWatchingLegacyWorkflow, setIsWatchingLegacyWorkflow] = useState(false);
6988
- const [legacyWatchResult, setLegacyWatchResult] = useState(null);
6989
- const client = useMastraClient();
6990
- const debouncedSetLegacyWorkflowWatchResult = useDebouncedCallback((record) => {
6991
- const formattedResults = Object.entries(record.results || {}).reduce(
6992
- (acc, [key, value]) => {
6993
- let output = value.status === "success" ? value.output : void 0;
6994
- if (output) {
6995
- output = Object.entries(output).reduce(
6996
- (_acc, [_key, _value]) => {
6997
- const val = _value;
6998
- _acc[_key] = val.type?.toLowerCase() === "buffer" ? { type: "Buffer", data: `[...buffered data]` } : val;
6999
- return _acc;
7000
- },
7001
- {}
7002
- );
7003
- }
7004
- acc[key] = { ...value, output };
7005
- return acc;
7006
- },
7007
- {}
7008
- );
7009
- const sanitizedRecord = {
7010
- ...record,
7011
- sanitizedOutput: record ? JSON.stringify({ ...record, results: formattedResults }, null, 2).slice(0, 5e4) : null
7012
- };
7013
- setLegacyWatchResult(sanitizedRecord);
7014
- }, 100);
7015
- const watchLegacyWorkflow = async ({ workflowId, runId }) => {
7016
- try {
7017
- setIsWatchingLegacyWorkflow(true);
7018
- const workflow = client.getLegacyWorkflow(workflowId);
7019
- await workflow.watch({ runId }, (record) => {
7020
- try {
7021
- debouncedSetLegacyWorkflowWatchResult(record);
7022
- } catch (err) {
7023
- console.error("Error processing workflow record:", err);
7024
- setLegacyWatchResult({
7025
- ...record
7026
- });
7027
- }
7028
- });
7029
- } catch (error) {
7030
- console.error("Error watching workflow:", error);
7031
- throw error;
7032
- } finally {
7033
- setIsWatchingLegacyWorkflow(false);
7034
- }
7035
- };
7036
- return {
7037
- watchLegacyWorkflow,
7038
- isWatchingLegacyWorkflow,
7039
- legacyWatchResult
7040
- };
7041
- };
7042
- const useResumeWorkflow = () => {
7043
- const [isResumingLegacyWorkflow, setIsResumingLegacyWorkflow] = useState(false);
7044
- const client = useMastraClient();
7045
- const resumeLegacyWorkflow = async ({
7046
- workflowId,
7047
- stepId,
7048
- runId,
7049
- context
7050
- }) => {
7051
- try {
7052
- setIsResumingLegacyWorkflow(true);
7053
- const response = await client.getLegacyWorkflow(workflowId).resume({ stepId, runId, context });
7054
- return response;
7055
- } catch (error) {
7056
- console.error("Error resuming workflow:", error);
7057
- throw error;
7058
- } finally {
7059
- setIsResumingLegacyWorkflow(false);
7060
- }
7061
- };
7062
- return {
7063
- resumeLegacyWorkflow,
7064
- isResumingLegacyWorkflow
7065
- };
6971
+ const lodashTitleCase = (str) => {
6972
+ const camelCased = str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^(.)/, (char) => char.toLowerCase());
6973
+ return camelCased.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).trim();
7066
6974
  };
7067
6975
 
7068
6976
  function extractConditions(group, type) {
@@ -8037,21 +7945,6 @@ function WorkflowConditionNode({ data }) {
8037
7945
  ] });
8038
7946
  }
8039
7947
 
8040
- const Clock = ({ startedAt, endedAt }) => {
8041
- const [time, setTime] = useState(startedAt);
8042
- useEffect(() => {
8043
- const interval = setInterval(() => {
8044
- setTime(Date.now());
8045
- }, 100);
8046
- return () => clearInterval(interval);
8047
- }, [startedAt]);
8048
- const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
8049
- return /* @__PURE__ */ jsxs("span", { className: "text-xs text-icon3", children: [
8050
- toSigFigs(timeDiff, 3),
8051
- "ms"
8052
- ] });
8053
- };
8054
-
8055
7948
  function WorkflowDefaultNode({
8056
7949
  data,
8057
7950
  onShowTrace,
@@ -8095,7 +7988,7 @@ function WorkflowDefaultNode({
8095
7988
  output: step?.output,
8096
7989
  error: step?.error,
8097
7990
  mapConfig: data.mapConfig,
8098
- onShowTrace: runId ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0
7991
+ onShowTrace: runId && onShowTrace ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0
8099
7992
  }
8100
7993
  )
8101
7994
  ]
@@ -8157,42 +8050,62 @@ function WorkflowLoopResultNode({ data }) {
8157
8050
  ] });
8158
8051
  }
8159
8052
 
8160
- function Spinner({ color = "#fff", className }) {
8161
- return /* @__PURE__ */ jsx(
8162
- "svg",
8163
- {
8164
- className: cn("animate-spin duration-700", className),
8165
- xmlns: "http://www.w3.org/2000/svg",
8166
- width: "24",
8167
- height: "24",
8168
- viewBox: "0 0 24 24",
8169
- fill: "none",
8170
- stroke: "currentColor",
8171
- strokeWidth: "2",
8172
- strokeLinecap: "round",
8173
- strokeLinejoin: "round",
8174
- children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
8175
- }
8176
- );
8177
- }
8053
+ const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
8054
+ SliderPrimitive.Root,
8055
+ {
8056
+ ref,
8057
+ className: cn("relative flex w-full touch-none select-none items-center", className),
8058
+ ...props,
8059
+ children: [
8060
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
8061
+ /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
8062
+ ]
8063
+ }
8064
+ ));
8065
+ Slider.displayName = SliderPrimitive.Root.displayName;
8178
8066
 
8179
- function LegacyWorkflowNestedGraph({
8180
- stepGraph,
8181
- stepSubscriberGraph,
8182
- open
8183
- }) {
8184
- const { nodes: initialNodes, edges: initialEdges } = contructLegacyNodesAndEdges({
8185
- stepGraph,
8186
- stepSubscriberGraph
8067
+ const ZoomSlider = forwardRef(({ className, ...props }) => {
8068
+ const { zoom } = useViewport();
8069
+ const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
8070
+ return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8071
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
8072
+ /* @__PURE__ */ jsx(
8073
+ Slider,
8074
+ {
8075
+ className: "w-[140px]",
8076
+ value: [zoom],
8077
+ min: 0.01,
8078
+ max: 1,
8079
+ step: 0.01,
8080
+ onValueChange: (values) => {
8081
+ zoomTo(values[0]);
8082
+ }
8083
+ }
8084
+ ),
8085
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
8086
+ /* @__PURE__ */ jsxs(Button$1, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8087
+ (100 * zoom).toFixed(0),
8088
+ "%"
8089
+ ] }),
8090
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
8091
+ ] });
8092
+ });
8093
+ ZoomSlider.displayName = "ZoomSlider";
8094
+
8095
+ function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
8096
+ const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8097
+ stepGraph
8187
8098
  });
8188
8099
  const [isMounted, setIsMounted] = useState(false);
8189
8100
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8190
8101
  const [edges] = useEdgesState(initialEdges);
8102
+ const { steps } = useCurrentRun();
8191
8103
  const nodeTypes = {
8192
- "default-node": WorkflowDefaultNode,
8104
+ "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
8193
8105
  "condition-node": WorkflowConditionNode,
8194
8106
  "after-node": WorkflowAfterNode,
8195
- "loop-result-node": WorkflowLoopResultNode
8107
+ "loop-result-node": WorkflowLoopResultNode,
8108
+ "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
8196
8109
  };
8197
8110
  useEffect(() => {
8198
8111
  if (open) {
@@ -8201,17 +8114,27 @@ function LegacyWorkflowNestedGraph({
8201
8114
  }, 500);
8202
8115
  }
8203
8116
  }, [open]);
8204
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative", children: isMounted ? /* @__PURE__ */ jsxs(
8117
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
8205
8118
  ReactFlow,
8206
8119
  {
8207
8120
  nodes,
8208
- edges,
8121
+ edges: edges.map((e) => ({
8122
+ ...e,
8123
+ style: {
8124
+ ...e.style,
8125
+ stroke: steps[`${workflowName}.${e.data?.previousStepId}`]?.status === "success" && steps[`${workflowName}.${e.data?.nextStepId}`] ? "#22c55e" : void 0
8126
+ }
8127
+ })),
8209
8128
  fitView: true,
8210
- fitViewOptions: { maxZoom: 0.85 },
8129
+ fitViewOptions: {
8130
+ maxZoom: 1
8131
+ },
8132
+ minZoom: 0.01,
8133
+ maxZoom: 1,
8211
8134
  nodeTypes,
8212
8135
  onNodesChange,
8213
8136
  children: [
8214
- /* @__PURE__ */ jsx(Controls, {}),
8137
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
8215
8138
  /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
8216
8139
  /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
8217
8140
  ]
@@ -8219,32 +8142,53 @@ function LegacyWorkflowNestedGraph({
8219
8142
  ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
8220
8143
  }
8221
8144
 
8222
- const LegacyWorkflowNestedGraphContext = createContext(
8145
+ const WorkflowNestedGraphContext = createContext(
8223
8146
  {}
8224
8147
  );
8225
- function LegacyWorkflowNestedGraphProvider({ children }) {
8148
+ function WorkflowNestedGraphProvider({ children }) {
8226
8149
  const [stepGraph, setStepGraph] = useState(null);
8227
- const [stepSubscriberGraph, setStepSubscriberGraph] = useState(null);
8150
+ const [parentStepGraphList, setParentStepGraphList] = useState([]);
8228
8151
  const [openDialog, setOpenDialog] = useState(false);
8229
8152
  const [label, setLabel] = useState("");
8153
+ const [fullStep, setFullStep] = useState("");
8154
+ const [switching, setSwitching] = useState(false);
8230
8155
  const closeNestedGraph = () => {
8231
- setOpenDialog(false);
8232
- setStepGraph(null);
8233
- setStepSubscriberGraph(null);
8234
- setLabel("");
8156
+ if (parentStepGraphList.length) {
8157
+ setSwitching(true);
8158
+ const lastStepGraph = parentStepGraphList[parentStepGraphList.length - 1];
8159
+ setStepGraph(lastStepGraph.stepGraph);
8160
+ setLabel(lastStepGraph.label);
8161
+ setFullStep(lastStepGraph.fullStep);
8162
+ setParentStepGraphList(parentStepGraphList.slice(0, -1));
8163
+ setTimeout(() => {
8164
+ setSwitching(false);
8165
+ }, 500);
8166
+ } else {
8167
+ setOpenDialog(false);
8168
+ setStepGraph(null);
8169
+ setLabel("");
8170
+ setFullStep("");
8171
+ }
8235
8172
  };
8236
8173
  const showNestedGraph = ({
8237
- label: label2,
8238
- stepGraph: stepGraph2,
8239
- stepSubscriberGraph: stepSubscriberGraph2
8174
+ label: newLabel,
8175
+ stepGraph: newStepGraph,
8176
+ fullStep: newFullStep
8240
8177
  }) => {
8241
- setLabel(label2);
8242
- setStepGraph(stepGraph2);
8243
- setStepSubscriberGraph(stepSubscriberGraph2);
8178
+ if (stepGraph) {
8179
+ setSwitching(true);
8180
+ setParentStepGraphList([...parentStepGraphList, { stepGraph, label, fullStep }]);
8181
+ }
8182
+ setLabel(newLabel);
8183
+ setFullStep(newFullStep);
8184
+ setStepGraph(newStepGraph);
8244
8185
  setOpenDialog(true);
8186
+ setTimeout(() => {
8187
+ setSwitching(false);
8188
+ }, 500);
8245
8189
  };
8246
8190
  return /* @__PURE__ */ jsxs(
8247
- LegacyWorkflowNestedGraphContext.Provider,
8191
+ WorkflowNestedGraphContext.Provider,
8248
8192
  {
8249
8193
  value: {
8250
8194
  showNestedGraph,
@@ -8252,7 +8196,7 @@ function LegacyWorkflowNestedGraphProvider({ children }) {
8252
8196
  },
8253
8197
  children: [
8254
8198
  children,
8255
- /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[40rem] h-[40rem] bg-[#121212] p-[0.5rem]", children: [
8199
+ /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[45rem] h-[45rem] max-w-[unset] bg-[#121212] p-[0.5rem]", children: [
8256
8200
  /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
8257
8201
  /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
8258
8202
  /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
@@ -8260,1415 +8204,2124 @@ function LegacyWorkflowNestedGraphProvider({ children }) {
8260
8204
  " workflow"
8261
8205
  ] })
8262
8206
  ] }),
8263
- /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
8264
- LegacyWorkflowNestedGraph,
8265
- {
8266
- stepGraph,
8267
- open: openDialog,
8268
- stepSubscriberGraph
8269
- }
8270
- ) })
8207
+ switching ? /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(WorkflowNestedGraph, { stepGraph, open: openDialog, workflowName: fullStep }) })
8271
8208
  ] }) }) })
8272
8209
  ]
8273
8210
  }
8274
8211
  );
8275
8212
  }
8276
8213
 
8277
- function LegacyWorkflowNestedNode({ data }) {
8278
- const { label, withoutTopHandle, withoutBottomHandle, stepGraph, stepSubscriberGraph } = data;
8279
- const { showNestedGraph } = useContext(LegacyWorkflowNestedGraphContext);
8280
- return /* @__PURE__ */ jsxs("div", { className: cn("bg-[rgba(29,29,29,0.5)] rounded-md h-full overflow-scroll w-[274px]"), children: [
8214
+ function WorkflowNestedNode({
8215
+ data,
8216
+ parentWorkflowName
8217
+ }) {
8218
+ const [isInputOpen, setIsInputOpen] = useState(false);
8219
+ const [isOutputOpen, setIsOutputOpen] = useState(false);
8220
+ const [isErrorOpen, setIsErrorOpen] = useState(false);
8221
+ const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
8222
+ const { steps, isRunning } = useCurrentRun();
8223
+ const { showNestedGraph } = useContext(WorkflowNestedGraphContext);
8224
+ const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig } = data;
8225
+ const fullLabel = parentWorkflowName ? `${parentWorkflowName}.${label}` : label;
8226
+ const step = steps[fullLabel];
8227
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
8228
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
8229
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8281
8230
  !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
8282
- /* @__PURE__ */ jsx("div", { className: "p-2 cursor-pointer", onClick: () => showNestedGraph({ label, stepGraph, stepSubscriberGraph }), children: /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-1.5 rounded-sm p-2 cursor-pointer", children: [
8283
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
8284
- /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
8285
- ] }) }),
8286
- !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
8287
- ] });
8288
- }
8289
-
8290
- function LegacyWorkflowGraphInner({ workflow }) {
8291
- const { nodes: initialNodes, edges: initialEdges } = contructLegacyNodesAndEdges({
8292
- stepGraph: workflow.serializedStepGraph || workflow.stepGraph,
8293
- stepSubscriberGraph: workflow.serializedStepSubscriberGraph || workflow.stepSubscriberGraph,
8294
- steps: workflow.steps
8295
- });
8296
- const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8297
- const [edges] = useEdgesState(initialEdges);
8298
- const nodeTypes = {
8299
- "default-node": WorkflowDefaultNode,
8300
- "condition-node": WorkflowConditionNode,
8301
- "after-node": WorkflowAfterNode,
8302
- "loop-result-node": WorkflowLoopResultNode,
8303
- "nested-node": LegacyWorkflowNestedNode
8304
- };
8305
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxs(
8306
- ReactFlow,
8307
- {
8308
- nodes,
8309
- edges,
8310
- nodeTypes,
8311
- onNodesChange,
8312
- fitView: true,
8313
- fitViewOptions: {
8314
- maxZoom: 0.85
8315
- },
8316
- children: [
8317
- /* @__PURE__ */ jsx(Controls, {}),
8318
- /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
8319
- /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
8320
- ]
8321
- }
8322
- ) });
8323
- }
8324
-
8325
- const lodashTitleCase = (str) => {
8326
- const camelCased = str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^(.)/, (char) => char.toLowerCase());
8327
- return camelCased.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).trim();
8328
- };
8329
-
8330
- function LegacyWorkflowGraph({ workflowId }) {
8331
- const { legacyWorkflow, isLoading } = useLegacyWorkflow(workflowId);
8332
- if (isLoading) {
8333
- return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[600px]" }) });
8334
- }
8335
- if (!legacyWorkflow) {
8336
- return /* @__PURE__ */ jsx("div", { className: "grid h-full place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
8337
- /* @__PURE__ */ jsx(AlertCircleIcon, {}),
8338
- /* @__PURE__ */ jsxs("div", { children: [
8339
- "We couldn't find ",
8340
- lodashTitleCase(workflowId),
8341
- " workflow."
8342
- ] })
8343
- ] }) });
8344
- }
8345
- return /* @__PURE__ */ jsx(LegacyWorkflowNestedGraphProvider, { children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(LegacyWorkflowGraphInner, { workflow: legacyWorkflow }) }) });
8346
- }
8347
-
8348
- const Form = React__default.forwardRef(({ children, ...props }, ref) => {
8349
- return /* @__PURE__ */ jsx("form", { ref, className: "space-y-4", ...props, children });
8350
- });
8351
-
8352
- const DISABLED_LABELS = ["boolean", "object", "array"];
8353
- const FieldWrapper = ({ label, children, id, field, error }) => {
8354
- const isDisabled = DISABLED_LABELS.includes(field.type);
8355
- return /* @__PURE__ */ jsxs("div", { className: "pb-4 last:pb-0", children: [
8356
- !isDisabled && /* @__PURE__ */ jsxs(Txt, { as: "label", variant: "ui-sm", className: "text-icon3 pb-1 block", htmlFor: id, children: [
8357
- label,
8358
- field.required && /* @__PURE__ */ jsx("span", { className: "text-accent2", children: " *" })
8359
- ] }),
8360
- children,
8361
- field.fieldConfig?.description && /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: "text-icon6", children: field.fieldConfig.description }),
8362
- error && /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: "text-accent2", children: error })
8231
+ /* @__PURE__ */ jsxs(
8232
+ "div",
8233
+ {
8234
+ className: cn(
8235
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
8236
+ step?.status === "success" && "ring-2 ring-accent1",
8237
+ step?.status === "failed" && "ring-2 ring-accent2"
8238
+ ),
8239
+ children: [
8240
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
8241
+ isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
8242
+ step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8243
+ step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8244
+ step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-icon3" }),
8245
+ step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon6 animate-spin" }),
8246
+ !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
8247
+ ] }),
8248
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
8249
+ label,
8250
+ " ",
8251
+ step?.startedAt && /* @__PURE__ */ jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
8252
+ ] })
8253
+ ] }),
8254
+ description && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
8255
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2 rounded-b-lg", children: [
8256
+ /* @__PURE__ */ jsx(Button, { onClick: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }), children: "View workflow" }),
8257
+ mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
8258
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
8259
+ /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8260
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8261
+ label,
8262
+ " map config"
8263
+ ] }),
8264
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
8265
+ ] }) })
8266
+ ] }),
8267
+ step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
8268
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
8269
+ /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8270
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8271
+ label,
8272
+ " input"
8273
+ ] }),
8274
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.input }) })
8275
+ ] }) })
8276
+ ] }),
8277
+ step?.output && /* @__PURE__ */ jsxs(Fragment, { children: [
8278
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
8279
+ /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8280
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8281
+ label,
8282
+ " output"
8283
+ ] }),
8284
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.output }) })
8285
+ ] }) })
8286
+ ] }),
8287
+ step?.error && /* @__PURE__ */ jsxs(Fragment, { children: [
8288
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
8289
+ /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8290
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8291
+ label,
8292
+ " error"
8293
+ ] }),
8294
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step?.error }) })
8295
+ ] }) })
8296
+ ] })
8297
+ ] })
8298
+ ]
8299
+ }
8300
+ ),
8301
+ !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
8363
8302
  ] });
8364
- };
8303
+ }
8365
8304
 
8366
- const alertVariants = cva(
8367
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
8368
- {
8369
- variants: {
8370
- variant: {
8371
- default: "bg-background text-foreground",
8372
- destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"
8373
- }
8374
- },
8375
- defaultVariants: {
8376
- variant: "default"
8305
+ function WorkflowGraphInner({ workflow, onShowTrace }) {
8306
+ const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
8307
+ const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8308
+ const [edges] = useEdgesState(initialEdges);
8309
+ const { steps, runId } = useCurrentRun();
8310
+ const nodeTypes = {
8311
+ "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { onShowTrace, ...props }),
8312
+ "condition-node": WorkflowConditionNode,
8313
+ "after-node": WorkflowAfterNode,
8314
+ "loop-result-node": WorkflowLoopResultNode,
8315
+ "nested-node": WorkflowNestedNode
8316
+ };
8317
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxs(
8318
+ ReactFlow,
8319
+ {
8320
+ nodes,
8321
+ edges: edges.map((e) => ({
8322
+ ...e,
8323
+ style: {
8324
+ ...e.style,
8325
+ stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
8326
+ }
8327
+ })),
8328
+ nodeTypes,
8329
+ onNodesChange,
8330
+ fitView: true,
8331
+ fitViewOptions: {
8332
+ maxZoom: 1
8333
+ },
8334
+ minZoom: 0.01,
8335
+ maxZoom: 1,
8336
+ children: [
8337
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
8338
+ /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
8339
+ /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
8340
+ ]
8377
8341
  }
8378
- }
8379
- );
8380
- const Alert = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
8381
- Alert.displayName = "Alert";
8382
- const AlertTitle = React.forwardRef(
8383
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 font-medium leading-none tracking-tight", className), ...props })
8384
- );
8385
- AlertTitle.displayName = "AlertTitle";
8386
- const AlertDescription = React.forwardRef(
8387
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props })
8388
- );
8389
- AlertDescription.displayName = "AlertDescription";
8390
-
8391
- const ErrorMessage = ({ error }) => /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
8392
- /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
8393
- /* @__PURE__ */ jsx(AlertTitle, { children: error })
8394
- ] });
8342
+ ) });
8343
+ }
8395
8344
 
8396
- const SubmitButton = ({ children }) => /* @__PURE__ */ jsx(Button$1, { type: "submit", children });
8345
+ function WorkflowGraph({ workflowId, onShowTrace, workflow, isLoading }) {
8346
+ const { snapshot } = useContext(WorkflowRunContext);
8347
+ if (isLoading) {
8348
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-full" }) });
8349
+ }
8350
+ if (!workflow) {
8351
+ return /* @__PURE__ */ jsx("div", { className: "grid h-full place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
8352
+ /* @__PURE__ */ jsx(AlertCircleIcon, {}),
8353
+ /* @__PURE__ */ jsxs("div", { children: [
8354
+ "We couldn't find ",
8355
+ lodashTitleCase(workflowId),
8356
+ " workflow."
8357
+ ] })
8358
+ ] }) });
8359
+ }
8360
+ return /* @__PURE__ */ jsx(WorkflowNestedGraphProvider, { children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
8361
+ WorkflowGraphInner,
8362
+ {
8363
+ workflow: snapshot?.serializedStepGraph ? { stepGraph: snapshot?.serializedStepGraph } : workflow,
8364
+ onShowTrace
8365
+ }
8366
+ ) }) }, snapshot?.runId ?? workflowId);
8367
+ }
8397
8368
 
8398
- const StringField = ({ inputProps, error, field, id }) => {
8399
- const { key, ...props } = inputProps;
8400
- return /* @__PURE__ */ jsx(Input, { id, className: error ? "border-destructive" : "", ...props, defaultValue: field.default });
8369
+ const useWorkflowRuns = (workflowId) => {
8370
+ const [runs, setRuns] = useState(null);
8371
+ const [isLoading, setIsLoading] = useState(true);
8372
+ const client = useMastraClient();
8373
+ useEffect(() => {
8374
+ const fetchWorkflow = async () => {
8375
+ setIsLoading(true);
8376
+ try {
8377
+ if (!workflowId) {
8378
+ setRuns(null);
8379
+ setIsLoading(false);
8380
+ return;
8381
+ }
8382
+ const res = await client.getWorkflow(workflowId).runs({ limit: 50 });
8383
+ setRuns(res);
8384
+ } catch (error) {
8385
+ setRuns(null);
8386
+ console.error("Error fetching workflow", error);
8387
+ toast.error("Error fetching workflow");
8388
+ } finally {
8389
+ setIsLoading(false);
8390
+ }
8391
+ };
8392
+ fetchWorkflow();
8393
+ }, [workflowId]);
8394
+ return { runs, isLoading };
8401
8395
  };
8402
8396
 
8403
- const NumberField = ({ inputProps, error, field, id }) => {
8404
- const { key, ...props } = inputProps;
8397
+ const useWorkflow = (workflowId) => {
8398
+ const [workflow, setWorkflow] = useState(null);
8399
+ const [isLoading, setIsLoading] = useState(true);
8400
+ const client = useMastraClient();
8405
8401
  useEffect(() => {
8406
- if (field.default !== void 0) {
8407
- props.onChange({
8408
- target: { value: Number(field.default), name: inputProps.name }
8409
- });
8410
- }
8411
- }, [field.default]);
8412
- return /* @__PURE__ */ jsx(
8413
- Input,
8414
- {
8415
- id,
8416
- type: "number",
8417
- className: error ? "border-destructive" : "",
8418
- ...props,
8419
- defaultValue: field.default !== void 0 ? Number(field.default) : void 0,
8420
- onChange: (e) => {
8421
- const value = e.target.value;
8422
- if (value !== "" && !isNaN(Number(value))) {
8423
- props.onChange({
8424
- target: { value, name: inputProps.name }
8425
- });
8402
+ const fetchWorkflow = async () => {
8403
+ setIsLoading(true);
8404
+ try {
8405
+ if (!workflowId) {
8406
+ setWorkflow(null);
8407
+ setIsLoading(false);
8408
+ return;
8426
8409
  }
8427
- },
8428
- onBlur: (e) => {
8429
- const value = e.target.value;
8430
- if (value !== "" && !isNaN(Number(value))) {
8431
- props.onChange({
8432
- target: { value: Number(value), name: inputProps.name }
8433
- });
8410
+ const res = await client.getWorkflow(workflowId).details();
8411
+ if (!res) {
8412
+ setWorkflow(null);
8413
+ console.error("Error fetching workflow");
8414
+ toast.error("Error fetching workflow");
8415
+ return;
8434
8416
  }
8417
+ setWorkflow(res);
8418
+ } catch (error) {
8419
+ setWorkflow(null);
8420
+ console.error("Error fetching workflow", error);
8421
+ toast.error("Error fetching workflow");
8422
+ } finally {
8423
+ setIsLoading(false);
8435
8424
  }
8436
- }
8437
- );
8425
+ };
8426
+ fetchWorkflow();
8427
+ }, [workflowId]);
8428
+ return { workflow, isLoading };
8438
8429
  };
8439
-
8440
- const Checkbox = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8441
- CheckboxPrimitive.Root,
8442
- {
8443
- ref,
8444
- className: cn(
8445
- "peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
8446
- className
8447
- ),
8448
- ...props,
8449
- children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: cn("flex items-center justify-center text-current"), children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) })
8450
- }
8451
- ));
8452
- Checkbox.displayName = CheckboxPrimitive.Root.displayName;
8453
-
8454
- const BooleanField = ({ field, label, id, inputProps, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
8455
- /* @__PURE__ */ jsx(
8456
- Checkbox,
8457
- {
8458
- id,
8459
- onCheckedChange: (checked) => {
8460
- const event = {
8461
- target: {
8462
- name: inputProps.name,
8463
- value: checked
8464
- }
8465
- };
8466
- inputProps.onChange(event);
8430
+ const useLegacyWorkflow = (workflowId) => {
8431
+ const [legacyWorkflow, setLegacyWorkflow] = useState(null);
8432
+ const [isLoading, setIsLoading] = useState(true);
8433
+ const client = useMastraClient();
8434
+ useEffect(() => {
8435
+ const fetchWorkflow = async () => {
8436
+ setIsLoading(true);
8437
+ try {
8438
+ if (!workflowId) {
8439
+ setLegacyWorkflow(null);
8440
+ setIsLoading(false);
8441
+ return;
8442
+ }
8443
+ const res = await client.getLegacyWorkflow(workflowId).details();
8444
+ if (!res) {
8445
+ setLegacyWorkflow(null);
8446
+ console.error("Error fetching legacy workflow");
8447
+ toast.error("Error fetching legacy workflow");
8448
+ return;
8449
+ }
8450
+ const steps = res.steps;
8451
+ const stepsWithWorkflow = await Promise.all(
8452
+ Object.values(steps)?.map(async (step) => {
8453
+ if (!step.workflowId) return step;
8454
+ const wFlow = await client.getLegacyWorkflow(step.workflowId).details();
8455
+ if (!wFlow) return step;
8456
+ return { ...step, stepGraph: wFlow.stepGraph, stepSubscriberGraph: wFlow.stepSubscriberGraph };
8457
+ })
8458
+ );
8459
+ const _steps = stepsWithWorkflow.reduce((acc, b) => {
8460
+ return { ...acc, [b.id]: b };
8461
+ }, {});
8462
+ setLegacyWorkflow({ ...res, steps: _steps });
8463
+ } catch (error) {
8464
+ setLegacyWorkflow(null);
8465
+ console.error("Error fetching legacy workflow", error);
8466
+ toast.error("Error fetching legacy workflow");
8467
+ } finally {
8468
+ setIsLoading(false);
8469
+ }
8470
+ };
8471
+ fetchWorkflow();
8472
+ }, [workflowId]);
8473
+ return { legacyWorkflow, isLoading };
8474
+ };
8475
+ const useExecuteWorkflow = () => {
8476
+ const client = useMastraClient();
8477
+ const createLegacyWorkflowRun = async ({ workflowId, prevRunId }) => {
8478
+ try {
8479
+ const workflow = client.getLegacyWorkflow(workflowId);
8480
+ const { runId: newRunId } = await workflow.createRun({ runId: prevRunId });
8481
+ return { runId: newRunId };
8482
+ } catch (error) {
8483
+ console.error("Error creating workflow run:", error);
8484
+ throw error;
8485
+ }
8486
+ };
8487
+ const startLegacyWorkflowRun = async ({
8488
+ workflowId,
8489
+ runId,
8490
+ input
8491
+ }) => {
8492
+ try {
8493
+ const workflow = client.getLegacyWorkflow(workflowId);
8494
+ await workflow.start({ runId, triggerData: input || {} });
8495
+ } catch (error) {
8496
+ console.error("Error starting workflow run:", error);
8497
+ throw error;
8498
+ }
8499
+ };
8500
+ return {
8501
+ startLegacyWorkflowRun,
8502
+ createLegacyWorkflowRun
8503
+ };
8504
+ };
8505
+ const useWatchWorkflow = () => {
8506
+ const [isWatchingLegacyWorkflow, setIsWatchingLegacyWorkflow] = useState(false);
8507
+ const [legacyWatchResult, setLegacyWatchResult] = useState(null);
8508
+ const client = useMastraClient();
8509
+ const debouncedSetLegacyWorkflowWatchResult = useDebouncedCallback((record) => {
8510
+ const formattedResults = Object.entries(record.results || {}).reduce(
8511
+ (acc, [key, value]) => {
8512
+ let output = value.status === "success" ? value.output : void 0;
8513
+ if (output) {
8514
+ output = Object.entries(output).reduce(
8515
+ (_acc, [_key, _value]) => {
8516
+ const val = _value;
8517
+ _acc[_key] = val.type?.toLowerCase() === "buffer" ? { type: "Buffer", data: `[...buffered data]` } : val;
8518
+ return _acc;
8519
+ },
8520
+ {}
8521
+ );
8522
+ }
8523
+ acc[key] = { ...value, output };
8524
+ return acc;
8467
8525
  },
8468
- defaultChecked: field.default,
8469
- disabled: inputProps.disabled || inputProps.readOnly
8526
+ {}
8527
+ );
8528
+ const sanitizedRecord = {
8529
+ ...record,
8530
+ sanitizedOutput: record ? JSON.stringify({ ...record, results: formattedResults }, null, 2).slice(0, 5e4) : null
8531
+ };
8532
+ setLegacyWatchResult(sanitizedRecord);
8533
+ }, 100);
8534
+ const watchLegacyWorkflow = async ({ workflowId, runId }) => {
8535
+ try {
8536
+ setIsWatchingLegacyWorkflow(true);
8537
+ const workflow = client.getLegacyWorkflow(workflowId);
8538
+ await workflow.watch({ runId }, (record) => {
8539
+ try {
8540
+ debouncedSetLegacyWorkflowWatchResult(record);
8541
+ } catch (err) {
8542
+ console.error("Error processing workflow record:", err);
8543
+ setLegacyWatchResult({
8544
+ ...record
8545
+ });
8546
+ }
8547
+ });
8548
+ } catch (error) {
8549
+ console.error("Error watching workflow:", error);
8550
+ throw error;
8551
+ } finally {
8552
+ setIsWatchingLegacyWorkflow(false);
8470
8553
  }
8471
- ),
8472
- /* @__PURE__ */ jsxs(Txt, { as: "label", variant: "ui-sm", className: "text-icon3", htmlFor: id, children: [
8473
- label,
8474
- field.required && /* @__PURE__ */ jsx("span", { className: "text-accent2", children: " *" })
8475
- ] })
8476
- ] });
8554
+ };
8555
+ return {
8556
+ watchLegacyWorkflow,
8557
+ isWatchingLegacyWorkflow,
8558
+ legacyWatchResult
8559
+ };
8560
+ };
8561
+ const useResumeWorkflow = () => {
8562
+ const [isResumingLegacyWorkflow, setIsResumingLegacyWorkflow] = useState(false);
8563
+ const client = useMastraClient();
8564
+ const resumeLegacyWorkflow = async ({
8565
+ workflowId,
8566
+ stepId,
8567
+ runId,
8568
+ context
8569
+ }) => {
8570
+ try {
8571
+ setIsResumingLegacyWorkflow(true);
8572
+ const response = await client.getLegacyWorkflow(workflowId).resume({ stepId, runId, context });
8573
+ return response;
8574
+ } catch (error) {
8575
+ console.error("Error resuming workflow:", error);
8576
+ throw error;
8577
+ } finally {
8578
+ setIsResumingLegacyWorkflow(false);
8579
+ }
8580
+ };
8581
+ return {
8582
+ resumeLegacyWorkflow,
8583
+ isResumingLegacyWorkflow
8584
+ };
8585
+ };
8477
8586
 
8478
- function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
8587
+ const LabelMappings = {
8588
+ "routing-step": "Decision making process",
8589
+ "agent-step": "Agent execution",
8590
+ "workflow-step": "Workflow execution"
8591
+ };
8592
+ const StepDropdown = () => {
8593
+ const [isExpanded, setIsExpanded] = useState(false);
8594
+ const { state } = useVNextNetworkChat();
8595
+ const message = useMessage();
8596
+ const id = message?.metadata?.custom?.id;
8597
+ if (!id) return /* @__PURE__ */ jsx("div", { children: "Something is wrong" });
8598
+ const currentState = state[id];
8599
+ const latestStepId = currentState.executionSteps[currentState.executionSteps.length - 1];
8600
+ const hasFinished = latestStepId === "finish";
8601
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8602
+ /* @__PURE__ */ jsxs(Button, { onClick: () => setIsExpanded(!isExpanded), children: [
8603
+ hasFinished ? /* @__PURE__ */ jsxs(Fragment, { children: [
8604
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }) }),
8605
+ "Done"
8606
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
8607
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, { className: "animate-spin" }) }),
8608
+ "Thinking..."
8609
+ ] }),
8610
+ /* @__PURE__ */ jsx(Icon, { className: "ml-2", children: /* @__PURE__ */ jsx(ChevronDown, { className: clsx("transition-transform -rotate-90", isExpanded && "rotate-0") }) })
8611
+ ] }),
8612
+ isExpanded ? /* @__PURE__ */ jsx(Steps, { id }) : null
8613
+ ] });
8614
+ };
8615
+ const Steps = ({ id }) => {
8616
+ const { state } = useVNextNetworkChat();
8617
+ const currentState = state[id];
8618
+ return /* @__PURE__ */ jsx("ol", { className: "flex flex-col gap-px rounded-lg overflow-hidden", children: currentState.executionSteps.filter((stepId) => stepId !== "start").map((stepId, index) => /* @__PURE__ */ jsx(StepEntry, { stepId, step: currentState.steps[stepId], runId: currentState.runId }, index)) });
8619
+ };
8620
+ const StepEntry = ({ stepId, step, runId }) => {
8621
+ const [expanded, setExpanded] = useState(false);
8622
+ const stepResult = step["step-result"];
8623
+ if (stepId === "finish") {
8624
+ return /* @__PURE__ */ jsx("div", { className: "bg-surface4 py-2 px-3 text-icon6 flex items-center gap-4 justify-between", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon6", children: "Process completed" }) });
8625
+ }
8626
+ return /* @__PURE__ */ jsxs("li", { children: [
8627
+ /* @__PURE__ */ jsxs(
8628
+ "button",
8629
+ {
8630
+ className: "bg-surface4 py-2 px-3 text-icon6 flex items-center gap-4 justify-between w-full text-left",
8631
+ onClick: () => setExpanded((s) => !s),
8632
+ children: [
8633
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8634
+ /* @__PURE__ */ jsx(StatusIcon, { status: stepResult ? stepResult?.status : "loading" }),
8635
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon6", children: LabelMappings[stepId] || stepId })
8636
+ ] }),
8637
+ step.metadata?.startTime && /* @__PURE__ */ jsx(StepClock, { step })
8638
+ ]
8639
+ }
8640
+ ),
8641
+ stepId === "routing-step" && expanded && /* @__PURE__ */ jsxs("div", { className: "bg-surface1 p-3 space-y-4", children: [
8642
+ /* @__PURE__ */ jsxs("div", { children: [
8643
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 font-medium", children: "Selection reason:" }),
8644
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon6", children: stepResult?.output?.selectionReason || "N/A" })
8645
+ ] }),
8646
+ /* @__PURE__ */ jsxs("div", { children: [
8647
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 font-medium", children: "Resource ID" }),
8648
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon6", children: stepResult?.output?.resourceId || "N/A" })
8649
+ ] })
8650
+ ] }),
8651
+ stepId === "workflow-step" && stepResult?.output?.resourceId ? /* @__PURE__ */ jsx(
8652
+ WorkflowStepResultDialog,
8653
+ {
8654
+ open: expanded,
8655
+ onOpenChange: setExpanded,
8656
+ workflowId: stepResult?.output?.resourceId,
8657
+ runId
8658
+ }
8659
+ ) : null
8660
+ ] });
8661
+ };
8662
+ const WorkflowStepResultDialog = ({ open, onOpenChange, workflowId, runId }) => {
8663
+ const { runs } = useWorkflowRuns(workflowId);
8664
+ const { workflow, isLoading } = useWorkflow(workflowId);
8665
+ const run = runs?.runs.find((run2) => run2.runId === runId);
8666
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsx(DialogContent, { className: "h-[90vh] w-[90%] max-w-[unset]", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 h-full", children: [
8667
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Workflow details" }),
8668
+ /* @__PURE__ */ jsx(WorkflowRunProvider, { snapshot: typeof run?.snapshot === "object" ? run.snapshot : void 0, children: /* @__PURE__ */ jsx(WorkflowGraph, { workflowId, workflow, isLoading }) })
8669
+ ] }) }) }) });
8670
+ };
8671
+ const StatusIcon = ({ status }) => {
8672
+ if (status === "error") {
8673
+ return /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }) });
8674
+ }
8675
+ if (status === "success") {
8676
+ return /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }) });
8677
+ }
8678
+ return /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, { className: "animate-spin" }) });
8679
+ };
8680
+ const StepClock = ({ step }) => {
8681
+ return /* @__PURE__ */ jsx(Badge$1, { children: /* @__PURE__ */ jsx(Clock, { startedAt: step.metadata.startTime, endedAt: step.metadata?.endTime }) });
8682
+ };
8683
+
8684
+ const NextAssistantMessage = ({
8685
+ ToolFallback: ToolFallbackCustom
8686
+ }) => {
8687
+ const data = useMessage();
8688
+ const isSolelyToolCall = data.content.length === 1 && data.content[0].type === "tool-call";
8689
+ const content = data.content[0];
8690
+ if (!content) {
8691
+ return null;
8692
+ }
8693
+ const textContent = content.text;
8694
+ if (textContent === "start") {
8695
+ return /* @__PURE__ */ jsx(StepDropdown, {});
8696
+ }
8697
+ return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "max-w-full", children: [
8698
+ /* @__PURE__ */ jsx("div", { className: "text-icon6 text-ui-lg leading-ui-lg", children: /* @__PURE__ */ jsx(
8699
+ MessagePrimitive.Content,
8700
+ {
8701
+ components: {
8702
+ Text: MarkdownText,
8703
+ tools: { Fallback: ToolFallbackCustom || ToolFallback$1 }
8704
+ }
8705
+ }
8706
+ ) }),
8707
+ /* @__PURE__ */ jsx("div", { className: "h-6 pt-1", children: !isSolelyToolCall && /* @__PURE__ */ jsx(AssistantActionBar, {}) })
8708
+ ] });
8709
+ };
8710
+ const AssistantActionBar = () => {
8711
+ return /* @__PURE__ */ jsx(
8712
+ ActionBarPrimitive.Root,
8713
+ {
8714
+ hideWhenRunning: true,
8715
+ autohide: "always",
8716
+ autohideFloat: "single-branch",
8717
+ className: "flex gap-1 items-center transition-all",
8718
+ children: /* @__PURE__ */ jsx(ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxs(TooltipIconButton, { tooltip: "Copy", className: "bg-transparent text-icon3 hover:text-icon6", children: [
8719
+ /* @__PURE__ */ jsx(MessagePrimitive.If, { copied: true, children: /* @__PURE__ */ jsx(CheckIcon$1, {}) }),
8720
+ /* @__PURE__ */ jsx(MessagePrimitive.If, { copied: false, children: /* @__PURE__ */ jsx(CopyIcon, {}) })
8721
+ ] }) })
8722
+ }
8723
+ );
8724
+ };
8725
+
8726
+ const NetworkThread = ({ ToolFallback, networkName, hasMemory, showFileSupport }) => {
8727
+ const areaRef = useRef(null);
8728
+ useAutoscroll(areaRef, { enabled: true });
8729
+ const WrappedAssistantMessage = (props) => {
8730
+ return /* @__PURE__ */ jsx(NextAssistantMessage, { ...props, ToolFallback });
8731
+ };
8732
+ return /* @__PURE__ */ jsxs(ThreadWrapper, { children: [
8733
+ /* @__PURE__ */ jsxs(ThreadPrimitive.Viewport, { className: "py-10 overflow-y-auto scroll-smooth h-full", ref: areaRef, autoScroll: false, children: [
8734
+ /* @__PURE__ */ jsxs("div", { children: [
8735
+ /* @__PURE__ */ jsx(ThreadWelcome, { networkName }),
8736
+ /* @__PURE__ */ jsx(
8737
+ ThreadPrimitive.Messages,
8738
+ {
8739
+ components: {
8740
+ UserMessage,
8741
+ EditComposer,
8742
+ AssistantMessage: WrappedAssistantMessage
8743
+ }
8744
+ }
8745
+ )
8746
+ ] }),
8747
+ /* @__PURE__ */ jsx(ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsx("div", {}) })
8748
+ ] }),
8749
+ /* @__PURE__ */ jsx(Composer, { hasMemory, showFileSupport })
8750
+ ] });
8751
+ };
8752
+ const ThreadWrapper = ({ children }) => {
8753
+ const hasAttachments = useHasAttachments();
8754
+ return /* @__PURE__ */ jsx(
8755
+ ThreadPrimitive.Root,
8756
+ {
8757
+ className: clsx(
8758
+ "max-w-[568px] w-full mx-auto px-4",
8759
+ hasAttachments ? "h-[calc(100%-208px)]" : "h-[calc(100%-112px)]"
8760
+ ),
8761
+ children
8762
+ }
8763
+ );
8764
+ };
8765
+ const ThreadWelcome = ({ networkName }) => {
8766
+ const safeNetworkName = networkName ?? "";
8767
+ const words = safeNetworkName.split(" ") ?? [];
8768
+ let initials = "A";
8769
+ if (words.length === 2) {
8770
+ initials = `${words[0][0]}${words[1][0]}`;
8771
+ } else if (safeNetworkName.length > 0) {
8772
+ initials = `${safeNetworkName[0]}`;
8773
+ } else {
8774
+ initials = "A";
8775
+ }
8776
+ return /* @__PURE__ */ jsx(ThreadPrimitive.Empty, { children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-grow flex-col items-center justify-center", children: [
8777
+ /* @__PURE__ */ jsx(Avatar, { children: /* @__PURE__ */ jsx(AvatarFallback, { children: initials }) }),
8778
+ /* @__PURE__ */ jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
8779
+ ] }) });
8780
+ };
8781
+ const Composer = ({ hasMemory, showFileSupport }) => {
8782
+ return /* @__PURE__ */ jsxs("div", { children: [
8783
+ /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
8784
+ /* @__PURE__ */ jsx(ComposerAttachments, {}),
8785
+ /* @__PURE__ */ jsxs("div", { className: "w-full bg-surface3 rounded-lg border-sm border-border1 px-3 py-4 mt-auto h-[100px]", children: [
8786
+ /* @__PURE__ */ jsx(ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(
8787
+ "textarea",
8788
+ {
8789
+ className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none",
8790
+ autoFocus: true,
8791
+ placeholder: "Enter your message...",
8792
+ name: "",
8793
+ id: ""
8794
+ }
8795
+ ) }),
8796
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
8797
+ /* @__PURE__ */ jsx(SpeechInput, {}),
8798
+ /* @__PURE__ */ jsx(ComposerAction, { showFileSupport })
8799
+ ] })
8800
+ ] })
8801
+ ] }),
8802
+ !hasMemory && /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon3 flex items-center gap-2 pt-0.5", children: [
8803
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(InfoIcon, {}) }),
8804
+ "Memory is not enabled. The conversation will not be persisted."
8805
+ ] })
8806
+ ] });
8807
+ };
8808
+ const SpeechInput = () => {
8809
+ const composerRuntime = useComposerRuntime();
8810
+ const { start, stop, isListening, transcript } = useSpeechRecognition();
8811
+ useEffect(() => {
8812
+ if (!transcript) return;
8813
+ composerRuntime.setText(transcript);
8814
+ }, [composerRuntime, transcript]);
8479
8815
  return /* @__PURE__ */ jsx(
8480
- DayPicker,
8816
+ TooltipIconButton,
8481
8817
  {
8482
- showOutsideDays,
8483
- className: cn("p-3", className),
8484
- classNames: {
8485
- months: "flex flex-col space-y-4 sm:space-y-0",
8486
- month: "space-y-4",
8487
- // month_caption: 'flex justify-center pt-1 relative items-center',
8488
- caption_label: "text-sm text-text font-medium",
8489
- nav: "space-x-1 flex items-center",
8490
- nav_button_previous: cn(
8491
- buttonVariants({ variant: "outline" }),
8492
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
8493
- "absolute left-4 top-[56px] z-10"
8494
- ),
8495
- nav_button_next: cn(
8496
- buttonVariants({ variant: "outline" }),
8497
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
8498
- "absolute right-4 top-[56px] z-10"
8499
- ),
8500
- dropdown_month: "w-full border-collapse space-y-1",
8501
- weeknumber: "flex",
8502
- day: cn(
8503
- buttonVariants({ variant: "ghost" }),
8504
- "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
8505
- props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md",
8506
- "h-8 w-8 p-0 hover:bg-lightGray-7/50 font-normal aria-selected:opacity-100"
8507
- ),
8508
- day_range_start: "day-range-start",
8509
- day_range_end: "day-range-end",
8510
- day_selected: "!bg-primary !text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
8511
- day_today: "bg-lightGray-7/50 text-accent-foreground",
8512
- day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
8513
- day_disabled: "text-muted-foreground opacity-50",
8514
- day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
8515
- day_hidden: "invisible",
8516
- ...classNames
8517
- },
8518
- components: {
8519
- // IconDropdown: ({ }) => (
8520
- // <CalendarIcon
8521
- // className={cn('h-4 w-4', {
8522
- // 'rotate-180': orientation === 'up',
8523
- // 'rotate-90': orientation === 'left',
8524
- // '-rotate-90': orientation === 'right',
8525
- // })}
8526
- // />
8527
- // ),
8528
- },
8529
- ...props
8818
+ type: "button",
8819
+ tooltip: isListening ? "Stop dictation" : "Start dictation",
8820
+ variant: "ghost",
8821
+ className: "rounded-full",
8822
+ onClick: () => isListening ? stop() : start(),
8823
+ children: isListening ? /* @__PURE__ */ jsx(CircleStopIcon, {}) : /* @__PURE__ */ jsx(Mic, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" })
8530
8824
  }
8531
8825
  );
8532
- }
8533
- Calendar.displayName = "Calendar";
8826
+ };
8827
+ const ComposerAction = ({ showFileSupport }) => {
8828
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8829
+ showFileSupport && /* @__PURE__ */ jsx(ComposerPrimitive.AddAttachment, { asChild: true, children: /* @__PURE__ */ jsx(TooltipIconButton, { tooltip: "Add attachment", variant: "ghost", className: "rounded-full", children: /* @__PURE__ */ jsx(PlusIcon, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" }) }) }),
8830
+ /* @__PURE__ */ jsx(ThreadPrimitive.If, { running: false, children: /* @__PURE__ */ jsx(ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsx(
8831
+ TooltipIconButton,
8832
+ {
8833
+ tooltip: "Send",
8834
+ variant: "default",
8835
+ className: "rounded-full border-sm border-[#363636] bg-[#292929]",
8836
+ children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-6 w-6 text-[#898989] hover:text-[#fff]" })
8837
+ }
8838
+ ) }) }),
8839
+ /* @__PURE__ */ jsx(ThreadPrimitive.If, { running: true, children: /* @__PURE__ */ jsx(ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsx(TooltipIconButton, { tooltip: "Cancel", variant: "default", children: /* @__PURE__ */ jsx(CircleStopIcon, {}) }) }) })
8840
+ ] });
8841
+ };
8842
+ const EditComposer = () => {
8843
+ return /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
8844
+ /* @__PURE__ */ jsx(ComposerPrimitive.Input, {}),
8845
+ /* @__PURE__ */ jsxs("div", { children: [
8846
+ /* @__PURE__ */ jsx(ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsx(Button$1, { variant: "ghost", children: "Cancel" }) }),
8847
+ /* @__PURE__ */ jsx(ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsx(Button$1, { children: "Send" }) })
8848
+ ] })
8849
+ ] });
8850
+ };
8851
+ const CircleStopIcon = () => {
8852
+ return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", width: "16", height: "16", children: /* @__PURE__ */ jsx("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" }) });
8853
+ };
8534
8854
 
8535
- const Popover = PopoverPrimitive.Root;
8536
- const PopoverTrigger = PopoverPrimitive.Trigger;
8537
- const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
8538
- PopoverPrimitive.Content,
8539
- {
8540
- ref,
8541
- align,
8542
- sideOffset,
8543
- className: cn(
8544
- "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
8545
- className
8546
- ),
8547
- ...props
8855
+ const MessagesContext = createContext({
8856
+ messages: [],
8857
+ setMessages: () => {
8858
+ },
8859
+ appendToLastMessage: () => {
8548
8860
  }
8549
- ) }));
8550
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
8551
-
8552
- const DatePicker = ({
8553
- value,
8554
- setValue,
8555
- children,
8556
- className,
8557
- placeholder,
8558
- ...props
8559
- }) => {
8560
- const [openPopover, setOpenPopover] = React.useState(false);
8561
- return /* @__PURE__ */ jsxs(Popover, { open: openPopover, onOpenChange: setOpenPopover, children: [
8562
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: children ? children : /* @__PURE__ */ jsx(
8563
- DefaultButton,
8861
+ });
8862
+ const MessagesProvider = ({ children }) => {
8863
+ const [messages, setMessages] = useState([]);
8864
+ const appendToLastMessage = (partial) => setMessages((msgs) => {
8865
+ const lastMsg = msgs[msgs.length - 1];
8866
+ const content = typeof lastMsg.content === "string" ? lastMsg.content : (lastMsg.content?.[0]).text;
8867
+ return [
8868
+ ...msgs.slice(0, -1),
8564
8869
  {
8565
- value,
8566
- placeholder,
8567
- className,
8568
- "data-testid": "datepicker-button"
8870
+ ...lastMsg,
8871
+ content: [{ type: "text", text: content + partial }]
8569
8872
  }
8570
- ) }),
8571
- /* @__PURE__ */ jsx(
8572
- PopoverContent,
8573
- {
8574
- className: "backdrop-blur-4xl w-auto p-0 bg-[#171717]",
8575
- align: "start",
8576
- "data-testid": "datepicker-calendar",
8577
- children: /* @__PURE__ */ jsx(
8578
- DatePickerOnly,
8579
- {
8580
- value,
8581
- setValue: (v) => setValue(v ? /* @__PURE__ */ new Date(`${v}z`) : null),
8582
- clearable: props.clearable,
8583
- setOpenPopover,
8584
- ...props
8873
+ ];
8874
+ });
8875
+ return /* @__PURE__ */ jsx(MessagesContext.Provider, { value: { messages, setMessages, appendToLastMessage }, children });
8876
+ };
8877
+ const useMessages = () => useContext(MessagesContext);
8878
+
8879
+ const formatJSON = async (code) => {
8880
+ const formatted = await prettier.format(code, {
8881
+ semi: false,
8882
+ parser: "json",
8883
+ printWidth: 80,
8884
+ tabWidth: 2,
8885
+ plugins: [prettierPluginBabel, prettierPluginEstree]
8886
+ });
8887
+ return formatted;
8888
+ };
8889
+
8890
+ const convertMessage = (message) => {
8891
+ return message;
8892
+ };
8893
+ function VNextMastraNetworkRuntimeProvider({
8894
+ children,
8895
+ networkId,
8896
+ memory,
8897
+ threadId,
8898
+ refreshThreadList,
8899
+ initialMessages
8900
+ }) {
8901
+ const runIdRef = useRef(void 0);
8902
+ const [isRunning, setIsRunning] = useState(false);
8903
+ const { messages, setMessages, appendToLastMessage } = useMessages();
8904
+ const [currentThreadId, setCurrentThreadId] = useState(threadId);
8905
+ const { handleStep, state, setState } = useVNextNetworkChat();
8906
+ const id = runIdRef.current;
8907
+ const currentState = id ? state[id] : void 0;
8908
+ useEffect(() => {
8909
+ if (!currentState) return;
8910
+ const hasFinished = Boolean(currentState?.steps?.["finish"]);
8911
+ if (!hasFinished) return;
8912
+ const workflowStep = currentState?.steps?.["workflow-step"];
8913
+ if (!workflowStep) return;
8914
+ const workflowStepResult = workflowStep?.["step-result"];
8915
+ if (!workflowStepResult) return;
8916
+ const workflowStepResultOutput = workflowStepResult?.output;
8917
+ if (!workflowStepResultOutput) return;
8918
+ const run = async () => {
8919
+ const parsedResult = JSON.parse(workflowStepResult?.output?.result ?? "{}") ?? {};
8920
+ const runResult = parsedResult?.runResult ?? {};
8921
+ const formatted = await formatJSON(JSON.stringify(runResult));
8922
+ setMessages((msgs) => [
8923
+ ...msgs,
8924
+ { role: "assistant", content: [{ type: "text", text: `\`\`\`json
8925
+ ${formatted}\`\`\`` }] }
8926
+ ]);
8927
+ };
8928
+ run();
8929
+ }, [currentState]);
8930
+ useEffect(() => {
8931
+ const hasNewInitialMessages = initialMessages && initialMessages?.length > messages?.length;
8932
+ if (messages.length === 0 || currentThreadId !== threadId || hasNewInitialMessages && currentThreadId === threadId) {
8933
+ const run = async (result, messageId) => {
8934
+ const formatted = await formatJSON(result);
8935
+ const finalResponse = `\`\`\`json
8936
+ ${formatted}\`\`\``;
8937
+ setMessages((currentConversation) => {
8938
+ return currentConversation.map((message) => {
8939
+ if (message.metadata?.custom?.id === messageId) {
8940
+ return { ...message, content: [{ type: "text", text: finalResponse }] };
8941
+ }
8942
+ return message;
8943
+ });
8944
+ });
8945
+ };
8946
+ if (initialMessages && threadId && memory) {
8947
+ for (const message of initialMessages) {
8948
+ if (message.role === "user") {
8949
+ setMessages((currentConversation) => [...currentConversation, message]);
8585
8950
  }
8586
- )
8951
+ if (message.role === "assistant") {
8952
+ const id2 = v4();
8953
+ const formattedMessageId = v4();
8954
+ const parts = message.parts;
8955
+ const routingStep = parts?.[2];
8956
+ const responseStep = parts?.[3];
8957
+ const routingDecision = JSON.parse(routingStep?.text ?? "{}");
8958
+ const resourceStepId = routingDecision?.resourceType === "agent" ? "agent-step" : "workflow-step";
8959
+ let finalResponse = responseStep?.text ?? "";
8960
+ let runId = "";
8961
+ let runResult = {};
8962
+ if (resourceStepId === "workflow-step") {
8963
+ const parsedResult = JSON.parse(responseStep?.text ?? "{}") ?? {};
8964
+ runResult = parsedResult?.runResult ?? {};
8965
+ runId = parsedResult?.runId ?? "";
8966
+ }
8967
+ setState((currentState2) => {
8968
+ return {
8969
+ ...currentState2,
8970
+ [id2]: {
8971
+ executionSteps: ["start", "routing-step", resourceStepId, "finish"],
8972
+ runId,
8973
+ steps: {
8974
+ start: {},
8975
+ "routing-step": {
8976
+ "step-result": {
8977
+ output: routingDecision,
8978
+ status: "success"
8979
+ }
8980
+ },
8981
+ [resourceStepId]: {
8982
+ "step-result": {
8983
+ output: {
8984
+ resourceId: routingDecision?.resourceId
8985
+ },
8986
+ status: "success"
8987
+ }
8988
+ },
8989
+ finish: {}
8990
+ }
8991
+ }
8992
+ };
8993
+ });
8994
+ setMessages((currentConversation) => {
8995
+ return [
8996
+ ...currentConversation,
8997
+ {
8998
+ role: "assistant",
8999
+ metadata: {
9000
+ custom: {
9001
+ id: id2
9002
+ }
9003
+ },
9004
+ content: [
9005
+ {
9006
+ type: "text",
9007
+ text: "start"
9008
+ }
9009
+ ]
9010
+ },
9011
+ {
9012
+ role: "assistant",
9013
+ content: [{ type: "text", text: resourceStepId === "workflow-step" ? "" : finalResponse }],
9014
+ metadata: {
9015
+ custom: {
9016
+ id: formattedMessageId
9017
+ }
9018
+ }
9019
+ }
9020
+ ];
9021
+ });
9022
+ if (resourceStepId === "workflow-step") {
9023
+ run(JSON.stringify(runResult), formattedMessageId);
9024
+ }
9025
+ }
9026
+ }
9027
+ setCurrentThreadId(threadId);
8587
9028
  }
8588
- )
9029
+ }
9030
+ }, [initialMessages, threadId, memory, messages]);
9031
+ const mastra = useMastraClient();
9032
+ const network = mastra.getVNextNetwork(networkId);
9033
+ const onNew = async (message) => {
9034
+ runIdRef.current = void 0;
9035
+ if (message.content[0]?.type !== "text") throw new Error("Only text messages are supported");
9036
+ const input = message.content[0].text;
9037
+ setMessages((currentConversation) => [...currentConversation, { role: "user", content: input }]);
9038
+ setIsRunning(true);
9039
+ try {
9040
+ await network.stream(
9041
+ {
9042
+ message: input,
9043
+ threadId,
9044
+ resourceId: networkId
9045
+ },
9046
+ (record) => {
9047
+ if (runIdRef.current) {
9048
+ if (record.type === "tool-call-delta") {
9049
+ appendToLastMessage(record.argsTextDelta);
9050
+ } else if (record.type === "tool-call-streaming-start") {
9051
+ setMessages((msgs) => [...msgs, { role: "assistant", content: [{ type: "text", text: "" }] }]);
9052
+ setTimeout(() => {
9053
+ refreshThreadList?.();
9054
+ }, 500);
9055
+ return;
9056
+ } else {
9057
+ handleStep(runIdRef.current, record);
9058
+ }
9059
+ } else if (record.type === "start") {
9060
+ const id2 = v4();
9061
+ runIdRef.current = id2;
9062
+ setMessages((currentConversation) => {
9063
+ return [
9064
+ ...currentConversation,
9065
+ {
9066
+ role: "assistant",
9067
+ metadata: {
9068
+ custom: {
9069
+ id: id2
9070
+ }
9071
+ },
9072
+ content: [
9073
+ {
9074
+ type: "text",
9075
+ text: "start"
9076
+ }
9077
+ ]
9078
+ }
9079
+ ];
9080
+ });
9081
+ }
9082
+ setTimeout(() => {
9083
+ refreshThreadList?.();
9084
+ }, 500);
9085
+ }
9086
+ );
9087
+ setIsRunning(false);
9088
+ } catch (error) {
9089
+ console.error("Error occurred in VNextMastraNetworkRuntimeProvider", error);
9090
+ setIsRunning(false);
9091
+ }
9092
+ };
9093
+ const runtime = useExternalStoreRuntime({
9094
+ isRunning,
9095
+ messages,
9096
+ convertMessage,
9097
+ onNew
9098
+ });
9099
+ return /* @__PURE__ */ jsxs(AssistantRuntimeProvider, { runtime, children: [
9100
+ " ",
9101
+ children,
9102
+ " "
8589
9103
  ] });
8590
- };
8591
- const DatePickerOnly = ({
8592
- value,
8593
- setValue,
8594
- setOpenPopover,
8595
- clearable,
8596
- placeholder,
8597
- className,
8598
- ...props
9104
+ }
9105
+
9106
+ const VNextNetworkChat = ({
9107
+ networkId,
9108
+ networkName,
9109
+ threadId,
9110
+ initialMessages,
9111
+ memory,
9112
+ refreshThreadList
8599
9113
  }) => {
8600
- const [inputValue, setInputValue] = React.useState(value ? format(value, "PP") : "");
8601
- const [selected, setSelected] = React.useState(value ? new Date(value) : void 0);
8602
- const debouncedDateUpdate = useDebouncedCallback((date) => {
8603
- if (isValid(date)) {
8604
- setSelected(date);
8605
- setValue?.(date);
8606
- setOpenPopover?.(false);
8607
- }
8608
- }, 2e3);
8609
- const handleInputChange = (e) => {
8610
- setInputValue(e.currentTarget.value);
8611
- const date = new Date(e.target.value);
8612
- debouncedDateUpdate(date);
9114
+ return /* @__PURE__ */ jsx(MessagesProvider, { children: /* @__PURE__ */ jsx(VNextNetworkChatProvider, { networkId, children: /* @__PURE__ */ jsx(
9115
+ VNextMastraNetworkRuntimeProvider,
9116
+ {
9117
+ networkId,
9118
+ initialMessages: initialMessages ?? [],
9119
+ threadId,
9120
+ memory,
9121
+ refreshThreadList,
9122
+ children: /* @__PURE__ */ jsx("div", { className: "h-full pb-4", children: /* @__PURE__ */ jsx(NetworkThread, { hasMemory: memory, networkName }) })
9123
+ },
9124
+ threadId
9125
+ ) }, threadId) }, threadId);
9126
+ };
9127
+
9128
+ function WorkflowTraces({ traces, error, runId, stepName }) {
9129
+ return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(WorkflowTracesInner, { traces, error, runId, stepName }) });
9130
+ }
9131
+ function WorkflowTracesInner({ traces, error, runId, stepName }) {
9132
+ const hasRunRef = useRef(false);
9133
+ const [sidebarWidth, setSidebarWidth] = useState(100);
9134
+ const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
9135
+ useEffect(() => {
9136
+ if (hasRunRef.current) return;
9137
+ if (!runId || !stepName) return;
9138
+ const matchingTrace = traces.find((trace) => trace.runId === runId);
9139
+ if (!matchingTrace) return;
9140
+ const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
9141
+ if (!matchingSpan) return;
9142
+ setTrace(matchingTrace.trace);
9143
+ setSpan(matchingSpan);
9144
+ setIsOpen(true);
9145
+ hasRunRef.current = true;
9146
+ }, [runId, traces, setTrace]);
9147
+ return /* @__PURE__ */ jsxs("main", { className: "h-full relative overflow-hidden flex", children: [
9148
+ /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsx(TracesTable, { traces, error }) }),
9149
+ open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
9150
+ ] });
9151
+ }
9152
+
9153
+ function LegacyWorkflowNestedGraph({
9154
+ stepGraph,
9155
+ stepSubscriberGraph,
9156
+ open
9157
+ }) {
9158
+ const { nodes: initialNodes, edges: initialEdges } = contructLegacyNodesAndEdges({
9159
+ stepGraph,
9160
+ stepSubscriberGraph
9161
+ });
9162
+ const [isMounted, setIsMounted] = useState(false);
9163
+ const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9164
+ const [edges] = useEdgesState(initialEdges);
9165
+ const nodeTypes = {
9166
+ "default-node": WorkflowDefaultNode,
9167
+ "condition-node": WorkflowConditionNode,
9168
+ "after-node": WorkflowAfterNode,
9169
+ "loop-result-node": WorkflowLoopResultNode
8613
9170
  };
8614
- const handleDaySelect = (date) => {
8615
- setSelected(date);
8616
- setValue?.(date);
8617
- setOpenPopover?.(false);
8618
- if (date) {
8619
- setInputValue(format(date, "PP"));
8620
- } else {
8621
- setInputValue("");
9171
+ useEffect(() => {
9172
+ if (open) {
9173
+ setTimeout(() => {
9174
+ setIsMounted(true);
9175
+ }, 500);
8622
9176
  }
8623
- };
8624
- const handleMonthSelect = (date) => {
8625
- setSelected(date);
8626
- if (date) {
8627
- setInputValue(format(date, "PP"));
8628
- } else {
8629
- setInputValue("");
9177
+ }, [open]);
9178
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative", children: isMounted ? /* @__PURE__ */ jsxs(
9179
+ ReactFlow,
9180
+ {
9181
+ nodes,
9182
+ edges,
9183
+ fitView: true,
9184
+ fitViewOptions: { maxZoom: 0.85 },
9185
+ nodeTypes,
9186
+ onNodesChange,
9187
+ children: [
9188
+ /* @__PURE__ */ jsx(Controls, {}),
9189
+ /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9190
+ /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
9191
+ ]
8630
9192
  }
9193
+ ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
9194
+ }
9195
+
9196
+ const LegacyWorkflowNestedGraphContext = createContext(
9197
+ {}
9198
+ );
9199
+ function LegacyWorkflowNestedGraphProvider({ children }) {
9200
+ const [stepGraph, setStepGraph] = useState(null);
9201
+ const [stepSubscriberGraph, setStepSubscriberGraph] = useState(null);
9202
+ const [openDialog, setOpenDialog] = useState(false);
9203
+ const [label, setLabel] = useState("");
9204
+ const closeNestedGraph = () => {
9205
+ setOpenDialog(false);
9206
+ setStepGraph(null);
9207
+ setStepSubscriberGraph(null);
9208
+ setLabel("");
9209
+ };
9210
+ const showNestedGraph = ({
9211
+ label: label2,
9212
+ stepGraph: stepGraph2,
9213
+ stepSubscriberGraph: stepSubscriberGraph2
9214
+ }) => {
9215
+ setLabel(label2);
9216
+ setStepGraph(stepGraph2);
9217
+ setStepSubscriberGraph(stepSubscriberGraph2);
9218
+ setOpenDialog(true);
8631
9219
  };
8632
9220
  return /* @__PURE__ */ jsxs(
8633
- "div",
9221
+ LegacyWorkflowNestedGraphContext.Provider,
8634
9222
  {
8635
- "aria-label": "Choose date",
8636
- className: "relative mt-2 flex flex-col gap-2",
8637
- onKeyDown: (e) => {
8638
- e.stopPropagation();
8639
- if (e.key === "Escape") {
8640
- setOpenPopover?.(false);
8641
- }
9223
+ value: {
9224
+ showNestedGraph,
9225
+ closeNestedGraph
8642
9226
  },
8643
9227
  children: [
8644
- /* @__PURE__ */ jsx("div", { className: "w-full px-3", children: /* @__PURE__ */ jsx(
8645
- Input,
8646
- {
8647
- type: "text",
8648
- value: inputValue,
8649
- onChange: handleInputChange,
8650
- placeholder,
8651
- className
8652
- }
8653
- ) }),
8654
- /* @__PURE__ */ jsx(
8655
- Calendar,
8656
- {
8657
- mode: "single",
8658
- month: selected,
8659
- selected,
8660
- onMonthChange: handleMonthSelect,
8661
- onSelect: handleDaySelect,
8662
- ...props
8663
- }
8664
- ),
8665
- /* @__PURE__ */ jsx("div", { className: "px-3 pb-2", children: clearable && /* @__PURE__ */ jsx(
8666
- Button$1,
8667
- {
8668
- variant: "outline",
8669
- tabIndex: 0,
8670
- className: "w-full !opacity-50 duration-200 hover:!opacity-100",
8671
- onClick: () => {
8672
- setValue(null);
8673
- setSelected(void 0);
8674
- setInputValue("");
8675
- setOpenPopover?.(false);
8676
- },
8677
- children: "Clear"
8678
- }
8679
- ) })
9228
+ children,
9229
+ /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[40rem] h-[40rem] bg-[#121212] p-[0.5rem]", children: [
9230
+ /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
9231
+ /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9232
+ /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
9233
+ label,
9234
+ " workflow"
9235
+ ] })
9236
+ ] }),
9237
+ /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
9238
+ LegacyWorkflowNestedGraph,
9239
+ {
9240
+ stepGraph,
9241
+ open: openDialog,
9242
+ stepSubscriberGraph
9243
+ }
9244
+ ) })
9245
+ ] }) }) })
8680
9246
  ]
8681
9247
  }
8682
9248
  );
9249
+ }
9250
+
9251
+ function LegacyWorkflowNestedNode({ data }) {
9252
+ const { label, withoutTopHandle, withoutBottomHandle, stepGraph, stepSubscriberGraph } = data;
9253
+ const { showNestedGraph } = useContext(LegacyWorkflowNestedGraphContext);
9254
+ return /* @__PURE__ */ jsxs("div", { className: cn("bg-[rgba(29,29,29,0.5)] rounded-md h-full overflow-scroll w-[274px]"), children: [
9255
+ !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
9256
+ /* @__PURE__ */ jsx("div", { className: "p-2 cursor-pointer", onClick: () => showNestedGraph({ label, stepGraph, stepSubscriberGraph }), children: /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-1.5 rounded-sm p-2 cursor-pointer", children: [
9257
+ /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9258
+ /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
9259
+ ] }) }),
9260
+ !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
9261
+ ] });
9262
+ }
9263
+
9264
+ function LegacyWorkflowGraphInner({ workflow }) {
9265
+ const { nodes: initialNodes, edges: initialEdges } = contructLegacyNodesAndEdges({
9266
+ stepGraph: workflow.serializedStepGraph || workflow.stepGraph,
9267
+ stepSubscriberGraph: workflow.serializedStepSubscriberGraph || workflow.stepSubscriberGraph,
9268
+ steps: workflow.steps
9269
+ });
9270
+ const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9271
+ const [edges] = useEdgesState(initialEdges);
9272
+ const nodeTypes = {
9273
+ "default-node": WorkflowDefaultNode,
9274
+ "condition-node": WorkflowConditionNode,
9275
+ "after-node": WorkflowAfterNode,
9276
+ "loop-result-node": WorkflowLoopResultNode,
9277
+ "nested-node": LegacyWorkflowNestedNode
9278
+ };
9279
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxs(
9280
+ ReactFlow,
9281
+ {
9282
+ nodes,
9283
+ edges,
9284
+ nodeTypes,
9285
+ onNodesChange,
9286
+ fitView: true,
9287
+ fitViewOptions: {
9288
+ maxZoom: 0.85
9289
+ },
9290
+ children: [
9291
+ /* @__PURE__ */ jsx(Controls, {}),
9292
+ /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9293
+ /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
9294
+ ]
9295
+ }
9296
+ ) });
9297
+ }
9298
+
9299
+ function LegacyWorkflowGraph({ workflowId }) {
9300
+ const { legacyWorkflow, isLoading } = useLegacyWorkflow(workflowId);
9301
+ if (isLoading) {
9302
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[600px]" }) });
9303
+ }
9304
+ if (!legacyWorkflow) {
9305
+ return /* @__PURE__ */ jsx("div", { className: "grid h-full place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
9306
+ /* @__PURE__ */ jsx(AlertCircleIcon, {}),
9307
+ /* @__PURE__ */ jsxs("div", { children: [
9308
+ "We couldn't find ",
9309
+ lodashTitleCase(workflowId),
9310
+ " workflow."
9311
+ ] })
9312
+ ] }) });
9313
+ }
9314
+ return /* @__PURE__ */ jsx(LegacyWorkflowNestedGraphProvider, { children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(LegacyWorkflowGraphInner, { workflow: legacyWorkflow }) }) });
9315
+ }
9316
+
9317
+ const Form = React__default.forwardRef(({ children, ...props }, ref) => {
9318
+ return /* @__PURE__ */ jsx("form", { ref, className: "space-y-4", ...props, children });
9319
+ });
9320
+
9321
+ const DISABLED_LABELS = ["boolean", "object", "array"];
9322
+ const FieldWrapper = ({ label, children, id, field, error }) => {
9323
+ const isDisabled = DISABLED_LABELS.includes(field.type);
9324
+ return /* @__PURE__ */ jsxs("div", { className: "pb-4 last:pb-0", children: [
9325
+ !isDisabled && /* @__PURE__ */ jsxs(Txt, { as: "label", variant: "ui-sm", className: "text-icon3 pb-1 block", htmlFor: id, children: [
9326
+ label,
9327
+ field.required && /* @__PURE__ */ jsx("span", { className: "text-accent2", children: " *" })
9328
+ ] }),
9329
+ children,
9330
+ field.fieldConfig?.description && /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: "text-icon6", children: field.fieldConfig.description }),
9331
+ error && /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: "text-accent2", children: error })
9332
+ ] });
8683
9333
  };
8684
- const DefaultButton = React.forwardRef(
8685
- ({ value, placeholder, className, ...props }, ref) => {
8686
- return /* @__PURE__ */ jsxs(
8687
- Button$1,
8688
- {
8689
- ref,
8690
- variant: "outline",
8691
- className: cn(
8692
- "bg-neutral-825 border-neutral-775 w-full justify-start whitespace-nowrap rounded-md border px-2 py-0 text-left flex items-center gap-1",
8693
- className
8694
- ),
8695
- ...props,
8696
- children: [
8697
- /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
8698
- value ? /* @__PURE__ */ jsx("span", { className: "text-white", children: format(value, "PPP") }) : /* @__PURE__ */ jsx("span", { className: "text-gray", children: placeholder ?? "Pick a date" })
8699
- ]
9334
+
9335
+ const alertVariants = cva(
9336
+ "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
9337
+ {
9338
+ variants: {
9339
+ variant: {
9340
+ default: "bg-background text-foreground",
9341
+ destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"
8700
9342
  }
8701
- );
9343
+ },
9344
+ defaultVariants: {
9345
+ variant: "default"
9346
+ }
8702
9347
  }
8703
9348
  );
8704
- DefaultButton.displayName = "DefaultButton";
9349
+ const Alert = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
9350
+ Alert.displayName = "Alert";
9351
+ const AlertTitle = React.forwardRef(
9352
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 font-medium leading-none tracking-tight", className), ...props })
9353
+ );
9354
+ AlertTitle.displayName = "AlertTitle";
9355
+ const AlertDescription = React.forwardRef(
9356
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props })
9357
+ );
9358
+ AlertDescription.displayName = "AlertDescription";
8705
9359
 
8706
- const DateField = ({ inputProps, field, error, id }) => {
9360
+ const ErrorMessage = ({ error }) => /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
9361
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
9362
+ /* @__PURE__ */ jsx(AlertTitle, { children: error })
9363
+ ] });
9364
+
9365
+ const SubmitButton = ({ children }) => /* @__PURE__ */ jsx(Button$1, { type: "submit", children });
9366
+
9367
+ const StringField = ({ inputProps, error, field, id }) => {
9368
+ const { key, ...props } = inputProps;
9369
+ return /* @__PURE__ */ jsx(Input, { id, className: error ? "border-destructive" : "", ...props, defaultValue: field.default });
9370
+ };
9371
+
9372
+ const NumberField = ({ inputProps, error, field, id }) => {
8707
9373
  const { key, ...props } = inputProps;
8708
- const [value, setValue] = useState(null);
8709
9374
  useEffect(() => {
8710
- if (field.default) {
8711
- const date = new Date(field.default);
8712
- if (isValid(date)) {
8713
- setValue(date);
8714
- }
9375
+ if (field.default !== void 0) {
9376
+ props.onChange({
9377
+ target: { value: Number(field.default), name: inputProps.name }
9378
+ });
8715
9379
  }
8716
- }, [field]);
9380
+ }, [field.default]);
8717
9381
  return /* @__PURE__ */ jsx(
8718
- DatePicker,
9382
+ Input,
8719
9383
  {
8720
9384
  id,
9385
+ type: "number",
8721
9386
  className: error ? "border-destructive" : "",
8722
- value,
8723
- setValue: (date) => {
8724
- const newDate = date ? new Date(date).toISOString() : date;
8725
- if (newDate) {
9387
+ ...props,
9388
+ defaultValue: field.default !== void 0 ? Number(field.default) : void 0,
9389
+ onChange: (e) => {
9390
+ const value = e.target.value;
9391
+ if (value !== "" && !isNaN(Number(value))) {
8726
9392
  props.onChange({
8727
- target: { value: newDate?.toString(), name: inputProps.name }
9393
+ target: { value, name: inputProps.name }
8728
9394
  });
8729
- setValue(new Date(newDate));
8730
9395
  }
8731
9396
  },
8732
- clearable: true
9397
+ onBlur: (e) => {
9398
+ const value = e.target.value;
9399
+ if (value !== "" && !isNaN(Number(value))) {
9400
+ props.onChange({
9401
+ target: { value: Number(value), name: inputProps.name }
9402
+ });
9403
+ }
9404
+ }
8733
9405
  }
8734
9406
  );
8735
9407
  };
8736
9408
 
8737
- const Select = SelectPrimitive.Root;
8738
- const SelectValue = SelectPrimitive.Value;
8739
- const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
8740
- SelectPrimitive.Trigger,
8741
- {
8742
- ref,
8743
- className: cn(
8744
- "flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
8745
- className
8746
- ),
8747
- ...props,
8748
- children: [
8749
- children,
8750
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
8751
- ]
8752
- }
8753
- ));
8754
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
8755
- const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
8756
- SelectPrimitive.Content,
8757
- {
8758
- ref,
8759
- className: cn(
8760
- "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
8761
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
8762
- className
8763
- ),
8764
- position,
8765
- ...props,
8766
- children: /* @__PURE__ */ jsx(
8767
- SelectPrimitive.Viewport,
8768
- {
8769
- className: cn(
8770
- "p-1",
8771
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
8772
- ),
8773
- children
8774
- }
8775
- )
8776
- }
8777
- ) }));
8778
- SelectContent.displayName = SelectPrimitive.Content.displayName;
8779
- const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
8780
- SelectPrimitive.Item,
9409
+ const Checkbox = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9410
+ CheckboxPrimitive.Root,
8781
9411
  {
8782
9412
  ref,
8783
9413
  className: cn(
8784
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-mastra-el-5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
9414
+ "peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
8785
9415
  className
8786
9416
  ),
8787
9417
  ...props,
8788
- children: [
8789
- /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
8790
- /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
8791
- ]
9418
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: cn("flex items-center justify-center text-current"), children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) })
8792
9419
  }
8793
9420
  ));
8794
- SelectItem.displayName = SelectPrimitive.Item.displayName;
9421
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
8795
9422
 
8796
- const SelectField = ({ field, inputProps, error, id, value }) => {
8797
- const { key, ...props } = inputProps;
8798
- return /* @__PURE__ */ jsxs(
8799
- Select,
9423
+ const BooleanField = ({ field, label, id, inputProps, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
9424
+ /* @__PURE__ */ jsx(
9425
+ Checkbox,
8800
9426
  {
8801
- ...props,
8802
- onValueChange: (value2) => {
8803
- const syntheticEvent = {
9427
+ id,
9428
+ onCheckedChange: (checked) => {
9429
+ const event = {
8804
9430
  target: {
8805
- value: value2,
8806
- name: inputProps.name
9431
+ name: inputProps.name,
9432
+ value: checked
8807
9433
  }
8808
9434
  };
8809
- props.onChange(syntheticEvent);
9435
+ inputProps.onChange(event);
9436
+ },
9437
+ defaultChecked: field.default,
9438
+ disabled: inputProps.disabled || inputProps.readOnly
9439
+ }
9440
+ ),
9441
+ /* @__PURE__ */ jsxs(Txt, { as: "label", variant: "ui-sm", className: "text-icon3", htmlFor: id, children: [
9442
+ label,
9443
+ field.required && /* @__PURE__ */ jsx("span", { className: "text-accent2", children: " *" })
9444
+ ] })
9445
+ ] });
9446
+
9447
+ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
9448
+ return /* @__PURE__ */ jsx(
9449
+ DayPicker,
9450
+ {
9451
+ showOutsideDays,
9452
+ className: cn("p-3", className),
9453
+ classNames: {
9454
+ months: "flex flex-col space-y-4 sm:space-y-0",
9455
+ month: "space-y-4",
9456
+ // month_caption: 'flex justify-center pt-1 relative items-center',
9457
+ caption_label: "text-sm text-text font-medium",
9458
+ nav: "space-x-1 flex items-center",
9459
+ nav_button_previous: cn(
9460
+ buttonVariants({ variant: "outline" }),
9461
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
9462
+ "absolute left-4 top-[56px] z-10"
9463
+ ),
9464
+ nav_button_next: cn(
9465
+ buttonVariants({ variant: "outline" }),
9466
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
9467
+ "absolute right-4 top-[56px] z-10"
9468
+ ),
9469
+ dropdown_month: "w-full border-collapse space-y-1",
9470
+ weeknumber: "flex",
9471
+ day: cn(
9472
+ buttonVariants({ variant: "ghost" }),
9473
+ "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
9474
+ props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md",
9475
+ "h-8 w-8 p-0 hover:bg-lightGray-7/50 font-normal aria-selected:opacity-100"
9476
+ ),
9477
+ day_range_start: "day-range-start",
9478
+ day_range_end: "day-range-end",
9479
+ day_selected: "!bg-primary !text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
9480
+ day_today: "bg-lightGray-7/50 text-accent-foreground",
9481
+ day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
9482
+ day_disabled: "text-muted-foreground opacity-50",
9483
+ day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
9484
+ day_hidden: "invisible",
9485
+ ...classNames
9486
+ },
9487
+ components: {
9488
+ // IconDropdown: ({ }) => (
9489
+ // <CalendarIcon
9490
+ // className={cn('h-4 w-4', {
9491
+ // 'rotate-180': orientation === 'up',
9492
+ // 'rotate-90': orientation === 'left',
9493
+ // '-rotate-90': orientation === 'right',
9494
+ // })}
9495
+ // />
9496
+ // ),
8810
9497
  },
8811
- defaultValue: field.default,
8812
- children: [
8813
- /* @__PURE__ */ jsx(SelectTrigger, { id, className: error ? "border-destructive" : "", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select an option" }) }),
8814
- /* @__PURE__ */ jsx(SelectContent, { children: (field.options || []).map(([key2, label]) => /* @__PURE__ */ jsx(SelectItem, { value: key2, children: label }, key2)) })
8815
- ]
9498
+ ...props
8816
9499
  }
8817
9500
  );
8818
- };
9501
+ }
9502
+ Calendar.displayName = "Calendar";
8819
9503
 
8820
- const ObjectWrapper = ({ label, children }) => {
8821
- const hasLabel = label !== "​" && label !== "";
8822
- return /* @__PURE__ */ jsxs("div", { className: "", children: [
8823
- hasLabel && /* @__PURE__ */ jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 flex items-center gap-1 pb-2", children: [
8824
- /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(Braces, {}) }),
8825
- label
8826
- ] }),
8827
- /* @__PURE__ */ jsx(
8828
- "div",
9504
+ const Popover = PopoverPrimitive.Root;
9505
+ const PopoverTrigger = PopoverPrimitive.Trigger;
9506
+ const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
9507
+ PopoverPrimitive.Content,
9508
+ {
9509
+ ref,
9510
+ align,
9511
+ sideOffset,
9512
+ className: cn(
9513
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
9514
+ className
9515
+ ),
9516
+ ...props
9517
+ }
9518
+ ) }));
9519
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
9520
+
9521
+ const DatePicker = ({
9522
+ value,
9523
+ setValue,
9524
+ children,
9525
+ className,
9526
+ placeholder,
9527
+ ...props
9528
+ }) => {
9529
+ const [openPopover, setOpenPopover] = React.useState(false);
9530
+ return /* @__PURE__ */ jsxs(Popover, { open: openPopover, onOpenChange: setOpenPopover, children: [
9531
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: children ? children : /* @__PURE__ */ jsx(
9532
+ DefaultButton,
8829
9533
  {
8830
- className: hasLabel ? "flex flex-col gap-1 [&>*]:border-dashed [&>*]:border-l [&>*]:border-l-border1 [&>*]:pl-4" : "",
8831
- children
9534
+ value,
9535
+ placeholder,
9536
+ className,
9537
+ "data-testid": "datepicker-button"
8832
9538
  }
8833
- )
8834
- ] });
8835
- };
8836
-
8837
- const ArrayWrapper = ({ label, children, onAddItem }) => {
8838
- return /* @__PURE__ */ jsxs("div", { children: [
8839
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
8840
- /* @__PURE__ */ jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 pb-2 flex items-center gap-1", children: [
8841
- /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(Brackets, {}) }),
8842
- label
8843
- ] }),
8844
- /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { delayDuration: 0, children: [
8845
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
8846
- "button",
9539
+ ) }),
9540
+ /* @__PURE__ */ jsx(
9541
+ PopoverContent,
9542
+ {
9543
+ className: "backdrop-blur-4xl w-auto p-0 bg-[#171717]",
9544
+ align: "start",
9545
+ "data-testid": "datepicker-calendar",
9546
+ children: /* @__PURE__ */ jsx(
9547
+ DatePickerOnly,
8847
9548
  {
8848
- onClick: onAddItem,
8849
- type: "button",
8850
- className: "text-icon3 bg-surface3 rounded-md p-1 hover:bg-surface4 hover:text-icon6 h-icon-sm w-icon-sm",
8851
- children: /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(PlusIcon, {}) })
9549
+ value,
9550
+ setValue: (v) => setValue(v ? /* @__PURE__ */ new Date(`${v}z`) : null),
9551
+ clearable: props.clearable,
9552
+ setOpenPopover,
9553
+ ...props
8852
9554
  }
8853
- ) }),
8854
- /* @__PURE__ */ jsx(TooltipContent, { children: "Add item" })
8855
- ] }) })
8856
- ] }),
8857
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children })
8858
- ] });
8859
- };
8860
-
8861
- const ArrayElementWrapper = ({ children, onRemove }) => {
8862
- return /* @__PURE__ */ jsxs("div", { className: "pl-4 border-l border-border1", children: [
8863
- children,
8864
- /* @__PURE__ */ jsxs(Button, { onClick: onRemove, type: "button", children: [
8865
- /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(TrashIcon, {}) }),
8866
- "Delete"
8867
- ] })
9555
+ )
9556
+ }
9557
+ )
8868
9558
  ] });
8869
9559
  };
8870
-
8871
- const RecordField = ({ inputProps, field, error, id }) => {
8872
- const { key, onChange, ...props } = inputProps;
8873
- const [pairs, setPairs] = React.useState(
8874
- () => Object.entries(field.default || {}).map(([key2, val]) => ({
8875
- id: key2 || v4(),
8876
- key: key2,
8877
- value: val
8878
- }))
8879
- );
8880
- React.useEffect(() => {
8881
- if (pairs.length === 0) {
8882
- setPairs([{ id: v4(), key: "", value: "" }]);
9560
+ const DatePickerOnly = ({
9561
+ value,
9562
+ setValue,
9563
+ setOpenPopover,
9564
+ clearable,
9565
+ placeholder,
9566
+ className,
9567
+ ...props
9568
+ }) => {
9569
+ const [inputValue, setInputValue] = React.useState(value ? format(value, "PP") : "");
9570
+ const [selected, setSelected] = React.useState(value ? new Date(value) : void 0);
9571
+ const debouncedDateUpdate = useDebouncedCallback((date) => {
9572
+ if (isValid(date)) {
9573
+ setSelected(date);
9574
+ setValue?.(date);
9575
+ setOpenPopover?.(false);
8883
9576
  }
8884
- }, [pairs]);
8885
- const updateForm = React.useCallback(
8886
- (newPairs) => {
8887
- const newValue = newPairs.reduce(
8888
- (acc, pair) => {
8889
- if (pair.key) {
8890
- acc[pair.key] = pair.value;
8891
- }
8892
- return acc;
8893
- },
8894
- {}
8895
- );
8896
- onChange?.({
8897
- target: { value: newValue, name: inputProps.name }
8898
- });
8899
- },
8900
- [onChange, inputProps.name]
8901
- );
8902
- const handleChange = (id2, field2, newValue) => {
8903
- setPairs((prev) => prev.map((pair) => pair.id === id2 ? { ...pair, [field2]: newValue } : pair));
8904
- };
8905
- const handleBlur = () => {
8906
- updateForm(pairs);
9577
+ }, 2e3);
9578
+ const handleInputChange = (e) => {
9579
+ setInputValue(e.currentTarget.value);
9580
+ const date = new Date(e.target.value);
9581
+ debouncedDateUpdate(date);
8907
9582
  };
8908
- const addPair = () => {
8909
- const newPairs = [...pairs, { id: v4(), key: "", value: "" }];
8910
- setPairs(newPairs);
8911
- updateForm(newPairs);
9583
+ const handleDaySelect = (date) => {
9584
+ setSelected(date);
9585
+ setValue?.(date);
9586
+ setOpenPopover?.(false);
9587
+ if (date) {
9588
+ setInputValue(format(date, "PP"));
9589
+ } else {
9590
+ setInputValue("");
9591
+ }
8912
9592
  };
8913
- const removePair = (id2) => {
8914
- const newPairs = pairs.filter((p) => p.id !== id2);
8915
- if (newPairs.length === 0) {
8916
- newPairs.push({ id: v4(), key: "", value: "" });
9593
+ const handleMonthSelect = (date) => {
9594
+ setSelected(date);
9595
+ if (date) {
9596
+ setInputValue(format(date, "PP"));
9597
+ } else {
9598
+ setInputValue("");
8917
9599
  }
8918
- setPairs(newPairs);
8919
- updateForm(newPairs);
8920
9600
  };
8921
- return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
8922
- pairs.map((pair) => /* @__PURE__ */ jsxs("div", { className: "relative space-y-2 rounded-lg border p-4", children: [
8923
- /* @__PURE__ */ jsx(
8924
- Button$1,
8925
- {
8926
- type: "button",
8927
- variant: "ghost",
8928
- size: "icon",
8929
- className: "absolute right-2 top-2",
8930
- onClick: () => removePair(pair.id),
8931
- children: /* @__PURE__ */ jsx(TrashIcon, { className: "h-4 w-4" })
9601
+ return /* @__PURE__ */ jsxs(
9602
+ "div",
9603
+ {
9604
+ "aria-label": "Choose date",
9605
+ className: "relative mt-2 flex flex-col gap-2",
9606
+ onKeyDown: (e) => {
9607
+ e.stopPropagation();
9608
+ if (e.key === "Escape") {
9609
+ setOpenPopover?.(false);
8932
9610
  }
8933
- ),
8934
- /* @__PURE__ */ jsxs("div", { className: "space-y-2 pt-6", children: [
8935
- /* @__PURE__ */ jsx(
9611
+ },
9612
+ children: [
9613
+ /* @__PURE__ */ jsx("div", { className: "w-full px-3", children: /* @__PURE__ */ jsx(
8936
9614
  Input,
8937
9615
  {
8938
- placeholder: "Key",
8939
- value: pair.key,
8940
- onChange: (e) => handleChange(pair.id, "key", e.target.value),
8941
- onBlur: handleBlur
9616
+ type: "text",
9617
+ value: inputValue,
9618
+ onChange: handleInputChange,
9619
+ placeholder,
9620
+ className
8942
9621
  }
8943
- ),
9622
+ ) }),
8944
9623
  /* @__PURE__ */ jsx(
8945
- Input,
9624
+ Calendar,
8946
9625
  {
8947
- placeholder: "Value",
8948
- value: pair.value,
8949
- onChange: (e) => handleChange(pair.id, "value", e.target.value),
8950
- onBlur: handleBlur
9626
+ mode: "single",
9627
+ month: selected,
9628
+ selected,
9629
+ onMonthChange: handleMonthSelect,
9630
+ onSelect: handleDaySelect,
9631
+ ...props
8951
9632
  }
8952
- )
8953
- ] })
8954
- ] }, pair.id)),
8955
- /* @__PURE__ */ jsxs(Button$1, { type: "button", variant: "outline", size: "sm", className: "w-full", onClick: addPair, children: [
8956
- /* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4" }),
8957
- "Add Key-Value Pair"
8958
- ] })
8959
- ] });
9633
+ ),
9634
+ /* @__PURE__ */ jsx("div", { className: "px-3 pb-2", children: clearable && /* @__PURE__ */ jsx(
9635
+ Button$1,
9636
+ {
9637
+ variant: "outline",
9638
+ tabIndex: 0,
9639
+ className: "w-full !opacity-50 duration-200 hover:!opacity-100",
9640
+ onClick: () => {
9641
+ setValue(null);
9642
+ setSelected(void 0);
9643
+ setInputValue("");
9644
+ setOpenPopover?.(false);
9645
+ },
9646
+ children: "Clear"
9647
+ }
9648
+ ) })
9649
+ ]
9650
+ }
9651
+ );
8960
9652
  };
9653
+ const DefaultButton = React.forwardRef(
9654
+ ({ value, placeholder, className, ...props }, ref) => {
9655
+ return /* @__PURE__ */ jsxs(
9656
+ Button$1,
9657
+ {
9658
+ ref,
9659
+ variant: "outline",
9660
+ className: cn(
9661
+ "bg-neutral-825 border-neutral-775 w-full justify-start whitespace-nowrap rounded-md border px-2 py-0 text-left flex items-center gap-1",
9662
+ className
9663
+ ),
9664
+ ...props,
9665
+ children: [
9666
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
9667
+ value ? /* @__PURE__ */ jsx("span", { className: "text-white", children: format(value, "PPP") }) : /* @__PURE__ */ jsx("span", { className: "text-gray", children: placeholder ?? "Pick a date" })
9668
+ ]
9669
+ }
9670
+ );
9671
+ }
9672
+ );
9673
+ DefaultButton.displayName = "DefaultButton";
8961
9674
 
8962
- const ShadcnUIComponents = {
8963
- Form,
8964
- FieldWrapper,
8965
- ErrorMessage,
8966
- SubmitButton,
8967
- ObjectWrapper,
8968
- ArrayWrapper,
8969
- ArrayElementWrapper
8970
- };
8971
- function AutoForm({
8972
- uiComponents,
8973
- formComponents,
8974
- readOnly,
8975
- ...props
8976
- }) {
9675
+ const DateField = ({ inputProps, field, error, id }) => {
9676
+ const { key, ...props } = inputProps;
9677
+ const [value, setValue] = useState(null);
9678
+ useEffect(() => {
9679
+ if (field.default) {
9680
+ const date = new Date(field.default);
9681
+ if (isValid(date)) {
9682
+ setValue(date);
9683
+ }
9684
+ }
9685
+ }, [field]);
8977
9686
  return /* @__PURE__ */ jsx(
8978
- AutoForm$1,
9687
+ DatePicker,
8979
9688
  {
8980
- ...props,
8981
- uiComponents: { ...ShadcnUIComponents, ...uiComponents },
8982
- formComponents: {
8983
- string: (props2) => /* @__PURE__ */ jsx(StringField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8984
- number: (props2) => /* @__PURE__ */ jsx(NumberField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8985
- boolean: (props2) => /* @__PURE__ */ jsx(BooleanField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8986
- date: (props2) => /* @__PURE__ */ jsx(DateField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8987
- select: (props2) => /* @__PURE__ */ jsx(SelectField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8988
- record: (props2) => /* @__PURE__ */ jsx(RecordField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
8989
- ...formComponents
8990
- }
9689
+ id,
9690
+ className: error ? "border-destructive" : "",
9691
+ value,
9692
+ setValue: (date) => {
9693
+ const newDate = date ? new Date(date).toISOString() : date;
9694
+ if (newDate) {
9695
+ props.onChange({
9696
+ target: { value: newDate?.toString(), name: inputProps.name }
9697
+ });
9698
+ setValue(new Date(newDate));
9699
+ }
9700
+ },
9701
+ clearable: true
8991
9702
  }
8992
9703
  );
8993
- }
8994
-
8995
- buildZodFieldConfig();
8996
-
8997
- function inferFieldType(schema, fieldConfig) {
8998
- if (fieldConfig?.fieldType) {
8999
- return fieldConfig.fieldType;
9000
- }
9001
- if (schema instanceof z.ZodObject) return "object";
9002
- if (schema instanceof z.ZodNumber) return "number";
9003
- if (schema instanceof z.ZodBoolean) return "boolean";
9004
- if (schema instanceof z.ZodDate || schema?.isDatetime || schema?.isDate) return "date";
9005
- if (schema instanceof z.ZodString) return "string";
9006
- if (schema instanceof z.ZodEnum) return "select";
9007
- if (schema instanceof z.ZodNativeEnum) return "select";
9008
- if (schema instanceof z.ZodArray) return "array";
9009
- if (schema instanceof z.ZodRecord) return "record";
9010
- return "string";
9011
- }
9012
-
9013
- function parseField(key, schema) {
9014
- const baseSchema = getBaseSchema(schema);
9015
- const fieldConfig = getFieldConfigInZodStack(schema);
9016
- const type = inferFieldType(baseSchema, fieldConfig);
9017
- const defaultValue = getDefaultValueInZodStack(schema);
9018
- const options = baseSchema._def?.values;
9019
- let optionValues = [];
9020
- if (options) {
9021
- if (!Array.isArray(options)) {
9022
- optionValues = Object.entries(options);
9023
- } else {
9024
- optionValues = options.map((value) => [value, value]);
9025
- }
9026
- }
9027
- let subSchema = [];
9028
- if (baseSchema instanceof z.ZodObject) {
9029
- subSchema = Object.entries(baseSchema.shape).map(([key2, field]) => parseField(key2, field));
9030
- }
9031
- if (baseSchema instanceof z.ZodArray) {
9032
- subSchema = [parseField("0", baseSchema._def.type)];
9033
- }
9034
- return {
9035
- key,
9036
- type,
9037
- required: !schema.isOptional(),
9038
- default: defaultValue,
9039
- description: baseSchema.description,
9040
- fieldConfig,
9041
- options: optionValues,
9042
- schema: subSchema
9043
- };
9044
- }
9045
- function getBaseSchema(schema) {
9046
- if ("innerType" in schema._def) {
9047
- return getBaseSchema(schema._def.innerType);
9048
- }
9049
- if ("schema" in schema._def) {
9050
- return getBaseSchema(schema._def.schema);
9051
- }
9052
- return schema;
9053
- }
9054
- function parseSchema(schema) {
9055
- const objectSchema = schema instanceof z.ZodEffects ? schema.innerType() : schema;
9056
- const shape = objectSchema.shape;
9057
- const fields = Object.entries(shape).map(([key, field]) => parseField(key, field));
9058
- return { fields };
9059
- }
9060
- class CustomZodProvider extends ZodProvider {
9061
- _schema;
9062
- constructor(schema) {
9063
- super(schema);
9064
- this._schema = schema;
9065
- }
9066
- parseSchema() {
9067
- return parseSchema(this._schema);
9068
- }
9069
- }
9070
-
9071
- const labelVariants = cva("text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
9072
- const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
9073
- Label.displayName = LabelPrimitive.Root.displayName;
9704
+ };
9074
9705
 
9075
- function isEmptyZodObject(schema) {
9076
- if (schema instanceof ZodObject) {
9077
- return Object.keys(schema.shape).length === 0;
9706
+ const Select = SelectPrimitive.Root;
9707
+ const SelectValue = SelectPrimitive.Value;
9708
+ const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
9709
+ SelectPrimitive.Trigger,
9710
+ {
9711
+ ref,
9712
+ className: cn(
9713
+ "flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
9714
+ className
9715
+ ),
9716
+ ...props,
9717
+ children: [
9718
+ children,
9719
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
9720
+ ]
9078
9721
  }
9079
- return false;
9080
- }
9081
- function DynamicForm({
9082
- schema,
9083
- onSubmit,
9084
- defaultValues,
9085
- isSubmitLoading,
9086
- submitButtonLabel,
9087
- className,
9088
- readOnly
9089
- }) {
9090
- const isNotZodObject = !(schema instanceof ZodObject);
9091
- if (!schema) {
9092
- console.error("no form schema found");
9093
- return null;
9722
+ ));
9723
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
9724
+ const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
9725
+ SelectPrimitive.Content,
9726
+ {
9727
+ ref,
9728
+ className: cn(
9729
+ "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
9730
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
9731
+ className
9732
+ ),
9733
+ position,
9734
+ ...props,
9735
+ children: /* @__PURE__ */ jsx(
9736
+ SelectPrimitive.Viewport,
9737
+ {
9738
+ className: cn(
9739
+ "p-1",
9740
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
9741
+ ),
9742
+ children
9743
+ }
9744
+ )
9094
9745
  }
9095
- const normalizedSchema = (schema2) => {
9096
- if (isEmptyZodObject(schema2)) {
9097
- return z$1.object({});
9098
- }
9099
- if (isNotZodObject) {
9100
- return z$1.object({
9101
- "​": schema2
9102
- });
9103
- }
9104
- return schema2;
9105
- };
9106
- const schemaProvider = new CustomZodProvider(normalizedSchema(schema));
9107
- const formProps = {
9108
- schema: schemaProvider,
9109
- onSubmit: async (values) => {
9110
- await onSubmit?.(isNotZodObject ? values["​"] || {} : values);
9111
- },
9112
- defaultValues: isNotZodObject ? defaultValues ? { "​": defaultValues } : void 0 : defaultValues,
9113
- formProps: {
9114
- className: ""
9115
- },
9116
- uiComponents: {
9117
- SubmitButton: ({ children }) => onSubmit ? /* @__PURE__ */ jsx(Button, { variant: "light", className: "w-full", size: "lg", disabled: isSubmitLoading, children: isSubmitLoading ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : submitButtonLabel || children }) : null
9118
- },
9119
- formComponents: {
9120
- Label: ({ value }) => /* @__PURE__ */ jsx(Label, { className: "text-sm font-normal", children: value })
9121
- },
9122
- withSubmit: true
9123
- };
9124
- return /* @__PURE__ */ jsx(AutoForm, { ...formProps, readOnly });
9125
- }
9746
+ ) }));
9747
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
9748
+ const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
9749
+ SelectPrimitive.Item,
9750
+ {
9751
+ ref,
9752
+ className: cn(
9753
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-mastra-el-5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
9754
+ className
9755
+ ),
9756
+ ...props,
9757
+ children: [
9758
+ /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
9759
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
9760
+ ]
9761
+ }
9762
+ ));
9763
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
9126
9764
 
9127
- function resolveSerializedZodOutput(obj) {
9128
- return Function("z", `"use strict";return (${obj});`)(z);
9129
- }
9765
+ const SelectField = ({ field, inputProps, error, id, value }) => {
9766
+ const { key, ...props } = inputProps;
9767
+ return /* @__PURE__ */ jsxs(
9768
+ Select,
9769
+ {
9770
+ ...props,
9771
+ onValueChange: (value2) => {
9772
+ const syntheticEvent = {
9773
+ target: {
9774
+ value: value2,
9775
+ name: inputProps.name
9776
+ }
9777
+ };
9778
+ props.onChange(syntheticEvent);
9779
+ },
9780
+ defaultValue: field.default,
9781
+ children: [
9782
+ /* @__PURE__ */ jsx(SelectTrigger, { id, className: error ? "border-destructive" : "", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select an option" }) }),
9783
+ /* @__PURE__ */ jsx(SelectContent, { children: (field.options || []).map(([key2, label]) => /* @__PURE__ */ jsx(SelectItem, { value: key2, children: label }, key2)) })
9784
+ ]
9785
+ }
9786
+ );
9787
+ };
9130
9788
 
9131
- function CodeBlockDemo({
9132
- code = "",
9133
- language = "ts",
9134
- filename,
9135
- className
9136
- }) {
9137
- return /* @__PURE__ */ jsxs(CodeBlock$1, { code, language, theme: themes.oneDark, children: [
9138
- 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,
9789
+ const ObjectWrapper = ({ label, children }) => {
9790
+ const hasLabel = label !== "" && label !== "";
9791
+ return /* @__PURE__ */ jsxs("div", { className: "", children: [
9792
+ hasLabel && /* @__PURE__ */ jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 flex items-center gap-1 pb-2", children: [
9793
+ /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(Braces, {}) }),
9794
+ label
9795
+ ] }),
9139
9796
  /* @__PURE__ */ jsx(
9140
- CodeBlock$1.Code,
9797
+ "div",
9141
9798
  {
9142
- className: cn("bg-transparent h-full p-6 rounded-xl whitespace-pre-wrap", filename ? "pt-10" : "", className),
9143
- children: /* @__PURE__ */ jsx("div", { className: "table-row", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
9144
- /* @__PURE__ */ jsx(CodeBlock$1.LineNumber, { className: "table-cell pr-4 text-sm text-right select-none text-gray-500/50" }),
9145
- /* @__PURE__ */ jsx(CodeBlock$1.LineContent, { className: "flex", children: /* @__PURE__ */ jsx(CodeBlock$1.Token, { className: "font-mono text-sm mastra-token" }) })
9146
- ] }) })
9799
+ className: hasLabel ? "flex flex-col gap-1 [&>*]:border-dashed [&>*]:border-l [&>*]:border-l-border1 [&>*]:pl-4" : "",
9800
+ children
9147
9801
  }
9148
9802
  )
9149
9803
  ] });
9150
- }
9804
+ };
9151
9805
 
9152
- const WorkflowCard = ({ header, children, footer }) => {
9153
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface4", children: [
9154
- /* @__PURE__ */ jsx("div", { className: "py-1 px-2 flex items-center gap-3", children: header }),
9155
- children && /* @__PURE__ */ jsx("div", { className: "border-t-sm border-border1", children }),
9156
- footer && /* @__PURE__ */ jsx("div", { className: "py-1 px-2 border-t-sm border-border1", children: footer })
9806
+ const ArrayWrapper = ({ label, children, onAddItem }) => {
9807
+ return /* @__PURE__ */ jsxs("div", { children: [
9808
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
9809
+ /* @__PURE__ */ jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 pb-2 flex items-center gap-1", children: [
9810
+ /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(Brackets, {}) }),
9811
+ label
9812
+ ] }),
9813
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { delayDuration: 0, children: [
9814
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
9815
+ "button",
9816
+ {
9817
+ onClick: onAddItem,
9818
+ type: "button",
9819
+ className: "text-icon3 bg-surface3 rounded-md p-1 hover:bg-surface4 hover:text-icon6 h-icon-sm w-icon-sm",
9820
+ children: /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(PlusIcon, {}) })
9821
+ }
9822
+ ) }),
9823
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Add item" })
9824
+ ] }) })
9825
+ ] }),
9826
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children })
9157
9827
  ] });
9158
9828
  };
9159
9829
 
9160
- const LegacyWorkflowStatus = ({ stepId, pathStatus, path }) => {
9161
- const status = pathStatus === "completed" ? "Completed" : stepId === path ? pathStatus.charAt(0).toUpperCase() + pathStatus.slice(1) : pathStatus === "executing" ? "Executing" : "Completed";
9162
- return /* @__PURE__ */ jsx(
9163
- WorkflowCard,
9164
- {
9165
- header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
9166
- /* @__PURE__ */ jsxs(Icon, { children: [
9167
- status === "Completed" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
9168
- status === "Failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
9169
- status === "Executing" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon3 animate-spin" })
9170
- ] }),
9171
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-lg", className: "text-icon6 font-medium", children: path })
9172
- ] })
9173
- }
9174
- );
9830
+ const ArrayElementWrapper = ({ children, onRemove }) => {
9831
+ return /* @__PURE__ */ jsxs("div", { className: "pl-4 border-l border-border1", children: [
9832
+ children,
9833
+ /* @__PURE__ */ jsxs(Button, { onClick: onRemove, type: "button", children: [
9834
+ /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(TrashIcon, {}) }),
9835
+ "Delete"
9836
+ ] })
9837
+ ] });
9175
9838
  };
9176
9839
 
9177
- const WorkflowResult = ({ jsonResult, sanitizedJsonResult }) => {
9178
- const { handleCopy } = useCopyToClipboard({ text: jsonResult });
9179
- const [expanded, setExpanded] = useState(false);
9180
- return /* @__PURE__ */ jsx(
9181
- WorkflowCard,
9182
- {
9183
- header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-between w-full", children: [
9184
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 flex items-center gap-3 font-medium", children: [
9185
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(DeploymentIcon, {}) }),
9186
- "Workflow Execution (JSON)"
9187
- ] }),
9188
- /* @__PURE__ */ jsxs(Tooltip, { children: [
9189
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
9190
- "button",
9191
- {
9192
- className: "p-2 rounded-lg hover:bg-surface5 transition-colors duration-150 ease-in-out text-icon3 hover:text-icon6",
9193
- onClick: () => handleCopy(),
9194
- children: /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(CopyIcon, {}) })
9195
- }
9196
- ) }),
9197
- /* @__PURE__ */ jsx(TooltipContent, { children: "Copy result" })
9198
- ] })
9199
- ] }),
9200
- footer: /* @__PURE__ */ jsx(
9201
- "button",
9202
- {
9203
- className: "w-full h-full text-center text-icon2 hover:text-icon6 text-ui-md",
9204
- onClick: () => setExpanded((s) => !s),
9205
- children: expanded ? "collapse" : "expand"
9206
- }
9207
- ),
9208
- children: expanded ? /* @__PURE__ */ jsx(CodeBlockDemo, { className: "w-full overflow-x-auto", code: sanitizedJsonResult || jsonResult, language: "json" }) : null
9209
- }
9840
+ const RecordField = ({ inputProps, field, error, id }) => {
9841
+ const { key, onChange, ...props } = inputProps;
9842
+ const [pairs, setPairs] = React.useState(
9843
+ () => Object.entries(field.default || {}).map(([key2, val]) => ({
9844
+ id: key2 || v4(),
9845
+ key: key2,
9846
+ value: val
9847
+ }))
9210
9848
  );
9211
- };
9212
-
9213
- function LegacyWorkflowTrigger({
9214
- workflowId,
9215
- setRunId
9216
- }) {
9217
- const { legacyResult: result, setLegacyResult: setResult, payload, setPayload } = useContext(WorkflowRunContext);
9218
- const { isLoading, legacyWorkflow: workflow } = useLegacyWorkflow(workflowId);
9219
- const { createLegacyWorkflowRun: createWorkflowRun, startLegacyWorkflowRun: startWorkflowRun } = useExecuteWorkflow();
9220
- const {
9221
- watchLegacyWorkflow: watchWorkflow,
9222
- legacyWatchResult: watchResult,
9223
- isWatchingLegacyWorkflow: isWatchingWorkflow
9224
- } = useWatchWorkflow();
9225
- const { resumeLegacyWorkflow: resumeWorkflow, isResumingLegacyWorkflow: isResumingWorkflow } = useResumeWorkflow();
9226
- const [suspendedSteps, setSuspendedSteps] = useState([]);
9227
- const [isRunning, setIsRunning] = useState(false);
9228
- const triggerSchema = workflow?.triggerSchema;
9229
- const handleExecuteWorkflow = async (data) => {
9230
- try {
9231
- if (!workflow) return;
9232
- setIsRunning(true);
9233
- setResult(null);
9234
- const { runId } = await createWorkflowRun({ workflowId });
9235
- setRunId?.(runId);
9236
- watchWorkflow({ workflowId, runId });
9237
- startWorkflowRun({ workflowId, runId, input: data });
9238
- } catch (err) {
9239
- setIsRunning(false);
9240
- toast.error("Error executing workflow");
9241
- }
9242
- };
9243
- const handleResumeWorkflow = async (step) => {
9244
- if (!workflow) return;
9245
- const { stepId, runId: prevRunId, context } = step;
9246
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
9247
- watchWorkflow({ workflowId, runId });
9248
- await resumeWorkflow({
9249
- stepId,
9250
- runId,
9251
- context,
9252
- workflowId
9253
- });
9254
- };
9255
- const watchResultToUse = result ?? watchResult;
9256
- const workflowActivePaths = watchResultToUse?.activePaths ?? {};
9257
- useEffect(() => {
9258
- setIsRunning(isWatchingWorkflow);
9259
- }, [isWatchingWorkflow]);
9260
- useEffect(() => {
9261
- if (!watchResultToUse?.activePaths || !result?.runId) return;
9262
- const suspended = Object.entries(watchResultToUse.activePaths).filter(([_, { status }]) => status === "suspended").map(([stepId, { suspendPayload }]) => ({
9263
- stepId,
9264
- runId: result.runId,
9265
- suspendPayload
9266
- }));
9267
- setSuspendedSteps(suspended);
9268
- }, [watchResultToUse, result]);
9269
- useEffect(() => {
9270
- if (watchResult) {
9271
- setResult(watchResult);
9849
+ React.useEffect(() => {
9850
+ if (pairs.length === 0) {
9851
+ setPairs([{ id: v4(), key: "", value: "" }]);
9272
9852
  }
9273
- }, [watchResult]);
9274
- if (isLoading) {
9275
- return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
9276
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }),
9277
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10" })
9278
- ] }) });
9279
- }
9280
- if (!workflow) return null;
9281
- const isSuspendedSteps = suspendedSteps.length > 0;
9282
- const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
9283
- const { sanitizedOutput, ...restResult } = result ?? {};
9284
- const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
9285
- return /* @__PURE__ */ jsx("div", { className: "h-full px-5 pt-3 pb-12", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
9286
- isResumingWorkflow && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
9287
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
9288
- /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
9289
- ] }),
9290
- !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
9291
- DynamicForm,
9292
- {
9293
- schema: zodInputSchema,
9294
- defaultValues: payload,
9295
- isSubmitLoading: isWatchingWorkflow,
9296
- submitButtonLabel: "Run",
9297
- onSubmit: (data) => {
9298
- setPayload(data);
9299
- handleExecuteWorkflow(data);
9853
+ }, [pairs]);
9854
+ const updateForm = React.useCallback(
9855
+ (newPairs) => {
9856
+ const newValue = newPairs.reduce(
9857
+ (acc, pair) => {
9858
+ if (pair.key) {
9859
+ acc[pair.key] = pair.value;
9860
+ }
9861
+ return acc;
9862
+ },
9863
+ {}
9864
+ );
9865
+ onChange?.({
9866
+ target: { value: newValue, name: inputProps.name }
9867
+ });
9868
+ },
9869
+ [onChange, inputProps.name]
9870
+ );
9871
+ const handleChange = (id2, field2, newValue) => {
9872
+ setPairs((prev) => prev.map((pair) => pair.id === id2 ? { ...pair, [field2]: newValue } : pair));
9873
+ };
9874
+ const handleBlur = () => {
9875
+ updateForm(pairs);
9876
+ };
9877
+ const addPair = () => {
9878
+ const newPairs = [...pairs, { id: v4(), key: "", value: "" }];
9879
+ setPairs(newPairs);
9880
+ updateForm(newPairs);
9881
+ };
9882
+ const removePair = (id2) => {
9883
+ const newPairs = pairs.filter((p) => p.id !== id2);
9884
+ if (newPairs.length === 0) {
9885
+ newPairs.push({ id: v4(), key: "", value: "" });
9886
+ }
9887
+ setPairs(newPairs);
9888
+ updateForm(newPairs);
9889
+ };
9890
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
9891
+ pairs.map((pair) => /* @__PURE__ */ jsxs("div", { className: "relative space-y-2 rounded-lg border p-4", children: [
9892
+ /* @__PURE__ */ jsx(
9893
+ Button$1,
9894
+ {
9895
+ type: "button",
9896
+ variant: "ghost",
9897
+ size: "icon",
9898
+ className: "absolute right-2 top-2",
9899
+ onClick: () => removePair(pair.id),
9900
+ children: /* @__PURE__ */ jsx(TrashIcon, { className: "h-4 w-4" })
9300
9901
  }
9301
- }
9302
- ) : /* @__PURE__ */ jsx(
9303
- Button,
9304
- {
9305
- className: "w-full",
9306
- variant: "light",
9307
- disabled: isRunning,
9308
- onClick: () => handleExecuteWorkflow(null),
9309
- children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
9310
- }
9311
- ) }),
9312
- isSuspendedSteps && suspendedSteps?.map((step) => {
9313
- const stepDefinition = workflow.steps[step.stepId];
9314
- const stepSchema = stepDefinition?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.inputSchema))) : z.record(z.string(), z.any());
9315
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
9316
- /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
9317
- step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
9318
- CodeBlockDemo,
9902
+ ),
9903
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 pt-6", children: [
9904
+ /* @__PURE__ */ jsx(
9905
+ Input,
9319
9906
  {
9320
- className: "w-full overflow-x-auto p-2",
9321
- code: JSON.stringify(step.suspendPayload, null, 2),
9322
- language: "json"
9907
+ placeholder: "Key",
9908
+ value: pair.key,
9909
+ onChange: (e) => handleChange(pair.id, "key", e.target.value),
9910
+ onBlur: handleBlur
9323
9911
  }
9324
- ) }),
9912
+ ),
9325
9913
  /* @__PURE__ */ jsx(
9326
- DynamicForm,
9914
+ Input,
9327
9915
  {
9328
- schema: stepSchema,
9329
- isSubmitLoading: isResumingWorkflow,
9330
- submitButtonLabel: "Resume",
9331
- onSubmit: (data) => {
9332
- handleResumeWorkflow({
9333
- stepId: step.stepId,
9334
- runId: step.runId,
9335
- suspendPayload: step.suspendPayload,
9336
- context: data
9337
- });
9338
- }
9916
+ placeholder: "Value",
9917
+ value: pair.value,
9918
+ onChange: (e) => handleChange(pair.id, "value", e.target.value),
9919
+ onBlur: handleBlur
9339
9920
  }
9340
9921
  )
9341
- ] });
9342
- }),
9343
- hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
9344
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
9345
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: Object.entries(workflowActivePaths)?.map(([stepId, { status: pathStatus, stepPath }]) => {
9346
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: stepPath?.map((path, idx) => {
9347
- return /* @__PURE__ */ jsx(LegacyWorkflowStatus, { stepId, pathStatus, path }, idx);
9348
- }) }, stepId);
9349
- }) })
9350
- ] }),
9351
- result && /* @__PURE__ */ jsxs(Fragment, { children: [
9352
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
9353
- /* @__PURE__ */ jsx(WorkflowResult, { sanitizedJsonResult: sanitizedOutput, jsonResult: JSON.stringify(restResult, null, 2) })
9922
+ ] })
9923
+ ] }, pair.id)),
9924
+ /* @__PURE__ */ jsxs(Button$1, { type: "button", variant: "outline", size: "sm", className: "w-full", onClick: addPair, children: [
9925
+ /* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4" }),
9926
+ "Add Key-Value Pair"
9354
9927
  ] })
9355
- ] }) });
9356
- }
9357
-
9358
- const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
9359
- SliderPrimitive.Root,
9360
- {
9361
- ref,
9362
- className: cn("relative flex w-full touch-none select-none items-center", className),
9363
- ...props,
9364
- children: [
9365
- /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
9366
- /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
9367
- ]
9368
- }
9369
- ));
9370
- Slider.displayName = SliderPrimitive.Root.displayName;
9371
-
9372
- const ZoomSlider = forwardRef(({ className, ...props }) => {
9373
- const { zoom } = useViewport();
9374
- const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
9375
- return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
9376
- /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
9377
- /* @__PURE__ */ jsx(
9378
- Slider,
9379
- {
9380
- className: "w-[140px]",
9381
- value: [zoom],
9382
- min: 0.01,
9383
- max: 1,
9384
- step: 0.01,
9385
- onValueChange: (values) => {
9386
- zoomTo(values[0]);
9387
- }
9388
- }
9389
- ),
9390
- /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
9391
- /* @__PURE__ */ jsxs(Button$1, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
9392
- (100 * zoom).toFixed(0),
9393
- "%"
9394
- ] }),
9395
- /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
9396
9928
  ] });
9397
- });
9398
- ZoomSlider.displayName = "ZoomSlider";
9929
+ };
9399
9930
 
9400
- function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
9401
- const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
9402
- stepGraph
9403
- });
9404
- const [isMounted, setIsMounted] = useState(false);
9405
- const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9406
- const [edges] = useEdgesState(initialEdges);
9407
- const { steps } = useCurrentRun();
9408
- const nodeTypes = {
9409
- "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
9410
- "condition-node": WorkflowConditionNode,
9411
- "after-node": WorkflowAfterNode,
9412
- "loop-result-node": WorkflowLoopResultNode,
9413
- "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
9414
- };
9415
- useEffect(() => {
9416
- if (open) {
9417
- setTimeout(() => {
9418
- setIsMounted(true);
9419
- }, 500);
9420
- }
9421
- }, [open]);
9422
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
9423
- ReactFlow,
9931
+ const ShadcnUIComponents = {
9932
+ Form,
9933
+ FieldWrapper,
9934
+ ErrorMessage,
9935
+ SubmitButton,
9936
+ ObjectWrapper,
9937
+ ArrayWrapper,
9938
+ ArrayElementWrapper
9939
+ };
9940
+ function AutoForm({
9941
+ uiComponents,
9942
+ formComponents,
9943
+ readOnly,
9944
+ ...props
9945
+ }) {
9946
+ return /* @__PURE__ */ jsx(
9947
+ AutoForm$1,
9424
9948
  {
9425
- nodes,
9426
- edges: edges.map((e) => ({
9427
- ...e,
9428
- style: {
9429
- ...e.style,
9430
- stroke: steps[`${workflowName}.${e.data?.previousStepId}`]?.status === "success" && steps[`${workflowName}.${e.data?.nextStepId}`] ? "#22c55e" : void 0
9431
- }
9432
- })),
9433
- fitView: true,
9434
- fitViewOptions: {
9435
- maxZoom: 1
9436
- },
9437
- minZoom: 0.01,
9438
- maxZoom: 1,
9439
- nodeTypes,
9440
- onNodesChange,
9441
- children: [
9442
- /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9443
- /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9444
- /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
9445
- ]
9949
+ ...props,
9950
+ uiComponents: { ...ShadcnUIComponents, ...uiComponents },
9951
+ formComponents: {
9952
+ string: (props2) => /* @__PURE__ */ jsx(StringField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9953
+ number: (props2) => /* @__PURE__ */ jsx(NumberField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9954
+ boolean: (props2) => /* @__PURE__ */ jsx(BooleanField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9955
+ date: (props2) => /* @__PURE__ */ jsx(DateField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9956
+ select: (props2) => /* @__PURE__ */ jsx(SelectField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9957
+ record: (props2) => /* @__PURE__ */ jsx(RecordField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
9958
+ ...formComponents
9959
+ }
9446
9960
  }
9447
- ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
9961
+ );
9448
9962
  }
9449
9963
 
9450
- const WorkflowNestedGraphContext = createContext(
9451
- {}
9452
- );
9453
- function WorkflowNestedGraphProvider({ children }) {
9454
- const [stepGraph, setStepGraph] = useState(null);
9455
- const [parentStepGraphList, setParentStepGraphList] = useState([]);
9456
- const [openDialog, setOpenDialog] = useState(false);
9457
- const [label, setLabel] = useState("");
9458
- const [fullStep, setFullStep] = useState("");
9459
- const [switching, setSwitching] = useState(false);
9460
- const closeNestedGraph = () => {
9461
- if (parentStepGraphList.length) {
9462
- setSwitching(true);
9463
- const lastStepGraph = parentStepGraphList[parentStepGraphList.length - 1];
9464
- setStepGraph(lastStepGraph.stepGraph);
9465
- setLabel(lastStepGraph.label);
9466
- setFullStep(lastStepGraph.fullStep);
9467
- setParentStepGraphList(parentStepGraphList.slice(0, -1));
9468
- setTimeout(() => {
9469
- setSwitching(false);
9470
- }, 500);
9964
+ buildZodFieldConfig();
9965
+
9966
+ function inferFieldType(schema, fieldConfig) {
9967
+ if (fieldConfig?.fieldType) {
9968
+ return fieldConfig.fieldType;
9969
+ }
9970
+ if (schema instanceof z.ZodObject) return "object";
9971
+ if (schema instanceof z.ZodNumber) return "number";
9972
+ if (schema instanceof z.ZodBoolean) return "boolean";
9973
+ if (schema instanceof z.ZodDate || schema?.isDatetime || schema?.isDate) return "date";
9974
+ if (schema instanceof z.ZodString) return "string";
9975
+ if (schema instanceof z.ZodEnum) return "select";
9976
+ if (schema instanceof z.ZodNativeEnum) return "select";
9977
+ if (schema instanceof z.ZodArray) return "array";
9978
+ if (schema instanceof z.ZodRecord) return "record";
9979
+ return "string";
9980
+ }
9981
+
9982
+ function parseField(key, schema) {
9983
+ const baseSchema = getBaseSchema(schema);
9984
+ const fieldConfig = getFieldConfigInZodStack(schema);
9985
+ const type = inferFieldType(baseSchema, fieldConfig);
9986
+ const defaultValue = getDefaultValueInZodStack(schema);
9987
+ const options = baseSchema._def?.values;
9988
+ let optionValues = [];
9989
+ if (options) {
9990
+ if (!Array.isArray(options)) {
9991
+ optionValues = Object.entries(options);
9471
9992
  } else {
9472
- setOpenDialog(false);
9473
- setStepGraph(null);
9474
- setLabel("");
9475
- setFullStep("");
9993
+ optionValues = options.map((value) => [value, value]);
9476
9994
  }
9995
+ }
9996
+ let subSchema = [];
9997
+ if (baseSchema instanceof z.ZodObject) {
9998
+ subSchema = Object.entries(baseSchema.shape).map(([key2, field]) => parseField(key2, field));
9999
+ }
10000
+ if (baseSchema instanceof z.ZodArray) {
10001
+ subSchema = [parseField("0", baseSchema._def.type)];
10002
+ }
10003
+ return {
10004
+ key,
10005
+ type,
10006
+ required: !schema.isOptional(),
10007
+ default: defaultValue,
10008
+ description: baseSchema.description,
10009
+ fieldConfig,
10010
+ options: optionValues,
10011
+ schema: subSchema
9477
10012
  };
9478
- const showNestedGraph = ({
9479
- label: newLabel,
9480
- stepGraph: newStepGraph,
9481
- fullStep: newFullStep
9482
- }) => {
9483
- if (stepGraph) {
9484
- setSwitching(true);
9485
- setParentStepGraphList([...parentStepGraphList, { stepGraph, label, fullStep }]);
10013
+ }
10014
+ function getBaseSchema(schema) {
10015
+ if ("innerType" in schema._def) {
10016
+ return getBaseSchema(schema._def.innerType);
10017
+ }
10018
+ if ("schema" in schema._def) {
10019
+ return getBaseSchema(schema._def.schema);
10020
+ }
10021
+ return schema;
10022
+ }
10023
+ function parseSchema(schema) {
10024
+ const objectSchema = schema instanceof z.ZodEffects ? schema.innerType() : schema;
10025
+ const shape = objectSchema.shape;
10026
+ const fields = Object.entries(shape).map(([key, field]) => parseField(key, field));
10027
+ return { fields };
10028
+ }
10029
+ class CustomZodProvider extends ZodProvider {
10030
+ _schema;
10031
+ constructor(schema) {
10032
+ super(schema);
10033
+ this._schema = schema;
10034
+ }
10035
+ parseSchema() {
10036
+ return parseSchema(this._schema);
10037
+ }
10038
+ }
10039
+
10040
+ const labelVariants = cva("text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
10041
+ const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
10042
+ Label.displayName = LabelPrimitive.Root.displayName;
10043
+
10044
+ function isEmptyZodObject(schema) {
10045
+ if (schema instanceof ZodObject) {
10046
+ return Object.keys(schema.shape).length === 0;
10047
+ }
10048
+ return false;
10049
+ }
10050
+ function DynamicForm({
10051
+ schema,
10052
+ onSubmit,
10053
+ defaultValues,
10054
+ isSubmitLoading,
10055
+ submitButtonLabel,
10056
+ className,
10057
+ readOnly
10058
+ }) {
10059
+ const isNotZodObject = !(schema instanceof ZodObject);
10060
+ if (!schema) {
10061
+ console.error("no form schema found");
10062
+ return null;
10063
+ }
10064
+ const normalizedSchema = (schema2) => {
10065
+ if (isEmptyZodObject(schema2)) {
10066
+ return z$1.object({});
9486
10067
  }
9487
- setLabel(newLabel);
9488
- setFullStep(newFullStep);
9489
- setStepGraph(newStepGraph);
9490
- setOpenDialog(true);
9491
- setTimeout(() => {
9492
- setSwitching(false);
9493
- }, 500);
9494
- };
9495
- return /* @__PURE__ */ jsxs(
9496
- WorkflowNestedGraphContext.Provider,
9497
- {
9498
- value: {
9499
- showNestedGraph,
9500
- closeNestedGraph
9501
- },
9502
- children: [
9503
- children,
9504
- /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[45rem] h-[45rem] max-w-[unset] bg-[#121212] p-[0.5rem]", children: [
9505
- /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
9506
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9507
- /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
9508
- label,
9509
- " workflow"
9510
- ] })
9511
- ] }),
9512
- switching ? /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(WorkflowNestedGraph, { stepGraph, open: openDialog, workflowName: fullStep }) })
9513
- ] }) }) })
9514
- ]
10068
+ if (isNotZodObject) {
10069
+ return z$1.object({
10070
+ "​": schema2
10071
+ });
9515
10072
  }
9516
- );
10073
+ return schema2;
10074
+ };
10075
+ const schemaProvider = new CustomZodProvider(normalizedSchema(schema));
10076
+ const formProps = {
10077
+ schema: schemaProvider,
10078
+ onSubmit: async (values) => {
10079
+ await onSubmit?.(isNotZodObject ? values["​"] || {} : values);
10080
+ },
10081
+ defaultValues: isNotZodObject ? defaultValues ? { "​": defaultValues } : void 0 : defaultValues,
10082
+ formProps: {
10083
+ className: ""
10084
+ },
10085
+ uiComponents: {
10086
+ SubmitButton: ({ children }) => onSubmit ? /* @__PURE__ */ jsx(Button, { variant: "light", className: "w-full", size: "lg", disabled: isSubmitLoading, children: isSubmitLoading ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : submitButtonLabel || children }) : null
10087
+ },
10088
+ formComponents: {
10089
+ Label: ({ value }) => /* @__PURE__ */ jsx(Label, { className: "text-sm font-normal", children: value })
10090
+ },
10091
+ withSubmit: true
10092
+ };
10093
+ return /* @__PURE__ */ jsx(AutoForm, { ...formProps, readOnly });
9517
10094
  }
9518
10095
 
9519
- function WorkflowNestedNode({
9520
- data,
9521
- parentWorkflowName
10096
+ function resolveSerializedZodOutput(obj) {
10097
+ return Function("z", `"use strict";return (${obj});`)(z);
10098
+ }
10099
+
10100
+ function CodeBlockDemo({
10101
+ code = "",
10102
+ language = "ts",
10103
+ filename,
10104
+ className
9522
10105
  }) {
9523
- const [isInputOpen, setIsInputOpen] = useState(false);
9524
- const [isOutputOpen, setIsOutputOpen] = useState(false);
9525
- const [isErrorOpen, setIsErrorOpen] = useState(false);
9526
- const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
9527
- const { steps, isRunning } = useCurrentRun();
9528
- const { showNestedGraph } = useContext(WorkflowNestedGraphContext);
9529
- const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig } = data;
9530
- const fullLabel = parentWorkflowName ? `${parentWorkflowName}.${label}` : label;
9531
- const step = steps[fullLabel];
9532
- const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
9533
- const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
9534
- return /* @__PURE__ */ jsxs(Fragment, { children: [
9535
- !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
9536
- /* @__PURE__ */ jsxs(
9537
- "div",
10106
+ return /* @__PURE__ */ jsxs(CodeBlock$1, { code, language, theme: themes.oneDark, children: [
10107
+ 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,
10108
+ /* @__PURE__ */ jsx(
10109
+ CodeBlock$1.Code,
9538
10110
  {
9539
- className: cn(
9540
- "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
9541
- step?.status === "success" && "ring-2 ring-accent1",
9542
- step?.status === "failed" && "ring-2 ring-accent2"
9543
- ),
9544
- children: [
9545
- /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
9546
- isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
9547
- step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
9548
- step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
9549
- step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-icon3" }),
9550
- step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon6 animate-spin" }),
9551
- !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
9552
- ] }),
9553
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
9554
- label,
9555
- " ",
9556
- step?.startedAt && /* @__PURE__ */ jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
9557
- ] })
9558
- ] }),
9559
- description && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
9560
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2 rounded-b-lg", children: [
9561
- /* @__PURE__ */ jsx(Button, { onClick: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }), children: "View workflow" }),
9562
- mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
9563
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
9564
- /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9565
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9566
- label,
9567
- " map config"
9568
- ] }),
9569
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
9570
- ] }) })
9571
- ] }),
9572
- step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
9573
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
9574
- /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9575
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9576
- label,
9577
- " input"
9578
- ] }),
9579
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.input }) })
9580
- ] }) })
9581
- ] }),
9582
- step?.output && /* @__PURE__ */ jsxs(Fragment, { children: [
9583
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
9584
- /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9585
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9586
- label,
9587
- " output"
9588
- ] }),
9589
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.output }) })
9590
- ] }) })
9591
- ] }),
9592
- step?.error && /* @__PURE__ */ jsxs(Fragment, { children: [
9593
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
9594
- /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9595
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9596
- label,
9597
- " error"
9598
- ] }),
9599
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step?.error }) })
9600
- ] }) })
9601
- ] })
9602
- ] })
9603
- ]
10111
+ className: cn("bg-transparent h-full p-6 rounded-xl whitespace-pre-wrap", filename ? "pt-10" : "", className),
10112
+ children: /* @__PURE__ */ jsx("div", { className: "table-row", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
10113
+ /* @__PURE__ */ jsx(CodeBlock$1.LineNumber, { className: "table-cell pr-4 text-sm text-right select-none text-gray-500/50" }),
10114
+ /* @__PURE__ */ jsx(CodeBlock$1.LineContent, { className: "flex", children: /* @__PURE__ */ jsx(CodeBlock$1.Token, { className: "font-mono text-sm mastra-token" }) })
10115
+ ] }) })
9604
10116
  }
9605
- ),
9606
- !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
10117
+ )
9607
10118
  ] });
9608
10119
  }
9609
10120
 
9610
- function WorkflowGraphInner({ workflow, onShowTrace }) {
9611
- const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
9612
- const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9613
- const [edges] = useEdgesState(initialEdges);
9614
- const { steps, runId } = useCurrentRun();
9615
- const nodeTypes = {
9616
- "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { onShowTrace, ...props }),
9617
- "condition-node": WorkflowConditionNode,
9618
- "after-node": WorkflowAfterNode,
9619
- "loop-result-node": WorkflowLoopResultNode,
9620
- "nested-node": WorkflowNestedNode
9621
- };
9622
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxs(
9623
- ReactFlow,
10121
+ const WorkflowCard = ({ header, children, footer }) => {
10122
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface4", children: [
10123
+ /* @__PURE__ */ jsx("div", { className: "py-1 px-2 flex items-center gap-3", children: header }),
10124
+ children && /* @__PURE__ */ jsx("div", { className: "border-t-sm border-border1", children }),
10125
+ footer && /* @__PURE__ */ jsx("div", { className: "py-1 px-2 border-t-sm border-border1", children: footer })
10126
+ ] });
10127
+ };
10128
+
10129
+ const LegacyWorkflowStatus = ({ stepId, pathStatus, path }) => {
10130
+ const status = pathStatus === "completed" ? "Completed" : stepId === path ? pathStatus.charAt(0).toUpperCase() + pathStatus.slice(1) : pathStatus === "executing" ? "Executing" : "Completed";
10131
+ return /* @__PURE__ */ jsx(
10132
+ WorkflowCard,
9624
10133
  {
9625
- nodes,
9626
- edges: edges.map((e) => ({
9627
- ...e,
9628
- style: {
9629
- ...e.style,
9630
- stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
10134
+ header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
10135
+ /* @__PURE__ */ jsxs(Icon, { children: [
10136
+ status === "Completed" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
10137
+ status === "Failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
10138
+ status === "Executing" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon3 animate-spin" })
10139
+ ] }),
10140
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-lg", className: "text-icon6 font-medium", children: path })
10141
+ ] })
10142
+ }
10143
+ );
10144
+ };
10145
+
10146
+ const WorkflowResult = ({ jsonResult, sanitizedJsonResult }) => {
10147
+ const { handleCopy } = useCopyToClipboard({ text: jsonResult });
10148
+ const [expanded, setExpanded] = useState(false);
10149
+ return /* @__PURE__ */ jsx(
10150
+ WorkflowCard,
10151
+ {
10152
+ header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-between w-full", children: [
10153
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 flex items-center gap-3 font-medium", children: [
10154
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(DeploymentIcon, {}) }),
10155
+ "Workflow Execution (JSON)"
10156
+ ] }),
10157
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10158
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10159
+ "button",
10160
+ {
10161
+ className: "p-2 rounded-lg hover:bg-surface5 transition-colors duration-150 ease-in-out text-icon3 hover:text-icon6",
10162
+ onClick: () => handleCopy(),
10163
+ children: /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(CopyIcon, {}) })
10164
+ }
10165
+ ) }),
10166
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Copy result" })
10167
+ ] })
10168
+ ] }),
10169
+ footer: /* @__PURE__ */ jsx(
10170
+ "button",
10171
+ {
10172
+ className: "w-full h-full text-center text-icon2 hover:text-icon6 text-ui-md",
10173
+ onClick: () => setExpanded((s) => !s),
10174
+ children: expanded ? "collapse" : "expand"
9631
10175
  }
9632
- })),
9633
- nodeTypes,
9634
- onNodesChange,
9635
- fitView: true,
9636
- fitViewOptions: {
9637
- maxZoom: 1
9638
- },
9639
- minZoom: 0.01,
9640
- maxZoom: 1,
9641
- children: [
9642
- /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9643
- /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9644
- /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
9645
- ]
10176
+ ),
10177
+ children: expanded ? /* @__PURE__ */ jsx(CodeBlockDemo, { className: "w-full overflow-x-auto", code: sanitizedJsonResult || jsonResult, language: "json" }) : null
9646
10178
  }
9647
- ) });
9648
- }
10179
+ );
10180
+ };
9649
10181
 
9650
- function WorkflowGraph({ workflowId, onShowTrace, workflow, isLoading }) {
9651
- const { snapshot } = useContext(WorkflowRunContext);
10182
+ function LegacyWorkflowTrigger({
10183
+ workflowId,
10184
+ setRunId
10185
+ }) {
10186
+ const { legacyResult: result, setLegacyResult: setResult, payload, setPayload } = useContext(WorkflowRunContext);
10187
+ const { isLoading, legacyWorkflow: workflow } = useLegacyWorkflow(workflowId);
10188
+ const { createLegacyWorkflowRun: createWorkflowRun, startLegacyWorkflowRun: startWorkflowRun } = useExecuteWorkflow();
10189
+ const {
10190
+ watchLegacyWorkflow: watchWorkflow,
10191
+ legacyWatchResult: watchResult,
10192
+ isWatchingLegacyWorkflow: isWatchingWorkflow
10193
+ } = useWatchWorkflow();
10194
+ const { resumeLegacyWorkflow: resumeWorkflow, isResumingLegacyWorkflow: isResumingWorkflow } = useResumeWorkflow();
10195
+ const [suspendedSteps, setSuspendedSteps] = useState([]);
10196
+ const [isRunning, setIsRunning] = useState(false);
10197
+ const triggerSchema = workflow?.triggerSchema;
10198
+ const handleExecuteWorkflow = async (data) => {
10199
+ try {
10200
+ if (!workflow) return;
10201
+ setIsRunning(true);
10202
+ setResult(null);
10203
+ const { runId } = await createWorkflowRun({ workflowId });
10204
+ setRunId?.(runId);
10205
+ watchWorkflow({ workflowId, runId });
10206
+ startWorkflowRun({ workflowId, runId, input: data });
10207
+ } catch (err) {
10208
+ setIsRunning(false);
10209
+ toast.error("Error executing workflow");
10210
+ }
10211
+ };
10212
+ const handleResumeWorkflow = async (step) => {
10213
+ if (!workflow) return;
10214
+ const { stepId, runId: prevRunId, context } = step;
10215
+ const { runId } = await createWorkflowRun({ workflowId, prevRunId });
10216
+ watchWorkflow({ workflowId, runId });
10217
+ await resumeWorkflow({
10218
+ stepId,
10219
+ runId,
10220
+ context,
10221
+ workflowId
10222
+ });
10223
+ };
10224
+ const watchResultToUse = result ?? watchResult;
10225
+ const workflowActivePaths = watchResultToUse?.activePaths ?? {};
10226
+ useEffect(() => {
10227
+ setIsRunning(isWatchingWorkflow);
10228
+ }, [isWatchingWorkflow]);
10229
+ useEffect(() => {
10230
+ if (!watchResultToUse?.activePaths || !result?.runId) return;
10231
+ const suspended = Object.entries(watchResultToUse.activePaths).filter(([_, { status }]) => status === "suspended").map(([stepId, { suspendPayload }]) => ({
10232
+ stepId,
10233
+ runId: result.runId,
10234
+ suspendPayload
10235
+ }));
10236
+ setSuspendedSteps(suspended);
10237
+ }, [watchResultToUse, result]);
10238
+ useEffect(() => {
10239
+ if (watchResult) {
10240
+ setResult(watchResult);
10241
+ }
10242
+ }, [watchResult]);
9652
10243
  if (isLoading) {
9653
- return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-full" }) });
9654
- }
9655
- if (!workflow) {
9656
- return /* @__PURE__ */ jsx("div", { className: "grid h-full place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
9657
- /* @__PURE__ */ jsx(AlertCircleIcon, {}),
9658
- /* @__PURE__ */ jsxs("div", { children: [
9659
- "We couldn't find ",
9660
- lodashTitleCase(workflowId),
9661
- " workflow."
9662
- ] })
10244
+ return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
10245
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }),
10246
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10" })
9663
10247
  ] }) });
9664
10248
  }
9665
- return /* @__PURE__ */ jsx(WorkflowNestedGraphProvider, { children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
9666
- WorkflowGraphInner,
9667
- {
9668
- workflow: snapshot?.serializedStepGraph ? { stepGraph: snapshot?.serializedStepGraph } : workflow,
9669
- onShowTrace
9670
- }
9671
- ) }) }, snapshot?.runId ?? workflowId);
10249
+ if (!workflow) return null;
10250
+ const isSuspendedSteps = suspendedSteps.length > 0;
10251
+ const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
10252
+ const { sanitizedOutput, ...restResult } = result ?? {};
10253
+ const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
10254
+ return /* @__PURE__ */ jsx("div", { className: "h-full px-5 pt-3 pb-12", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
10255
+ isResumingWorkflow && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
10256
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
10257
+ /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
10258
+ ] }),
10259
+ !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
10260
+ DynamicForm,
10261
+ {
10262
+ schema: zodInputSchema,
10263
+ defaultValues: payload,
10264
+ isSubmitLoading: isWatchingWorkflow,
10265
+ submitButtonLabel: "Run",
10266
+ onSubmit: (data) => {
10267
+ setPayload(data);
10268
+ handleExecuteWorkflow(data);
10269
+ }
10270
+ }
10271
+ ) : /* @__PURE__ */ jsx(
10272
+ Button,
10273
+ {
10274
+ className: "w-full",
10275
+ variant: "light",
10276
+ disabled: isRunning,
10277
+ onClick: () => handleExecuteWorkflow(null),
10278
+ children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
10279
+ }
10280
+ ) }),
10281
+ isSuspendedSteps && suspendedSteps?.map((step) => {
10282
+ const stepDefinition = workflow.steps[step.stepId];
10283
+ const stepSchema = stepDefinition?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.inputSchema))) : z.record(z.string(), z.any());
10284
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
10285
+ /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
10286
+ step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
10287
+ CodeBlockDemo,
10288
+ {
10289
+ className: "w-full overflow-x-auto p-2",
10290
+ code: JSON.stringify(step.suspendPayload, null, 2),
10291
+ language: "json"
10292
+ }
10293
+ ) }),
10294
+ /* @__PURE__ */ jsx(
10295
+ DynamicForm,
10296
+ {
10297
+ schema: stepSchema,
10298
+ isSubmitLoading: isResumingWorkflow,
10299
+ submitButtonLabel: "Resume",
10300
+ onSubmit: (data) => {
10301
+ handleResumeWorkflow({
10302
+ stepId: step.stepId,
10303
+ runId: step.runId,
10304
+ suspendPayload: step.suspendPayload,
10305
+ context: data
10306
+ });
10307
+ }
10308
+ }
10309
+ )
10310
+ ] });
10311
+ }),
10312
+ hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
10313
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
10314
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: Object.entries(workflowActivePaths)?.map(([stepId, { status: pathStatus, stepPath }]) => {
10315
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: stepPath?.map((path, idx) => {
10316
+ return /* @__PURE__ */ jsx(LegacyWorkflowStatus, { stepId, pathStatus, path }, idx);
10317
+ }) }, stepId);
10318
+ }) })
10319
+ ] }),
10320
+ result && /* @__PURE__ */ jsxs(Fragment, { children: [
10321
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
10322
+ /* @__PURE__ */ jsx(WorkflowResult, { sanitizedJsonResult: sanitizedOutput, jsonResult: JSON.stringify(restResult, null, 2) })
10323
+ ] })
10324
+ ] }) });
9672
10325
  }
9673
10326
 
9674
10327
  function WorkflowTrigger({
@@ -10308,5 +10961,5 @@ function usePolling({
10308
10961
  };
10309
10962
  }
10310
10963
 
10311
- export { AgentChat, AgentCoinIcon, AgentContext, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentProvider, AgentTraces, AiIcon, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityIcon, EntityName, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, NetworkChat, NetworkContext, NetworkProvider, OpenAIIcon, PromptIcon, RepoIcon, Row, ScoreIcon, SettingsIcon, SlashIcon, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolsIcon, TraceIcon, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTraces, WorkflowTrigger, useCurrentRun, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition };
10964
+ export { AgentChat, AgentCoinIcon, AgentContext, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentProvider, AgentTraces, AiIcon, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityIcon, EntityName, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, NetworkChat, NetworkContext, NetworkProvider, OpenAIIcon, PromptIcon, RepoIcon, Row, ScoreIcon, SettingsIcon, SlashIcon, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolsIcon, TraceIcon, TsIcon, Txt, TxtCell, UnitCell, VNextNetworkChat, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTraces, WorkflowTrigger, useCurrentRun, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition };
10312
10965
  //# sourceMappingURL=index.es.js.map