@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.es.js CHANGED
@@ -7340,14 +7340,17 @@ const getStepNodeAndEdge = ({
7340
7340
  xIndex,
7341
7341
  yIndex,
7342
7342
  prevNodeIds,
7343
+ prevStepIds,
7343
7344
  nextStepFlow,
7344
7345
  condition,
7345
7346
  allPrevNodeIds
7346
7347
  }) => {
7347
7348
  let nextNodeIds = [];
7349
+ let nextStepIds = [];
7348
7350
  if (nextStepFlow?.type === "step" || nextStepFlow?.type === "foreach" || nextStepFlow?.type === "loop") {
7349
7351
  const nextStepId = allPrevNodeIds?.includes(nextStepFlow.step.id) ? `${nextStepFlow.step.id}-${yIndex + 1}` : nextStepFlow.step.id;
7350
7352
  nextNodeIds = [nextStepId];
7353
+ nextStepIds = [nextStepFlow.step.id];
7351
7354
  }
7352
7355
  if (nextStepFlow?.type === "parallel") {
7353
7356
  nextNodeIds = nextStepFlow?.steps.map((step) => {
@@ -7355,9 +7358,11 @@ const getStepNodeAndEdge = ({
7355
7358
  const nextStepId = allPrevNodeIds?.includes(stepId) ? `${stepId}-${yIndex + 1}` : stepId;
7356
7359
  return nextStepId;
7357
7360
  }) || [];
7361
+ nextStepIds = nextStepFlow?.steps.map((step) => step.step.id) || [];
7358
7362
  }
7359
7363
  if (nextStepFlow?.type === "conditional") {
7360
7364
  nextNodeIds = nextStepFlow?.serializedConditions.map((cond) => cond.id) || [];
7365
+ nextStepIds = nextStepFlow?.steps?.map((step) => step.step.id) || [];
7361
7366
  }
7362
7367
  if (stepFlow.type === "step" || stepFlow.type === "foreach") {
7363
7368
  const hasGraph = stepFlow.step.component === "WORKFLOW";
@@ -7370,6 +7375,8 @@ const getStepNodeAndEdge = ({
7370
7375
  type: "condition-node",
7371
7376
  data: {
7372
7377
  label: condition.id,
7378
+ previousStepId: prevStepIds[prevStepIds.length - 1],
7379
+ nextStepId: stepFlow.step.id,
7373
7380
  withoutTopHandle: false,
7374
7381
  withoutBottomHandle: !nextNodeIds.length,
7375
7382
  isLarge: true,
@@ -7386,38 +7393,43 @@ const getStepNodeAndEdge = ({
7386
7393
  description: stepFlow.step.description,
7387
7394
  withoutTopHandle: condition ? false : !prevNodeIds.length,
7388
7395
  withoutBottomHandle: !nextNodeIds.length,
7389
- stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0
7396
+ stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0,
7397
+ mapConfig: stepFlow.step.mapConfig
7390
7398
  }
7391
7399
  }
7392
7400
  ];
7393
7401
  const edges = [
7394
7402
  ...!prevNodeIds.length ? [] : condition ? [
7395
- ...prevNodeIds.map((prevNodeId) => ({
7403
+ ...prevNodeIds.map((prevNodeId, i) => ({
7396
7404
  id: `e${prevNodeId}-${condition.id}`,
7397
7405
  source: prevNodeId,
7406
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7398
7407
  target: condition.id,
7399
7408
  ...defaultEdgeOptions
7400
7409
  })),
7401
7410
  {
7402
7411
  id: `e${condition.id}-${nodeId}`,
7403
7412
  source: condition.id,
7413
+ data: { previousStepId: prevStepIds[prevStepIds.length - 1], nextStepId: stepFlow.step.id },
7404
7414
  target: nodeId,
7405
7415
  ...defaultEdgeOptions
7406
7416
  }
7407
- ] : prevNodeIds.map((prevNodeId) => ({
7417
+ ] : prevNodeIds.map((prevNodeId, i) => ({
7408
7418
  id: `e${prevNodeId}-${nodeId}`,
7409
7419
  source: prevNodeId,
7420
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7410
7421
  target: nodeId,
7411
7422
  ...defaultEdgeOptions
7412
7423
  })),
7413
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7424
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7414
7425
  id: `e${nodeId}-${nextNodeId}`,
7415
7426
  source: nodeId,
7427
+ data: { previousStepId: stepFlow.step.id, nextStepId: nextStepIds[i] },
7416
7428
  target: nextNodeId,
7417
7429
  ...defaultEdgeOptions
7418
7430
  }))
7419
7431
  ];
7420
- return { nodes, edges, nextPrevNodeIds: [nodeId] };
7432
+ return { nodes, edges, nextPrevNodeIds: [nodeId], nextPrevStepIds: [stepFlow.step.id] };
7421
7433
  }
7422
7434
  if (stepFlow.type === "loop") {
7423
7435
  const { step: _step, serializedCondition, loopType } = stepFlow;
@@ -7441,6 +7453,9 @@ const getStepNodeAndEdge = ({
7441
7453
  type: "condition-node",
7442
7454
  data: {
7443
7455
  label: serializedCondition.id,
7456
+ // conditionStepId: _step.id,
7457
+ previousStepId: _step.id,
7458
+ nextStepId: nextStepIds[0],
7444
7459
  withoutTopHandle: false,
7445
7460
  withoutBottomHandle: !nextNodeIds.length,
7446
7461
  isLarge: true,
@@ -7449,67 +7464,85 @@ const getStepNodeAndEdge = ({
7449
7464
  }
7450
7465
  ];
7451
7466
  const edges = [
7452
- ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId) => ({
7467
+ ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId, i) => ({
7453
7468
  id: `e${prevNodeId}-${_step.id}`,
7454
7469
  source: prevNodeId,
7470
+ data: { previousStepId: prevStepIds[i], nextStepId: _step.id },
7455
7471
  target: _step.id,
7456
7472
  ...defaultEdgeOptions
7457
7473
  })),
7458
7474
  {
7459
7475
  id: `e${_step.id}-${serializedCondition.id}`,
7460
7476
  source: _step.id,
7477
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[0] },
7461
7478
  target: serializedCondition.id,
7462
7479
  ...defaultEdgeOptions
7463
7480
  },
7464
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7481
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7465
7482
  id: `e${serializedCondition.id}-${nextNodeId}`,
7466
7483
  source: serializedCondition.id,
7484
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[i] },
7467
7485
  target: nextNodeId,
7468
7486
  ...defaultEdgeOptions
7469
7487
  }))
7470
7488
  ];
7471
- return { nodes, edges, nextPrevNodeIds: [serializedCondition.id] };
7489
+ return { nodes, edges, nextPrevNodeIds: [serializedCondition.id], nextPrevStepIds: [_step.id] };
7472
7490
  }
7473
7491
  if (stepFlow.type === "parallel") {
7474
7492
  let nodes = [];
7475
7493
  let edges = [];
7494
+ let nextPrevStepIds = [];
7476
7495
  stepFlow.steps.forEach((_stepFlow, index) => {
7477
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7496
+ const {
7497
+ nodes: _nodes,
7498
+ edges: _edges,
7499
+ nextPrevStepIds: _nextPrevStepIds
7500
+ } = getStepNodeAndEdge({
7478
7501
  stepFlow: _stepFlow,
7479
7502
  xIndex: index,
7480
7503
  yIndex,
7481
7504
  prevNodeIds,
7505
+ prevStepIds,
7482
7506
  nextStepFlow,
7483
7507
  allPrevNodeIds
7484
7508
  });
7485
7509
  nodes.push(..._nodes);
7486
7510
  edges.push(..._edges);
7511
+ nextPrevStepIds.push(..._nextPrevStepIds);
7487
7512
  });
7488
- return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id) };
7513
+ return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id), nextPrevStepIds };
7489
7514
  }
7490
7515
  if (stepFlow.type === "conditional") {
7491
7516
  let nodes = [];
7492
7517
  let edges = [];
7518
+ let nextPrevStepIds = [];
7493
7519
  stepFlow.steps.forEach((_stepFlow, index) => {
7494
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7520
+ const {
7521
+ nodes: _nodes,
7522
+ edges: _edges,
7523
+ nextPrevStepIds: _nextPrevStepIds
7524
+ } = getStepNodeAndEdge({
7495
7525
  stepFlow: _stepFlow,
7496
7526
  xIndex: index,
7497
7527
  yIndex,
7498
7528
  prevNodeIds,
7529
+ prevStepIds,
7499
7530
  nextStepFlow,
7500
7531
  condition: stepFlow.serializedConditions[index],
7501
7532
  allPrevNodeIds
7502
7533
  });
7503
7534
  nodes.push(..._nodes);
7504
7535
  edges.push(..._edges);
7536
+ nextPrevStepIds.push(..._nextPrevStepIds);
7505
7537
  });
7506
7538
  return {
7507
7539
  nodes,
7508
7540
  edges,
7509
- 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
7510
7543
  };
7511
7544
  }
7512
- return { nodes: [], edges: [], nextPrevNodeIds: [] };
7545
+ return { nodes: [], edges: [], nextPrevNodeIds: [], nextPrevStepIds: [] };
7513
7546
  };
7514
7547
  const constructNodesAndEdges = ({
7515
7548
  stepGraph
@@ -7523,23 +7556,27 @@ const constructNodesAndEdges = ({
7523
7556
  let nodes = [];
7524
7557
  let edges = [];
7525
7558
  let prevNodeIds = [];
7559
+ let prevStepIds = [];
7526
7560
  let allPrevNodeIds = [];
7527
7561
  for (let index = 0; index < stepGraph.length; index++) {
7528
7562
  const {
7529
7563
  nodes: _nodes,
7530
7564
  edges: _edges,
7531
- nextPrevNodeIds
7565
+ nextPrevNodeIds,
7566
+ nextPrevStepIds
7532
7567
  } = getStepNodeAndEdge({
7533
7568
  stepFlow: stepGraph[index],
7534
7569
  xIndex: index,
7535
7570
  yIndex: index,
7536
7571
  prevNodeIds,
7572
+ prevStepIds,
7537
7573
  nextStepFlow: index === stepGraph.length - 1 ? void 0 : stepGraph[index + 1],
7538
7574
  allPrevNodeIds
7539
7575
  });
7540
7576
  nodes.push(..._nodes);
7541
7577
  edges.push(..._edges);
7542
7578
  prevNodeIds = nextPrevNodeIds;
7579
+ prevStepIds = nextPrevStepIds;
7543
7580
  allPrevNodeIds.push(...prevNodeIds);
7544
7581
  }
7545
7582
  const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);
@@ -7619,105 +7656,6 @@ const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...pr
7619
7656
  ));
7620
7657
  ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
7621
7658
 
7622
- function WorkflowConditionNode({ data }) {
7623
- const { conditions } = data;
7624
- const [open, setOpen] = useState(true);
7625
- const [openDialog, setOpenDialog] = useState(false);
7626
- const type = conditions[0]?.type;
7627
- const isCollapsible = (conditions.some((condition) => condition.fnString) || conditions?.length > 1) && type !== "else";
7628
- return /* @__PURE__ */ jsxs(
7629
- Collapsible,
7630
- {
7631
- open: !isCollapsible ? true : open,
7632
- onOpenChange: (_open) => {
7633
- if (isCollapsible) {
7634
- setOpen(_open);
7635
- }
7636
- },
7637
- className: cn("bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2"),
7638
- children: [
7639
- /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
7640
- /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
7641
- /* @__PURE__ */ jsx(
7642
- Text,
7643
- {
7644
- size: "xs",
7645
- weight: "medium",
7646
- className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
7647
- children: type?.toUpperCase()
7648
- }
7649
- ),
7650
- isCollapsible && /* @__PURE__ */ jsx(
7651
- ChevronDown,
7652
- {
7653
- className: cn("w-4 h-4 transition-transform", {
7654
- "transform rotate-180": open
7655
- })
7656
- }
7657
- )
7658
- ] }),
7659
- type === "else" ? null : /* @__PURE__ */ jsx(CollapsibleContent, { className: "flex flex-col gap-2", children: conditions.map((condition, index) => {
7660
- return condition.fnString ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
7661
- /* @__PURE__ */ jsx(Highlight, { theme: themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(
7662
- "pre",
7663
- {
7664
- className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full cursor-pointer rounded-lg mt-2`,
7665
- style: {
7666
- ...style,
7667
- backgroundColor: "transparent",
7668
- border: "1px solid #343434",
7669
- maxHeight: "9.62rem"
7670
- },
7671
- onClick: () => setOpenDialog(true),
7672
- children: tokens.map((line, i) => /* @__PURE__ */ jsxs("div", { ...getLineProps({ line }), children: [
7673
- /* @__PURE__ */ jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7674
- line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, key))
7675
- ] }, i))
7676
- }
7677
- ) }),
7678
- /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: setOpenDialog, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-[30rem] bg-[#121212] p-[0.5rem]", children: [
7679
- /* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Condition Function" }),
7680
- /* @__PURE__ */ jsx(ScrollArea, { className: "w-full p-2", maxHeight: "400px", children: /* @__PURE__ */ jsx(Highlight, { theme: themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(
7681
- "pre",
7682
- {
7683
- className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full rounded-lg mt-2 dark:bg-zinc-800`,
7684
- style: {
7685
- ...style,
7686
- backgroundColor: "#121212",
7687
- padding: "0 0.75rem 0 0"
7688
- },
7689
- children: tokens.map((line, i) => /* @__PURE__ */ jsxs("div", { ...getLineProps({ line }), children: [
7690
- /* @__PURE__ */ jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7691
- line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, key))
7692
- ] }, i))
7693
- }
7694
- ) }) })
7695
- ] }) })
7696
- ] }, `${condition.fnString}-${index}`) : /* @__PURE__ */ jsx(Fragment$1, { children: condition.ref?.step ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
7697
- index === 0 ? null : /* @__PURE__ */ jsx(
7698
- Text,
7699
- {
7700
- size: "xs",
7701
- weight: "medium",
7702
- className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px]",
7703
- children: condition.conj?.toLocaleUpperCase() || "WHEN"
7704
- }
7705
- ),
7706
- /* @__PURE__ */ jsxs(Text, { size: "xs", className: " text-mastra-el-3 flex-1", children: [
7707
- condition.ref.step.id || condition.ref.step,
7708
- "'s ",
7709
- condition.ref.path,
7710
- " ",
7711
- Object.entries(condition.query).map(([key, value]) => `${key} ${String(value)}`)
7712
- ] })
7713
- ] }) : null }, `${condition.ref?.path}-${index}`);
7714
- }) }),
7715
- /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
7716
- ]
7717
- }
7718
- );
7719
- }
7720
-
7721
7659
  function convertWorkflowRunStateToWatchResult(runState) {
7722
7660
  const runId = runState.runId;
7723
7661
  const steps = {};
@@ -7826,12 +7764,156 @@ const useCurrentRun = () => {
7826
7764
  return { steps, isRunning: Boolean(context.payload) };
7827
7765
  };
7828
7766
 
7767
+ function WorkflowConditionNode({ data }) {
7768
+ const { conditions, previousStepId, nextStepId } = data;
7769
+ const [open, setOpen] = useState(true);
7770
+ const [openDialog, setOpenDialog] = useState(false);
7771
+ const type = conditions[0]?.type;
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];
7776
+ return /* @__PURE__ */ jsxs(
7777
+ Collapsible,
7778
+ {
7779
+ open: !isCollapsible ? true : open,
7780
+ onOpenChange: (_open) => {
7781
+ if (isCollapsible) {
7782
+ setOpen(_open);
7783
+ }
7784
+ },
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
+ ),
7790
+ children: [
7791
+ /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
7792
+ /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
7793
+ /* @__PURE__ */ jsx(
7794
+ Text,
7795
+ {
7796
+ size: "xs",
7797
+ weight: "medium",
7798
+ className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px] w-fit",
7799
+ children: type?.toUpperCase()
7800
+ }
7801
+ ),
7802
+ isCollapsible && /* @__PURE__ */ jsx(
7803
+ ChevronDown,
7804
+ {
7805
+ className: cn("w-4 h-4 transition-transform", {
7806
+ "transform rotate-180": open
7807
+ })
7808
+ }
7809
+ )
7810
+ ] }),
7811
+ type === "else" ? null : /* @__PURE__ */ jsx(CollapsibleContent, { className: "flex flex-col gap-2", children: conditions.map((condition, index) => {
7812
+ return condition.fnString ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
7813
+ /* @__PURE__ */ jsx(Highlight, { theme: themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(
7814
+ "pre",
7815
+ {
7816
+ className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full cursor-pointer rounded-lg mt-2`,
7817
+ style: {
7818
+ ...style,
7819
+ backgroundColor: "transparent",
7820
+ border: "1px solid #343434",
7821
+ maxHeight: "9.62rem"
7822
+ },
7823
+ onClick: () => setOpenDialog(true),
7824
+ children: tokens.map((line, i) => /* @__PURE__ */ jsxs("div", { ...getLineProps({ line }), children: [
7825
+ /* @__PURE__ */ jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7826
+ line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, key))
7827
+ ] }, i))
7828
+ }
7829
+ ) }),
7830
+ /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: setOpenDialog, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-[30rem] bg-[#121212] p-[0.5rem]", children: [
7831
+ /* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Condition Function" }),
7832
+ /* @__PURE__ */ jsx(ScrollArea, { className: "w-full p-2", maxHeight: "400px", children: /* @__PURE__ */ jsx(Highlight, { theme: themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(
7833
+ "pre",
7834
+ {
7835
+ className: `${className} relative font-mono text-sm overflow-x-auto p-3 w-full rounded-lg mt-2 dark:bg-zinc-800`,
7836
+ style: {
7837
+ ...style,
7838
+ backgroundColor: "#121212",
7839
+ padding: "0 0.75rem 0 0"
7840
+ },
7841
+ children: tokens.map((line, i) => /* @__PURE__ */ jsxs("div", { ...getLineProps({ line }), children: [
7842
+ /* @__PURE__ */ jsx("span", { className: "inline-block mr-2 text-muted-foreground", children: i + 1 }),
7843
+ line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, key))
7844
+ ] }, i))
7845
+ }
7846
+ ) }) })
7847
+ ] }) })
7848
+ ] }, `${condition.fnString}-${index}`) : /* @__PURE__ */ jsx(Fragment$1, { children: condition.ref?.step ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
7849
+ index === 0 ? null : /* @__PURE__ */ jsx(
7850
+ Text,
7851
+ {
7852
+ size: "xs",
7853
+ weight: "medium",
7854
+ className: "text-mastra-el-3 bg-mastra-bg-11 my-auto block rounded-[0.125rem] px-2 py-1 text-[10px]",
7855
+ children: condition.conj?.toLocaleUpperCase() || "WHEN"
7856
+ }
7857
+ ),
7858
+ /* @__PURE__ */ jsxs(Text, { size: "xs", className: " text-mastra-el-3 flex-1", children: [
7859
+ condition.ref.step.id || condition.ref.step,
7860
+ "'s ",
7861
+ condition.ref.path,
7862
+ " ",
7863
+ Object.entries(condition.query).map(([key, value]) => `${key} ${String(value)}`)
7864
+ ] })
7865
+ ] }) : null }, `${condition.ref?.path}-${index}`);
7866
+ }) }),
7867
+ /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
7868
+ ]
7869
+ }
7870
+ );
7871
+ }
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
+
7829
7910
  function WorkflowDefaultNode({ data }) {
7830
7911
  const [isInputOpen, setIsInputOpen] = useState(false);
7831
7912
  const [isOutputOpen, setIsOutputOpen] = useState(false);
7832
7913
  const [isErrorOpen, setIsErrorOpen] = useState(false);
7914
+ const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
7833
7915
  const { steps, isRunning } = useCurrentRun();
7834
- const { label, description, withoutTopHandle, withoutBottomHandle } = data;
7916
+ const { label, description, withoutTopHandle, withoutBottomHandle, mapConfig } = data;
7835
7917
  const step = steps[label];
7836
7918
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7837
7919
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
@@ -7840,13 +7922,13 @@ function WorkflowDefaultNode({ data }) {
7840
7922
  /* @__PURE__ */ jsxs(
7841
7923
  "div",
7842
7924
  {
7843
- className: clsx(
7925
+ className: cn(
7844
7926
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
7845
7927
  step?.status === "success" && "ring-2 ring-accent1",
7846
7928
  step?.status === "failed" && "ring-2 ring-accent2"
7847
7929
  ),
7848
7930
  children: [
7849
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3", children: [
7931
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
7850
7932
  isRunning && /* @__PURE__ */ jsxs(Icon, { children: [
7851
7933
  step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
7852
7934
  step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
@@ -7861,7 +7943,17 @@ function WorkflowDefaultNode({ data }) {
7861
7943
  ] })
7862
7944
  ] }),
7863
7945
  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: [
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
+ ] }),
7865
7957
  step?.input && /* @__PURE__ */ jsxs(Fragment, { children: [
7866
7958
  /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
7867
7959
  /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7899,41 +7991,6 @@ function WorkflowDefaultNode({ data }) {
7899
7991
  !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden", color: "red" } })
7900
7992
  ] });
7901
7993
  }
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
- };
7937
7994
 
7938
7995
  function WorkflowAfterNode({ data }) {
7939
7996
  const { steps } = data;
@@ -9237,7 +9294,7 @@ function WorkflowNestedGraph({ stepGraph, open }) {
9237
9294
  }, 500);
9238
9295
  }
9239
9296
  }, [open]);
9240
- 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(
9241
9298
  ReactFlow,
9242
9299
  {
9243
9300
  nodes,
@@ -9324,14 +9381,88 @@ function WorkflowNestedGraphProvider({ children }) {
9324
9381
  }
9325
9382
 
9326
9383
  function WorkflowNestedNode({ data }) {
9327
- 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();
9328
9389
  const { showNestedGraph } = useContext(WorkflowNestedGraphContext);
9329
- 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: [
9330
9395
  !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
9331
- /* @__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: [
9332
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
9333
- /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
9334
- ] }) }),
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
+ ),
9335
9466
  !withoutBottomHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: { visibility: "hidden" } })
9336
9467
  ] });
9337
9468
  }
@@ -9356,7 +9487,7 @@ function WorkflowGraphInner({ workflow }) {
9356
9487
  ...e,
9357
9488
  style: {
9358
9489
  ...e.style,
9359
- stroke: steps[e.source]?.status === "success" ? "#22c55e" : void 0
9490
+ stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
9360
9491
  }
9361
9492
  })),
9362
9493
  nodeTypes,