@mastra/playground-ui 5.1.10-alpha.0 → 5.1.10

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
@@ -40,11 +40,11 @@ require('@xyflow/react/dist/style.css');
40
40
  const Dagre = require('@dagrejs/dagre');
41
41
  const prismReactRenderer = require('prism-react-renderer');
42
42
  const ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
43
- const useDebounce = require('use-debounce');
44
- const uuid = require('@lukeed/uuid');
45
43
  const prettier = require('prettier');
46
44
  const prettierPluginBabel = require('prettier/plugins/babel');
47
45
  const prettierPluginEstree = require('prettier/plugins/estree');
46
+ const useDebounce = require('use-debounce');
47
+ const uuid = require('@lukeed/uuid');
48
48
  const jsonSchemaToZod = require('json-schema-to-zod');
49
49
  const superjson = require('superjson');
50
50
  const z = require('zod');
@@ -8118,6 +8118,92 @@ const CodeDialogContent = ({ data }) => {
8118
8118
  }
8119
8119
  };
8120
8120
 
8121
+ const formatJSON = async (code) => {
8122
+ const formatted = await prettier.format(code, {
8123
+ semi: false,
8124
+ parser: "json",
8125
+ printWidth: 80,
8126
+ tabWidth: 2,
8127
+ plugins: [prettierPluginBabel, prettierPluginEstree]
8128
+ });
8129
+ return formatted;
8130
+ };
8131
+ const isValidJson = (str) => {
8132
+ try {
8133
+ const obj = JSON.parse(str);
8134
+ return !!obj && typeof obj === "object";
8135
+ } catch (e) {
8136
+ return false;
8137
+ }
8138
+ };
8139
+
8140
+ const WorkflowRunEventForm = ({ event, runId, onSendEvent }) => {
8141
+ const [eventData, setEventData] = React.useState("");
8142
+ const [isLoading, setIsLoading] = React.useState(false);
8143
+ const [error, setError] = React.useState(null);
8144
+ const theme = useCodemirrorTheme();
8145
+ const { handleCopy } = useCopyToClipboard({ text: eventData });
8146
+ const handleSendEvent = async () => {
8147
+ let data;
8148
+ setIsLoading(true);
8149
+ setError(null);
8150
+ try {
8151
+ data = JSON.parse(eventData);
8152
+ } catch (error2) {
8153
+ setError("Invalid JSON");
8154
+ setIsLoading(false);
8155
+ return;
8156
+ }
8157
+ try {
8158
+ const result = await onSendEvent({ event, data, runId });
8159
+ sonner.toast.success(result.message);
8160
+ } catch (error2) {
8161
+ console.error("Error sending event", error2);
8162
+ setError("Error sending event");
8163
+ } finally {
8164
+ setIsLoading(false);
8165
+ }
8166
+ };
8167
+ const buttonClass = "text-icon3 hover:text-icon6";
8168
+ const formatEventData = async () => {
8169
+ if (!isValidJson(eventData)) {
8170
+ setError("Invalid JSON");
8171
+ return;
8172
+ }
8173
+ const formatted = await formatJSON(eventData);
8174
+ setEventData(formatted);
8175
+ };
8176
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8178
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pb-2", children: [
8179
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", variant: "ui-md", className: "text-icon3", children: "Event data (JSON)" }),
8180
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8181
+ /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
8182
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: formatEventData, className: buttonClass, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Braces, {}) }) }) }),
8183
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Format the event data JSON" })
8184
+ ] }),
8185
+ /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
8186
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleCopy, className: buttonClass, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, {}) }) }) }),
8187
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Copy event data" })
8188
+ ] })
8189
+ ] })
8190
+ ] }),
8191
+ /* @__PURE__ */ jsxRuntime.jsx(
8192
+ CodeMirror,
8193
+ {
8194
+ value: eventData,
8195
+ onChange: setEventData,
8196
+ theme,
8197
+ extensions: [langJson.jsonLanguage],
8198
+ className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
8199
+ }
8200
+ ),
8201
+ error && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-md", className: "text-accent2", children: error })
8202
+ ] }),
8203
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end pt-4", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleSendEvent, disabled: isLoading, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-4 h-4 animate-spin" }) : "Send" }) })
8204
+ ] });
8205
+ };
8206
+
8121
8207
  const WorkflowStepActionBar = ({
8122
8208
  input,
8123
8209
  output,
@@ -8125,17 +8211,22 @@ const WorkflowStepActionBar = ({
8125
8211
  error,
8126
8212
  mapConfig,
8127
8213
  stepName,
8214
+ event,
8128
8215
  onShowTrace,
8129
- onShowNestedGraph
8216
+ onShowNestedGraph,
8217
+ onSendEvent,
8218
+ runId
8130
8219
  }) => {
8131
8220
  const [isInputOpen, setIsInputOpen] = React.useState(false);
8132
8221
  const [isOutputOpen, setIsOutputOpen] = React.useState(false);
8133
8222
  const [isResumeDataOpen, setIsResumeDataOpen] = React.useState(false);
8134
8223
  const [isErrorOpen, setIsErrorOpen] = React.useState(false);
8135
8224
  const [isMapConfigOpen, setIsMapConfigOpen] = React.useState(false);
8225
+ const [isEventFormOpen, setIsEventFormOpen] = React.useState(false);
8136
8226
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
8137
8227
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
8138
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (input || output || error || mapConfig || resumeData || onShowNestedGraph) && /* @__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: [
8228
+ const showEventForm = event && onSendEvent && runId;
8229
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (input || output || error || mapConfig || resumeData || onShowNestedGraph || showEventForm) && /* @__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: [
8139
8230
  onShowNestedGraph && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onShowNestedGraph, children: "View nested graph" }),
8140
8231
  mapConfig && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8141
8232
  /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
@@ -8187,7 +8278,18 @@ const WorkflowStepActionBar = ({
8187
8278
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: error }) })
8188
8279
  ] }) })
8189
8280
  ] }),
8190
- onShowTrace && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onShowTrace, children: "Show trace" })
8281
+ onShowTrace && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onShowTrace, children: "Show trace" }),
8282
+ showEventForm && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8283
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setIsEventFormOpen(true), children: "Send event" }),
8284
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isEventFormOpen, onOpenChange: setIsEventFormOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
8285
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: dialogTitleClass, children: [
8286
+ "Send ",
8287
+ event,
8288
+ " event"
8289
+ ] }),
8290
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunEventForm, { event, runId, onSendEvent }) })
8291
+ ] }) })
8292
+ ] })
8191
8293
  ] }) });
8192
8294
  };
8193
8295
 
@@ -8297,7 +8399,8 @@ function WorkflowConditionNode({ data }) {
8297
8399
  function WorkflowDefaultNode({
8298
8400
  data,
8299
8401
  onShowTrace,
8300
- parentWorkflowName
8402
+ parentWorkflowName,
8403
+ onSendEvent
8301
8404
  }) {
8302
8405
  const { steps, isRunning, runId } = useCurrentRun();
8303
8406
  const { label, description, withoutTopHandle, withoutBottomHandle, mapConfig, event, duration, date } = data;
@@ -8356,7 +8459,10 @@ function WorkflowDefaultNode({
8356
8459
  output: step?.output,
8357
8460
  error: step?.error,
8358
8461
  mapConfig,
8359
- onShowTrace: runId && onShowTrace ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0
8462
+ event: step?.status === "waiting" ? event : void 0,
8463
+ onShowTrace: runId && onShowTrace ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0,
8464
+ runId,
8465
+ onSendEvent
8360
8466
  }
8361
8467
  )
8362
8468
  ]
@@ -8446,7 +8552,13 @@ const ZoomSlider = React.forwardRef(({ className, ...props }) => {
8446
8552
  });
8447
8553
  ZoomSlider.displayName = "ZoomSlider";
8448
8554
 
8449
- function WorkflowNestedGraph({ stepGraph, open, workflowName, onShowTrace }) {
8555
+ function WorkflowNestedGraph({
8556
+ stepGraph,
8557
+ open,
8558
+ workflowName,
8559
+ onShowTrace,
8560
+ onSendEvent
8561
+ }) {
8450
8562
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8451
8563
  stepGraph
8452
8564
  });
@@ -8455,11 +8567,27 @@ function WorkflowNestedGraph({ stepGraph, open, workflowName, onShowTrace }) {
8455
8567
  const [edges] = react$2.useEdgesState(initialEdges);
8456
8568
  const { steps } = useCurrentRun();
8457
8569
  const nodeTypes = {
8458
- "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, onShowTrace, ...props }),
8570
+ "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(
8571
+ WorkflowDefaultNode,
8572
+ {
8573
+ parentWorkflowName: workflowName,
8574
+ onShowTrace,
8575
+ onSendEvent,
8576
+ ...props
8577
+ }
8578
+ ),
8459
8579
  "condition-node": WorkflowConditionNode,
8460
8580
  "after-node": WorkflowAfterNode,
8461
8581
  "loop-result-node": WorkflowLoopResultNode,
8462
- "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, onShowTrace, ...props })
8582
+ "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(
8583
+ WorkflowNestedNode,
8584
+ {
8585
+ parentWorkflowName: workflowName,
8586
+ onShowTrace,
8587
+ onSendEvent,
8588
+ ...props
8589
+ }
8590
+ )
8463
8591
  };
8464
8592
  React.useEffect(() => {
8465
8593
  if (open) {
@@ -8501,7 +8629,8 @@ const WorkflowNestedGraphContext = React.createContext(
8501
8629
  );
8502
8630
  function WorkflowNestedGraphProvider({
8503
8631
  children,
8504
- onShowTrace
8632
+ onShowTrace,
8633
+ onSendEvent
8505
8634
  }) {
8506
8635
  const [stepGraph, setStepGraph] = React.useState(null);
8507
8636
  const [parentStepGraphList, setParentStepGraphList] = React.useState([]);
@@ -8558,7 +8687,8 @@ function WorkflowNestedGraphProvider({
8558
8687
  stepGraph,
8559
8688
  open: openDialog,
8560
8689
  workflowName: fullStep,
8561
- onShowTrace
8690
+ onShowTrace,
8691
+ onSendEvent
8562
8692
  }
8563
8693
  ) })
8564
8694
  ] }) }) }, `${label}-${fullStep}`)
@@ -8570,11 +8700,12 @@ function WorkflowNestedGraphProvider({
8570
8700
  function WorkflowNestedNode({
8571
8701
  data,
8572
8702
  parentWorkflowName,
8573
- onShowTrace
8703
+ onShowTrace,
8704
+ onSendEvent
8574
8705
  }) {
8575
8706
  const { steps, isRunning, runId } = useCurrentRun();
8576
8707
  const { showNestedGraph } = React.useContext(WorkflowNestedGraphContext);
8577
- const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig } = data;
8708
+ const { label, description, withoutTopHandle, withoutBottomHandle, stepGraph, mapConfig, event } = data;
8578
8709
  const fullLabel = parentWorkflowName ? `${parentWorkflowName}.${label}` : label;
8579
8710
  const step = steps[fullLabel];
8580
8711
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -8585,14 +8716,17 @@ function WorkflowNestedNode({
8585
8716
  className: cn(
8586
8717
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
8587
8718
  step?.status === "success" && "ring-2 ring-accent1",
8588
- step?.status === "failed" && "ring-2 ring-accent2"
8719
+ step?.status === "failed" && "ring-2 ring-accent2",
8720
+ step?.status === "suspended" && "ring-2 ring-accent3",
8721
+ step?.status === "waiting" && "ring-2 ring-accent5"
8589
8722
  ),
8590
8723
  children: [
8591
8724
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
8592
8725
  isRunning && /* @__PURE__ */ jsxRuntime.jsxs(Icon, { children: [
8593
8726
  step?.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx(CrossIcon, { className: "text-accent2" }),
8594
8727
  step?.status === "success" && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "text-accent1" }),
8595
- step?.status === "suspended" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PauseIcon, { className: "text-icon3" }),
8728
+ step?.status === "suspended" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PauseIcon, { className: "text-accent3" }),
8729
+ step?.status === "waiting" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HourglassIcon, { className: "text-accent5" }),
8596
8730
  step?.status === "running" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "text-icon6 animate-spin" }),
8597
8731
  !step && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDashed, { className: "text-icon2" })
8598
8732
  ] }),
@@ -8613,7 +8747,10 @@ function WorkflowNestedNode({
8613
8747
  error: step?.error,
8614
8748
  mapConfig,
8615
8749
  onShowTrace: runId && onShowTrace ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0,
8616
- onShowNestedGraph: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph })
8750
+ onShowNestedGraph: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }),
8751
+ onSendEvent,
8752
+ event: step?.status === "waiting" ? event : void 0,
8753
+ runId
8617
8754
  }
8618
8755
  )
8619
8756
  ]
@@ -8623,17 +8760,17 @@ function WorkflowNestedNode({
8623
8760
  ] });
8624
8761
  }
8625
8762
 
8626
- function WorkflowGraphInner({ workflow, onShowTrace }) {
8763
+ function WorkflowGraphInner({ workflow, onShowTrace, onSendEvent }) {
8627
8764
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
8628
8765
  const [nodes, _, onNodesChange] = react$2.useNodesState(initialNodes);
8629
8766
  const [edges] = react$2.useEdgesState(initialEdges);
8630
8767
  const { steps, runId } = useCurrentRun();
8631
8768
  const nodeTypes = {
8632
- "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowDefaultNode, { onShowTrace, ...props }),
8769
+ "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowDefaultNode, { onShowTrace, onSendEvent, ...props }),
8633
8770
  "condition-node": WorkflowConditionNode,
8634
8771
  "after-node": WorkflowAfterNode,
8635
8772
  "loop-result-node": WorkflowLoopResultNode,
8636
- "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedNode, { onShowTrace, ...props })
8773
+ "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedNode, { onShowTrace, onSendEvent, ...props })
8637
8774
  };
8638
8775
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxRuntime.jsxs(
8639
8776
  react$2.ReactFlow,
@@ -8663,7 +8800,7 @@ function WorkflowGraphInner({ workflow, onShowTrace }) {
8663
8800
  ) });
8664
8801
  }
8665
8802
 
8666
- function WorkflowGraph({ workflowId, onShowTrace, workflow, isLoading }) {
8803
+ function WorkflowGraph({ workflowId, onShowTrace, workflow, isLoading, onSendEvent }) {
8667
8804
  const { snapshot } = React.useContext(WorkflowRunContext);
8668
8805
  if (isLoading) {
8669
8806
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }) });
@@ -8678,13 +8815,22 @@ function WorkflowGraph({ workflowId, onShowTrace, workflow, isLoading }) {
8678
8815
  ] })
8679
8816
  ] }) });
8680
8817
  }
8681
- return /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedGraphProvider, { onShowTrace, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
8682
- WorkflowGraphInner,
8818
+ return /* @__PURE__ */ jsxRuntime.jsx(
8819
+ WorkflowNestedGraphProvider,
8683
8820
  {
8684
- workflow: snapshot?.serializedStepGraph ? { stepGraph: snapshot?.serializedStepGraph } : workflow,
8685
- onShowTrace
8686
- }
8687
- ) }) }, snapshot?.runId ?? workflowId);
8821
+ onShowTrace,
8822
+ onSendEvent,
8823
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
8824
+ WorkflowGraphInner,
8825
+ {
8826
+ workflow: snapshot?.serializedStepGraph ? { stepGraph: snapshot?.serializedStepGraph } : workflow,
8827
+ onShowTrace,
8828
+ onSendEvent
8829
+ }
8830
+ ) })
8831
+ },
8832
+ snapshot?.runId ?? workflowId
8833
+ );
8688
8834
  }
8689
8835
 
8690
8836
  const useWorkflowRuns = (workflowId) => {
@@ -9249,17 +9395,6 @@ const MessagesProvider = ({ children }) => {
9249
9395
  };
9250
9396
  const useMessages = () => React.useContext(MessagesContext);
9251
9397
 
9252
- const formatJSON = async (code) => {
9253
- const formatted = await prettier.format(code, {
9254
- semi: false,
9255
- parser: "json",
9256
- printWidth: 80,
9257
- tabWidth: 2,
9258
- plugins: [prettierPluginBabel, prettierPluginEstree]
9259
- });
9260
- return formatted;
9261
- };
9262
-
9263
9398
  const convertMessage = (message) => {
9264
9399
  return message;
9265
9400
  };