@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.cjs.js CHANGED
@@ -28,6 +28,7 @@ const dateFns = require('date-fns');
28
28
  const TabsPrimitive = require('@radix-ui/react-tabs');
29
29
  const sonner = require('sonner');
30
30
  const react$1 = require('motion/react');
31
+ const colors = require('./colors-Du4i-E0i.cjs');
31
32
  const uiUtils = require('@ai-sdk/ui-utils');
32
33
  const Markdown = require('react-markdown');
33
34
  const useDebounce = require('use-debounce');
@@ -50,6 +51,7 @@ const uuid = require('@lukeed/uuid');
50
51
  const zod = require('@autoform/zod');
51
52
  const LabelPrimitive = require('@radix-ui/react-label');
52
53
  const reactCodeBlock = require('react-code-block');
54
+ const SliderPrimitive = require('@radix-ui/react-slider');
53
55
  const reactTable = require('@tanstack/react-table');
54
56
 
55
57
  function _interopNamespaceDefault(e) {
@@ -80,6 +82,7 @@ const CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(Check
80
82
  const PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(PopoverPrimitive);
81
83
  const SelectPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(SelectPrimitive);
82
84
  const LabelPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(LabelPrimitive);
85
+ const SliderPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(SliderPrimitive);
83
86
 
84
87
  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}
85
88
 
@@ -4140,7 +4143,7 @@ const DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) =
4140
4143
  DialogPrimitive__namespace.Title,
4141
4144
  {
4142
4145
  ref,
4143
- className: cn("text-lg font-semibold leading-none tracking-tight", className),
4146
+ className: clsx("text-lg font-semibold leading-none tracking-tight", className),
4144
4147
  ...props
4145
4148
  }
4146
4149
  ));
@@ -4855,23 +4858,47 @@ const defaultModelSettings$1 = {
4855
4858
  topP: 1
4856
4859
  };
4857
4860
  const AgentContext = React.createContext({});
4858
- function AgentProvider({ agentId, children }) {
4861
+ function AgentProvider({
4862
+ agentId,
4863
+ defaultGenerateOptions,
4864
+ defaultStreamOptions,
4865
+ children
4866
+ }) {
4859
4867
  const {
4860
4868
  modelSettings: modelSettingsStore,
4861
4869
  setModelSettings: setModelSettingsStore,
4862
4870
  chatWithGenerate: chatWithGenerateStore,
4863
4871
  setChatWithGenerate: setChatWithGenerateStore
4864
4872
  } = useAgentStore();
4865
- const modelSettings = modelSettingsStore[agentId] || defaultModelSettings$1;
4873
+ const chatWithGenerate = chatWithGenerateStore[agentId] || false;
4874
+ const setChatWithGenerate = (chatWithGenerate2) => {
4875
+ setChatWithGenerateStore({ [agentId]: chatWithGenerate2 });
4876
+ };
4877
+ const modelSettings = React.useMemo(() => {
4878
+ if (modelSettingsStore[agentId]) return modelSettingsStore[agentId];
4879
+ if (chatWithGenerate) {
4880
+ return {
4881
+ maxRetries: defaultGenerateOptions?.maxRetries ?? defaultModelSettings$1.maxRetries,
4882
+ maxSteps: defaultGenerateOptions?.maxSteps ?? defaultModelSettings$1.maxSteps,
4883
+ temperature: defaultGenerateOptions?.temperature ?? defaultModelSettings$1.temperature,
4884
+ topP: defaultGenerateOptions?.topP ?? defaultModelSettings$1.topP,
4885
+ ...defaultGenerateOptions
4886
+ };
4887
+ } else {
4888
+ return {
4889
+ maxRetries: defaultStreamOptions?.maxRetries ?? defaultModelSettings$1.maxRetries,
4890
+ maxSteps: defaultStreamOptions?.maxSteps ?? defaultModelSettings$1.maxSteps,
4891
+ temperature: defaultStreamOptions?.temperature ?? defaultModelSettings$1.temperature,
4892
+ topP: defaultStreamOptions?.topP ?? defaultModelSettings$1.topP,
4893
+ ...defaultStreamOptions
4894
+ };
4895
+ }
4896
+ }, [agentId, defaultGenerateOptions, defaultStreamOptions, chatWithGenerate, modelSettingsStore]);
4866
4897
  const setModelSettings = (modelSettings2) => {
4867
4898
  setModelSettingsStore({ [agentId]: modelSettings2 });
4868
4899
  };
4869
4900
  const resetModelSettings = () => {
4870
- setModelSettings(defaultModelSettings$1);
4871
- };
4872
- const chatWithGenerate = chatWithGenerateStore[agentId] || false;
4873
- const setChatWithGenerate = (chatWithGenerate2) => {
4874
- setChatWithGenerateStore({ [agentId]: chatWithGenerate2 });
4901
+ setModelSettingsStore({ [agentId]: null });
4875
4902
  };
4876
4903
  return /* @__PURE__ */ jsxRuntime.jsx(
4877
4904
  AgentContext.Provider,
@@ -5977,7 +6004,7 @@ const useCodemirrorTheme = () => {
5977
6004
  fontSize: "0.8rem",
5978
6005
  lineHighlight: "transparent",
5979
6006
  gutterBackground: "transparent",
5980
- gutterForeground: "#939393",
6007
+ gutterForeground: colors.Colors.surface3,
5981
6008
  background: "transparent"
5982
6009
  },
5983
6010
  styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
@@ -7345,14 +7372,17 @@ const getStepNodeAndEdge = ({
7345
7372
  xIndex,
7346
7373
  yIndex,
7347
7374
  prevNodeIds,
7375
+ prevStepIds,
7348
7376
  nextStepFlow,
7349
7377
  condition,
7350
7378
  allPrevNodeIds
7351
7379
  }) => {
7352
7380
  let nextNodeIds = [];
7381
+ let nextStepIds = [];
7353
7382
  if (nextStepFlow?.type === "step" || nextStepFlow?.type === "foreach" || nextStepFlow?.type === "loop") {
7354
7383
  const nextStepId = allPrevNodeIds?.includes(nextStepFlow.step.id) ? `${nextStepFlow.step.id}-${yIndex + 1}` : nextStepFlow.step.id;
7355
7384
  nextNodeIds = [nextStepId];
7385
+ nextStepIds = [nextStepFlow.step.id];
7356
7386
  }
7357
7387
  if (nextStepFlow?.type === "parallel") {
7358
7388
  nextNodeIds = nextStepFlow?.steps.map((step) => {
@@ -7360,9 +7390,11 @@ const getStepNodeAndEdge = ({
7360
7390
  const nextStepId = allPrevNodeIds?.includes(stepId) ? `${stepId}-${yIndex + 1}` : stepId;
7361
7391
  return nextStepId;
7362
7392
  }) || [];
7393
+ nextStepIds = nextStepFlow?.steps.map((step) => step.step.id) || [];
7363
7394
  }
7364
7395
  if (nextStepFlow?.type === "conditional") {
7365
7396
  nextNodeIds = nextStepFlow?.serializedConditions.map((cond) => cond.id) || [];
7397
+ nextStepIds = nextStepFlow?.steps?.map((step) => step.step.id) || [];
7366
7398
  }
7367
7399
  if (stepFlow.type === "step" || stepFlow.type === "foreach") {
7368
7400
  const hasGraph = stepFlow.step.component === "WORKFLOW";
@@ -7375,6 +7407,8 @@ const getStepNodeAndEdge = ({
7375
7407
  type: "condition-node",
7376
7408
  data: {
7377
7409
  label: condition.id,
7410
+ previousStepId: prevStepIds[prevStepIds.length - 1],
7411
+ nextStepId: stepFlow.step.id,
7378
7412
  withoutTopHandle: false,
7379
7413
  withoutBottomHandle: !nextNodeIds.length,
7380
7414
  isLarge: true,
@@ -7391,38 +7425,43 @@ const getStepNodeAndEdge = ({
7391
7425
  description: stepFlow.step.description,
7392
7426
  withoutTopHandle: condition ? false : !prevNodeIds.length,
7393
7427
  withoutBottomHandle: !nextNodeIds.length,
7394
- stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0
7428
+ stepGraph: hasGraph ? stepFlow.step.serializedStepFlow : void 0,
7429
+ mapConfig: stepFlow.step.mapConfig
7395
7430
  }
7396
7431
  }
7397
7432
  ];
7398
7433
  const edges = [
7399
7434
  ...!prevNodeIds.length ? [] : condition ? [
7400
- ...prevNodeIds.map((prevNodeId) => ({
7435
+ ...prevNodeIds.map((prevNodeId, i) => ({
7401
7436
  id: `e${prevNodeId}-${condition.id}`,
7402
7437
  source: prevNodeId,
7438
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7403
7439
  target: condition.id,
7404
7440
  ...defaultEdgeOptions
7405
7441
  })),
7406
7442
  {
7407
7443
  id: `e${condition.id}-${nodeId}`,
7408
7444
  source: condition.id,
7445
+ data: { previousStepId: prevStepIds[prevStepIds.length - 1], nextStepId: stepFlow.step.id },
7409
7446
  target: nodeId,
7410
7447
  ...defaultEdgeOptions
7411
7448
  }
7412
- ] : prevNodeIds.map((prevNodeId) => ({
7449
+ ] : prevNodeIds.map((prevNodeId, i) => ({
7413
7450
  id: `e${prevNodeId}-${nodeId}`,
7414
7451
  source: prevNodeId,
7452
+ data: { previousStepId: prevStepIds[i], nextStepId: stepFlow.step.id },
7415
7453
  target: nodeId,
7416
7454
  ...defaultEdgeOptions
7417
7455
  })),
7418
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7456
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7419
7457
  id: `e${nodeId}-${nextNodeId}`,
7420
7458
  source: nodeId,
7459
+ data: { previousStepId: stepFlow.step.id, nextStepId: nextStepIds[i] },
7421
7460
  target: nextNodeId,
7422
7461
  ...defaultEdgeOptions
7423
7462
  }))
7424
7463
  ];
7425
- return { nodes, edges, nextPrevNodeIds: [nodeId] };
7464
+ return { nodes, edges, nextPrevNodeIds: [nodeId], nextPrevStepIds: [stepFlow.step.id] };
7426
7465
  }
7427
7466
  if (stepFlow.type === "loop") {
7428
7467
  const { step: _step, serializedCondition, loopType } = stepFlow;
@@ -7446,6 +7485,9 @@ const getStepNodeAndEdge = ({
7446
7485
  type: "condition-node",
7447
7486
  data: {
7448
7487
  label: serializedCondition.id,
7488
+ // conditionStepId: _step.id,
7489
+ previousStepId: _step.id,
7490
+ nextStepId: nextStepIds[0],
7449
7491
  withoutTopHandle: false,
7450
7492
  withoutBottomHandle: !nextNodeIds.length,
7451
7493
  isLarge: true,
@@ -7454,67 +7496,85 @@ const getStepNodeAndEdge = ({
7454
7496
  }
7455
7497
  ];
7456
7498
  const edges = [
7457
- ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId) => ({
7499
+ ...!prevNodeIds.length ? [] : prevNodeIds.map((prevNodeId, i) => ({
7458
7500
  id: `e${prevNodeId}-${_step.id}`,
7459
7501
  source: prevNodeId,
7502
+ data: { previousStepId: prevStepIds[i], nextStepId: _step.id },
7460
7503
  target: _step.id,
7461
7504
  ...defaultEdgeOptions
7462
7505
  })),
7463
7506
  {
7464
7507
  id: `e${_step.id}-${serializedCondition.id}`,
7465
7508
  source: _step.id,
7509
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[0] },
7466
7510
  target: serializedCondition.id,
7467
7511
  ...defaultEdgeOptions
7468
7512
  },
7469
- ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId) => ({
7513
+ ...!nextNodeIds.length ? [] : nextNodeIds.map((nextNodeId, i) => ({
7470
7514
  id: `e${serializedCondition.id}-${nextNodeId}`,
7471
7515
  source: serializedCondition.id,
7516
+ data: { previousStepId: _step.id, nextStepId: nextStepIds[i] },
7472
7517
  target: nextNodeId,
7473
7518
  ...defaultEdgeOptions
7474
7519
  }))
7475
7520
  ];
7476
- return { nodes, edges, nextPrevNodeIds: [serializedCondition.id] };
7521
+ return { nodes, edges, nextPrevNodeIds: [serializedCondition.id], nextPrevStepIds: [_step.id] };
7477
7522
  }
7478
7523
  if (stepFlow.type === "parallel") {
7479
7524
  let nodes = [];
7480
7525
  let edges = [];
7526
+ let nextPrevStepIds = [];
7481
7527
  stepFlow.steps.forEach((_stepFlow, index) => {
7482
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7528
+ const {
7529
+ nodes: _nodes,
7530
+ edges: _edges,
7531
+ nextPrevStepIds: _nextPrevStepIds
7532
+ } = getStepNodeAndEdge({
7483
7533
  stepFlow: _stepFlow,
7484
7534
  xIndex: index,
7485
7535
  yIndex,
7486
7536
  prevNodeIds,
7537
+ prevStepIds,
7487
7538
  nextStepFlow,
7488
7539
  allPrevNodeIds
7489
7540
  });
7490
7541
  nodes.push(..._nodes);
7491
7542
  edges.push(..._edges);
7543
+ nextPrevStepIds.push(..._nextPrevStepIds);
7492
7544
  });
7493
- return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id) };
7545
+ return { nodes, edges, nextPrevNodeIds: nodes.map((node) => node.id), nextPrevStepIds };
7494
7546
  }
7495
7547
  if (stepFlow.type === "conditional") {
7496
7548
  let nodes = [];
7497
7549
  let edges = [];
7550
+ let nextPrevStepIds = [];
7498
7551
  stepFlow.steps.forEach((_stepFlow, index) => {
7499
- const { nodes: _nodes, edges: _edges } = getStepNodeAndEdge({
7552
+ const {
7553
+ nodes: _nodes,
7554
+ edges: _edges,
7555
+ nextPrevStepIds: _nextPrevStepIds
7556
+ } = getStepNodeAndEdge({
7500
7557
  stepFlow: _stepFlow,
7501
7558
  xIndex: index,
7502
7559
  yIndex,
7503
7560
  prevNodeIds,
7561
+ prevStepIds,
7504
7562
  nextStepFlow,
7505
7563
  condition: stepFlow.serializedConditions[index],
7506
7564
  allPrevNodeIds
7507
7565
  });
7508
7566
  nodes.push(..._nodes);
7509
7567
  edges.push(..._edges);
7568
+ nextPrevStepIds.push(..._nextPrevStepIds);
7510
7569
  });
7511
7570
  return {
7512
7571
  nodes,
7513
7572
  edges,
7514
- 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
7515
7575
  };
7516
7576
  }
7517
- return { nodes: [], edges: [], nextPrevNodeIds: [] };
7577
+ return { nodes: [], edges: [], nextPrevNodeIds: [], nextPrevStepIds: [] };
7518
7578
  };
7519
7579
  const constructNodesAndEdges = ({
7520
7580
  stepGraph
@@ -7528,23 +7588,27 @@ const constructNodesAndEdges = ({
7528
7588
  let nodes = [];
7529
7589
  let edges = [];
7530
7590
  let prevNodeIds = [];
7591
+ let prevStepIds = [];
7531
7592
  let allPrevNodeIds = [];
7532
7593
  for (let index = 0; index < stepGraph.length; index++) {
7533
7594
  const {
7534
7595
  nodes: _nodes,
7535
7596
  edges: _edges,
7536
- nextPrevNodeIds
7597
+ nextPrevNodeIds,
7598
+ nextPrevStepIds
7537
7599
  } = getStepNodeAndEdge({
7538
7600
  stepFlow: stepGraph[index],
7539
7601
  xIndex: index,
7540
7602
  yIndex: index,
7541
7603
  prevNodeIds,
7604
+ prevStepIds,
7542
7605
  nextStepFlow: index === stepGraph.length - 1 ? void 0 : stepGraph[index + 1],
7543
7606
  allPrevNodeIds
7544
7607
  });
7545
7608
  nodes.push(..._nodes);
7546
7609
  edges.push(..._edges);
7547
7610
  prevNodeIds = nextPrevNodeIds;
7611
+ prevStepIds = nextPrevStepIds;
7548
7612
  allPrevNodeIds.push(...prevNodeIds);
7549
7613
  }
7550
7614
  const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(nodes, edges);
@@ -7624,12 +7688,123 @@ const ScrollBar = React__namespace.forwardRef(({ className, orientation = "verti
7624
7688
  ));
7625
7689
  ScrollBar.displayName = ScrollAreaPrimitive__namespace.ScrollAreaScrollbar.displayName;
7626
7690
 
7691
+ function convertWorkflowRunStateToWatchResult(runState) {
7692
+ const runId = runState.runId;
7693
+ const steps = {};
7694
+ const context = runState.context || {};
7695
+ Object.entries(context).forEach(([stepId, stepResult]) => {
7696
+ if (stepId !== "input" && "status" in stepResult) {
7697
+ const result = stepResult;
7698
+ steps[stepId] = {
7699
+ status: result.status,
7700
+ output: "output" in result ? result.output : void 0,
7701
+ payload: "payload" in result ? result.payload : void 0,
7702
+ resumePayload: "resumePayload" in result ? result.resumePayload : void 0,
7703
+ error: "error" in result ? result.error : void 0,
7704
+ startedAt: "startedAt" in result ? result.startedAt : Date.now(),
7705
+ endedAt: "endedAt" in result ? result.endedAt : void 0,
7706
+ suspendedAt: "suspendedAt" in result ? result.suspendedAt : void 0,
7707
+ resumedAt: "resumedAt" in result ? result.resumedAt : void 0
7708
+ };
7709
+ }
7710
+ });
7711
+ const status = determineWorkflowStatus(steps);
7712
+ return {
7713
+ type: "watch",
7714
+ payload: {
7715
+ workflowState: {
7716
+ status,
7717
+ steps,
7718
+ output: runState.value,
7719
+ payload: context.input,
7720
+ error: void 0
7721
+ }
7722
+ },
7723
+ eventTimestamp: new Date(runState.timestamp),
7724
+ runId
7725
+ };
7726
+ }
7727
+ function determineWorkflowStatus(steps) {
7728
+ const stepStatuses = Object.values(steps).map((step) => step.status);
7729
+ if (stepStatuses.includes("failed")) {
7730
+ return "failed";
7731
+ }
7732
+ if (stepStatuses.includes("suspended")) {
7733
+ return "suspended";
7734
+ }
7735
+ if (stepStatuses.every((status) => status === "success")) {
7736
+ return "success";
7737
+ }
7738
+ return "running";
7739
+ }
7740
+
7741
+ const WorkflowRunContext = React.createContext({});
7742
+ function WorkflowRunProvider({
7743
+ children,
7744
+ snapshot
7745
+ }) {
7746
+ const [legacyResult, setLegacyResult] = React.useState(null);
7747
+ const [result, setResult] = React.useState(
7748
+ () => snapshot ? convertWorkflowRunStateToWatchResult(snapshot) : null
7749
+ );
7750
+ const [payload, setPayload] = React.useState(null);
7751
+ const clearData = () => {
7752
+ setLegacyResult(null);
7753
+ setResult(null);
7754
+ setPayload(null);
7755
+ };
7756
+ React.useEffect(() => {
7757
+ if (snapshot?.runId) {
7758
+ setResult(convertWorkflowRunStateToWatchResult(snapshot));
7759
+ } else {
7760
+ setResult(null);
7761
+ }
7762
+ }, [snapshot?.runId ?? ""]);
7763
+ return /* @__PURE__ */ jsxRuntime.jsx(
7764
+ WorkflowRunContext.Provider,
7765
+ {
7766
+ value: {
7767
+ legacyResult,
7768
+ setLegacyResult,
7769
+ result,
7770
+ setResult,
7771
+ payload,
7772
+ setPayload,
7773
+ clearData
7774
+ },
7775
+ children
7776
+ }
7777
+ );
7778
+ }
7779
+
7780
+ const useCurrentRun = () => {
7781
+ const context = React.useContext(WorkflowRunContext);
7782
+ const workflowCurrentSteps = context.result?.payload?.workflowState?.steps ?? {};
7783
+ const steps = Object.entries(workflowCurrentSteps).reduce((acc, [key, value]) => {
7784
+ return {
7785
+ ...acc,
7786
+ [key]: {
7787
+ error: value.error,
7788
+ startedAt: value.startedAt,
7789
+ endedAt: value.endedAt,
7790
+ status: value.status,
7791
+ output: value.output,
7792
+ input: value.payload
7793
+ }
7794
+ };
7795
+ }, {});
7796
+ return { steps, isRunning: Boolean(context.payload) };
7797
+ };
7798
+
7627
7799
  function WorkflowConditionNode({ data }) {
7628
- const { conditions } = data;
7800
+ const { conditions, previousStepId, nextStepId } = data;
7629
7801
  const [open, setOpen] = React.useState(true);
7630
7802
  const [openDialog, setOpenDialog] = React.useState(false);
7631
7803
  const type = conditions[0]?.type;
7632
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];
7633
7808
  return /* @__PURE__ */ jsxRuntime.jsxs(
7634
7809
  Collapsible,
7635
7810
  {
@@ -7639,7 +7814,11 @@ function WorkflowConditionNode({ data }) {
7639
7814
  setOpen(_open);
7640
7815
  }
7641
7816
  },
7642
- className: cn("bg-mastra-bg-3 rounded-md w-[274px] flex flex-col p-2 gap-2"),
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
+ ),
7643
7822
  children: [
7644
7823
  /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
7645
7824
  /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full", children: [
@@ -7723,16 +7902,125 @@ function WorkflowConditionNode({ data }) {
7723
7902
  );
7724
7903
  }
7725
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
+
7726
7942
  function WorkflowDefaultNode({ data }) {
7727
- const { label, description, withoutTopHandle, withoutBottomHandle } = data;
7728
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("bg-mastra-bg-8 rounded-md w-[274px]"), children: [
7943
+ const [isInputOpen, setIsInputOpen] = React.useState(false);
7944
+ const [isOutputOpen, setIsOutputOpen] = React.useState(false);
7945
+ const [isErrorOpen, setIsErrorOpen] = React.useState(false);
7946
+ const [isMapConfigOpen, setIsMapConfigOpen] = React.useState(false);
7947
+ const { steps, isRunning } = useCurrentRun();
7948
+ const { label, description, withoutTopHandle, withoutBottomHandle, mapConfig } = data;
7949
+ const step = steps[label];
7950
+ const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7951
+ const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7952
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7729
7953
  !withoutTopHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
7730
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm bg-mastra-bg-9 flex items-center gap-[6px] rounded-sm p-2", children: [
7731
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Footprints, { className: "text-current w-4 h-4" }),
7732
- /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
7733
- ] }) }),
7734
- description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-mastra-bg-4 rounded-b-md p-2 text-[10px] text-left text-mastra-el-4", children: description }),
7735
- !withoutBottomHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden" } })
7954
+ /* @__PURE__ */ jsxRuntime.jsxs(
7955
+ "div",
7956
+ {
7957
+ className: cn(
7958
+ "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
7959
+ step?.status === "success" && "ring-2 ring-accent1",
7960
+ step?.status === "failed" && "ring-2 ring-accent2"
7961
+ ),
7962
+ children: [
7963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
7964
+ isRunning && /* @__PURE__ */ jsxRuntime.jsxs(Icon, { children: [
7965
+ step?.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx(CrossIcon, { className: "text-accent2" }),
7966
+ step?.status === "success" && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "text-accent1" }),
7967
+ step?.status === "suspended" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PauseIcon, { className: "text-icon3" }),
7968
+ step?.status === "running" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "text-icon6 animate-spin" }),
7969
+ !step && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDashed, { className: "text-icon2" })
7970
+ ] }),
7971
+ /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
7972
+ label,
7973
+ " ",
7974
+ step?.startedAt && /* @__PURE__ */ jsxRuntime.jsx(Clock, { startedAt: step.startedAt, endedAt: step.endedAt })
7975
+ ] })
7976
+ ] }),
7977
+ description && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3 px-3 pb-2", children: description }),
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
+ ] }),
7989
+ step?.input && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7990
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
7991
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
7992
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
7993
+ label,
7994
+ " input"
7995
+ ] }),
7996
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step.input }) })
7997
+ ] }) })
7998
+ ] }),
7999
+ step?.output && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8000
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
8001
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
8002
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
8003
+ label,
8004
+ " output"
8005
+ ] }),
8006
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step.output }) })
8007
+ ] }) })
8008
+ ] }),
8009
+ step?.error && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8010
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
8011
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
8012
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
8013
+ label,
8014
+ " error"
8015
+ ] }),
8016
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: step?.error }) })
8017
+ ] }) })
8018
+ ] })
8019
+ ] })
8020
+ ]
8021
+ }
8022
+ ),
8023
+ !withoutBottomHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden", color: "red" } })
7736
8024
  ] });
7737
8025
  }
7738
8026
 
@@ -8768,33 +9056,6 @@ function CodeBlockDemo({
8768
9056
  ] });
8769
9057
  }
8770
9058
 
8771
- const WorkflowRunContext = React.createContext({});
8772
- function WorkflowRunProvider({ children }) {
8773
- const [legacyResult, setLegacyResult] = React.useState(null);
8774
- const [result, setResult] = React.useState(null);
8775
- const [payload, setPayload] = React.useState(null);
8776
- const clearData = () => {
8777
- setLegacyResult(null);
8778
- setResult(null);
8779
- setPayload(null);
8780
- };
8781
- return /* @__PURE__ */ jsxRuntime.jsx(
8782
- WorkflowRunContext.Provider,
8783
- {
8784
- value: {
8785
- legacyResult,
8786
- setLegacyResult,
8787
- result,
8788
- setResult,
8789
- payload,
8790
- setPayload,
8791
- clearData
8792
- },
8793
- children
8794
- }
8795
- );
8796
- }
8797
-
8798
9059
  const WorkflowCard = ({ header, children, footer }) => {
8799
9060
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface4", children: [
8800
9061
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-1 px-2 flex items-center gap-3", children: header }),
@@ -9002,6 +9263,48 @@ function LegacyWorkflowTrigger({
9002
9263
  ] }) });
9003
9264
  }
9004
9265
 
9266
+ const Slider = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
9267
+ SliderPrimitive__namespace.Root,
9268
+ {
9269
+ ref,
9270
+ className: cn("relative flex w-full touch-none select-none items-center", className),
9271
+ ...props,
9272
+ children: [
9273
+ /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Range, { className: "absolute h-full bg-primary/50" }) }),
9274
+ /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.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" })
9275
+ ]
9276
+ }
9277
+ ));
9278
+ Slider.displayName = SliderPrimitive__namespace.Root.displayName;
9279
+
9280
+ const ZoomSlider = React.forwardRef(({ className, ...props }) => {
9281
+ const { zoom } = react$2.useViewport();
9282
+ const { zoomTo, zoomIn, zoomOut, fitView } = react$2.useReactFlow();
9283
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$2.Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
9284
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-4 w-4" }) }),
9285
+ /* @__PURE__ */ jsxRuntime.jsx(
9286
+ Slider,
9287
+ {
9288
+ className: "w-[140px]",
9289
+ value: [zoom],
9290
+ min: 0.01,
9291
+ max: 1,
9292
+ step: 0.01,
9293
+ onValueChange: (values) => {
9294
+ zoomTo(values[0]);
9295
+ }
9296
+ }
9297
+ ),
9298
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }) }),
9299
+ /* @__PURE__ */ jsxRuntime.jsxs(Button$1, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
9300
+ (100 * zoom).toFixed(0),
9301
+ "%"
9302
+ ] }),
9303
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize, { className: "h-4 w-4" }) })
9304
+ ] });
9305
+ });
9306
+ ZoomSlider.displayName = "ZoomSlider";
9307
+
9005
9308
  function WorkflowNestedGraph({ stepGraph, open }) {
9006
9309
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
9007
9310
  stepGraph
@@ -9023,17 +9326,21 @@ function WorkflowNestedGraph({ stepGraph, open }) {
9023
9326
  }, 500);
9024
9327
  }
9025
9328
  }, [open]);
9026
- 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(
9027
9330
  react$2.ReactFlow,
9028
9331
  {
9029
9332
  nodes,
9030
9333
  edges,
9031
9334
  fitView: true,
9032
- fitViewOptions: { maxZoom: 0.85 },
9335
+ fitViewOptions: {
9336
+ maxZoom: 1
9337
+ },
9338
+ minZoom: 0.01,
9339
+ maxZoom: 1,
9033
9340
  nodeTypes,
9034
9341
  onNodesChange,
9035
9342
  children: [
9036
- /* @__PURE__ */ jsxRuntime.jsx(react$2.Controls, {}),
9343
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomSlider, { position: "bottom-left" }),
9037
9344
  /* @__PURE__ */ jsxRuntime.jsx(react$2.MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9038
9345
  /* @__PURE__ */ jsxRuntime.jsx(react$2.Background, { variant: react$2.BackgroundVariant.Lines, gap: 12, size: 0.5 })
9039
9346
  ]
@@ -9090,7 +9397,7 @@ function WorkflowNestedGraphProvider({ children }) {
9090
9397
  },
9091
9398
  children: [
9092
9399
  children,
9093
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsxRuntime.jsx(DialogPortal, { children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "w-[40rem] h-[40rem] bg-[#121212] p-[0.5rem]", children: [
9400
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsxRuntime.jsx(DialogPortal, { children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "w-[45rem] h-[45rem] max-w-[unset] bg-[#121212] p-[0.5rem]", children: [
9094
9401
  /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-2.5 left-2.5", children: [
9095
9402
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "text-current w-4 h-4" }),
9096
9403
  /* @__PURE__ */ jsxRuntime.jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
@@ -9106,14 +9413,88 @@ function WorkflowNestedGraphProvider({ children }) {
9106
9413
  }
9107
9414
 
9108
9415
  function WorkflowNestedNode({ data }) {
9109
- 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();
9110
9421
  const { showNestedGraph } = React.useContext(WorkflowNestedGraphContext);
9111
- 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: [
9112
9427
  !withoutTopHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "target", position: react$2.Position.Top, style: { visibility: "hidden" } }),
9113
- /* @__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: [
9114
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "text-current w-4 h-4" }),
9115
- /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: label })
9116
- ] }) }),
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
+ ),
9117
9498
  !withoutBottomHandle && /* @__PURE__ */ jsxRuntime.jsx(react$2.Handle, { type: "source", position: react$2.Position.Bottom, style: { visibility: "hidden" } })
9118
9499
  ] });
9119
9500
  }
@@ -9122,6 +9503,7 @@ function WorkflowGraphInner({ workflow }) {
9122
9503
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
9123
9504
  const [nodes, _, onNodesChange] = react$2.useNodesState(initialNodes);
9124
9505
  const [edges] = react$2.useEdgesState(initialEdges);
9506
+ const { steps } = useCurrentRun();
9125
9507
  const nodeTypes = {
9126
9508
  "default-node": WorkflowDefaultNode,
9127
9509
  "condition-node": WorkflowConditionNode,
@@ -9129,19 +9511,27 @@ function WorkflowGraphInner({ workflow }) {
9129
9511
  "loop-result-node": WorkflowLoopResultNode,
9130
9512
  "nested-node": WorkflowNestedNode
9131
9513
  };
9132
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
9514
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxRuntime.jsxs(
9133
9515
  react$2.ReactFlow,
9134
9516
  {
9135
9517
  nodes,
9136
- edges,
9518
+ edges: edges.map((e) => ({
9519
+ ...e,
9520
+ style: {
9521
+ ...e.style,
9522
+ stroke: steps[e.data?.previousStepId]?.status === "success" && steps[e.data?.nextStepId] ? "#22c55e" : void 0
9523
+ }
9524
+ })),
9137
9525
  nodeTypes,
9138
9526
  onNodesChange,
9139
9527
  fitView: true,
9140
9528
  fitViewOptions: {
9141
- maxZoom: 0.85
9529
+ maxZoom: 1
9142
9530
  },
9531
+ minZoom: 0.01,
9532
+ maxZoom: 1,
9143
9533
  children: [
9144
- /* @__PURE__ */ jsxRuntime.jsx(react$2.Controls, {}),
9534
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomSlider, { position: "bottom-left" }),
9145
9535
  /* @__PURE__ */ jsxRuntime.jsx(react$2.MiniMap, { pannable: true, zoomable: true, maskColor: "#121212", bgColor: "#171717", nodeColor: "#2c2c2c" }),
9146
9536
  /* @__PURE__ */ jsxRuntime.jsx(react$2.Background, { variant: react$2.BackgroundVariant.Dots, gap: 12, size: 0.5 })
9147
9537
  ]
@@ -9827,6 +10217,7 @@ exports.WorkflowRunProvider = WorkflowRunProvider;
9827
10217
  exports.WorkflowTraces = WorkflowTraces;
9828
10218
  exports.WorkflowTrigger = WorkflowTrigger;
9829
10219
  exports.refineTraces = refineTraces;
10220
+ exports.useCurrentRun = useCurrentRun;
9830
10221
  exports.usePlaygroundStore = usePlaygroundStore;
9831
10222
  exports.usePolling = usePolling;
9832
10223
  exports.useSpeechRecognition = useSpeechRecognition;