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

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] }]
@@ -7314,14 +7340,17 @@ const getStepNodeAndEdge = ({
7314
7340
  xIndex,
7315
7341
  yIndex,
7316
7342
  prevNodeIds,
7343
+ prevStepIds,
7317
7344
  nextStepFlow,
7318
7345
  condition,
7319
7346
  allPrevNodeIds
7320
7347
  }) => {
7321
7348
  let nextNodeIds = [];
7349
+ let nextStepIds = [];
7322
7350
  if (nextStepFlow?.type === "step" || nextStepFlow?.type === "foreach" || nextStepFlow?.type === "loop") {
7323
7351
  const nextStepId = allPrevNodeIds?.includes(nextStepFlow.step.id) ? `${nextStepFlow.step.id}-${yIndex + 1}` : nextStepFlow.step.id;
7324
7352
  nextNodeIds = [nextStepId];
7353
+ nextStepIds = [nextStepFlow.step.id];
7325
7354
  }
7326
7355
  if (nextStepFlow?.type === "parallel") {
7327
7356
  nextNodeIds = nextStepFlow?.steps.map((step) => {
@@ -7329,9 +7358,11 @@ const getStepNodeAndEdge = ({
7329
7358
  const nextStepId = allPrevNodeIds?.includes(stepId) ? `${stepId}-${yIndex + 1}` : stepId;
7330
7359
  return nextStepId;
7331
7360
  }) || [];
7361
+ nextStepIds = nextStepFlow?.steps.map((step) => step.step.id) || [];
7332
7362
  }
7333
7363
  if (nextStepFlow?.type === "conditional") {
7334
7364
  nextNodeIds = nextStepFlow?.serializedConditions.map((cond) => cond.id) || [];
7365
+ nextStepIds = nextStepFlow?.steps?.map((step) => step.step.id) || [];
7335
7366
  }
7336
7367
  if (stepFlow.type === "step" || stepFlow.type === "foreach") {
7337
7368
  const hasGraph = stepFlow.step.component === "WORKFLOW";
@@ -7344,6 +7375,8 @@ const getStepNodeAndEdge = ({
7344
7375
  type: "condition-node",
7345
7376
  data: {
7346
7377
  label: condition.id,
7378
+ previousStepId: prevStepIds[prevStepIds.length - 1],
7379
+ nextStepId: stepFlow.step.id,
7347
7380
  withoutTopHandle: false,
7348
7381
  withoutBottomHandle: !nextNodeIds.length,
7349
7382
  isLarge: true,
@@ -7360,38 +7393,43 @@ const getStepNodeAndEdge = ({
7360
7393
  description: stepFlow.step.description,
7361
7394
  withoutTopHandle: condition ? false : !prevNodeIds.length,
7362
7395
  withoutBottomHandle: !nextNodeIds.length,
7363
- stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0
7396
+ stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0,
7397
+ mapConfig: stepFlow.step.mapConfig
7364
7398
  }
7365
7399
  }
7366
7400
  ];
7367
7401
  const edges = [
7368
7402
  ...!prevNodeIds.length ? [] : condition ? [
7369
- ...prevNodeIds.map((prevNodeId) => ({
7403
+ ...prevNodeIds.map((prevNodeId, i) => ({
7370
7404
  id: `e${prevNodeId}-${condition.id}`,
7371
7405
  source: prevNodeId,
7406
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7372
7407
  target: condition.id,
7373
7408
  ...defaultEdgeOptions
7374
7409
  })),
7375
7410
  {
7376
7411
  id: `e${condition.id}-${nodeId}`,
7377
7412
  source: condition.id,
7413
+ data: { previousStepId: prevStepIds[prevStepIds.length - 1], nextStepId: stepFlow.step.id },
7378
7414
  target: nodeId,
7379
7415
  ...defaultEdgeOptions
7380
7416
  }
7381
- ] : prevNodeIds.map((prevNodeId) => ({
7417
+ ] : prevNodeIds.map((prevNodeId, i) => ({
7382
7418
  id: `e${prevNodeId}-${nodeId}`,
7383
7419
  source: prevNodeId,
7420
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7384
7421
  target: nodeId,
7385
7422
  ...defaultEdgeOptions
7386
7423
  })),
7387
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7424
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7388
7425
  id: `e${nodeId}-${nextNodeId}`,
7389
7426
  source: nodeId,
7427
+ data: { previousStepId: stepFlow.step.id, nextStepId: nextStepIds[i] },
7390
7428
  target: nextNodeId,
7391
7429
  ...defaultEdgeOptions
7392
7430
  }))
7393
7431
  ];
7394
- return { nodes, edges, nextPrevNodeIds: [nodeId] };
7432
+ return { nodes, edges, nextPrevNodeIds: [nodeId], nextPrevStepIds: [stepFlow.step.id] };
7395
7433
  }
7396
7434
  if (stepFlow.type === "loop") {
7397
7435
  const { step: _step, serializedCondition, loopType } = stepFlow;
@@ -7415,6 +7453,9 @@ const getStepNodeAndEdge = ({
7415
7453
  type: "condition-node",
7416
7454
  data: {
7417
7455
  label: serializedCondition.id,
7456
+ // conditionStepId: _step.id,
7457
+ previousStepId: _step.id,
7458
+ nextStepId: nextStepIds[0],
7418
7459
  withoutTopHandle: false,
7419
7460
  withoutBottomHandle: !nextNodeIds.length,
7420
7461
  isLarge: true,
@@ -7423,67 +7464,85 @@ const getStepNodeAndEdge = ({
7423
7464
  }
7424
7465
  ];
7425
7466
  const edges = [
7426
- ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId) => ({
7467
+ ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId, i) => ({
7427
7468
  id: `e${prevNodeId}-${_step.id}`,
7428
7469
  source: prevNodeId,
7470
+ data: { previousStepId: prevStepIds[i], nextStepId: _step.id },
7429
7471
  target: _step.id,
7430
7472
  ...defaultEdgeOptions
7431
7473
  })),
7432
7474
  {
7433
7475
  id: `e${_step.id}-${serializedCondition.id}`,
7434
7476
  source: _step.id,
7477
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[0] },
7435
7478
  target: serializedCondition.id,
7436
7479
  ...defaultEdgeOptions
7437
7480
  },
7438
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7481
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7439
7482
  id: `e${serializedCondition.id}-${nextNodeId}`,
7440
7483
  source: serializedCondition.id,
7484
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[i] },
7441
7485
  target: nextNodeId,
7442
7486
  ...defaultEdgeOptions
7443
7487
  }))
7444
7488
  ];
7445
- return { nodes, edges, nextPrevNodeIds: [serializedCondition.id] };
7489
+ return { nodes, edges, nextPrevNodeIds: [serializedCondition.id], nextPrevStepIds: [_step.id] };
7446
7490
  }
7447
7491
  if (stepFlow.type === "parallel") {
7448
7492
  let nodes = [];
7449
7493
  let edges = [];
7494
+ let nextPrevStepIds = [];
7450
7495
  stepFlow.steps.forEach((_stepFlow, index) => {
7451
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7496
+ const {
7497
+ nodes: _nodes,
7498
+ edges: _edges,
7499
+ nextPrevStepIds: _nextPrevStepIds
7500
+ } = getStepNodeAndEdge({
7452
7501
  stepFlow: _stepFlow,
7453
7502
  xIndex: index,
7454
7503
  yIndex,
7455
7504
  prevNodeIds,
7505
+ prevStepIds,
7456
7506
  nextStepFlow,
7457
7507
  allPrevNodeIds
7458
7508
  });
7459
7509
  nodes.push(..._nodes);
7460
7510
  edges.push(..._edges);
7511
+ nextPrevStepIds.push(..._nextPrevStepIds);
7461
7512
  });
7462
- return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id) };
7513
+ return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id), nextPrevStepIds };
7463
7514
  }
7464
7515
  if (stepFlow.type === "conditional") {
7465
7516
  let nodes = [];
7466
7517
  let edges = [];
7518
+ let nextPrevStepIds = [];
7467
7519
  stepFlow.steps.forEach((_stepFlow, index) => {
7468
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7520
+ const {
7521
+ nodes: _nodes,
7522
+ edges: _edges,
7523
+ nextPrevStepIds: _nextPrevStepIds
7524
+ } = getStepNodeAndEdge({
7469
7525
  stepFlow: _stepFlow,
7470
7526
  xIndex: index,
7471
7527
  yIndex,
7472
7528
  prevNodeIds,
7529
+ prevStepIds,
7473
7530
  nextStepFlow,
7474
7531
  condition: stepFlow.serializedConditions[index],
7475
7532
  allPrevNodeIds
7476
7533
  });
7477
7534
  nodes.push(..._nodes);
7478
7535
  edges.push(..._edges);
7536
+ nextPrevStepIds.push(..._nextPrevStepIds);
7479
7537
  });
7480
7538
  return {
7481
7539
  nodes,
7482
7540
  edges,
7483
- nextPrevNodeIds: nodes.filter(({ type }) => type !== "condition-node").map((node) => node.id)
7541
+ nextPrevNodeIds: nodes.filter(({ type }) => type !== "condition-node").map((node) => node.id),
7542
+ nextPrevStepIds
7484
7543
  };
7485
7544
  }
7486
- return { nodes: [], edges: [], nextPrevNodeIds: [] };
7545
+ return { nodes: [], edges: [], nextPrevNodeIds: [], nextPrevStepIds: [] };
7487
7546
  };
7488
7547
  const constructNodesAndEdges = ({
7489
7548
  stepGraph
@@ -7497,23 +7556,27 @@ const constructNodesAndEdges = ({
7497
7556
  let nodes = [];
7498
7557
  let edges = [];
7499
7558
  let prevNodeIds = [];
7559
+ let prevStepIds = [];
7500
7560
  let allPrevNodeIds = [];
7501
7561
  for (let index = 0; index < stepGraph.length; index++) {
7502
7562
  const {
7503
7563
  nodes: _nodes,
7504
7564
  edges: _edges,
7505
- nextPrevNodeIds
7565
+ nextPrevNodeIds,
7566
+ nextPrevStepIds
7506
7567
  } = getStepNodeAndEdge({
7507
7568
  stepFlow: stepGraph[index],
7508
7569
  xIndex: index,
7509
7570
  yIndex: index,
7510
7571
  prevNodeIds,
7572
+ prevStepIds,
7511
7573
  nextStepFlow: index === stepGraph.length - 1 ? void 0 : stepGraph[index + 1],
7512
7574
  allPrevNodeIds
7513
7575
  });
7514
7576
  nodes.push(..._nodes);
7515
7577
  edges.push(..._edges);
7516
7578
  prevNodeIds = nextPrevNodeIds;
7579
+ prevStepIds = nextPrevStepIds;
7517
7580
  allPrevNodeIds.push(...prevNodeIds);
7518
7581
  }
7519
7582
  const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);
@@ -7593,12 +7656,123 @@ const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...pr
7593
7656
  ));
7594
7657
  ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
7595
7658
 
7659
+ function convertWorkflowRunStateToWatchResult(runState) {
7660
+ const runId = runState.runId;
7661
+ const steps = {};
7662
+ const context = runState.context || {};
7663
+ Object.entries(context).forEach(([stepId, stepResult]) => {
7664
+ if (stepId !== "input" && "status" in stepResult) {
7665
+ const result = stepResult;
7666
+ steps[stepId] = {
7667
+ status: result.status,
7668
+ output: "output" in result ? result.output : void 0,
7669
+ payload: "payload" in result ? result.payload : void 0,
7670
+ resumePayload: "resumePayload" in result ? result.resumePayload : void 0,
7671
+ error: "error" in result ? result.error : void 0,
7672
+ startedAt: "startedAt" in result ? result.startedAt : Date.now(),
7673
+ endedAt: "endedAt" in result ? result.endedAt : void 0,
7674
+ suspendedAt: "suspendedAt" in result ? result.suspendedAt : void 0,
7675
+ resumedAt: "resumedAt" in result ? result.resumedAt : void 0
7676
+ };
7677
+ }
7678
+ });
7679
+ const status = determineWorkflowStatus(steps);
7680
+ return {
7681
+ type: "watch",
7682
+ payload: {
7683
+ workflowState: {
7684
+ status,
7685
+ steps,
7686
+ output: runState.value,
7687
+ payload: context.input,
7688
+ error: void 0
7689
+ }
7690
+ },
7691
+ eventTimestamp: new Date(runState.timestamp),
7692
+ runId
7693
+ };
7694
+ }
7695
+ function determineWorkflowStatus(steps) {
7696
+ const stepStatuses = Object.values(steps).map((step) => step.status);
7697
+ if (stepStatuses.includes("failed")) {
7698
+ return "failed";
7699
+ }
7700
+ if (stepStatuses.includes("suspended")) {
7701
+ return "suspended";
7702
+ }
7703
+ if (stepStatuses.every((status) => status === "success")) {
7704
+ return "success";
7705
+ }
7706
+ return "running";
7707
+ }
7708
+
7709
+ const WorkflowRunContext = createContext({});
7710
+ function WorkflowRunProvider({
7711
+ children,
7712
+ snapshot
7713
+ }) {
7714
+ const [legacyResult, setLegacyResult] = useState(null);
7715
+ const [result, setResult] = useState(
7716
+ () => snapshot ? convertWorkflowRunStateToWatchResult(snapshot) : null
7717
+ );
7718
+ const [payload, setPayload] = useState(null);
7719
+ const clearData = () => {
7720
+ setLegacyResult(null);
7721
+ setResult(null);
7722
+ setPayload(null);
7723
+ };
7724
+ useEffect(() => {
7725
+ if (snapshot?.runId) {
7726
+ setResult(convertWorkflowRunStateToWatchResult(snapshot));
7727
+ } else {
7728
+ setResult(null);
7729
+ }
7730
+ }, [snapshot?.runId ?? ""]);
7731
+ return /* @__PURE__ */ jsx(
7732
+ WorkflowRunContext.Provider,
7733
+ {
7734
+ value: {
7735
+ legacyResult,
7736
+ setLegacyResult,
7737
+ result,
7738
+ setResult,
7739
+ payload,
7740
+ setPayload,
7741
+ clearData
7742
+ },
7743
+ children
7744
+ }
7745
+ );
7746
+ }
7747
+
7748
+ const useCurrentRun = () => {
7749
+ const context = useContext(WorkflowRunContext);
7750
+ const workflowCurrentSteps = context.result?.payload?.workflowState?.steps ?? {};
7751
+ const steps = Object.entries(workflowCurrentSteps).reduce((acc, [key, value]) => {
7752
+ return {
7753
+ ...acc,
7754
+ [key]: {
7755
+ error: value.error,
7756
+ startedAt: value.startedAt,
7757
+ endedAt: value.endedAt,
7758
+ status: value.status,
7759
+ output: value.output,
7760
+ input: value.payload
7761
+ }
7762
+ };
7763
+ }, {});
7764
+ return { steps, isRunning: Boolean(context.payload) };
7765
+ };
7766
+
7596
7767
  function WorkflowConditionNode({ data }) {
7597
- const { conditions } = data;
7768
+ const { conditions, previousStepId, nextStepId } = data;
7598
7769
  const [open, setOpen] = useState(true);
7599
7770
  const [openDialog, setOpenDialog] = useState(false);
7600
7771
  const type = conditions[0]?.type;
7601
7772
  const isCollapsible = (conditions.some((condition) => condition.fnString) || conditions?.length > 1) && type !== "else";
7773
+ const { steps } = useCurrentRun();
7774
+ const previousStep = steps[previousStepId];
7775
+ const nextStep = steps[nextStepId];
7602
7776
  return /* @__PURE__ */ jsxs(
7603
7777
  Collapsible,
7604
7778
  {
@@ -7608,7 +7782,11 @@ function WorkflowConditionNode({ data }) {
7608
7782
  setOpen(_open);
7609
7783
  }
7610
7784
  },
7611
- className: cn("bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2"),
7785
+ className: cn(
7786
+ "bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2 border-sm border-border1",
7787
+ previousStep?.status === "success" && nextStep && "ring-2 ring-accent1",
7788
+ previousStep?.status === "failed" && nextStep && "ring-2 ring-accent2"
7789
+ ),
7612
7790
  children: [
7613
7791
  /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
7614
7792
  /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
@@ -7692,16 +7870,125 @@ function WorkflowConditionNode({ data }) {
7692
7870
  );
7693
7871
  }
7694
7872
 
7873
+ const Clock = ({ startedAt, endedAt }) => {
7874
+ const [time, setTime] = useState(startedAt);
7875
+ useEffect(() => {
7876
+ const interval = setInterval(() => {
7877
+ setTime(Date.now());
7878
+ }, 100);
7879
+ return () => clearInterval(interval);
7880
+ }, [startedAt]);
7881
+ const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
7882
+ return /* @__PURE__ */ jsxs("span", { className: "text-xs text-icon3", children: [
7883
+ toSigFigs(timeDiff, 3),
7884
+ "ms"
7885
+ ] });
7886
+ };
7887
+
7888
+ const CodeDialogContent = ({ data }) => {
7889
+ const theme = useCodemirrorTheme();
7890
+ if (typeof data !== "string") {
7891
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7892
+ /* @__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) }) }),
7893
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(data, null, 2), theme, extensions: [jsonLanguage] }) })
7894
+ ] });
7895
+ }
7896
+ try {
7897
+ const json = JSON.parse(data);
7898
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7899
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
7900
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(json, null, 2), theme, extensions: [jsonLanguage] }) })
7901
+ ] });
7902
+ } catch (error) {
7903
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7904
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
7905
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [] }) })
7906
+ ] });
7907
+ }
7908
+ };
7909
+
7695
7910
  function WorkflowDefaultNode({ data }) {
7696
- const { label, description, withoutTopHandle, withoutBottomHandle } = data;
7697
- return /* @__PURE__ */ jsxs("div", { className: cn("bg-mastra-bg-8 rounded-md w-[274px]"), children: [
7911
+ const [isInputOpen, setIsInputOpen] = useState(false);
7912
+ const [isOutputOpen, setIsOutputOpen] = useState(false);
7913
+ const [isErrorOpen, setIsErrorOpen] = useState(false);
7914
+ const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
7915
+ const { steps, isRunning } = useCurrentRun();
7916
+ const { label, description, withoutTopHandle, withoutBottomHandle, mapConfig } = data;
7917
+ const step = steps[label];
7918
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7919
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7920
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7698
7921
  !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" } })
7922
+ /* @__PURE__ */ jsxs(
7923
+ "div",
7924
+ {
7925
+ className: cn(
7926
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
7927
+ step?.status === "success" && "ring-2 ring-accent1",
7928
+ step?.status === "failed" && "ring-2 ring-accent2"
7929
+ ),
7930
+ children: [
7931
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
7932
+ isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
7933
+ step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
7934
+ step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
7935
+ step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-icon3" }),
7936
+ step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon6 animate-spin" }),
7937
+ !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
7938
+ ] }),
7939
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
7940
+ label,
7941
+ " ",
7942
+ step?.startedAt && /* @__PURE__ */ jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
7943
+ ] })
7944
+ ] }),
7945
+ description && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
7946
+ (step?.input || step?.output || step?.error || mapConfig) && /* @__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: [
7947
+ mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
7948
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
7949
+ /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7950
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7951
+ label,
7952
+ " map config"
7953
+ ] }),
7954
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
7955
+ ] }) })
7956
+ ] }),
7957
+ step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
7958
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
7959
+ /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7960
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7961
+ label,
7962
+ " input"
7963
+ ] }),
7964
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.input }) })
7965
+ ] }) })
7966
+ ] }),
7967
+ step?.output && /* @__PURE__ */ jsxs(Fragment, { children: [
7968
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
7969
+ /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7970
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7971
+ label,
7972
+ " output"
7973
+ ] }),
7974
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.output }) })
7975
+ ] }) })
7976
+ ] }),
7977
+ step?.error && /* @__PURE__ */ jsxs(Fragment, { children: [
7978
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
7979
+ /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7980
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
7981
+ label,
7982
+ " error"
7983
+ ] }),
7984
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step?.error }) })
7985
+ ] }) })
7986
+ ] })
7987
+ ] })
7988
+ ]
7989
+ }
7990
+ ),
7991
+ !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden", color: "red" } })
7705
7992
  ] });
7706
7993
  }
7707
7994
 
@@ -8737,33 +9024,6 @@ function CodeBlockDemo({
8737
9024
  ] });
8738
9025
  }
8739
9026
 
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
9027
  const WorkflowCard = ({ header, children, footer }) => {
8768
9028
  return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface4", children: [
8769
9029
  /* @__PURE__ */ jsx("div", { className: "py-1 px-2 flex items-center gap-3", children: header }),
@@ -8971,6 +9231,48 @@ function LegacyWorkflowTrigger({
8971
9231
  ] }) });
8972
9232
  }
8973
9233
 
9234
+ const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
9235
+ SliderPrimitive.Root,
9236
+ {
9237
+ ref,
9238
+ className: cn("relative flex w-full touch-none select-none items-center", className),
9239
+ ...props,
9240
+ children: [
9241
+ /* @__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" }) }),
9242
+ /* @__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" })
9243
+ ]
9244
+ }
9245
+ ));
9246
+ Slider.displayName = SliderPrimitive.Root.displayName;
9247
+
9248
+ const ZoomSlider = forwardRef(({ className, ...props }) => {
9249
+ const { zoom } = useViewport();
9250
+ const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
9251
+ return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
9252
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
9253
+ /* @__PURE__ */ jsx(
9254
+ Slider,
9255
+ {
9256
+ className: "w-[140px]",
9257
+ value: [zoom],
9258
+ min: 0.01,
9259
+ max: 1,
9260
+ step: 0.01,
9261
+ onValueChange: (values) => {
9262
+ zoomTo(values[0]);
9263
+ }
9264
+ }
9265
+ ),
9266
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
9267
+ /* @__PURE__ */ jsxs(Button$1, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
9268
+ (100 * zoom).toFixed(0),
9269
+ "%"
9270
+ ] }),
9271
+ /* @__PURE__ */ jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
9272
+ ] });
9273
+ });
9274
+ ZoomSlider.displayName = "ZoomSlider";
9275
+
8974
9276
  function WorkflowNestedGraph({ stepGraph, open }) {
8975
9277
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8976
9278
  stepGraph
@@ -8992,17 +9294,21 @@ function WorkflowNestedGraph({ stepGraph, open }) {
8992
9294
  }, 500);
8993
9295
  }
8994
9296
  }, [open]);
8995
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative", children: isMounted ? /* @__PURE__ */ jsxs(
9297
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
8996
9298
  ReactFlow,
8997
9299
  {
8998
9300
  nodes,
8999
9301
  edges,
9000
9302
  fitView: true,
9001
- fitViewOptions: { maxZoom: 0.85 },
9303
+ fitViewOptions: {
9304
+ maxZoom: 1
9305
+ },
9306
+ minZoom: 0.01,
9307
+ maxZoom: 1,
9002
9308
  nodeTypes,
9003
9309
  onNodesChange,
9004
9310
  children: [
9005
- /* @__PURE__ */ jsx(Controls, {}),
9311
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9006
9312
  /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9007
9313
  /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
9008
9314
  ]
@@ -9059,7 +9365,7 @@ function WorkflowNestedGraphProvider({ children }) {
9059
9365
  },
9060
9366
  children: [
9061
9367
  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: [
9368
+ /* @__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
9369
  /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
9064
9370
  /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9065
9371
  /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
@@ -9075,14 +9381,88 @@ function WorkflowNestedGraphProvider({ children }) {
9075
9381
  }
9076
9382
 
9077
9383
  function WorkflowNestedNode({ data }) {
9078
- const { label, withoutTopHandle, withoutBottomHandle, stepGraph } = data;
9384
+ const [isInputOpen, setIsInputOpen] = useState(false);
9385
+ const [isOutputOpen, setIsOutputOpen] = useState(false);
9386
+ const [isErrorOpen, setIsErrorOpen] = useState(false);
9387
+ const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
9388
+ const { steps, isRunning } = useCurrentRun();
9079
9389
  const { showNestedGraph } = useContext(WorkflowNestedGraphContext);
9080
- return /* @__PURE__ */ jsxs("div", { className: cn("bg-[rgba(29,29,29,0.5)] rounded-md h-full overflow-scroll w-[274px]"), children: [
9390
+ const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig } = data;
9391
+ const step = steps[label];
9392
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
9393
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
9394
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9081
9395
  !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
9082
- /* @__PURE__ */ jsx("div", { className: "p-2 cursor-pointer", onClick: () => showNestedGraph({ label, stepGraph }), children: /* @__PURE__ */ jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-1.5 rounded-sm p-2 cursor-pointer", children: [
9083
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9084
- /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
9085
- ] }) }),
9396
+ /* @__PURE__ */ jsxs(
9397
+ "div",
9398
+ {
9399
+ className: cn(
9400
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
9401
+ step?.status === "success" && "ring-2 ring-accent1",
9402
+ step?.status === "failed" && "ring-2 ring-accent2"
9403
+ ),
9404
+ children: [
9405
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
9406
+ isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
9407
+ step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
9408
+ step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
9409
+ step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-icon3" }),
9410
+ step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-icon6 animate-spin" }),
9411
+ !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
9412
+ ] }),
9413
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
9414
+ label,
9415
+ " ",
9416
+ step?.startedAt && /* @__PURE__ */ jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
9417
+ ] })
9418
+ ] }),
9419
+ description && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
9420
+ /* @__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: [
9421
+ /* @__PURE__ */ jsx(Button, { onClick: () => showNestedGraph({ label, stepGraph }), children: "View workflow" }),
9422
+ mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
9423
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
9424
+ /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9425
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9426
+ label,
9427
+ " map config"
9428
+ ] }),
9429
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
9430
+ ] }) })
9431
+ ] }),
9432
+ step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
9433
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
9434
+ /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9435
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9436
+ label,
9437
+ " input"
9438
+ ] }),
9439
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.input }) })
9440
+ ] }) })
9441
+ ] }),
9442
+ step?.output && /* @__PURE__ */ jsxs(Fragment, { children: [
9443
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
9444
+ /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9445
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9446
+ label,
9447
+ " output"
9448
+ ] }),
9449
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step.output }) })
9450
+ ] }) })
9451
+ ] }),
9452
+ step?.error && /* @__PURE__ */ jsxs(Fragment, { children: [
9453
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
9454
+ /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9455
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9456
+ label,
9457
+ " error"
9458
+ ] }),
9459
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: step?.error }) })
9460
+ ] }) })
9461
+ ] })
9462
+ ] })
9463
+ ]
9464
+ }
9465
+ ),
9086
9466
  !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
9087
9467
  ] });
9088
9468
  }
@@ -9091,6 +9471,7 @@ function WorkflowGraphInner({ workflow }) {
9091
9471
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
9092
9472
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9093
9473
  const [edges] = useEdgesState(initialEdges);
9474
+ const { steps } = useCurrentRun();
9094
9475
  const nodeTypes = {
9095
9476
  "default-node": WorkflowDefaultNode,
9096
9477
  "condition-node": WorkflowConditionNode,
@@ -9098,19 +9479,27 @@ function WorkflowGraphInner({ workflow }) {
9098
9479
  "loop-result-node": WorkflowLoopResultNode,
9099
9480
  "nested-node": WorkflowNestedNode
9100
9481
  };
9101
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxs(
9482
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxs(
9102
9483
  ReactFlow,
9103
9484
  {
9104
9485
  nodes,
9105
- edges,
9486
+ edges: edges.map((e) => ({
9487
+ ...e,
9488
+ style: {
9489
+ ...e.style,
9490
+ stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
9491
+ }
9492
+ })),
9106
9493
  nodeTypes,
9107
9494
  onNodesChange,
9108
9495
  fitView: true,
9109
9496
  fitViewOptions: {
9110
- maxZoom: 0.85
9497
+ maxZoom: 1
9111
9498
  },
9499
+ minZoom: 0.01,
9500
+ maxZoom: 1,
9112
9501
  children: [
9113
- /* @__PURE__ */ jsx(Controls, {}),
9502
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9114
9503
  /* @__PURE__ */ jsx(MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9115
9504
  /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Dots, gap: 12, size: 0.5 })
9116
9505
  ]
@@ -9700,5 +10089,5 @@ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
9700
10089
  return { traces, firstCallLoading, error };
9701
10090
  };
9702
10091
 
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 };
10092
+ 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
10093
  //# sourceMappingURL=index.es.js.map