@mastra/playground-ui 5.1.1-alpha.4 → 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.cjs.js CHANGED
@@ -7372,14 +7372,17 @@ const getStepNodeAndEdge = ({
7372
7372
  xIndex,
7373
7373
  yIndex,
7374
7374
  prevNodeIds,
7375
+ prevStepIds,
7375
7376
  nextStepFlow,
7376
7377
  condition,
7377
7378
  allPrevNodeIds
7378
7379
  }) => {
7379
7380
  let nextNodeIds = [];
7381
+ let nextStepIds = [];
7380
7382
  if (nextStepFlow?.type === "step" || nextStepFlow?.type === "foreach" || nextStepFlow?.type === "loop") {
7381
7383
  const nextStepId = allPrevNodeIds?.includes(nextStepFlow.step.id) ? `${nextStepFlow.step.id}-${yIndex + 1}` : nextStepFlow.step.id;
7382
7384
  nextNodeIds = [nextStepId];
7385
+ nextStepIds = [nextStepFlow.step.id];
7383
7386
  }
7384
7387
  if (nextStepFlow?.type === "parallel") {
7385
7388
  nextNodeIds = nextStepFlow?.steps.map((step) => {
@@ -7387,9 +7390,11 @@ const getStepNodeAndEdge = ({
7387
7390
  const nextStepId = allPrevNodeIds?.includes(stepId) ? `${stepId}-${yIndex + 1}` : stepId;
7388
7391
  return nextStepId;
7389
7392
  }) || [];
7393
+ nextStepIds = nextStepFlow?.steps.map((step) => step.step.id) || [];
7390
7394
  }
7391
7395
  if (nextStepFlow?.type === "conditional") {
7392
7396
  nextNodeIds = nextStepFlow?.serializedConditions.map((cond) => cond.id) || [];
7397
+ nextStepIds = nextStepFlow?.steps?.map((step) => step.step.id) || [];
7393
7398
  }
7394
7399
  if (stepFlow.type === "step" || stepFlow.type === "foreach") {
7395
7400
  const hasGraph = stepFlow.step.component === "WORKFLOW";
@@ -7402,6 +7407,8 @@ const getStepNodeAndEdge = ({
7402
7407
  type: "condition-node",
7403
7408
  data: {
7404
7409
  label: condition.id,
7410
+ previousStepId: prevStepIds[prevStepIds.length - 1],
7411
+ nextStepId: stepFlow.step.id,
7405
7412
  withoutTopHandle: false,
7406
7413
  withoutBottomHandle: !nextNodeIds.length,
7407
7414
  isLarge: true,
@@ -7418,38 +7425,43 @@ const getStepNodeAndEdge = ({
7418
7425
  description: stepFlow.step.description,
7419
7426
  withoutTopHandle: condition ? false : !prevNodeIds.length,
7420
7427
  withoutBottomHandle: !nextNodeIds.length,
7421
- stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0
7428
+ stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0,
7429
+ mapConfig: stepFlow.step.mapConfig
7422
7430
  }
7423
7431
  }
7424
7432
  ];
7425
7433
  const edges = [
7426
7434
  ...!prevNodeIds.length ? [] : condition ? [
7427
- ...prevNodeIds.map((prevNodeId) => ({
7435
+ ...prevNodeIds.map((prevNodeId, i) => ({
7428
7436
  id: `e${prevNodeId}-${condition.id}`,
7429
7437
  source: prevNodeId,
7438
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7430
7439
  target: condition.id,
7431
7440
  ...defaultEdgeOptions
7432
7441
  })),
7433
7442
  {
7434
7443
  id: `e${condition.id}-${nodeId}`,
7435
7444
  source: condition.id,
7445
+ data: { previousStepId: prevStepIds[prevStepIds.length - 1], nextStepId: stepFlow.step.id },
7436
7446
  target: nodeId,
7437
7447
  ...defaultEdgeOptions
7438
7448
  }
7439
- ] : prevNodeIds.map((prevNodeId) => ({
7449
+ ] : prevNodeIds.map((prevNodeId, i) => ({
7440
7450
  id: `e${prevNodeId}-${nodeId}`,
7441
7451
  source: prevNodeId,
7452
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7442
7453
  target: nodeId,
7443
7454
  ...defaultEdgeOptions
7444
7455
  })),
7445
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7456
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7446
7457
  id: `e${nodeId}-${nextNodeId}`,
7447
7458
  source: nodeId,
7459
+ data: { previousStepId: stepFlow.step.id, nextStepId: nextStepIds[i] },
7448
7460
  target: nextNodeId,
7449
7461
  ...defaultEdgeOptions
7450
7462
  }))
7451
7463
  ];
7452
- return { nodes, edges, nextPrevNodeIds: [nodeId] };
7464
+ return { nodes, edges, nextPrevNodeIds: [nodeId], nextPrevStepIds: [stepFlow.step.id] };
7453
7465
  }
7454
7466
  if (stepFlow.type === "loop") {
7455
7467
  const { step: _step, serializedCondition, loopType } = stepFlow;
@@ -7473,6 +7485,9 @@ const getStepNodeAndEdge = ({
7473
7485
  type: "condition-node",
7474
7486
  data: {
7475
7487
  label: serializedCondition.id,
7488
+ // conditionStepId: _step.id,
7489
+ previousStepId: _step.id,
7490
+ nextStepId: nextStepIds[0],
7476
7491
  withoutTopHandle: false,
7477
7492
  withoutBottomHandle: !nextNodeIds.length,
7478
7493
  isLarge: true,
@@ -7481,67 +7496,85 @@ const getStepNodeAndEdge = ({
7481
7496
  }
7482
7497
  ];
7483
7498
  const edges = [
7484
- ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId) => ({
7499
+ ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId, i) => ({
7485
7500
  id: `e${prevNodeId}-${_step.id}`,
7486
7501
  source: prevNodeId,
7502
+ data: { previousStepId: prevStepIds[i], nextStepId: _step.id },
7487
7503
  target: _step.id,
7488
7504
  ...defaultEdgeOptions
7489
7505
  })),
7490
7506
  {
7491
7507
  id: `e${_step.id}-${serializedCondition.id}`,
7492
7508
  source: _step.id,
7509
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[0] },
7493
7510
  target: serializedCondition.id,
7494
7511
  ...defaultEdgeOptions
7495
7512
  },
7496
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7513
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7497
7514
  id: `e${serializedCondition.id}-${nextNodeId}`,
7498
7515
  source: serializedCondition.id,
7516
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[i] },
7499
7517
  target: nextNodeId,
7500
7518
  ...defaultEdgeOptions
7501
7519
  }))
7502
7520
  ];
7503
- return { nodes, edges, nextPrevNodeIds: [serializedCondition.id] };
7521
+ return { nodes, edges, nextPrevNodeIds: [serializedCondition.id], nextPrevStepIds: [_step.id] };
7504
7522
  }
7505
7523
  if (stepFlow.type === "parallel") {
7506
7524
  let nodes = [];
7507
7525
  let edges = [];
7526
+ let nextPrevStepIds = [];
7508
7527
  stepFlow.steps.forEach((_stepFlow, index) => {
7509
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7528
+ const {
7529
+ nodes: _nodes,
7530
+ edges: _edges,
7531
+ nextPrevStepIds: _nextPrevStepIds
7532
+ } = getStepNodeAndEdge({
7510
7533
  stepFlow: _stepFlow,
7511
7534
  xIndex: index,
7512
7535
  yIndex,
7513
7536
  prevNodeIds,
7537
+ prevStepIds,
7514
7538
  nextStepFlow,
7515
7539
  allPrevNodeIds
7516
7540
  });
7517
7541
  nodes.push(..._nodes);
7518
7542
  edges.push(..._edges);
7543
+ nextPrevStepIds.push(..._nextPrevStepIds);
7519
7544
  });
7520
- return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id) };
7545
+ return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id), nextPrevStepIds };
7521
7546
  }
7522
7547
  if (stepFlow.type === "conditional") {
7523
7548
  let nodes = [];
7524
7549
  let edges = [];
7550
+ let nextPrevStepIds = [];
7525
7551
  stepFlow.steps.forEach((_stepFlow, index) => {
7526
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7552
+ const {
7553
+ nodes: _nodes,
7554
+ edges: _edges,
7555
+ nextPrevStepIds: _nextPrevStepIds
7556
+ } = getStepNodeAndEdge({
7527
7557
  stepFlow: _stepFlow,
7528
7558
  xIndex: index,
7529
7559
  yIndex,
7530
7560
  prevNodeIds,
7561
+ prevStepIds,
7531
7562
  nextStepFlow,
7532
7563
  condition: stepFlow.serializedConditions[index],
7533
7564
  allPrevNodeIds
7534
7565
  });
7535
7566
  nodes.push(..._nodes);
7536
7567
  edges.push(..._edges);
7568
+ nextPrevStepIds.push(..._nextPrevStepIds);
7537
7569
  });
7538
7570
  return {
7539
7571
  nodes,
7540
7572
  edges,
7541
- nextPrevNodeIds: nodes.filter(({ type }) => type !== "condition-node").map((node) => node.id)
7573
+ nextPrevNodeIds: nodes.filter(({ type }) => type !== "condition-node").map((node) => node.id),
7574
+ nextPrevStepIds
7542
7575
  };
7543
7576
  }
7544
- return { nodes: [], edges: [], nextPrevNodeIds: [] };
7577
+ return { nodes: [], edges: [], nextPrevNodeIds: [], nextPrevStepIds: [] };
7545
7578
  };
7546
7579
  const constructNodesAndEdges = ({
7547
7580
  stepGraph
@@ -7555,23 +7588,27 @@ const constructNodesAndEdges = ({
7555
7588
  let nodes = [];
7556
7589
  let edges = [];
7557
7590
  let prevNodeIds = [];
7591
+ let prevStepIds = [];
7558
7592
  let allPrevNodeIds = [];
7559
7593
  for (let index = 0; index < stepGraph.length; index++) {
7560
7594
  const {
7561
7595
  nodes: _nodes,
7562
7596
  edges: _edges,
7563
- nextPrevNodeIds
7597
+ nextPrevNodeIds,
7598
+ nextPrevStepIds
7564
7599
  } = getStepNodeAndEdge({
7565
7600
  stepFlow: stepGraph[index],
7566
7601
  xIndex: index,
7567
7602
  yIndex: index,
7568
7603
  prevNodeIds,
7604
+ prevStepIds,
7569
7605
  nextStepFlow: index === stepGraph.length - 1 ? void 0 : stepGraph[index + 1],
7570
7606
  allPrevNodeIds
7571
7607
  });
7572
7608
  nodes.push(..._nodes);
7573
7609
  edges.push(..._edges);
7574
7610
  prevNodeIds = nextPrevNodeIds;
7611
+ prevStepIds = nextPrevStepIds;
7575
7612
  allPrevNodeIds.push(...prevNodeIds);
7576
7613
  }
7577
7614
  const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);
@@ -7651,105 +7688,6 @@ const ScrollBar = React__namespace.forwardRef(({ className, orientation = "verti
7651
7688
  ));
7652
7689
  ScrollBar.displayName = ScrollAreaPrimitive__namespace.ScrollAreaScrollbar.displayName;
7653
7690
 
7654
- function WorkflowConditionNode({ data }) {
7655
- const { conditions } = data;
7656
- const [open, setOpen] = React.useState(true);
7657
- const [openDialog, setOpenDialog] = React.useState(false);
7658
- const type = conditions[0]?.type;
7659
- const isCollapsible = (conditions.some((condition) => condition.fnString) || conditions?.length > 1) && type !== "else";
7660
- return /* @__PURE__ */ jsxRuntime.jsxs(
7661
- Collapsible,
7662
- {
7663
- open: !isCollapsible ? true : open,
7664
- onOpenChange: (_open) => {
7665
- if (isCollapsible) {
7666
- setOpen(_open);
7667
- }
7668
- },
7669
- className: cn("bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2"),
7670
- children: [
7671
- /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
7672
- /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
7673
- /* @__PURE__ */ jsxRuntime.jsx(
7674
- Text,
7675
- {
7676
- size: "xs",
7677
- weight: "medium",
7678
- className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
7679
- children: type?.toUpperCase()
7680
- }
7681
- ),
7682
- isCollapsible && /* @__PURE__ */ jsxRuntime.jsx(
7683
- lucideReact.ChevronDown,
7684
- {
7685
- className: cn("w-4 h-4 transition-transform", {
7686
- "transform rotate-180": open
7687
- })
7688
- }
7689
- )
7690
- ] }),
7691
- type === "else" ? null : /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent, { className: "flex flex-col gap-2", children: conditions.map((condition, index) => {
7692
- return condition.fnString ? /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
7693
- /* @__PURE__ */ jsxRuntime.jsx(prismReactRenderer.Highlight, { theme: prismReactRenderer.themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsxRuntime.jsx(
7694
- "pre",
7695
- {
7696
- className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full cursor-pointer rounded-lg mt-2`,
7697
- style: {
7698
- ...style,
7699
- backgroundColor: "transparent",
7700
- border: "1px solid #343434",
7701
- maxHeight: "9.62rem"
7702
- },
7703
- onClick: () => setOpenDialog(true),
7704
- children: tokens.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { ...getLineProps({ line }), children: [
7705
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7706
- line.map((token, key) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...getTokenProps({ token }) }, key))
7707
- ] }, i))
7708
- }
7709
- ) }),
7710
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: openDialog, onOpenChange: setOpenDialog, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "max-w-[30rem] bg-[#121212] p-[0.5rem]", children: [
7711
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "sr-only", children: "Condition Function" }),
7712
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "w-full p-2", maxHeight: "400px", children: /* @__PURE__ */ jsxRuntime.jsx(prismReactRenderer.Highlight, { theme: prismReactRenderer.themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsxRuntime.jsx(
7713
- "pre",
7714
- {
7715
- className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full rounded-lg mt-2 dark:bg-zinc-800`,
7716
- style: {
7717
- ...style,
7718
- backgroundColor: "#121212",
7719
- padding: "0 0.75rem 0 0"
7720
- },
7721
- children: tokens.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { ...getLineProps({ line }), children: [
7722
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7723
- line.map((token, key) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...getTokenProps({ token }) }, key))
7724
- ] }, i))
7725
- }
7726
- ) }) })
7727
- ] }) })
7728
- ] }, `${condition.fnString}-${index}`) : /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: condition.ref?.step ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
7729
- index === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(
7730
- Text,
7731
- {
7732
- size: "xs",
7733
- weight: "medium",
7734
- className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px]",
7735
- children: condition.conj?.toLocaleUpperCase() || "WHEN"
7736
- }
7737
- ),
7738
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { size: "xs", className: " text-mastra-el-3 flex-1", children: [
7739
- condition.ref.step.id || condition.ref.step,
7740
- "'s ",
7741
- condition.ref.path,
7742
- " ",
7743
- Object.entries(condition.query).map(([key, value]) => `${key} ${String(value)}`)
7744
- ] })
7745
- ] }) : null }, `${condition.ref?.path}-${index}`);
7746
- }) }),
7747
- /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden" } })
7748
- ]
7749
- }
7750
- );
7751
- }
7752
-
7753
7691
  function convertWorkflowRunStateToWatchResult(runState) {
7754
7692
  const runId = runState.runId;
7755
7693
  const steps = {};
@@ -7858,12 +7796,156 @@ const useCurrentRun = () => {
7858
7796
  return { steps, isRunning: Boolean(context.payload) };
7859
7797
  };
7860
7798
 
7799
+ function WorkflowConditionNode({ data }) {
7800
+ const { conditions, previousStepId, nextStepId } = data;
7801
+ const [open, setOpen] = React.useState(true);
7802
+ const [openDialog, setOpenDialog] = React.useState(false);
7803
+ const type = conditions[0]?.type;
7804
+ const isCollapsible = (conditions.some((condition) => condition.fnString) || conditions?.length > 1) && type !== "else";
7805
+ const { steps } = useCurrentRun();
7806
+ const previousStep = steps[previousStepId];
7807
+ const nextStep = steps[nextStepId];
7808
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7809
+ Collapsible,
7810
+ {
7811
+ open: !isCollapsible ? true : open,
7812
+ onOpenChange: (_open) => {
7813
+ if (isCollapsible) {
7814
+ setOpen(_open);
7815
+ }
7816
+ },
7817
+ className: cn(
7818
+ "bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2 border-sm border-border1",
7819
+ previousStep?.status === "success" && nextStep && "ring-2 ring-accent1",
7820
+ previousStep?.status === "failed" && nextStep && "ring-2 ring-accent2"
7821
+ ),
7822
+ children: [
7823
+ /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
7824
+ /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
7825
+ /* @__PURE__ */ jsxRuntime.jsx(
7826
+ Text,
7827
+ {
7828
+ size: "xs",
7829
+ weight: "medium",
7830
+ className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
7831
+ children: type?.toUpperCase()
7832
+ }
7833
+ ),
7834
+ isCollapsible && /* @__PURE__ */ jsxRuntime.jsx(
7835
+ lucideReact.ChevronDown,
7836
+ {
7837
+ className: cn("w-4 h-4 transition-transform", {
7838
+ "transform rotate-180": open
7839
+ })
7840
+ }
7841
+ )
7842
+ ] }),
7843
+ type === "else" ? null : /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent, { className: "flex flex-col gap-2", children: conditions.map((condition, index) => {
7844
+ return condition.fnString ? /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
7845
+ /* @__PURE__ */ jsxRuntime.jsx(prismReactRenderer.Highlight, { theme: prismReactRenderer.themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsxRuntime.jsx(
7846
+ "pre",
7847
+ {
7848
+ className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full cursor-pointer rounded-lg mt-2`,
7849
+ style: {
7850
+ ...style,
7851
+ backgroundColor: "transparent",
7852
+ border: "1px solid #343434",
7853
+ maxHeight: "9.62rem"
7854
+ },
7855
+ onClick: () => setOpenDialog(true),
7856
+ children: tokens.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { ...getLineProps({ line }), children: [
7857
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7858
+ line.map((token, key) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...getTokenProps({ token }) }, key))
7859
+ ] }, i))
7860
+ }
7861
+ ) }),
7862
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: openDialog, onOpenChange: setOpenDialog, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "max-w-[30rem] bg-[#121212] p-[0.5rem]", children: [
7863
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "sr-only", children: "Condition Function" }),
7864
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "w-full p-2", maxHeight: "400px", children: /* @__PURE__ */ jsxRuntime.jsx(prismReactRenderer.Highlight, { theme: prismReactRenderer.themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsxRuntime.jsx(
7865
+ "pre",
7866
+ {
7867
+ className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full rounded-lg mt-2 dark:bg-zinc-800`,
7868
+ style: {
7869
+ ...style,
7870
+ backgroundColor: "#121212",
7871
+ padding: "0 0.75rem 0 0"
7872
+ },
7873
+ children: tokens.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { ...getLineProps({ line }), children: [
7874
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7875
+ line.map((token, key) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...getTokenProps({ token }) }, key))
7876
+ ] }, i))
7877
+ }
7878
+ ) }) })
7879
+ ] }) })
7880
+ ] }, `${condition.fnString}-${index}`) : /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: condition.ref?.step ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
7881
+ index === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(
7882
+ Text,
7883
+ {
7884
+ size: "xs",
7885
+ weight: "medium",
7886
+ className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px]",
7887
+ children: condition.conj?.toLocaleUpperCase() || "WHEN"
7888
+ }
7889
+ ),
7890
+ /* @__PURE__ */ jsxRuntime.jsxs(Text, { size: "xs", className: " text-mastra-el-3 flex-1", children: [
7891
+ condition.ref.step.id || condition.ref.step,
7892
+ "'s ",
7893
+ condition.ref.path,
7894
+ " ",
7895
+ Object.entries(condition.query).map(([key, value]) => `${key} ${String(value)}`)
7896
+ ] })
7897
+ ] }) : null }, `${condition.ref?.path}-${index}`);
7898
+ }) }),
7899
+ /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden" } })
7900
+ ]
7901
+ }
7902
+ );
7903
+ }
7904
+
7905
+ const Clock = ({ startedAt, endedAt }) => {
7906
+ const [time, setTime] = React.useState(startedAt);
7907
+ React.useEffect(() => {
7908
+ const interval = setInterval(() => {
7909
+ setTime(Date.now());
7910
+ }, 100);
7911
+ return () => clearInterval(interval);
7912
+ }, [startedAt]);
7913
+ const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
7914
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-icon3", children: [
7915
+ toSigFigs(timeDiff, 3),
7916
+ "ms"
7917
+ ] });
7918
+ };
7919
+
7920
+ const CodeDialogContent = ({ data }) => {
7921
+ const theme = useCodemirrorTheme();
7922
+ if (typeof data !== "string") {
7923
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7924
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: JSON.stringify(data, null, 2) }) }),
7925
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: JSON.stringify(data, null, 2), theme, extensions: [langJson.jsonLanguage] }) })
7926
+ ] });
7927
+ }
7928
+ try {
7929
+ const json = JSON.parse(data);
7930
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
7932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: JSON.stringify(json, null, 2), theme, extensions: [langJson.jsonLanguage] }) })
7933
+ ] });
7934
+ } catch (error) {
7935
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7936
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
7937
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: data, theme, extensions: [] }) })
7938
+ ] });
7939
+ }
7940
+ };
7941
+
7861
7942
  function WorkflowDefaultNode({ data }) {
7862
7943
  const [isInputOpen, setIsInputOpen] = React.useState(false);
7863
7944
  const [isOutputOpen, setIsOutputOpen] = React.useState(false);
7864
7945
  const [isErrorOpen, setIsErrorOpen] = React.useState(false);
7946
+ const [isMapConfigOpen, setIsMapConfigOpen] = React.useState(false);
7865
7947
  const { steps, isRunning } = useCurrentRun();
7866
- const { label, description, withoutTopHandle, withoutBottomHandle } = data;
7948
+ const { label, description, withoutTopHandle, withoutBottomHandle, mapConfig } = data;
7867
7949
  const step = steps[label];
7868
7950
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7869
7951
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
@@ -7872,13 +7954,13 @@ function WorkflowDefaultNode({ data }) {
7872
7954
  /* @__PURE__ */ jsxRuntime.jsxs(
7873
7955
  "div",
7874
7956
  {
7875
- className: clsx(
7957
+ className: cn(
7876
7958
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
7877
7959
  step?.status === "success" && "ring-2 ring-accent1",
7878
7960
  step?.status === "failed" && "ring-2 ring-accent2"
7879
7961
  ),
7880
7962
  children: [
7881
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3", children: [
7963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
7882
7964
  isRunning && /* @__PURE__ */ jsxRuntime.jsxs(Icon, { children: [
7883
7965
  step?.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx(CrossIcon, { className: "text-accent2" }),
7884
7966
  step?.status === "success" && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "text-accent1" }),
@@ -7893,7 +7975,17 @@ function WorkflowDefaultNode({ data }) {
7893
7975
  ] })
7894
7976
  ] }),
7895
7977
  description && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
7896
- (step?.input || step?.output) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2", children: [
7978
+ (step?.input || step?.output || step?.error || mapConfig) && /* @__PURE__ */ jsxRuntime.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: [
7979
+ mapConfig && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7980
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
7981
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
7982
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
7983
+ label,
7984
+ " map config"
7985
+ ] }),
7986
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: mapConfig }) })
7987
+ ] }) })
7988
+ ] }),
7897
7989
  step?.input && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7898
7990
  /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
7899
7991
  /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7931,41 +8023,6 @@ function WorkflowDefaultNode({ data }) {
7931
8023
  !withoutBottomHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden", color: "red" } })
7932
8024
  ] });
7933
8025
  }
7934
- const CodeDialogContent = ({ data }) => {
7935
- const theme = useCodemirrorTheme();
7936
- if (typeof data !== "string") {
7937
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7938
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: JSON.stringify(data, null, 2) }) }),
7939
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: JSON.stringify(data, null, 2), theme, extensions: [langJson.jsonLanguage] }) })
7940
- ] });
7941
- }
7942
- try {
7943
- const json = JSON.parse(data);
7944
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7945
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
7946
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: json, theme, extensions: [langJson.jsonLanguage] }) })
7947
- ] });
7948
- } catch (error) {
7949
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
7950
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
7951
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: data, theme, extensions: [] }) })
7952
- ] });
7953
- }
7954
- };
7955
- const Clock = ({ startedAt, endedAt }) => {
7956
- const [time, setTime] = React.useState(startedAt);
7957
- React.useEffect(() => {
7958
- const interval = setInterval(() => {
7959
- setTime(Date.now());
7960
- }, 100);
7961
- return () => clearInterval(interval);
7962
- }, [startedAt]);
7963
- const timeDiff = endedAt ? endedAt - startedAt : time - startedAt;
7964
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-icon3", children: [
7965
- toSigFigs(timeDiff, 3),
7966
- "ms"
7967
- ] });
7968
- };
7969
8026
 
7970
8027
  function WorkflowAfterNode({ data }) {
7971
8028
  const { steps } = data;
@@ -9269,7 +9326,7 @@ function WorkflowNestedGraph({ stepGraph, open }) {
9269
9326
  }, 500);
9270
9327
  }
9271
9328
  }, [open]);
9272
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full relative", children: isMounted ? /* @__PURE__ */ jsxRuntime.jsxs(
9329
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxRuntime.jsxs(
9273
9330
  react$2.ReactFlow,
9274
9331
  {
9275
9332
  nodes,
@@ -9356,14 +9413,88 @@ function WorkflowNestedGraphProvider({ children }) {
9356
9413
  }
9357
9414
 
9358
9415
  function WorkflowNestedNode({ data }) {
9359
- const { label, withoutTopHandle, withoutBottomHandle, stepGraph } = data;
9416
+ const [isInputOpen, setIsInputOpen] = React.useState(false);
9417
+ const [isOutputOpen, setIsOutputOpen] = React.useState(false);
9418
+ const [isErrorOpen, setIsErrorOpen] = React.useState(false);
9419
+ const [isMapConfigOpen, setIsMapConfigOpen] = React.useState(false);
9420
+ const { steps, isRunning } = useCurrentRun();
9360
9421
  const { showNestedGraph } = React.useContext(WorkflowNestedGraphContext);
9361
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("bg-[rgba(29,29,29,0.5)] rounded-md h-full overflow-scroll w-[274px]"), children: [
9422
+ const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig } = data;
9423
+ const step = steps[label];
9424
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
9425
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
9426
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9362
9427
  !withoutTopHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
9363
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 cursor-pointer", onClick: () => showNestedGraph({ label, stepGraph }), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-1.5 rounded-sm p-2 cursor-pointer", children: [
9364
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "text-current w-4 h-4" }),
9365
- /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
9366
- ] }) }),
9428
+ /* @__PURE__ */ jsxRuntime.jsxs(
9429
+ "div",
9430
+ {
9431
+ className: cn(
9432
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
9433
+ step?.status === "success" && "ring-2 ring-accent1",
9434
+ step?.status === "failed" && "ring-2 ring-accent2"
9435
+ ),
9436
+ children: [
9437
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
9438
+ isRunning && /* @__PURE__ */ jsxRuntime.jsxs(Icon, { children: [
9439
+ step?.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx(CrossIcon, { className: "text-accent2" }),
9440
+ step?.status === "success" && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "text-accent1" }),
9441
+ step?.status === "suspended" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PauseIcon, { className: "text-icon3" }),
9442
+ step?.status === "running" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "text-icon6 animate-spin" }),
9443
+ !step && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDashed, { className: "text-icon2" })
9444
+ ] }),
9445
+ /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
9446
+ label,
9447
+ " ",
9448
+ step?.startedAt && /* @__PURE__ */ jsxRuntime.jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
9449
+ ] })
9450
+ ] }),
9451
+ description && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
9452
+ /* @__PURE__ */ jsxRuntime.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: [
9453
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => showNestedGraph({ label, stepGraph }), children: "View workflow" }),
9454
+ mapConfig && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9455
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
9456
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
9457
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
9458
+ label,
9459
+ " map config"
9460
+ ] }),
9461
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: mapConfig }) })
9462
+ ] }) })
9463
+ ] }),
9464
+ step?.input && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9465
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
9466
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
9467
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
9468
+ label,
9469
+ " input"
9470
+ ] }),
9471
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step.input }) })
9472
+ ] }) })
9473
+ ] }),
9474
+ step?.output && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9475
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
9476
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
9477
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
9478
+ label,
9479
+ " output"
9480
+ ] }),
9481
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step.output }) })
9482
+ ] }) })
9483
+ ] }),
9484
+ step?.error && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9485
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
9486
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
9487
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
9488
+ label,
9489
+ " error"
9490
+ ] }),
9491
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step?.error }) })
9492
+ ] }) })
9493
+ ] })
9494
+ ] })
9495
+ ]
9496
+ }
9497
+ ),
9367
9498
  !withoutBottomHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden" } })
9368
9499
  ] });
9369
9500
  }
@@ -9388,7 +9519,7 @@ function WorkflowGraphInner({ workflow }) {
9388
9519
  ...e,
9389
9520
  style: {
9390
9521
  ...e.style,
9391
- stroke: steps[e.source]?.status === "success" ? "#22c55e" : void 0
9522
+ stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
9392
9523
  }
9393
9524
  })),
9394
9525
  nodeTypes,