@mastra/playground-ui 7.0.0-beta.11 → 7.0.0-beta.13

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
@@ -32,6 +32,7 @@ const prismReactRenderer = require('prism-react-renderer');
32
32
  const CollapsiblePrimitive = require('@radix-ui/react-collapsible');
33
33
  const ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
34
34
  const view = require('@codemirror/view');
35
+ const langJavascript = require('@codemirror/lang-javascript');
35
36
  const CheckboxPrimitive = require('@radix-ui/react-checkbox');
36
37
  const dateFns = require('date-fns');
37
38
  const useDebounce = require('use-debounce');
@@ -4679,7 +4680,8 @@ const ToolBadge = ({
4679
4680
  metadata,
4680
4681
  toolOutput,
4681
4682
  toolCallId,
4682
- toolApprovalMetadata
4683
+ toolApprovalMetadata,
4684
+ suspendPayload
4683
4685
  }) => {
4684
4686
  let argSlot = null;
4685
4687
  try {
@@ -4689,6 +4691,7 @@ const ToolBadge = ({
4689
4691
  argSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: args });
4690
4692
  }
4691
4693
  let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result, "data-testid": "tool-result" });
4694
+ let suspendPayloadSlot = typeof suspendPayload === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: suspendPayload }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: suspendPayload, "data-testid": "tool-suspend-payload" });
4692
4695
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
4693
4696
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
4694
4697
  const toolCalled = result || toolOutput.length > 0;
@@ -4705,12 +4708,16 @@ const ToolBadge = ({
4705
4708
  input: agentNetworkInput
4706
4709
  }
4707
4710
  ),
4708
- initialCollapsed: !!!toolApprovalMetadata,
4711
+ initialCollapsed: !!!(toolApprovalMetadata ?? suspendPayload),
4709
4712
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
4710
4713
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4711
4714
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4712
4715
  argSlot
4713
4716
  ] }),
4717
+ suspendPayloadSlot !== void 0 && suspendPayload && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4718
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool suspend payload" }),
4719
+ suspendPayloadSlot
4720
+ ] }),
4714
4721
  resultSlot !== void 0 && result && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4715
4722
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4716
4723
  resultSlot
@@ -5027,7 +5034,8 @@ const useExecuteWorkflow = () => {
5027
5034
  requestContext$1.set(key, value);
5028
5035
  });
5029
5036
  const workflow = client.getWorkflow(workflowId);
5030
- await workflow.start({ runId, inputData: input || {}, requestContext: requestContext$1 });
5037
+ const run = await workflow.createRun({ runId });
5038
+ await run.start({ inputData: input || {}, requestContext: requestContext$1 });
5031
5039
  } catch (error) {
5032
5040
  console.error("Error starting workflow run:", error);
5033
5041
  throw error;
@@ -5047,7 +5055,8 @@ const useExecuteWorkflow = () => {
5047
5055
  requestContext$1.set(key, value);
5048
5056
  });
5049
5057
  const workflow = client.getWorkflow(workflowId);
5050
- const result = await workflow.startAsync({ runId, inputData: input || {}, requestContext: requestContext$1 });
5058
+ const run = await workflow.createRun({ runId });
5059
+ const result = await run.startAsync({ inputData: input || {}, requestContext: requestContext$1 });
5051
5060
  return result;
5052
5061
  } catch (error) {
5053
5062
  console.error("Error starting workflow run:", error);
@@ -5140,8 +5149,8 @@ const useStreamWorkflow = () => {
5140
5149
  requestContext$1.set(key, value);
5141
5150
  });
5142
5151
  const workflow = client.getWorkflow(workflowId);
5143
- const stream = await workflow.streamVNext({
5144
- runId,
5152
+ const run = await workflow.createRun({ runId });
5153
+ const stream = await run.streamVNext({
5145
5154
  inputData,
5146
5155
  requestContext: requestContext$1,
5147
5156
  closeOnSuspend: true,
@@ -5203,7 +5212,8 @@ const useStreamWorkflow = () => {
5203
5212
  return;
5204
5213
  }
5205
5214
  const workflow = client.getWorkflow(workflowId);
5206
- const stream = await workflow.observeStreamVNext({ runId });
5215
+ const run = await workflow.createRun({ runId });
5216
+ const stream = await run.observeStreamVNext();
5207
5217
  if (!stream) {
5208
5218
  return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
5209
5219
  }
@@ -5261,8 +5271,8 @@ const useStreamWorkflow = () => {
5261
5271
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5262
5272
  requestContext$1.set(key, value);
5263
5273
  });
5264
- const stream = await workflow.resumeStreamVNext({
5265
- runId,
5274
+ const run = await workflow.createRun({ runId });
5275
+ const stream = await run.resumeStreamVNext({
5266
5276
  step,
5267
5277
  resumeData,
5268
5278
  requestContext: requestContext$1,
@@ -5311,6 +5321,7 @@ const useStreamWorkflow = () => {
5311
5321
  mutationFn: async ({
5312
5322
  workflowId,
5313
5323
  requestContext: playgroundRequestContext,
5324
+ runId,
5314
5325
  ...params
5315
5326
  }) => {
5316
5327
  if (timeTravelStreamRef.current) {
@@ -5323,7 +5334,8 @@ const useStreamWorkflow = () => {
5323
5334
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5324
5335
  requestContext$1.set(key, value);
5325
5336
  });
5326
- const stream = await workflow.timeTravelStream({
5337
+ const run = await workflow.createRun({ runId });
5338
+ const stream = await run.timeTravelStream({
5327
5339
  ...params,
5328
5340
  requestContext: requestContext$1,
5329
5341
  tracingOptions: settings?.tracingOptions
@@ -5414,7 +5426,9 @@ const useCancelWorkflowRun = () => {
5414
5426
  const cancelWorkflowRun = reactQuery.useMutation({
5415
5427
  mutationFn: async ({ workflowId, runId }) => {
5416
5428
  try {
5417
- const response = await client.getWorkflow(workflowId).cancelRun(runId);
5429
+ const workflow = client.getWorkflow(workflowId);
5430
+ const run = await workflow.createRun({ runId });
5431
+ const response = await run.cancelRun();
5418
5432
  return response;
5419
5433
  } catch (error) {
5420
5434
  console.error("Error canceling workflow run:", error);
@@ -5508,6 +5522,58 @@ const useDeleteWorkflowRun = (workflowId) => {
5508
5522
  });
5509
5523
  };
5510
5524
 
5525
+ const WorkflowStepDetailContext = React.createContext(null);
5526
+ function useWorkflowStepDetail() {
5527
+ const context = React.useContext(WorkflowStepDetailContext);
5528
+ if (!context) {
5529
+ throw new Error("useWorkflowStepDetail must be used within WorkflowStepDetailProvider");
5530
+ }
5531
+ return context;
5532
+ }
5533
+ function WorkflowStepDetailProvider({ children }) {
5534
+ const [stepDetail, setStepDetail] = React.useState(null);
5535
+ const showMapConfig = React.useCallback(
5536
+ ({ stepName, stepId, mapConfig }) => {
5537
+ setStepDetail({
5538
+ type: "map-config",
5539
+ stepName,
5540
+ stepId,
5541
+ mapConfig
5542
+ });
5543
+ },
5544
+ []
5545
+ );
5546
+ const showNestedGraph = React.useCallback(
5547
+ ({ label, stepGraph, fullStep }) => {
5548
+ setStepDetail({
5549
+ type: "nested-graph",
5550
+ stepName: label,
5551
+ nestedGraph: {
5552
+ label,
5553
+ stepGraph,
5554
+ fullStep
5555
+ }
5556
+ });
5557
+ },
5558
+ []
5559
+ );
5560
+ const closeStepDetail = React.useCallback(() => {
5561
+ setStepDetail(null);
5562
+ }, []);
5563
+ return /* @__PURE__ */ jsxRuntime.jsx(
5564
+ WorkflowStepDetailContext.Provider,
5565
+ {
5566
+ value: {
5567
+ stepDetail,
5568
+ showMapConfig,
5569
+ showNestedGraph,
5570
+ closeStepDetail
5571
+ },
5572
+ children
5573
+ }
5574
+ );
5575
+ }
5576
+
5511
5577
  const WorkflowRunContext = React.createContext({});
5512
5578
  function WorkflowRunProvider({
5513
5579
  children,
@@ -5609,7 +5675,7 @@ function WorkflowRunProvider({
5609
5675
  isLoadingRunExecutionResult,
5610
5676
  withoutTimeTravel
5611
5677
  },
5612
- children
5678
+ children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepDetailProvider, { children })
5613
5679
  }
5614
5680
  );
5615
5681
  }
@@ -6268,26 +6334,46 @@ const SyntaxHighlighter$1 = ({ data }) => {
6268
6334
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: formattedCode, theme, extensions: [langJson.jsonLanguage] }) });
6269
6335
  };
6270
6336
 
6271
- const CodeDialogContent = ({ data }) => {
6337
+ const CodeDialogContent = ({
6338
+ data,
6339
+ language = "auto"
6340
+ }) => {
6272
6341
  const theme = useCodemirrorTheme$1();
6342
+ const getExtensions = (content) => {
6343
+ if (language === "javascript") {
6344
+ return [langJavascript.javascript(), view.EditorView.lineWrapping];
6345
+ }
6346
+ if (language === "json") {
6347
+ return [langJson.jsonLanguage, view.EditorView.lineWrapping];
6348
+ }
6349
+ try {
6350
+ JSON.parse(content);
6351
+ return [langJson.jsonLanguage, view.EditorView.lineWrapping];
6352
+ } catch {
6353
+ if (content.includes("=>") || content.includes("function") || content.includes("const ") || content.includes("return ")) {
6354
+ return [langJavascript.javascript(), view.EditorView.lineWrapping];
6355
+ }
6356
+ return [view.EditorView.lineWrapping];
6357
+ }
6358
+ };
6273
6359
  if (typeof data !== "string") {
6360
+ const content = JSON.stringify(data, null, 2);
6274
6361
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6275
- /* @__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) }) }),
6276
- /* @__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] }) })
6362
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content }) }),
6363
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: content, theme, extensions: [langJson.jsonLanguage, view.EditorView.lineWrapping] }) })
6277
6364
  ] });
6278
6365
  }
6366
+ const extensions = getExtensions(data);
6367
+ let displayContent = data;
6279
6368
  try {
6280
6369
  const json = JSON.parse(data);
6281
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6282
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
6283
- /* @__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] }) })
6284
- ] });
6285
- } catch (error) {
6286
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6287
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
6288
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: data, theme, extensions: [] }) })
6289
- ] });
6370
+ displayContent = JSON.stringify(json, null, 2);
6371
+ } catch {
6290
6372
  }
6373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6374
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: data }) }),
6375
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: displayContent, theme, extensions }) })
6376
+ ] });
6291
6377
  };
6292
6378
 
6293
6379
  const Form = React.forwardRef(({ children, ...props }, ref) => {
@@ -7801,9 +7887,9 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7801
7887
  const parsedResume = resumeData.trim() ? JSON.parse(resumeData) : {};
7802
7888
  const parsedContext = contextValue.trim() ? JSON.parse(contextValue) : {};
7803
7889
  const parsedNestedContext = nestedContextValue.trim() ? JSON.parse(nestedContextValue) : {};
7804
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
7890
+ const run = await createWorkflowRun({ workflowId, prevRunId });
7805
7891
  const payload = {
7806
- runId,
7892
+ runId: run.runId,
7807
7893
  workflowId,
7808
7894
  step: stepKey,
7809
7895
  inputData: data,
@@ -7915,12 +8001,29 @@ const WorkflowStepActionBar = ({
7915
8001
  const [isResumeDataOpen, setIsResumeDataOpen] = React.useState(false);
7916
8002
  const [isErrorOpen, setIsErrorOpen] = React.useState(false);
7917
8003
  const [isTripwireOpen, setIsTripwireOpen] = React.useState(false);
7918
- const [isMapConfigOpen, setIsMapConfigOpen] = React.useState(false);
7919
8004
  const [isTimeTravelOpen, setIsTimeTravelOpen] = React.useState(false);
7920
8005
  const { withoutTimeTravel } = React.useContext(WorkflowRunContext);
8006
+ const { showMapConfig, stepDetail, closeStepDetail } = useWorkflowStepDetail();
7921
8007
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7922
8008
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7923
8009
  const showTimeTravel = !withoutTimeTravel && stepKey && !mapConfig;
8010
+ const isMapConfigOpen = stepDetail?.type === "map-config" && stepDetail?.stepName === stepName;
8011
+ const isNestedGraphOpen = stepDetail?.type === "nested-graph" && stepDetail?.stepName === stepName;
8012
+ const activeButtonClass = "ring-2 ring-accent1 ring-offset-1 ring-offset-transparent";
8013
+ const handleMapConfigClick = () => {
8014
+ if (isMapConfigOpen) {
8015
+ closeStepDetail();
8016
+ } else {
8017
+ showMapConfig({ stepName, stepId, mapConfig });
8018
+ }
8019
+ };
8020
+ const handleNestedGraphClick = () => {
8021
+ if (isNestedGraphOpen) {
8022
+ closeStepDetail();
8023
+ } else {
8024
+ onShowNestedGraph?.();
8025
+ }
8026
+ };
7924
8027
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (input || output || error || tripwire || mapConfig || resumeData || onShowNestedGraph || showTimeTravel) && /* @__PURE__ */ jsxRuntime.jsxs(
7925
8028
  "div",
7926
8029
  {
@@ -7934,7 +8037,7 @@ const WorkflowStepActionBar = ({
7934
8037
  status === "running" && "bg-accent6Dark"
7935
8038
  ),
7936
8039
  children: [
7937
- onShowNestedGraph && /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: onShowNestedGraph, children: "View nested graph" }),
8040
+ onShowNestedGraph && /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: handleNestedGraphClick, className: cn(isNestedGraphOpen && activeButtonClass), children: "View nested graph" }),
7938
8041
  showTimeTravel && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7939
8042
  /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setIsTimeTravelOpen(true), children: "Time travel" }),
7940
8043
  /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isTimeTravelOpen, onOpenChange: setIsTimeTravelOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7945,19 +8048,7 @@ const WorkflowStepActionBar = ({
7945
8048
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowTimeTravelForm, { stepKey, closeModal: () => setIsTimeTravelOpen(false) }) })
7946
8049
  ] }) })
7947
8050
  ] }),
7948
- mapConfig && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7949
- /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
7950
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
7951
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: dialogTitleClass, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
7952
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7953
- stepName,
7954
- " Map Config"
7955
- ] }),
7956
- stepId && stepId !== stepName && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-icon3 font-normal", children: stepId })
7957
- ] }) }),
7958
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: mapConfig }) })
7959
- ] }) })
7960
- ] }),
8051
+ mapConfig && /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: handleMapConfigClick, className: cn(isMapConfigOpen && activeButtonClass), children: "Map config" }),
7961
8052
  input && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7962
8053
  /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setIsInputOpen(true), children: "Input" }),
7963
8054
  /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -8099,7 +8190,7 @@ function WorkflowConditionNode({ data }) {
8099
8190
  "pre",
8100
8191
  {
8101
8192
  className: cn(
8102
- "relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 overflow-scroll",
8193
+ "relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 whitespace-pre-wrap break-words",
8103
8194
  className,
8104
8195
  previousDisplayStatus === "success" && nextStep && "!bg-accent1Dark",
8105
8196
  previousDisplayStatus === "failed" && nextStep && "!bg-accent2Dark",
@@ -8352,172 +8443,29 @@ function WorkflowLoopResultNode({ data }) {
8352
8443
  );
8353
8444
  }
8354
8445
 
8355
- function Spinner({ color = "#fff", className }) {
8356
- return /* @__PURE__ */ jsxRuntime.jsx(
8357
- "svg",
8358
- {
8359
- className: clsx("animate-spin duration-700", className),
8360
- xmlns: "http://www.w3.org/2000/svg",
8361
- width: "24",
8362
- height: "24",
8363
- viewBox: "0 0 24 24",
8364
- fill: "none",
8365
- stroke: "currentColor",
8366
- strokeWidth: "2",
8367
- strokeLinecap: "round",
8368
- strokeLinejoin: "round",
8369
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
8370
- }
8371
- );
8372
- }
8373
-
8374
- const Slider = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
8375
- SliderPrimitive__namespace.Root,
8376
- {
8377
- ref,
8378
- className: cn("relative flex w-full touch-none select-none items-center", className),
8379
- ...props,
8380
- children: [
8381
- /* @__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" }) }),
8382
- /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors disabled:pointer-events-none disabled:opacity-50" })
8383
- ]
8384
- }
8385
- ));
8386
- Slider.displayName = SliderPrimitive__namespace.Root.displayName;
8387
-
8388
- const ZoomSlider = React.forwardRef(({ className, ...props }) => {
8389
- const { zoom } = react$2.useViewport();
8390
- const { zoomTo, zoomIn, zoomOut, fitView } = react$2.useReactFlow();
8391
- return /* @__PURE__ */ jsxRuntime.jsxs(react$2.Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8392
- /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-4 w-4" }) }),
8393
- /* @__PURE__ */ jsxRuntime.jsx(
8394
- Slider,
8395
- {
8396
- className: "w-[140px]",
8397
- value: [zoom],
8398
- min: 0.01,
8399
- max: 1,
8400
- step: 0.01,
8401
- onValueChange: (values) => {
8402
- zoomTo(values[0]);
8403
- }
8404
- }
8405
- ),
8406
- /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }) }),
8407
- /* @__PURE__ */ jsxRuntime.jsxs(Button$2, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8408
- (100 * zoom).toFixed(0),
8409
- "%"
8410
- ] }),
8411
- /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize, { className: "h-4 w-4" }) })
8412
- ] });
8413
- });
8414
- ZoomSlider.displayName = "ZoomSlider";
8415
-
8416
- function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
8417
- const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8418
- stepGraph
8419
- });
8420
- const [isMounted, setIsMounted] = React.useState(false);
8421
- const [nodes, _, onNodesChange] = react$2.useNodesState(initialNodes);
8422
- const [edges] = react$2.useEdgesState(initialEdges);
8423
- const { steps } = useCurrentRun();
8424
- const nodeTypes = {
8425
- "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
8426
- "condition-node": WorkflowConditionNode,
8427
- "after-node": WorkflowAfterNode,
8428
- "loop-result-node": WorkflowLoopResultNode,
8429
- "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
8430
- };
8431
- React.useEffect(() => {
8432
- if (open) {
8433
- setTimeout(() => {
8434
- setIsMounted(true);
8435
- }, 500);
8436
- }
8437
- }, [open]);
8438
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxRuntime.jsxs(
8439
- react$2.ReactFlow,
8440
- {
8441
- nodes,
8442
- edges: edges.map((e) => ({
8443
- ...e,
8444
- style: {
8445
- ...e.style,
8446
- stroke: steps[`${workflowName}.${e.data?.previousStepId}`]?.status === "success" && steps[`${workflowName}.${e.data?.nextStepId}`] ? "#22c55e" : e.data?.conditionNode && !steps[`${workflowName}.${e.data?.previousStepId}`] && Boolean(steps[`${workflowName}.${e.data?.nextStepId}`]?.status) ? "#22c55e" : void 0
8447
- }
8448
- })),
8449
- fitView: true,
8450
- fitViewOptions: {
8451
- maxZoom: 1
8452
- },
8453
- minZoom: 0.01,
8454
- maxZoom: 1,
8455
- nodeTypes,
8456
- onNodesChange,
8457
- children: [
8458
- /* @__PURE__ */ jsxRuntime.jsx(ZoomSlider, { position: "bottom-left" }),
8459
- /* @__PURE__ */ jsxRuntime.jsx(react$2.Background, { variant: react$2.BackgroundVariant.Lines, gap: 12, size: 0.5 })
8460
- ]
8461
- }
8462
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) }) });
8463
- }
8464
-
8465
8446
  const WorkflowNestedGraphContext = React.createContext(
8466
8447
  {}
8467
8448
  );
8468
8449
  function WorkflowNestedGraphProvider({ children }) {
8469
- const [stepGraph, setStepGraph] = React.useState(null);
8470
- const [parentStepGraphList, setParentStepGraphList] = React.useState([]);
8471
- const [openDialog, setOpenDialog] = React.useState(false);
8472
- const [label, setLabel] = React.useState("");
8473
- const [fullStep, setFullStep] = React.useState("");
8474
- const closeNestedGraph = () => {
8475
- if (parentStepGraphList.length) {
8476
- const lastStepGraph = parentStepGraphList[parentStepGraphList.length - 1];
8477
- setStepGraph(lastStepGraph.stepGraph);
8478
- setLabel(lastStepGraph.label);
8479
- setFullStep(lastStepGraph.fullStep);
8480
- setParentStepGraphList(parentStepGraphList.slice(0, -1));
8481
- } else {
8482
- setOpenDialog(false);
8483
- setStepGraph(null);
8484
- setLabel("");
8485
- setFullStep("");
8486
- }
8487
- };
8450
+ const { showNestedGraph: showNestedGraphInPanel, closeStepDetail } = useWorkflowStepDetail();
8488
8451
  const showNestedGraph = ({
8489
- label: newLabel,
8490
- stepGraph: newStepGraph,
8491
- fullStep: newFullStep
8452
+ label,
8453
+ stepGraph,
8454
+ fullStep
8492
8455
  }) => {
8493
- if (stepGraph) {
8494
- setParentStepGraphList([...parentStepGraphList, { stepGraph, label, fullStep }]);
8495
- }
8496
- setLabel(newLabel);
8497
- setFullStep(newFullStep);
8498
- setStepGraph(newStepGraph);
8499
- setOpenDialog(true);
8456
+ showNestedGraphInPanel({ label, stepGraph, fullStep });
8500
8457
  };
8501
- return /* @__PURE__ */ jsxRuntime.jsxs(
8458
+ const closeNestedGraph = () => {
8459
+ closeStepDetail();
8460
+ };
8461
+ return /* @__PURE__ */ jsxRuntime.jsx(
8502
8462
  WorkflowNestedGraphContext.Provider,
8503
8463
  {
8504
8464
  value: {
8505
8465
  showNestedGraph,
8506
8466
  closeNestedGraph
8507
8467
  },
8508
- children: [
8509
- children,
8510
- /* @__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: [
8511
- /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-3 left-3 z-50", children: [
8512
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "text-current w-4 h-4" }),
8513
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
8514
- label,
8515
- " workflow"
8516
- ] })
8517
- ] }),
8518
- /* @__PURE__ */ jsxRuntime.jsx(react$2.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedGraph, { stepGraph, open: openDialog, workflowName: fullStep }) })
8519
- ] }) }) }, `${label}-${fullStep}`)
8520
- ]
8468
+ children
8521
8469
  }
8522
8470
  );
8523
8471
  }
@@ -8616,6 +8564,48 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8616
8564
  ] });
8617
8565
  }
8618
8566
 
8567
+ const Slider = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
8568
+ SliderPrimitive__namespace.Root,
8569
+ {
8570
+ ref,
8571
+ className: cn("relative flex w-full touch-none select-none items-center", className),
8572
+ ...props,
8573
+ children: [
8574
+ /* @__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" }) }),
8575
+ /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors disabled:pointer-events-none disabled:opacity-50" })
8576
+ ]
8577
+ }
8578
+ ));
8579
+ Slider.displayName = SliderPrimitive__namespace.Root.displayName;
8580
+
8581
+ const ZoomSlider = React.forwardRef(({ className, ...props }) => {
8582
+ const { zoom } = react$2.useViewport();
8583
+ const { zoomTo, zoomIn, zoomOut, fitView } = react$2.useReactFlow();
8584
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$2.Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8585
+ /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-4 w-4" }) }),
8586
+ /* @__PURE__ */ jsxRuntime.jsx(
8587
+ Slider,
8588
+ {
8589
+ className: "w-[140px]",
8590
+ value: [zoom],
8591
+ min: 0.01,
8592
+ max: 1,
8593
+ step: 0.01,
8594
+ onValueChange: (values) => {
8595
+ zoomTo(values[0]);
8596
+ }
8597
+ }
8598
+ ),
8599
+ /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }) }),
8600
+ /* @__PURE__ */ jsxRuntime.jsxs(Button$2, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8601
+ (100 * zoom).toFixed(0),
8602
+ "%"
8603
+ ] }),
8604
+ /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize, { className: "h-4 w-4" }) })
8605
+ ] });
8606
+ });
8607
+ ZoomSlider.displayName = "ZoomSlider";
8608
+
8619
8609
  function WorkflowGraphInner({ workflow }) {
8620
8610
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
8621
8611
  const [nodes, _, onNodesChange] = react$2.useNodesState(initialNodes);
@@ -8824,11 +8814,11 @@ function WorkflowTrigger({
8824
8814
  setIsRunning(true);
8825
8815
  setCancelResponse(null);
8826
8816
  setResult(null);
8827
- const { runId } = await createWorkflowRun({ workflowId });
8828
- setRunId?.(runId);
8829
- setInnerRunId(runId);
8830
- setContextRunId(runId);
8831
- streamWorkflow({ workflowId, runId, inputData: data, requestContext });
8817
+ const run = await createWorkflowRun({ workflowId });
8818
+ setRunId?.(run.runId);
8819
+ setInnerRunId(run.runId);
8820
+ setContextRunId(run.runId);
8821
+ streamWorkflow({ workflowId, runId: run.runId, inputData: data, requestContext });
8832
8822
  } catch (err) {
8833
8823
  setIsRunning(false);
8834
8824
  sonner.toast.error("Error executing workflow");
@@ -8838,10 +8828,10 @@ function WorkflowTrigger({
8838
8828
  if (!workflow) return;
8839
8829
  setCancelResponse(null);
8840
8830
  const { stepId, runId: prevRunId, resumeData } = step;
8841
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
8831
+ const run = await createWorkflowRun({ workflowId, prevRunId });
8842
8832
  await resumeWorkflow({
8843
8833
  step: stepId,
8844
- runId,
8834
+ runId: run.runId,
8845
8835
  resumeData,
8846
8836
  workflowId,
8847
8837
  requestContext
@@ -8885,7 +8875,7 @@ function WorkflowTrigger({
8885
8875
  const workflowActivePaths = streamResultToUse?.steps ?? {};
8886
8876
  const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
8887
8877
  const doneStatuses = ["success", "failed", "canceled", "tripwire"];
8888
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full pt-3 pb-12 overflow-y-auto", children: [
8878
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full pt-3 overflow-y-auto", children: [
8889
8879
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 px-5 pb-5 border-b-sm border-border1", children: [
8890
8880
  isSuspendedSteps && isStreamingWorkflow && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
8891
8881
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin text-icon6" }) }),
@@ -8968,12 +8958,16 @@ function WorkflowTrigger({
8968
8958
  const { status } = step;
8969
8959
  let output = void 0;
8970
8960
  let suspendOutput = void 0;
8961
+ let error = void 0;
8971
8962
  if (step.status === "suspended") {
8972
8963
  suspendOutput = step.suspendOutput;
8973
8964
  }
8974
8965
  if (step.status === "success") {
8975
8966
  output = step.output;
8976
8967
  }
8968
+ if (step.status === "failed") {
8969
+ error = step.error;
8970
+ }
8977
8971
  const tripwireInfo = step.status === "failed" && step.tripwire ? step.tripwire : streamResultToUse?.status === "tripwire" ? {
8978
8972
  reason: streamResultToUse?.tripwire?.reason,
8979
8973
  retry: streamResultToUse?.tripwire?.retry,
@@ -8986,7 +8980,7 @@ function WorkflowTrigger({
8986
8980
  {
8987
8981
  stepId,
8988
8982
  status: displayStatus,
8989
- result: output ?? suspendOutput ?? {},
8983
+ result: output ?? suspendOutput ?? error ?? {},
8990
8984
  tripwire: tripwireInfo
8991
8985
  },
8992
8986
  stepId
@@ -9555,14 +9549,28 @@ const PlaygroundTabs = ({
9555
9549
  const TabList$1 = ({ children, className }) => {
9556
9550
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: "border-b border-border1 flex min-w-full shrink-0", children }) });
9557
9551
  };
9558
- const Tab$1 = ({ children, value, onClick }) => {
9559
- return /* @__PURE__ */ jsxRuntime.jsx(
9552
+ const Tab$1 = ({ children, value, onClick, onClose }) => {
9553
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9560
9554
  TabsTrigger,
9561
9555
  {
9562
9556
  value,
9563
- className: "text-xs p-3 text-mastra-el-3 data-[state=active]:text-mastra-el-5 data-[state=active]:border-b-2 whitespace-nowrap flex-shrink-0",
9557
+ className: "text-xs p-3 text-mastra-el-3 data-[state=active]:text-mastra-el-5 data-[state=active]:border-b-2 whitespace-nowrap flex-shrink-0 flex items-center gap-1.5",
9564
9558
  onClick,
9565
- children
9559
+ children: [
9560
+ children,
9561
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
9562
+ "button",
9563
+ {
9564
+ onClick: (e) => {
9565
+ e.stopPropagation();
9566
+ onClose();
9567
+ },
9568
+ className: "p-0.5 hover:bg-surface3 rounded transition-colors",
9569
+ "aria-label": "Close tab",
9570
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
9571
+ }
9572
+ )
9573
+ ]
9566
9574
  }
9567
9575
  );
9568
9576
  };
@@ -9590,20 +9598,127 @@ const TracingRunOptions = () => {
9590
9598
  strValue = JSON.stringify(settings?.tracingOptions, null, 2);
9591
9599
  } catch {
9592
9600
  }
9593
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 px-5 py-2", children: [
9594
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Tracing Options" }),
9595
- /* @__PURE__ */ jsxRuntime.jsx(
9596
- CodeMirror,
9597
- {
9598
- value: strValue,
9599
- onChange: handleChange,
9600
- theme,
9601
- extensions: [langJson.jsonLanguage],
9602
- className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9603
- }
9604
- )
9601
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 px-5 py-2", children: [
9602
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Tracing Options" }),
9603
+ /* @__PURE__ */ jsxRuntime.jsx(
9604
+ CodeMirror,
9605
+ {
9606
+ value: strValue,
9607
+ onChange: handleChange,
9608
+ theme,
9609
+ extensions: [langJson.jsonLanguage],
9610
+ className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9611
+ }
9612
+ )
9613
+ ] });
9614
+ };
9615
+
9616
+ function Spinner({ color = "#fff", className }) {
9617
+ return /* @__PURE__ */ jsxRuntime.jsx(
9618
+ "svg",
9619
+ {
9620
+ className: clsx("animate-spin duration-700", className),
9621
+ xmlns: "http://www.w3.org/2000/svg",
9622
+ width: "24",
9623
+ height: "24",
9624
+ viewBox: "0 0 24 24",
9625
+ fill: "none",
9626
+ stroke: "currentColor",
9627
+ strokeWidth: "2",
9628
+ strokeLinecap: "round",
9629
+ strokeLinejoin: "round",
9630
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
9631
+ }
9632
+ );
9633
+ }
9634
+
9635
+ function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
9636
+ const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
9637
+ stepGraph
9638
+ });
9639
+ const [isMounted, setIsMounted] = React.useState(false);
9640
+ const [nodes, _, onNodesChange] = react$2.useNodesState(initialNodes);
9641
+ const [edges] = react$2.useEdgesState(initialEdges);
9642
+ const { steps } = useCurrentRun();
9643
+ const nodeTypes = {
9644
+ "default-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
9645
+ "condition-node": WorkflowConditionNode,
9646
+ "after-node": WorkflowAfterNode,
9647
+ "loop-result-node": WorkflowLoopResultNode,
9648
+ "nested-node": (props) => /* @__PURE__ */ jsxRuntime.jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
9649
+ };
9650
+ React.useEffect(() => {
9651
+ if (open) {
9652
+ setTimeout(() => {
9653
+ setIsMounted(true);
9654
+ }, 500);
9655
+ }
9656
+ }, [open]);
9657
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxRuntime.jsxs(
9658
+ react$2.ReactFlow,
9659
+ {
9660
+ nodes,
9661
+ edges: edges.map((e) => ({
9662
+ ...e,
9663
+ style: {
9664
+ ...e.style,
9665
+ stroke: steps[`${workflowName}.${e.data?.previousStepId}`]?.status === "success" && steps[`${workflowName}.${e.data?.nextStepId}`] ? "#22c55e" : e.data?.conditionNode && !steps[`${workflowName}.${e.data?.previousStepId}`] && Boolean(steps[`${workflowName}.${e.data?.nextStepId}`]?.status) ? "#22c55e" : void 0
9666
+ }
9667
+ })),
9668
+ fitView: true,
9669
+ fitViewOptions: {
9670
+ maxZoom: 1
9671
+ },
9672
+ minZoom: 0.01,
9673
+ maxZoom: 1,
9674
+ nodeTypes,
9675
+ onNodesChange,
9676
+ children: [
9677
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomSlider, { position: "bottom-left" }),
9678
+ /* @__PURE__ */ jsxRuntime.jsx(react$2.Background, { variant: react$2.BackgroundVariant.Lines, gap: 12, size: 0.5 })
9679
+ ]
9680
+ }
9681
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) }) });
9682
+ }
9683
+
9684
+ function WorkflowStepDetailContent() {
9685
+ const { stepDetail, closeStepDetail } = useWorkflowStepDetail();
9686
+ if (!stepDetail) {
9687
+ return null;
9688
+ }
9689
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
9690
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b-sm border-border1 bg-surface1", children: [
9691
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9692
+ stepDetail.type === "map-config" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "w-4 h-4", style: { color: BADGE_COLORS.map } }),
9693
+ stepDetail.type === "nested-graph" && /* @__PURE__ */ jsxRuntime.jsx(WorkflowIcon, { className: "w-4 h-4", style: { color: BADGE_COLORS.workflow } }),
9694
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9695
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-md", className: "text-icon6 font-medium", children: stepDetail.type === "map-config" ? `${stepDetail.stepName} Config` : `${stepDetail.stepName} Workflow` }),
9696
+ stepDetail.type === "map-config" && stepDetail.stepId && stepDetail.stepId !== stepDetail.stepName && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: stepDetail.stepId })
9697
+ ] })
9698
+ ] }),
9699
+ /* @__PURE__ */ jsxRuntime.jsx(
9700
+ "button",
9701
+ {
9702
+ onClick: closeStepDetail,
9703
+ className: "p-1 hover:bg-surface3 rounded transition-colors",
9704
+ "aria-label": "Close",
9705
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4 text-icon3" })
9706
+ }
9707
+ )
9708
+ ] }),
9709
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto", children: [
9710
+ stepDetail.type === "map-config" && stepDetail.mapConfig && /* @__PURE__ */ jsxRuntime.jsx(CodeDialogContent, { data: stepDetail.mapConfig }),
9711
+ stepDetail.type === "nested-graph" && stepDetail.nestedGraph && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full min-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
9712
+ WorkflowNestedGraph,
9713
+ {
9714
+ stepGraph: stepDetail.nestedGraph.stepGraph,
9715
+ open: true,
9716
+ workflowName: stepDetail.nestedGraph.fullStep
9717
+ }
9718
+ ) }) })
9719
+ ] })
9605
9720
  ] });
9606
- };
9721
+ }
9607
9722
 
9608
9723
  function WorkflowInformation({ workflowId, initialRunId }) {
9609
9724
  const { data: workflow, isLoading, error } = useWorkflow(workflowId);
@@ -9618,10 +9733,21 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9618
9733
  cancelWorkflowRun,
9619
9734
  isCancellingWorkflowRun
9620
9735
  } = React.useContext(WorkflowRunContext);
9736
+ const { stepDetail, closeStepDetail } = useWorkflowStepDetail();
9621
9737
  const [tab, setTab] = React.useState("current-run");
9622
9738
  const [runId, setRunId] = React.useState("");
9623
9739
  const { handleCopy } = useCopyToClipboard({ text: workflowId });
9624
9740
  const stepsCount = Object.keys(workflow?.steps ?? {}).length;
9741
+ const nodeDetailTabName = React.useMemo(() => {
9742
+ if (!stepDetail) return null;
9743
+ if (stepDetail.type === "map-config") {
9744
+ return "Map Config";
9745
+ }
9746
+ if (stepDetail.type === "nested-graph") {
9747
+ return "Nested Workflow";
9748
+ }
9749
+ return "Node";
9750
+ }, [stepDetail]);
9625
9751
  React.useEffect(() => {
9626
9752
  if (!runId && !initialRunId) {
9627
9753
  closeStreamsAndReset();
@@ -9633,6 +9759,19 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9633
9759
  toast.error(`Error loading workflow: ${errorMessage}`);
9634
9760
  }
9635
9761
  }, [error]);
9762
+ React.useEffect(() => {
9763
+ if (stepDetail) {
9764
+ setTab("node-details");
9765
+ } else if (tab === "node-details") {
9766
+ setTab("current-run");
9767
+ }
9768
+ }, [stepDetail]);
9769
+ const handleTabChange = (newTab) => {
9770
+ if (tab === "node-details" && newTab !== "node-details") {
9771
+ closeStepDetail();
9772
+ }
9773
+ setTab(newTab);
9774
+ };
9636
9775
  if (error) {
9637
9776
  return null;
9638
9777
  }
@@ -9649,10 +9788,24 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9649
9788
  ] }),
9650
9789
  workflow?.isProcessorWorkflow && /* @__PURE__ */ jsxRuntime.jsx(Badge, { icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Cpu, { className: "h-3 w-3" }), className: "bg-violet-500/20 text-violet-400", children: "Processor" })
9651
9790
  ] }) }),
9652
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "current-run", value: tab, onValueChange: setTab, children: [
9791
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-auto border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "current-run", value: tab, onValueChange: handleTabChange, className: "h-full", children: [
9653
9792
  /* @__PURE__ */ jsxRuntime.jsxs(TabList$1, { children: [
9654
9793
  /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "current-run", children: "Current Run" }),
9655
- /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "run-options", children: "Run options" })
9794
+ /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "run-options", children: "Run Options" }),
9795
+ stepDetail && nodeDetailTabName && /* @__PURE__ */ jsxRuntime.jsxs(
9796
+ Tab$1,
9797
+ {
9798
+ value: "node-details",
9799
+ onClose: () => {
9800
+ closeStepDetail();
9801
+ setTab("current-run");
9802
+ },
9803
+ children: [
9804
+ nodeDetailTabName,
9805
+ " Details"
9806
+ ]
9807
+ }
9808
+ )
9656
9809
  ] }),
9657
9810
  /* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "current-run", children: workflowId ? initialRunId ? /* @__PURE__ */ jsxRuntime.jsx(
9658
9811
  WorkflowRunDetail,
@@ -9687,7 +9840,8 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9687
9840
  cancelWorkflowRun
9688
9841
  }
9689
9842
  ) : null }),
9690
- /* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "run-options", children: /* @__PURE__ */ jsxRuntime.jsx(TracingRunOptions, {}) })
9843
+ /* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "run-options", children: /* @__PURE__ */ jsxRuntime.jsx(TracingRunOptions, {}) }),
9844
+ stepDetail && /* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "node-details", children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepDetailContent, {}) })
9691
9845
  ] }) })
9692
9846
  ] });
9693
9847
  }
@@ -9919,7 +10073,8 @@ const WorkflowBadge = ({
9919
10073
  isStreaming,
9920
10074
  metadata,
9921
10075
  toolCallId,
9922
- toolApprovalMetadata
10076
+ toolApprovalMetadata,
10077
+ suspendPayload
9923
10078
  }) => {
9924
10079
  const { runId, status } = result || {};
9925
10080
  const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(workflowId);
@@ -9931,6 +10086,7 @@ const WorkflowBadge = ({
9931
10086
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
9932
10087
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
9933
10088
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
10089
+ let suspendPayloadSlot = typeof suspendPayload === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: suspendPayload }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$1, { data: suspendPayload, "data-testid": "tool-suspend-payload" });
9934
10090
  if (isWorkflowLoading || !workflow) return /* @__PURE__ */ jsxRuntime.jsx(LoadingBadge, {});
9935
10091
  return /* @__PURE__ */ jsxRuntime.jsxs(
9936
10092
  BadgeWrapper,
@@ -9947,6 +10103,10 @@ const WorkflowBadge = ({
9947
10103
  }
9948
10104
  ),
9949
10105
  children: [
10106
+ suspendPayloadSlot !== void 0 && suspendPayload && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10107
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool suspend payload" }),
10108
+ suspendPayloadSlot
10109
+ ] }),
9950
10110
  !isStreaming && !isLoading && /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { snapshot, workflowId, initialRunId: runId, withoutTimeTravel: true, children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }) }),
9951
10111
  isStreaming && /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }),
9952
10112
  /* @__PURE__ */ jsxRuntime.jsx(ToolApprovalButtons, { toolCalled: !!status, toolCallId, toolApprovalMetadata })
@@ -10082,7 +10242,9 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10082
10242
  const agentToolName = toolName.startsWith("agent-") ? toolName.substring("agent-".length) : toolName;
10083
10243
  const workflowToolName = toolName.startsWith("workflow-") ? toolName.substring("workflow-".length) : toolName;
10084
10244
  const requireApprovalMetadata = metadata?.mode === "stream" && metadata?.requireApprovalMetadata;
10085
- const toolApprovalMetadata = requireApprovalMetadata ? requireApprovalMetadata?.[toolCallId] : void 0;
10245
+ const suspendedTools = metadata?.mode === "stream" && metadata?.suspendedTools;
10246
+ const toolApprovalMetadata = requireApprovalMetadata ? requireApprovalMetadata?.[toolName] ?? requireApprovalMetadata?.[toolCallId] : void 0;
10247
+ const suspendedToolMetadata = suspendedTools ? suspendedTools?.[toolName] : void 0;
10086
10248
  useWorkflowStream(result);
10087
10249
  if (isAgent) {
10088
10250
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -10106,7 +10268,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10106
10268
  result,
10107
10269
  metadata,
10108
10270
  toolCallId,
10109
- toolApprovalMetadata
10271
+ toolApprovalMetadata,
10272
+ suspendPayload: suspendedToolMetadata?.suspendPayload
10110
10273
  }
10111
10274
  );
10112
10275
  }
@@ -10119,7 +10282,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10119
10282
  toolOutput: result?.toolOutput || [],
10120
10283
  metadata,
10121
10284
  toolCallId,
10122
- toolApprovalMetadata
10285
+ toolApprovalMetadata,
10286
+ suspendPayload: suspendedToolMetadata?.suspendPayload
10123
10287
  }
10124
10288
  );
10125
10289
  };
@@ -11200,25 +11364,36 @@ const ThreadWelcome = ({ agentName }) => {
11200
11364
  };
11201
11365
  const Composer = ({ hasMemory, agentId }) => {
11202
11366
  const { setThreadInput } = useThreadInput();
11367
+ const textareaRef = React.useRef(null);
11203
11368
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-4", children: /* @__PURE__ */ jsxRuntime.jsxs(react.ComposerPrimitive.Root, { children: [
11204
11369
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ComposerAttachments, {}) }),
11205
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface3 rounded-lg border-sm border-border1 py-4 mt-auto max-w-[568px] w-full mx-auto px-4 focus-within:outline focus-within:outline-accent1 -outline-offset-2", children: [
11206
- /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
11207
- "textarea",
11208
- {
11209
- className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none outline-none",
11210
- autoFocus: document.activeElement === document.body,
11211
- placeholder: "Enter your message...",
11212
- name: "",
11213
- id: "",
11214
- onChange: (e) => setThreadInput?.(e.target.value)
11215
- }
11216
- ) }),
11217
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11218
- /* @__PURE__ */ jsxRuntime.jsx(SpeechInput, { agentId }),
11219
- /* @__PURE__ */ jsxRuntime.jsx(ComposerAction, {})
11220
- ] })
11221
- ] })
11370
+ /* @__PURE__ */ jsxRuntime.jsxs(
11371
+ "div",
11372
+ {
11373
+ className: "bg-surface3 rounded-lg border-sm border-border1 py-4 mt-auto max-w-[568px] w-full mx-auto px-4 focus-within:outline focus-within:outline-accent1 -outline-offset-2",
11374
+ onClick: () => {
11375
+ textareaRef.current?.focus();
11376
+ },
11377
+ children: [
11378
+ /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
11379
+ "textarea",
11380
+ {
11381
+ ref: textareaRef,
11382
+ className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none outline-none",
11383
+ autoFocus: document.activeElement === document.body,
11384
+ placeholder: "Enter your message...",
11385
+ name: "",
11386
+ id: "",
11387
+ onChange: (e) => setThreadInput?.(e.target.value)
11388
+ }
11389
+ ) }),
11390
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11391
+ /* @__PURE__ */ jsxRuntime.jsx(SpeechInput, { agentId }),
11392
+ /* @__PURE__ */ jsxRuntime.jsx(ComposerAction, {})
11393
+ ] })
11394
+ ]
11395
+ }
11396
+ )
11222
11397
  ] }) });
11223
11398
  };
11224
11399
  const SpeechInput = ({ agentId }) => {
@@ -11556,34 +11731,33 @@ function useAgentSettingsState({ agentId, defaultSettings: defaultSettingsProp }
11556
11731
  React.useEffect(() => {
11557
11732
  try {
11558
11733
  const stored = localStorage.getItem(LOCAL_STORAGE_KEY);
11559
- if (stored) {
11560
- const parsed = JSON.parse(stored);
11561
- const settings2 = {
11562
- ...parsed,
11563
- modelSettings: {
11564
- ...defaultSettingsProp?.modelSettings ?? {},
11565
- ...parsed?.modelSettings ?? {}
11566
- }
11567
- };
11568
- setSettingsState(settings2 ?? void 0);
11569
- }
11734
+ const parsed = stored ? JSON.parse(stored) : {};
11735
+ const mergedSettings = {
11736
+ ...parsed,
11737
+ modelSettings: {
11738
+ ...defaultSettings.modelSettings,
11739
+ ...parsed?.modelSettings ?? {},
11740
+ ...defaultSettingsProp?.modelSettings ?? {}
11741
+ // Code defaults win
11742
+ }
11743
+ };
11744
+ setSettingsState(mergedSettings);
11570
11745
  } catch (e) {
11571
- console.error(e);
11572
11746
  }
11573
- }, [LOCAL_STORAGE_KEY]);
11747
+ }, [LOCAL_STORAGE_KEY, defaultSettingsProp]);
11574
11748
  const setSettings = (settingsValue) => {
11575
11749
  setSettingsState((prev) => ({ ...prev, ...settingsValue }));
11576
11750
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({ ...settingsValue, agentId }));
11577
11751
  };
11578
11752
  const resetAll = () => {
11579
- const settings2 = {
11753
+ const resetSettings = {
11580
11754
  modelSettings: {
11581
- ...defaultSettingsProp?.modelSettings ?? {},
11582
- ...defaultSettings.modelSettings
11755
+ ...defaultSettings.modelSettings,
11756
+ ...defaultSettingsProp?.modelSettings ?? {}
11583
11757
  }
11584
11758
  };
11585
- setSettingsState(settings2);
11586
- localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(settings2));
11759
+ setSettingsState(resetSettings);
11760
+ localStorage.removeItem(LOCAL_STORAGE_KEY);
11587
11761
  };
11588
11762
  return {
11589
11763
  settings,
@@ -11734,18 +11908,19 @@ const initializeMessageState = (initialMessages) => {
11734
11908
  };
11735
11909
  } else if (part.toolInvocation.state === "call") {
11736
11910
  const toolCallId = part.toolInvocation.toolCallId;
11911
+ const toolName = part.toolInvocation.toolName;
11737
11912
  const pendingToolApprovals = message.metadata?.pendingToolApprovals;
11738
11913
  const suspensionData = pendingToolApprovals?.[toolCallId];
11739
11914
  if (suspensionData) {
11740
11915
  return {
11741
11916
  type: "tool-call",
11742
11917
  toolCallId,
11743
- toolName: part.toolInvocation.toolName,
11918
+ toolName,
11744
11919
  args: part.toolInvocation.args,
11745
11920
  metadata: {
11746
11921
  mode: "stream",
11747
11922
  requireApprovalMetadata: {
11748
- [toolCallId]: suspensionData
11923
+ [toolName]: suspensionData
11749
11924
  }
11750
11925
  }
11751
11926
  };
@@ -11815,6 +11990,7 @@ function MastraRuntimeProvider({
11815
11990
  temperature,
11816
11991
  topK,
11817
11992
  topP,
11993
+ seed,
11818
11994
  chatWithGenerateLegacy,
11819
11995
  chatWithGenerate,
11820
11996
  chatWithNetwork,
@@ -11833,7 +12009,9 @@ function MastraRuntimeProvider({
11833
12009
  temperature,
11834
12010
  topK,
11835
12011
  topP,
11836
- maxTokens,
12012
+ seed,
12013
+ maxOutputTokens: maxTokens,
12014
+ // AI SDK v5 uses maxOutputTokens
11837
12015
  instructions,
11838
12016
  providerOptions,
11839
12017
  maxSteps,
@@ -11932,6 +12110,7 @@ function MastraRuntimeProvider({
11932
12110
  temperature,
11933
12111
  topK,
11934
12112
  topP,
12113
+ seed,
11935
12114
  instructions,
11936
12115
  requestContext: requestContextInstance,
11937
12116
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -12048,6 +12227,7 @@ function MastraRuntimeProvider({
12048
12227
  temperature,
12049
12228
  topK,
12050
12229
  topP,
12230
+ seed,
12051
12231
  instructions,
12052
12232
  requestContext: requestContextInstance,
12053
12233
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -12368,54 +12548,60 @@ const AgentAdvancedSettings = () => {
12368
12548
  ] }),
12369
12549
  /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleContent, { className: collapsibleContentClassName, children: [
12370
12550
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
12371
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "top-k", children: "Top K" }),
12551
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "frequency-penalty", children: "Frequency Penalty" }),
12372
12552
  /* @__PURE__ */ jsxRuntime.jsx(
12373
12553
  Input,
12374
12554
  {
12375
- id: "top-k",
12555
+ id: "frequency-penalty",
12376
12556
  type: "number",
12377
- value: settings?.modelSettings?.topK || "",
12557
+ step: "0.1",
12558
+ min: "-1",
12559
+ max: "1",
12560
+ value: settings?.modelSettings?.frequencyPenalty ?? "",
12378
12561
  onChange: (e) => setSettings({
12379
12562
  ...settings,
12380
12563
  modelSettings: {
12381
12564
  ...settings?.modelSettings,
12382
- topK: e.target.value ? Number(e.target.value) : void 0
12565
+ frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12383
12566
  }
12384
12567
  })
12385
12568
  }
12386
12569
  )
12387
12570
  ] }),
12388
12571
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
12389
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "frequency-penalty", children: "Frequency Penalty" }),
12572
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "presence-penalty", children: "Presence Penalty" }),
12390
12573
  /* @__PURE__ */ jsxRuntime.jsx(
12391
12574
  Input,
12392
12575
  {
12393
- id: "frequency-penalty",
12576
+ id: "presence-penalty",
12394
12577
  type: "number",
12395
- value: settings?.modelSettings?.frequencyPenalty || "",
12578
+ step: "0.1",
12579
+ min: "-1",
12580
+ max: "1",
12581
+ value: settings?.modelSettings?.presencePenalty ?? "",
12396
12582
  onChange: (e) => setSettings({
12397
12583
  ...settings,
12398
12584
  modelSettings: {
12399
12585
  ...settings?.modelSettings,
12400
- frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12586
+ presencePenalty: e.target.value ? Number(e.target.value) : void 0
12401
12587
  }
12402
12588
  })
12403
12589
  }
12404
12590
  )
12405
12591
  ] }),
12406
12592
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
12407
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "presence-penalty", children: "Presence Penalty" }),
12593
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "top-k", children: "Top K" }),
12408
12594
  /* @__PURE__ */ jsxRuntime.jsx(
12409
12595
  Input,
12410
12596
  {
12411
- id: "presence-penalty",
12597
+ id: "top-k",
12412
12598
  type: "number",
12413
- value: settings?.modelSettings?.presencePenalty || "",
12599
+ value: settings?.modelSettings?.topK || "",
12414
12600
  onChange: (e) => setSettings({
12415
12601
  ...settings,
12416
12602
  modelSettings: {
12417
12603
  ...settings?.modelSettings,
12418
- presencePenalty: e.target.value ? Number(e.target.value) : void 0
12604
+ topK: e.target.value ? Number(e.target.value) : void 0
12419
12605
  }
12420
12606
  })
12421
12607
  }
@@ -12475,6 +12661,24 @@ const AgentAdvancedSettings = () => {
12475
12661
  }
12476
12662
  )
12477
12663
  ] }),
12664
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
12665
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "seed", children: "Seed" }),
12666
+ /* @__PURE__ */ jsxRuntime.jsx(
12667
+ Input,
12668
+ {
12669
+ id: "seed",
12670
+ type: "number",
12671
+ value: settings?.modelSettings?.seed || "",
12672
+ onChange: (e) => setSettings({
12673
+ ...settings,
12674
+ modelSettings: {
12675
+ ...settings?.modelSettings,
12676
+ seed: e.target.value ? Number(e.target.value) : void 0
12677
+ }
12678
+ })
12679
+ }
12680
+ )
12681
+ ] }),
12478
12682
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 col-span-2", children: [
12479
12683
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
12480
12684
  /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "provider-options", children: "Provider Options" }),
@@ -15486,6 +15690,7 @@ const AgentMetadataModelList = ({
15486
15690
  }) => {
15487
15691
  const [modelConfigs, setModelConfigs] = React.useState(() => modelList);
15488
15692
  const hasMultipleModels = modelConfigs.length > 1;
15693
+ const enabledCount = modelConfigs.filter((m) => m.enabled !== false).length;
15489
15694
  const handleDragEnd = (result) => {
15490
15695
  if (!result.destination) {
15491
15696
  return;
@@ -15520,7 +15725,8 @@ const AgentMetadataModelList = ({
15520
15725
  modelConfig,
15521
15726
  updateModelInModelList: updateModel,
15522
15727
  showDragHandle: hasMultipleModels,
15523
- dragHandleProps: provided2.dragHandleProps
15728
+ dragHandleProps: provided2.dragHandleProps,
15729
+ isLastEnabled: modelConfig.enabled !== false && enabledCount === 1
15524
15730
  }
15525
15731
  ) }) }, modelConfig.id)),
15526
15732
  provided.placeholder
@@ -15530,7 +15736,8 @@ const AgentMetadataModelListItem = ({
15530
15736
  modelConfig,
15531
15737
  updateModelInModelList,
15532
15738
  showDragHandle,
15533
- dragHandleProps
15739
+ dragHandleProps,
15740
+ isLastEnabled
15534
15741
  }) => {
15535
15742
  const [enabled, setEnabled] = React.useState(() => modelConfig.enabled);
15536
15743
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-background hover:bg-muted/50 transition-colors", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 p-2", children: [
@@ -15544,7 +15751,10 @@ const AgentMetadataModelListItem = ({
15544
15751
  autoSave: true
15545
15752
  }
15546
15753
  ) }),
15547
- /* @__PURE__ */ jsxRuntime.jsx(
15754
+ isLastEnabled ? /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
15755
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(Switch, { checked: enabled, disabled: true, className: "pointer-events-none" }) }) }),
15756
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "At least one model must be enabled" }) })
15757
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx(
15548
15758
  Switch,
15549
15759
  {
15550
15760
  checked: enabled,
@@ -15562,7 +15772,14 @@ function usePromptEnhancer({ agentId }) {
15562
15772
  const client = react$1.useMastraClient();
15563
15773
  return reactQuery.useMutation({
15564
15774
  mutationFn: async ({ instructions, userComment }) => {
15565
- return await client.getAgent(agentId).enhanceInstructions(instructions, userComment);
15775
+ try {
15776
+ return await client.getAgent(agentId).enhanceInstructions(instructions, userComment);
15777
+ } catch (error) {
15778
+ const errorMessage = error instanceof Error ? error.message : "Error enhancing prompt";
15779
+ toast.error(errorMessage);
15780
+ console.error("Error enhancing prompt:", error);
15781
+ throw error;
15782
+ }
15566
15783
  }
15567
15784
  });
15568
15785
  }
@@ -15605,21 +15822,53 @@ const PromptEnhancer = ({ agentId }) => {
15605
15822
  const PromptEnhancerTextarea = ({ agentId }) => {
15606
15823
  const { prompt, setPrompt } = useAgentPromptExperiment();
15607
15824
  const { mutateAsync: enhancePrompt, isPending } = usePromptEnhancer({ agentId });
15825
+ const { data: agent, isLoading: isAgentLoading, isError: isAgentError } = useAgent(agentId);
15826
+ const { data: providersData, isLoading: isProvidersLoading } = useAgentsModelProviders();
15827
+ const providers = providersData?.providers || [];
15828
+ const isProviderConnected = (providerId) => {
15829
+ const cleanId = cleanProviderId(providerId);
15830
+ const provider = providers.find((p) => cleanProviderId(p.id) === cleanId);
15831
+ return provider?.connected === true;
15832
+ };
15833
+ const hasConnectedModel = () => {
15834
+ if (agent?.modelList && agent.modelList.length > 0) {
15835
+ return agent.modelList.some((m) => m.enabled !== false && isProviderConnected(m.model.provider));
15836
+ }
15837
+ return agent?.provider ? isProviderConnected(agent.provider) : false;
15838
+ };
15839
+ const isDataLoading = isAgentLoading || isProvidersLoading;
15840
+ const hasValidModel = !isDataLoading && !isAgentError && hasConnectedModel();
15608
15841
  const handleSubmit = async (e) => {
15609
15842
  e.preventDefault();
15610
15843
  const form = e.target;
15611
15844
  const formData = new FormData(form);
15612
15845
  const userComment = formData.get("userComment");
15613
- const result = await enhancePrompt({ instructions: prompt, userComment });
15614
- form.reset();
15615
- setPrompt(result.new_prompt);
15846
+ try {
15847
+ const result = await enhancePrompt({ instructions: prompt, userComment });
15848
+ form.reset();
15849
+ setPrompt(result.new_prompt);
15850
+ } catch {
15851
+ }
15616
15852
  };
15853
+ const isDisabled = isPending || !hasValidModel;
15854
+ const showWarning = !isDataLoading && !hasValidModel;
15617
15855
  return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
15618
- /* @__PURE__ */ jsxRuntime.jsx(Input, { name: "userComment", placeholder: "Enter your comment here...", className: "resize-none", disabled: isPending }),
15619
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(Button$1, { variant: "light", type: "submit", disabled: isPending, children: [
15620
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: isPending ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcwIcon, {}) }),
15621
- "Enhance prompt"
15622
- ] }) })
15856
+ /* @__PURE__ */ jsxRuntime.jsx(
15857
+ Input,
15858
+ {
15859
+ name: "userComment",
15860
+ placeholder: "Enter your comment here...",
15861
+ className: "resize-none",
15862
+ disabled: isDisabled
15863
+ }
15864
+ ),
15865
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end items-center gap-2", children: [
15866
+ showWarning && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-yellow-200", children: "No model with a configured API key found." }),
15867
+ /* @__PURE__ */ jsxRuntime.jsxs(Button$1, { variant: "light", type: "submit", disabled: isDisabled, children: [
15868
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: isPending ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcwIcon, {}) }),
15869
+ "Enhance prompt"
15870
+ ] })
15871
+ ] })
15623
15872
  ] });
15624
15873
  };
15625
15874
 
@@ -16393,13 +16642,16 @@ const AgentWorkingMemory = ({ agentId }) => {
16393
16642
  placeholder: "Enter working memory content..."
16394
16643
  }
16395
16644
  ),
16396
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
16645
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: !threadExists ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
16646
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { tabIndex: 0, children: /* @__PURE__ */ jsxRuntime.jsx(Button$2, { variant: "secondary", size: "sm", disabled: true, className: "text-xs pointer-events-none", children: "Edit Working Memory" }) }) }),
16647
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Working memory will be available after the agent calls updateWorkingMemory" }) })
16648
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
16397
16649
  Button$2,
16398
16650
  {
16399
16651
  variant: "secondary",
16400
16652
  size: "sm",
16401
16653
  onClick: () => setIsEditing(true),
16402
- disabled: !threadExists || isUpdating,
16654
+ disabled: isUpdating,
16403
16655
  className: "text-xs",
16404
16656
  children: "Edit Working Memory"
16405
16657
  }
@@ -16496,22 +16748,6 @@ const AgentMemoryConfig = ({ agentId }) => {
16496
16748
  ]
16497
16749
  });
16498
16750
  }
16499
- if (config.workingMemory) {
16500
- sections.push({
16501
- title: "Working Memory",
16502
- items: [
16503
- {
16504
- label: "Enabled",
16505
- value: config.workingMemory.enabled,
16506
- badge: config.workingMemory.enabled ? "success" : void 0
16507
- },
16508
- ...config.workingMemory.enabled ? [
16509
- { label: "Scope", value: config.workingMemory.scope || "resource" },
16510
- { label: "Template", value: config.workingMemory.template || "default" }
16511
- ] : []
16512
- ]
16513
- });
16514
- }
16515
16751
  return sections;
16516
16752
  }, [config]);
16517
16753
  const toggleSection = (title) => {
@@ -16571,7 +16807,7 @@ const AgentMemoryConfig = ({ agentId }) => {
16571
16807
  ),
16572
16808
  expandedSections.has(section.title) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2 space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-1", children: [
16573
16809
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-icon3", children: item.label }),
16574
- renderValue(item.value || "", item.badge)
16810
+ renderValue(item.value ?? "", item.badge)
16575
16811
  ] }, `${section.title}-${item.label}`)) })
16576
16812
  ] }, section.title)) })
16577
16813
  ] });
@@ -18702,6 +18938,17 @@ const Tabs = Object.assign(TabsRoot, {
18702
18938
  Content: TabContent
18703
18939
  });
18704
18940
 
18941
+ function isTokenDetailsObject(value) {
18942
+ return typeof value === "object" && value !== null;
18943
+ }
18944
+ const detailKeyLabels = {
18945
+ text: "Text",
18946
+ cacheRead: "Cache Read",
18947
+ cacheWrite: "Cache Write",
18948
+ audio: "Audio",
18949
+ image: "Image",
18950
+ reasoning: "Reasoning"
18951
+ };
18705
18952
  function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18706
18953
  if (!traceUsage && !spanUsage) {
18707
18954
  console.warn("No usage data available");
@@ -18806,6 +19053,14 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18806
19053
  cachedInputTokens: {
18807
19054
  label: "Cached Input Tokens",
18808
19055
  icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRightToLineIcon, {})
19056
+ },
19057
+ inputDetails: {
19058
+ label: "Input Details",
19059
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRightIcon, {})
19060
+ },
19061
+ outputDetails: {
19062
+ label: "Output Details",
19063
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRightToLineIcon, {})
18809
19064
  }
18810
19065
  };
18811
19066
  const commonTokenPresentations = {
@@ -18821,47 +19076,79 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18821
19076
  };
18822
19077
  let usageKeyOrder = [];
18823
19078
  if (hasV5Format) {
18824
- usageKeyOrder = ["totalTokens", "inputTokens", "outputTokens", "reasoningTokens", "cachedInputTokens"];
19079
+ usageKeyOrder = [
19080
+ "totalTokens",
19081
+ "inputTokens",
19082
+ "outputTokens",
19083
+ "reasoningTokens",
19084
+ "cachedInputTokens",
19085
+ "inputDetails",
19086
+ "outputDetails"
19087
+ ];
18825
19088
  } else {
18826
19089
  usageKeyOrder = ["totalTokens", "promptTokens", "completionTokens"];
18827
19090
  }
18828
- const usageAsArray = Object.entries(traceUsage || spanUsage || {}).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
18829
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxRuntime.jsxs(
18830
- "div",
18831
- {
18832
- className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
18833
- "min-h-[5.5rem]": traceUsage
18834
- }),
18835
- children: [
18836
- /* @__PURE__ */ jsxRuntime.jsxs(
18837
- "div",
18838
- {
18839
- className: cn(
18840
- "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
18841
- "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
18842
- ),
18843
- children: [
18844
- tokenPresentations?.[key]?.icon,
18845
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
18846
- /* @__PURE__ */ jsxRuntime.jsx("b", { className: "text-[1rem]", children: value })
18847
- ]
18848
- }
18849
- ),
18850
- tokensByProviderValid && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxRuntime.jsxs(
18851
- "dl",
18852
- {
18853
- className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
18854
- children: [
18855
- /* @__PURE__ */ jsxRuntime.jsx("dt", { children: provider }),
18856
- /* @__PURE__ */ jsxRuntime.jsx("dd", { children: providerTokens?.[key] })
18857
- ]
18858
- },
18859
- provider
18860
- )) })
18861
- ]
18862
- },
18863
- key
18864
- )) });
19091
+ const usageAsArray = Object.entries(traceUsage || spanUsage || {}).filter((entry) => {
19092
+ const value = entry[1];
19093
+ return typeof value === "number" || isTokenDetailsObject(value);
19094
+ }).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
19095
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => {
19096
+ const isObject = isTokenDetailsObject(value);
19097
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19098
+ "div",
19099
+ {
19100
+ className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
19101
+ "min-h-[5.5rem]": traceUsage
19102
+ }),
19103
+ children: [
19104
+ /* @__PURE__ */ jsxRuntime.jsxs(
19105
+ "div",
19106
+ {
19107
+ className: cn(
19108
+ "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
19109
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
19110
+ ),
19111
+ children: [
19112
+ tokenPresentations?.[key]?.icon,
19113
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
19114
+ !isObject && /* @__PURE__ */ jsxRuntime.jsx("b", { className: "text-[1rem]", children: value })
19115
+ ]
19116
+ }
19117
+ ),
19118
+ isObject && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(value).map(([detailKey, detailValue]) => {
19119
+ if (typeof detailValue !== "number") return null;
19120
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19121
+ "dl",
19122
+ {
19123
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
19124
+ children: [
19125
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: detailKeyLabels[detailKey] || detailKey }),
19126
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: detailValue })
19127
+ ]
19128
+ },
19129
+ detailKey
19130
+ );
19131
+ }) }),
19132
+ !isObject && tokensByProviderValid && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => {
19133
+ const tokenValue = providerTokens?.[key];
19134
+ if (typeof tokenValue !== "number") return null;
19135
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19136
+ "dl",
19137
+ {
19138
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
19139
+ children: [
19140
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: provider }),
19141
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: tokenValue })
19142
+ ]
19143
+ },
19144
+ provider
19145
+ );
19146
+ }) })
19147
+ ]
19148
+ },
19149
+ key
19150
+ );
19151
+ }) });
18865
19152
  }
18866
19153
 
18867
19154
  function isTokenLimitExceeded(span) {
@@ -18974,7 +19261,7 @@ function SpanTabs({
18974
19261
  SpanScoring,
18975
19262
  {
18976
19263
  traceId: trace?.traceId,
18977
- isTopLevelSpan: span?.parentSpanId === null,
19264
+ isTopLevelSpan: !Boolean(span?.parentSpanId),
18978
19265
  spanId: span?.spanId,
18979
19266
  entityType,
18980
19267
  scorers,
@@ -20134,14 +20421,6 @@ const MCPToolPanel = ({ toolId, serverId }) => {
20134
20421
  );
20135
20422
  };
20136
20423
 
20137
- const CodeMirrorBlock = (props) => {
20138
- const theme = useCodemirrorTheme$1();
20139
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4 relative", children: [
20140
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy code", content: props.value || "No content" }) }),
20141
- /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { extensions: [langJson.json()], theme, ...props })
20142
- ] });
20143
- };
20144
-
20145
20424
  const MCPDetail = ({ isLoading, server }) => {
20146
20425
  const [{ sseUrl, httpStreamUrl }, setUrls] = React.useState({
20147
20426
  sseUrl: "",
@@ -20163,112 +20442,45 @@ const MCPDetail = ({ isLoading, server }) => {
20163
20442
  if (isLoading) return null;
20164
20443
  if (!server)
20165
20444
  return /* @__PURE__ */ jsxRuntime.jsx(MainContentContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon3 font-medium py-20 text-center", children: "Server not found" }) });
20445
+ const commandLineConfig = `npx -y mcp-remote ${sseUrl}`;
20166
20446
  return /* @__PURE__ */ jsxRuntime.jsxs(MainContentContent, { isDivided: true, children: [
20167
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-8 py-20 mx-auto max-w-[604px] w-full", children: [
20447
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-8 py-12 mx-auto max-w-2xl w-full", children: [
20168
20448
  /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon6 font-medium pb-4", children: server.name }),
20169
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
20170
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
20171
- /* @__PURE__ */ jsxRuntime.jsx(
20172
- Badge,
20173
- {
20174
- icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "SSE" }),
20175
- className: "!text-icon4",
20176
- children: sseUrl
20177
- }
20178
- ),
20179
- /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" })
20180
- ] }),
20181
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
20182
- /* @__PURE__ */ jsxRuntime.jsx(
20183
- Badge,
20184
- {
20185
- icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "HTTP" }),
20186
- className: "!text-icon4",
20187
- children: httpStreamUrl
20188
- }
20189
- ),
20190
- /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" })
20191
- ] })
20192
- ] }),
20193
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 pt-3 pb-9", children: [
20449
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 pb-6", children: [
20194
20450
  /* @__PURE__ */ jsxRuntime.jsx(Badge, { icon: /* @__PURE__ */ jsxRuntime.jsx(FolderIcon, { className: "text-icon6" }), className: "rounded-r-sm !text-icon4", children: "Version" }),
20195
20451
  /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "rounded-l-sm !text-icon4", children: server.version_detail.version })
20196
20452
  ] }),
20197
- /* @__PURE__ */ jsxRuntime.jsx(McpSetupTabs, { sseUrl, serverName: server.name })
20453
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3 pb-4", children: "This MCP server can be accessed through multiple transport methods. Choose the one that best fits your use case." }),
20454
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
20455
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20456
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "HTTP" }), children: "Regular HTTP Endpoint" }),
20457
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for stateless HTTP transport with streamable responses." }),
20458
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
20459
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: httpStreamUrl }),
20460
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" }) })
20461
+ ] })
20462
+ ] }),
20463
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20464
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "SSE" }), children: "Server-Sent Events" }),
20465
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for real-time communication via SSE." }),
20466
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
20467
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: sseUrl }),
20468
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" }) })
20469
+ ] })
20470
+ ] }),
20471
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20472
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "CLI" }), children: "Command Line" }),
20473
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for local command-line access via npx and mcp-remote." }),
20474
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
20475
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: commandLineConfig }),
20476
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy Command Line Config", content: commandLineConfig, iconSize: "sm" }) })
20477
+ ] })
20478
+ ] })
20479
+ ] })
20198
20480
  ] }),
20199
20481
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll border-l-sm border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(McpToolList, { server }) })
20200
20482
  ] });
20201
20483
  };
20202
- const McpSetupTabs = ({ sseUrl, serverName }) => {
20203
- const { Link } = useLinkComponent();
20204
- return /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "cursor", children: [
20205
- /* @__PURE__ */ jsxRuntime.jsxs(TabList$1, { children: [
20206
- /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "cursor", children: "Cursor" }),
20207
- /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "windsurf", children: "Windsurf" })
20208
- ] }),
20209
- /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "cursor", children: [
20210
- /* @__PURE__ */ jsxRuntime.jsxs(Txt, { className: "text-icon3 pb-4", children: [
20211
- "Cursor comes with built-in MCP Support.",
20212
- " ",
20213
- /* @__PURE__ */ jsxRuntime.jsx(
20214
- Link,
20215
- {
20216
- href: "https://docs.cursor.com/context/model-context-protocol",
20217
- target: "_blank",
20218
- rel: "noopener noreferrer",
20219
- className: "underline hover:text-icon6",
20220
- children: "Following the documentation"
20221
- }
20222
- ),
20223
- ", you can register an MCP server using SSE with the following configuration."
20224
- ] }),
20225
- /* @__PURE__ */ jsxRuntime.jsx(
20226
- CodeMirrorBlock,
20227
- {
20228
- editable: false,
20229
- value: `{
20230
- "mcpServers": {
20231
- "${serverName}": {
20232
- "url": "${sseUrl}"
20233
- }
20234
- }
20235
- }`
20236
- }
20237
- )
20238
- ] }),
20239
- /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "windsurf", children: [
20240
- /* @__PURE__ */ jsxRuntime.jsxs(Txt, { className: "text-icon3 pb-4", children: [
20241
- "Windsurf comes with built-in MCP Support.",
20242
- " ",
20243
- /* @__PURE__ */ jsxRuntime.jsx(
20244
- Link,
20245
- {
20246
- href: "https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json",
20247
- target: "_blank",
20248
- rel: "noopener noreferrer",
20249
- className: "underline hover:text-icon6",
20250
- children: "Following the documentation"
20251
- }
20252
- ),
20253
- ", you can register an MCP server using SSE with the following configuration."
20254
- ] }),
20255
- /* @__PURE__ */ jsxRuntime.jsx(
20256
- CodeMirrorBlock,
20257
- {
20258
- editable: false,
20259
- value: `{
20260
- "mcpServers": {
20261
- "${serverName}": {
20262
- "command": "npx",
20263
- "args": ["-y", "mcp-remote", "${sseUrl}"]
20264
- }
20265
- }
20266
- }`
20267
- }
20268
- )
20269
- ] })
20270
- ] });
20271
- };
20272
20484
  const McpToolList = ({ server }) => {
20273
20485
  const { data: tools = {}, isLoading } = useMCPServerTools(server);
20274
20486
  if (isLoading) return null;
@@ -20710,6 +20922,8 @@ exports.WorkflowRunContext = WorkflowRunContext;
20710
20922
  exports.WorkflowRunDetail = WorkflowRunDetail;
20711
20923
  exports.WorkflowRunList = WorkflowRunList;
20712
20924
  exports.WorkflowRunProvider = WorkflowRunProvider;
20925
+ exports.WorkflowStepDetailContext = WorkflowStepDetailContext;
20926
+ exports.WorkflowStepDetailProvider = WorkflowStepDetailProvider;
20713
20927
  exports.WorkflowTable = WorkflowTable;
20714
20928
  exports.WorkflowTrigger = WorkflowTrigger;
20715
20929
  exports.WorkingMemoryContext = WorkingMemoryContext;
@@ -20772,6 +20986,7 @@ exports.useUpdateModelInModelList = useUpdateModelInModelList;
20772
20986
  exports.useWorkflow = useWorkflow;
20773
20987
  exports.useWorkflowRunExecutionResult = useWorkflowRunExecutionResult;
20774
20988
  exports.useWorkflowRuns = useWorkflowRuns;
20989
+ exports.useWorkflowStepDetail = useWorkflowStepDetail;
20775
20990
  exports.useWorkflows = useWorkflows;
20776
20991
  exports.useWorkingMemory = useWorkingMemory;
20777
20992
  Object.keys(reactQuery).forEach(k => {