@mastra/playground-ui 5.1.1-alpha.2 → 5.1.1-alpha.4

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
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, ComposerPrimitive, useAttachment, AttachmentPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
3
- import { CheckIcon as CheckIcon$1, CopyIcon, ChevronUpIcon, X, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Copy, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Check, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon, Plus, Loader2, CirclePause } from 'lucide-react';
3
+ import { CheckIcon as CheckIcon$1, CopyIcon, ChevronUpIcon, X, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Copy, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Check, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, PauseIcon, Loader2, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon, Plus, Minus, Maximize, CirclePause } from 'lucide-react';
4
4
  import * as React from 'react';
5
5
  import React__default, { forwardRef, useState, useEffect, memo, useMemo, useRef, createContext, useContext, useCallback, Suspense, Fragment as Fragment$1 } from 'react';
6
6
  import { Slot } from '@radix-ui/react-slot';
@@ -26,11 +26,12 @@ import { format, formatDistanceToNow, isValid } from 'date-fns';
26
26
  import * as TabsPrimitive from '@radix-ui/react-tabs';
27
27
  import { toast } from 'sonner';
28
28
  import { AnimatePresence } from 'motion/react';
29
+ import { C as Colors } from './colors-CBG_Mm7P.js';
29
30
  import { processDataStream } from '@ai-sdk/ui-utils';
30
31
  import Markdown from 'react-markdown';
31
32
  import { useDebouncedCallback } from 'use-debounce';
32
33
  import { RuntimeContext as RuntimeContext$1 } from '@mastra/core/runtime-context';
33
- import { MarkerType, Handle, Position, useNodesState, useEdgesState, ReactFlow, Controls, MiniMap, Background, BackgroundVariant, ReactFlowProvider } from '@xyflow/react';
34
+ import { MarkerType, Handle, Position, useNodesState, useEdgesState, ReactFlow, Controls, MiniMap, Background, BackgroundVariant, ReactFlowProvider, useViewport, useReactFlow, Panel } from '@xyflow/react';
34
35
  import '@xyflow/react/dist/style.css';
35
36
  import Dagre from '@dagrejs/dagre';
36
37
  import { Highlight, themes } from 'prism-react-renderer';
@@ -48,6 +49,7 @@ import { v4 } from '@lukeed/uuid';
48
49
  import { ZodProvider, getFieldConfigInZodStack, getDefaultValueInZodStack } from '@autoform/zod';
49
50
  import * as LabelPrimitive from '@radix-ui/react-label';
50
51
  import { CodeBlock as CodeBlock$1 } from 'react-code-block';
52
+ import * as SliderPrimitive from '@radix-ui/react-slider';
51
53
  import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
52
54
 
53
55
  import './index.css';function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
@@ -4109,7 +4111,7 @@ const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
4109
4111
  DialogPrimitive.Title,
4110
4112
  {
4111
4113
  ref,
4112
- className: cn("text-lg font-semibold leading-none tracking-tight", className),
4114
+ className: clsx("text-lg font-semibold leading-none tracking-tight", className),
4113
4115
  ...props
4114
4116
  }
4115
4117
  ));
@@ -4824,23 +4826,47 @@ const defaultModelSettings$1 = {
4824
4826
  topP: 1
4825
4827
  };
4826
4828
  const AgentContext = createContext({});
4827
- function AgentProvider({ agentId, children }) {
4829
+ function AgentProvider({
4830
+ agentId,
4831
+ defaultGenerateOptions,
4832
+ defaultStreamOptions,
4833
+ children
4834
+ }) {
4828
4835
  const {
4829
4836
  modelSettings: modelSettingsStore,
4830
4837
  setModelSettings: setModelSettingsStore,
4831
4838
  chatWithGenerate: chatWithGenerateStore,
4832
4839
  setChatWithGenerate: setChatWithGenerateStore
4833
4840
  } = useAgentStore();
4834
- const modelSettings = modelSettingsStore[agentId] || defaultModelSettings$1;
4841
+ const chatWithGenerate = chatWithGenerateStore[agentId] || false;
4842
+ const setChatWithGenerate = (chatWithGenerate2) => {
4843
+ setChatWithGenerateStore({ [agentId]: chatWithGenerate2 });
4844
+ };
4845
+ const modelSettings = useMemo(() => {
4846
+ if (modelSettingsStore[agentId]) return modelSettingsStore[agentId];
4847
+ if (chatWithGenerate) {
4848
+ return {
4849
+ maxRetries: defaultGenerateOptions?.maxRetries ?? defaultModelSettings$1.maxRetries,
4850
+ maxSteps: defaultGenerateOptions?.maxSteps ?? defaultModelSettings$1.maxSteps,
4851
+ temperature: defaultGenerateOptions?.temperature ?? defaultModelSettings$1.temperature,
4852
+ topP: defaultGenerateOptions?.topP ?? defaultModelSettings$1.topP,
4853
+ ...defaultGenerateOptions
4854
+ };
4855
+ } else {
4856
+ return {
4857
+ maxRetries: defaultStreamOptions?.maxRetries ?? defaultModelSettings$1.maxRetries,
4858
+ maxSteps: defaultStreamOptions?.maxSteps ?? defaultModelSettings$1.maxSteps,
4859
+ temperature: defaultStreamOptions?.temperature ?? defaultModelSettings$1.temperature,
4860
+ topP: defaultStreamOptions?.topP ?? defaultModelSettings$1.topP,
4861
+ ...defaultStreamOptions
4862
+ };
4863
+ }
4864
+ }, [agentId, defaultGenerateOptions, defaultStreamOptions, chatWithGenerate, modelSettingsStore]);
4835
4865
  const setModelSettings = (modelSettings2) => {
4836
4866
  setModelSettingsStore({ [agentId]: modelSettings2 });
4837
4867
  };
4838
4868
  const resetModelSettings = () => {
4839
- setModelSettings(defaultModelSettings$1);
4840
- };
4841
- const chatWithGenerate = chatWithGenerateStore[agentId] || false;
4842
- const setChatWithGenerate = (chatWithGenerate2) => {
4843
- setChatWithGenerateStore({ [agentId]: chatWithGenerate2 });
4869
+ setModelSettingsStore({ [agentId]: null });
4844
4870
  };
4845
4871
  return /* @__PURE__ */ jsx(
4846
4872
  AgentContext.Provider,
@@ -5946,7 +5972,7 @@ const useCodemirrorTheme = () => {
5946
5972
  fontSize: "0.8rem",
5947
5973
  lineHighlight: "transparent",
5948
5974
  gutterBackground: "transparent",
5949
- gutterForeground: "#939393",
5975
+ gutterForeground: Colors.surface3,
5950
5976
  background: "transparent"
5951
5977
  },
5952
5978
  styles: [{ tag: [tags.className, tags.propertyName] }]
@@ -7692,18 +7718,222 @@ function WorkflowConditionNode({ data }) {
7692
7718
  );
7693
7719
  }
7694
7720
 
7721
+ function convertWorkflowRunStateToWatchResult(runState) {
7722
+ const runId = runState.runId;
7723
+ const steps = {};
7724
+ const context = runState.context || {};
7725
+ Object.entries(context).forEach(([stepId, stepResult]) => {
7726
+ if (stepId !== "input" && "status" in stepResult) {
7727
+ const result = stepResult;
7728
+ steps[stepId] = {
7729
+ status: result.status,
7730
+ output: "output" in result ? result.output : void 0,
7731
+ payload: "payload" in result ? result.payload : void 0,
7732
+ resumePayload: "resumePayload" in result ? result.resumePayload : void 0,
7733
+ error: "error" in result ? result.error : void 0,
7734
+ startedAt: "startedAt" in result ? result.startedAt : Date.now(),
7735
+ endedAt: "endedAt" in result ? result.endedAt : void 0,
7736
+ suspendedAt: "suspendedAt" in result ? result.suspendedAt : void 0,
7737
+ resumedAt: "resumedAt" in result ? result.resumedAt : void 0
7738
+ };
7739
+ }
7740
+ });
7741
+ const status = determineWorkflowStatus(steps);
7742
+ return {
7743
+ type: "watch",
7744
+ payload: {
7745
+ workflowState: {
7746
+ status,
7747
+ steps,
7748
+ output: runState.value,
7749
+ payload: context.input,
7750
+ error: void 0
7751
+ }
7752
+ },
7753
+ eventTimestamp: new Date(runState.timestamp),
7754
+ runId
7755
+ };
7756
+ }
7757
+ function determineWorkflowStatus(steps) {
7758
+ const stepStatuses = Object.values(steps).map((step) => step.status);
7759
+ if (stepStatuses.includes("failed")) {
7760
+ return "failed";
7761
+ }
7762
+ if (stepStatuses.includes("suspended")) {
7763
+ return "suspended";
7764
+ }
7765
+ if (stepStatuses.every((status) => status === "success")) {
7766
+ return "success";
7767
+ }
7768
+ return "running";
7769
+ }
7770
+
7771
+ const WorkflowRunContext = createContext({});
7772
+ function WorkflowRunProvider({
7773
+ children,
7774
+ snapshot
7775
+ }) {
7776
+ const [legacyResult, setLegacyResult] = useState(null);
7777
+ const [result, setResult] = useState(
7778
+ () => snapshot ? convertWorkflowRunStateToWatchResult(snapshot) : null
7779
+ );
7780
+ const [payload, setPayload] = useState(null);
7781
+ const clearData = () => {
7782
+ setLegacyResult(null);
7783
+ setResult(null);
7784
+ setPayload(null);
7785
+ };
7786
+ useEffect(() => {
7787
+ if (snapshot?.runId) {
7788
+ setResult(convertWorkflowRunStateToWatchResult(snapshot));
7789
+ } else {
7790
+ setResult(null);
7791
+ }
7792
+ }, [snapshot?.runId ?? ""]);
7793
+ return /* @__PURE__ */ jsx(
7794
+ WorkflowRunContext.Provider,
7795
+ {
7796
+ value: {
7797
+ legacyResult,
7798
+ setLegacyResult,
7799
+ result,
7800
+ setResult,
7801
+ payload,
7802
+ setPayload,
7803
+ clearData
7804
+ },
7805
+ children
7806
+ }
7807
+ );
7808
+ }
7809
+
7810
+ const useCurrentRun = () => {
7811
+ const context = useContext(WorkflowRunContext);
7812
+ const workflowCurrentSteps = context.result?.payload?.workflowState?.steps ?? {};
7813
+ const steps = Object.entries(workflowCurrentSteps).reduce((acc, [key, value]) => {
7814
+ return {
7815
+ ...acc,
7816
+ [key]: {
7817
+ error: value.error,
7818
+ startedAt: value.startedAt,
7819
+ endedAt: value.endedAt,
7820
+ status: value.status,
7821
+ output: value.output,
7822
+ input: value.payload
7823
+ }
7824
+ };
7825
+ }, {});
7826
+ return { steps, isRunning: Boolean(context.payload) };
7827
+ };
7828
+
7695
7829
  function WorkflowDefaultNode({ data }) {
7830
+ const [isInputOpen, setIsInputOpen] = useState(false);
7831
+ const [isOutputOpen, setIsOutputOpen] = useState(false);
7832
+ const [isErrorOpen, setIsErrorOpen] = useState(false);
7833
+ const { steps, isRunning } = useCurrentRun();
7696
7834
  const { label, description, withoutTopHandle, withoutBottomHandle } = data;
7697
- return /* @__PURE__ */ jsxs("div", { className: cn("bg-mastra-bg-8 rounded-md w-[274px]"), children: [
7835
+ const step = steps[label];
7836
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7837
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7838
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7698
7839
  !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
7699
- /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-[6px] rounded-sm p-2", children: [
7700
- /* @__PURE__ */ jsx(Footprints, { className: "text-current w-4 h-4" }),
7701
- /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
7702
- ] }) }),
7703
- description && /* @__PURE__ */ jsx("div", { className: "bg-mastra-bg-4 rounded-b-md p-2 text-[10px] text-left text-mastra-el-4", children: description }),
7704
- !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
7840
+ /* @__PURE__ */ jsxs(
7841
+ "div",
7842
+ {
7843
+ className: clsx(
7844
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
7845
+ step?.status === "success" && "ring-2 ring-accent1",
7846
+ step?.status === "failed" && "ring-2 ring-accent2"
7847
+ ),
7848
+ children: [
7849
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3", children: [
7850
+ isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
7851
+ step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
7852
+ step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
7853
+ step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-icon3" }),
7854
+ step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon6 animate-spin" }),
7855
+ !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
7856
+ ] }),
7857
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
7858
+ label,
7859
+ " ",
7860
+ step?.startedAt && /* @__PURE__ */ jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
7861
+ ] })
7862
+ ] }),
7863
+ description && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
7864
+ (step?.input || step?.output) && /* @__PURE__ */ jsxs("div", { className: "flex items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2", children: [
7865
+ step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
7866
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
7867
+ /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7868
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7869
+ label,
7870
+ " input"
7871
+ ] }),
7872
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.input }) })
7873
+ ] }) })
7874
+ ] }),
7875
+ step?.output && /* @__PURE__ */ jsxs(Fragment, { children: [
7876
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
7877
+ /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7878
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7879
+ label,
7880
+ " output"
7881
+ ] }),
7882
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.output }) })
7883
+ ] }) })
7884
+ ] }),
7885
+ step?.error && /* @__PURE__ */ jsxs(Fragment, { children: [
7886
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
7887
+ /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7888
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7889
+ label,
7890
+ " error"
7891
+ ] }),
7892
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step?.error }) })
7893
+ ] }) })
7894
+ ] })
7895
+ ] })
7896
+ ]
7897
+ }
7898
+ ),
7899
+ !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden", color: "red" } })
7705
7900
  ] });
7706
7901
  }
7902
+ const CodeDialogContent = ({ data }) => {
7903
+ const theme = useCodemirrorTheme();
7904
+ if (typeof data !== "string") {
7905
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7906
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(data, null, 2) }) }),
7907
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(data, null, 2), theme, extensions: [jsonLanguage] }) })
7908
+ ] });
7909
+ }
7910
+ try {
7911
+ const json = JSON.parse(data);
7912
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7913
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
7914
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: json, theme, extensions: [jsonLanguage] }) })
7915
+ ] });
7916
+ } catch (error) {
7917
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7918
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
7919
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [] }) })
7920
+ ] });
7921
+ }
7922
+ };
7923
+ const Clock = ({ startedAt, endedAt }) => {
7924
+ const [time, setTime] = useState(startedAt);
7925
+ useEffect(() => {
7926
+ const interval = setInterval(() => {
7927
+ setTime(Date.now());
7928
+ }, 100);
7929
+ return () => clearInterval(interval);
7930
+ }, [startedAt]);
7931
+ const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
7932
+ return /* @__PURE__ */ jsxs("span", { className: "text-xs text-icon3", children: [
7933
+ toSigFigs(timeDiff, 3),
7934
+ "ms"
7935
+ ] });
7936
+ };
7707
7937
 
7708
7938
  function WorkflowAfterNode({ data }) {
7709
7939
  const { steps } = data;
@@ -8737,33 +8967,6 @@ function CodeBlockDemo({
8737
8967
  ] });
8738
8968
  }
8739
8969
 
8740
- const WorkflowRunContext = createContext({});
8741
- function WorkflowRunProvider({ children }) {
8742
- const [legacyResult, setLegacyResult] = useState(null);
8743
- const [result, setResult] = useState(null);
8744
- const [payload, setPayload] = useState(null);
8745
- const clearData = () => {
8746
- setLegacyResult(null);
8747
- setResult(null);
8748
- setPayload(null);
8749
- };
8750
- return /* @__PURE__ */ jsx(
8751
- WorkflowRunContext.Provider,
8752
- {
8753
- value: {
8754
- legacyResult,
8755
- setLegacyResult,
8756
- result,
8757
- setResult,
8758
- payload,
8759
- setPayload,
8760
- clearData
8761
- },
8762
- children
8763
- }
8764
- );
8765
- }
8766
-
8767
8970
  const WorkflowCard = ({ header, children, footer }) => {
8768
8971
  return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface4", children: [
8769
8972
  /* @__PURE__ */ jsx("div", { className: "py-1 px-2 flex items-center gap-3", children: header }),
@@ -8971,6 +9174,48 @@ function LegacyWorkflowTrigger({
8971
9174
  ] }) });
8972
9175
  }
8973
9176
 
9177
+ const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
9178
+ SliderPrimitive.Root,
9179
+ {
9180
+ ref,
9181
+ className: cn("relative flex w-full touch-none select-none items-center", className),
9182
+ ...props,
9183
+ children: [
9184
+ /* @__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" }) }),
9185
+ /* @__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" })
9186
+ ]
9187
+ }
9188
+ ));
9189
+ Slider.displayName = SliderPrimitive.Root.displayName;
9190
+
9191
+ const ZoomSlider = forwardRef(({ className, ...props }) => {
9192
+ const { zoom } = useViewport();
9193
+ const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
9194
+ return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
9195
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
9196
+ /* @__PURE__ */ jsx(
9197
+ Slider,
9198
+ {
9199
+ className: "w-[140px]",
9200
+ value: [zoom],
9201
+ min: 0.01,
9202
+ max: 1,
9203
+ step: 0.01,
9204
+ onValueChange: (values) => {
9205
+ zoomTo(values[0]);
9206
+ }
9207
+ }
9208
+ ),
9209
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
9210
+ /* @__PURE__ */ jsxs(Button$1, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
9211
+ (100 * zoom).toFixed(0),
9212
+ "%"
9213
+ ] }),
9214
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
9215
+ ] });
9216
+ });
9217
+ ZoomSlider.displayName = "ZoomSlider";
9218
+
8974
9219
  function WorkflowNestedGraph({ stepGraph, open }) {
8975
9220
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8976
9221
  stepGraph
@@ -8998,11 +9243,15 @@ function WorkflowNestedGraph({ stepGraph, open }) {
8998
9243
  nodes,
8999
9244
  edges,
9000
9245
  fitView: true,
9001
- fitViewOptions: { maxZoom: 0.85 },
9246
+ fitViewOptions: {
9247
+ maxZoom: 1
9248
+ },
9249
+ minZoom: 0.01,
9250
+ maxZoom: 1,
9002
9251
  nodeTypes,
9003
9252
  onNodesChange,
9004
9253
  children: [
9005
- /* @__PURE__ */ jsx(Controls, {}),
9254
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9006
9255
  /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9007
9256
  /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
9008
9257
  ]
@@ -9059,7 +9308,7 @@ function WorkflowNestedGraphProvider({ children }) {
9059
9308
  },
9060
9309
  children: [
9061
9310
  children,
9062
- /* @__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: [
9311
+ /* @__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: [
9063
9312
  /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
9064
9313
  /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9065
9314
  /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
@@ -9091,6 +9340,7 @@ function WorkflowGraphInner({ workflow }) {
9091
9340
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
9092
9341
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9093
9342
  const [edges] = useEdgesState(initialEdges);
9343
+ const { steps } = useCurrentRun();
9094
9344
  const nodeTypes = {
9095
9345
  "default-node": WorkflowDefaultNode,
9096
9346
  "condition-node": WorkflowConditionNode,
@@ -9098,19 +9348,27 @@ function WorkflowGraphInner({ workflow }) {
9098
9348
  "loop-result-node": WorkflowLoopResultNode,
9099
9349
  "nested-node": WorkflowNestedNode
9100
9350
  };
9101
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxs(
9351
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxs(
9102
9352
  ReactFlow,
9103
9353
  {
9104
9354
  nodes,
9105
- edges,
9355
+ edges: edges.map((e) => ({
9356
+ ...e,
9357
+ style: {
9358
+ ...e.style,
9359
+ stroke: steps[e.source]?.status === "success" ? "#22c55e" : void 0
9360
+ }
9361
+ })),
9106
9362
  nodeTypes,
9107
9363
  onNodesChange,
9108
9364
  fitView: true,
9109
9365
  fitViewOptions: {
9110
- maxZoom: 0.85
9366
+ maxZoom: 1
9111
9367
  },
9368
+ minZoom: 0.01,
9369
+ maxZoom: 1,
9112
9370
  children: [
9113
- /* @__PURE__ */ jsx(Controls, {}),
9371
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9114
9372
  /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9115
9373
  /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
9116
9374
  ]
@@ -9700,5 +9958,5 @@ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
9700
9958
  return { traces, firstCallLoading, error };
9701
9959
  };
9702
9960
 
9703
- 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, 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, TraceContext, TraceIcon, TraceProvider, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowTraces, WorkflowTrigger, refineTraces, usePlaygroundStore, usePolling, useSpeechRecognition, useTraces };
9961
+ 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, 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, TraceContext, TraceIcon, TraceProvider, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowTraces, WorkflowTrigger, refineTraces, useCurrentRun, usePlaygroundStore, usePolling, useSpeechRecognition, useTraces };
9704
9962
  //# sourceMappingURL=index.es.js.map