@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.es.js CHANGED
@@ -32,6 +32,7 @@ import { Highlight, themes } from 'prism-react-renderer';
32
32
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
33
33
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
34
34
  import { EditorView } from '@codemirror/view';
35
+ import { javascript } from '@codemirror/lang-javascript';
35
36
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
36
37
  import { format, isValid, formatDate, isToday } from 'date-fns';
37
38
  import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
@@ -4645,7 +4646,8 @@ const ToolBadge = ({
4645
4646
  metadata,
4646
4647
  toolOutput,
4647
4648
  toolCallId,
4648
- toolApprovalMetadata
4649
+ toolApprovalMetadata,
4650
+ suspendPayload
4649
4651
  }) => {
4650
4652
  let argSlot = null;
4651
4653
  try {
@@ -4655,6 +4657,7 @@ const ToolBadge = ({
4655
4657
  argSlot = /* @__PURE__ */ jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: args });
4656
4658
  }
4657
4659
  let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: result }) : /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result, "data-testid": "tool-result" });
4660
+ let suspendPayloadSlot = typeof suspendPayload === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: suspendPayload }) : /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: suspendPayload, "data-testid": "tool-suspend-payload" });
4658
4661
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
4659
4662
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
4660
4663
  const toolCalled = result || toolOutput.length > 0;
@@ -4671,12 +4674,16 @@ const ToolBadge = ({
4671
4674
  input: agentNetworkInput
4672
4675
  }
4673
4676
  ),
4674
- initialCollapsed: !!!toolApprovalMetadata,
4677
+ initialCollapsed: !!!(toolApprovalMetadata ?? suspendPayload),
4675
4678
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4676
4679
  /* @__PURE__ */ jsxs("div", { children: [
4677
4680
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4678
4681
  argSlot
4679
4682
  ] }),
4683
+ suspendPayloadSlot !== void 0 && suspendPayload && /* @__PURE__ */ jsxs("div", { children: [
4684
+ /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool suspend payload" }),
4685
+ suspendPayloadSlot
4686
+ ] }),
4680
4687
  resultSlot !== void 0 && result && /* @__PURE__ */ jsxs("div", { children: [
4681
4688
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4682
4689
  resultSlot
@@ -4993,7 +5000,8 @@ const useExecuteWorkflow = () => {
4993
5000
  requestContext.set(key, value);
4994
5001
  });
4995
5002
  const workflow = client.getWorkflow(workflowId);
4996
- await workflow.start({ runId, inputData: input || {}, requestContext });
5003
+ const run = await workflow.createRun({ runId });
5004
+ await run.start({ inputData: input || {}, requestContext });
4997
5005
  } catch (error) {
4998
5006
  console.error("Error starting workflow run:", error);
4999
5007
  throw error;
@@ -5013,7 +5021,8 @@ const useExecuteWorkflow = () => {
5013
5021
  requestContext.set(key, value);
5014
5022
  });
5015
5023
  const workflow = client.getWorkflow(workflowId);
5016
- const result = await workflow.startAsync({ runId, inputData: input || {}, requestContext });
5024
+ const run = await workflow.createRun({ runId });
5025
+ const result = await run.startAsync({ inputData: input || {}, requestContext });
5017
5026
  return result;
5018
5027
  } catch (error) {
5019
5028
  console.error("Error starting workflow run:", error);
@@ -5106,8 +5115,8 @@ const useStreamWorkflow = () => {
5106
5115
  requestContext.set(key, value);
5107
5116
  });
5108
5117
  const workflow = client.getWorkflow(workflowId);
5109
- const stream = await workflow.streamVNext({
5110
- runId,
5118
+ const run = await workflow.createRun({ runId });
5119
+ const stream = await run.streamVNext({
5111
5120
  inputData,
5112
5121
  requestContext,
5113
5122
  closeOnSuspend: true,
@@ -5169,7 +5178,8 @@ const useStreamWorkflow = () => {
5169
5178
  return;
5170
5179
  }
5171
5180
  const workflow = client.getWorkflow(workflowId);
5172
- const stream = await workflow.observeStreamVNext({ runId });
5181
+ const run = await workflow.createRun({ runId });
5182
+ const stream = await run.observeStreamVNext();
5173
5183
  if (!stream) {
5174
5184
  return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
5175
5185
  }
@@ -5227,8 +5237,8 @@ const useStreamWorkflow = () => {
5227
5237
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5228
5238
  requestContext.set(key, value);
5229
5239
  });
5230
- const stream = await workflow.resumeStreamVNext({
5231
- runId,
5240
+ const run = await workflow.createRun({ runId });
5241
+ const stream = await run.resumeStreamVNext({
5232
5242
  step,
5233
5243
  resumeData,
5234
5244
  requestContext,
@@ -5277,6 +5287,7 @@ const useStreamWorkflow = () => {
5277
5287
  mutationFn: async ({
5278
5288
  workflowId,
5279
5289
  requestContext: playgroundRequestContext,
5290
+ runId,
5280
5291
  ...params
5281
5292
  }) => {
5282
5293
  if (timeTravelStreamRef.current) {
@@ -5289,7 +5300,8 @@ const useStreamWorkflow = () => {
5289
5300
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5290
5301
  requestContext.set(key, value);
5291
5302
  });
5292
- const stream = await workflow.timeTravelStream({
5303
+ const run = await workflow.createRun({ runId });
5304
+ const stream = await run.timeTravelStream({
5293
5305
  ...params,
5294
5306
  requestContext,
5295
5307
  tracingOptions: settings?.tracingOptions
@@ -5380,7 +5392,9 @@ const useCancelWorkflowRun = () => {
5380
5392
  const cancelWorkflowRun = useMutation({
5381
5393
  mutationFn: async ({ workflowId, runId }) => {
5382
5394
  try {
5383
- const response = await client.getWorkflow(workflowId).cancelRun(runId);
5395
+ const workflow = client.getWorkflow(workflowId);
5396
+ const run = await workflow.createRun({ runId });
5397
+ const response = await run.cancelRun();
5384
5398
  return response;
5385
5399
  } catch (error) {
5386
5400
  console.error("Error canceling workflow run:", error);
@@ -5474,6 +5488,58 @@ const useDeleteWorkflowRun = (workflowId) => {
5474
5488
  });
5475
5489
  };
5476
5490
 
5491
+ const WorkflowStepDetailContext = createContext(null);
5492
+ function useWorkflowStepDetail() {
5493
+ const context = useContext(WorkflowStepDetailContext);
5494
+ if (!context) {
5495
+ throw new Error("useWorkflowStepDetail must be used within WorkflowStepDetailProvider");
5496
+ }
5497
+ return context;
5498
+ }
5499
+ function WorkflowStepDetailProvider({ children }) {
5500
+ const [stepDetail, setStepDetail] = useState(null);
5501
+ const showMapConfig = useCallback(
5502
+ ({ stepName, stepId, mapConfig }) => {
5503
+ setStepDetail({
5504
+ type: "map-config",
5505
+ stepName,
5506
+ stepId,
5507
+ mapConfig
5508
+ });
5509
+ },
5510
+ []
5511
+ );
5512
+ const showNestedGraph = useCallback(
5513
+ ({ label, stepGraph, fullStep }) => {
5514
+ setStepDetail({
5515
+ type: "nested-graph",
5516
+ stepName: label,
5517
+ nestedGraph: {
5518
+ label,
5519
+ stepGraph,
5520
+ fullStep
5521
+ }
5522
+ });
5523
+ },
5524
+ []
5525
+ );
5526
+ const closeStepDetail = useCallback(() => {
5527
+ setStepDetail(null);
5528
+ }, []);
5529
+ return /* @__PURE__ */ jsx(
5530
+ WorkflowStepDetailContext.Provider,
5531
+ {
5532
+ value: {
5533
+ stepDetail,
5534
+ showMapConfig,
5535
+ showNestedGraph,
5536
+ closeStepDetail
5537
+ },
5538
+ children
5539
+ }
5540
+ );
5541
+ }
5542
+
5477
5543
  const WorkflowRunContext = createContext({});
5478
5544
  function WorkflowRunProvider({
5479
5545
  children,
@@ -5575,7 +5641,7 @@ function WorkflowRunProvider({
5575
5641
  isLoadingRunExecutionResult,
5576
5642
  withoutTimeTravel
5577
5643
  },
5578
- children
5644
+ children: /* @__PURE__ */ jsx(WorkflowStepDetailProvider, { children })
5579
5645
  }
5580
5646
  );
5581
5647
  }
@@ -6234,26 +6300,46 @@ const SyntaxHighlighter$1 = ({ data }) => {
6234
6300
  return /* @__PURE__ */ jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] }) });
6235
6301
  };
6236
6302
 
6237
- const CodeDialogContent = ({ data }) => {
6303
+ const CodeDialogContent = ({
6304
+ data,
6305
+ language = "auto"
6306
+ }) => {
6238
6307
  const theme = useCodemirrorTheme$1();
6308
+ const getExtensions = (content) => {
6309
+ if (language === "javascript") {
6310
+ return [javascript(), EditorView.lineWrapping];
6311
+ }
6312
+ if (language === "json") {
6313
+ return [jsonLanguage, EditorView.lineWrapping];
6314
+ }
6315
+ try {
6316
+ JSON.parse(content);
6317
+ return [jsonLanguage, EditorView.lineWrapping];
6318
+ } catch {
6319
+ if (content.includes("=>") || content.includes("function") || content.includes("const ") || content.includes("return ")) {
6320
+ return [javascript(), EditorView.lineWrapping];
6321
+ }
6322
+ return [EditorView.lineWrapping];
6323
+ }
6324
+ };
6239
6325
  if (typeof data !== "string") {
6326
+ const content = JSON.stringify(data, null, 2);
6240
6327
  return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6241
- /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(data, null, 2) }) }),
6242
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(data, null, 2), theme, extensions: [jsonLanguage] }) })
6328
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content }) }),
6329
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: content, theme, extensions: [jsonLanguage, EditorView.lineWrapping] }) })
6243
6330
  ] });
6244
6331
  }
6332
+ const extensions = getExtensions(data);
6333
+ let displayContent = data;
6245
6334
  try {
6246
6335
  const json = JSON.parse(data);
6247
- return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6248
- /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
6249
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(json, null, 2), theme, extensions: [jsonLanguage] }) })
6250
- ] });
6251
- } catch (error) {
6252
- return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6253
- /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
6254
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [] }) })
6255
- ] });
6336
+ displayContent = JSON.stringify(json, null, 2);
6337
+ } catch {
6256
6338
  }
6339
+ return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6340
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
6341
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: displayContent, theme, extensions }) })
6342
+ ] });
6257
6343
  };
6258
6344
 
6259
6345
  const Form = React__default.forwardRef(({ children, ...props }, ref) => {
@@ -7767,9 +7853,9 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7767
7853
  const parsedResume = resumeData.trim() ? JSON.parse(resumeData) : {};
7768
7854
  const parsedContext = contextValue.trim() ? JSON.parse(contextValue) : {};
7769
7855
  const parsedNestedContext = nestedContextValue.trim() ? JSON.parse(nestedContextValue) : {};
7770
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
7856
+ const run = await createWorkflowRun({ workflowId, prevRunId });
7771
7857
  const payload = {
7772
- runId,
7858
+ runId: run.runId,
7773
7859
  workflowId,
7774
7860
  step: stepKey,
7775
7861
  inputData: data,
@@ -7881,12 +7967,29 @@ const WorkflowStepActionBar = ({
7881
7967
  const [isResumeDataOpen, setIsResumeDataOpen] = useState(false);
7882
7968
  const [isErrorOpen, setIsErrorOpen] = useState(false);
7883
7969
  const [isTripwireOpen, setIsTripwireOpen] = useState(false);
7884
- const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
7885
7970
  const [isTimeTravelOpen, setIsTimeTravelOpen] = useState(false);
7886
7971
  const { withoutTimeTravel } = useContext(WorkflowRunContext);
7972
+ const { showMapConfig, stepDetail, closeStepDetail } = useWorkflowStepDetail();
7887
7973
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7888
7974
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7889
7975
  const showTimeTravel = !withoutTimeTravel && stepKey && !mapConfig;
7976
+ const isMapConfigOpen = stepDetail?.type === "map-config" && stepDetail?.stepName === stepName;
7977
+ const isNestedGraphOpen = stepDetail?.type === "nested-graph" && stepDetail?.stepName === stepName;
7978
+ const activeButtonClass = "ring-2 ring-accent1 ring-offset-1 ring-offset-transparent";
7979
+ const handleMapConfigClick = () => {
7980
+ if (isMapConfigOpen) {
7981
+ closeStepDetail();
7982
+ } else {
7983
+ showMapConfig({ stepName, stepId, mapConfig });
7984
+ }
7985
+ };
7986
+ const handleNestedGraphClick = () => {
7987
+ if (isNestedGraphOpen) {
7988
+ closeStepDetail();
7989
+ } else {
7990
+ onShowNestedGraph?.();
7991
+ }
7992
+ };
7890
7993
  return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || tripwire || mapConfig || resumeData || onShowNestedGraph || showTimeTravel) && /* @__PURE__ */ jsxs(
7891
7994
  "div",
7892
7995
  {
@@ -7900,7 +8003,7 @@ const WorkflowStepActionBar = ({
7900
8003
  status === "running" && "bg-accent6Dark"
7901
8004
  ),
7902
8005
  children: [
7903
- onShowNestedGraph && /* @__PURE__ */ jsx(Button$1, { onClick: onShowNestedGraph, children: "View nested graph" }),
8006
+ onShowNestedGraph && /* @__PURE__ */ jsx(Button$1, { onClick: handleNestedGraphClick, className: cn(isNestedGraphOpen && activeButtonClass), children: "View nested graph" }),
7904
8007
  showTimeTravel && /* @__PURE__ */ jsxs(Fragment, { children: [
7905
8008
  /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsTimeTravelOpen(true), children: "Time travel" }),
7906
8009
  /* @__PURE__ */ jsx(Dialog, { open: isTimeTravelOpen, onOpenChange: setIsTimeTravelOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7911,19 +8014,7 @@ const WorkflowStepActionBar = ({
7911
8014
  /* @__PURE__ */ jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsx(WorkflowTimeTravelForm, { stepKey, closeModal: () => setIsTimeTravelOpen(false) }) })
7912
8015
  ] }) })
7913
8016
  ] }),
7914
- mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
7915
- /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
7916
- /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7917
- /* @__PURE__ */ jsx(DialogTitle, { className: dialogTitleClass, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
7918
- /* @__PURE__ */ jsxs("div", { children: [
7919
- stepName,
7920
- " Map Config"
7921
- ] }),
7922
- stepId && stepId !== stepName && /* @__PURE__ */ jsx("div", { className: "text-xs text-icon3 font-normal", children: stepId })
7923
- ] }) }),
7924
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
7925
- ] }) })
7926
- ] }),
8017
+ mapConfig && /* @__PURE__ */ jsx(Button$1, { onClick: handleMapConfigClick, className: cn(isMapConfigOpen && activeButtonClass), children: "Map config" }),
7927
8018
  input && /* @__PURE__ */ jsxs(Fragment, { children: [
7928
8019
  /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsInputOpen(true), children: "Input" }),
7929
8020
  /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -8065,7 +8156,7 @@ function WorkflowConditionNode({ data }) {
8065
8156
  "pre",
8066
8157
  {
8067
8158
  className: cn(
8068
- "relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 overflow-scroll",
8159
+ "relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 whitespace-pre-wrap break-words",
8069
8160
  className,
8070
8161
  previousDisplayStatus === "success" && nextStep && "!bg-accent1Dark",
8071
8162
  previousDisplayStatus === "failed" && nextStep && "!bg-accent2Dark",
@@ -8318,172 +8409,29 @@ function WorkflowLoopResultNode({ data }) {
8318
8409
  );
8319
8410
  }
8320
8411
 
8321
- function Spinner({ color = "#fff", className }) {
8322
- return /* @__PURE__ */ jsx(
8323
- "svg",
8324
- {
8325
- className: clsx("animate-spin duration-700", className),
8326
- xmlns: "http://www.w3.org/2000/svg",
8327
- width: "24",
8328
- height: "24",
8329
- viewBox: "0 0 24 24",
8330
- fill: "none",
8331
- stroke: "currentColor",
8332
- strokeWidth: "2",
8333
- strokeLinecap: "round",
8334
- strokeLinejoin: "round",
8335
- children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
8336
- }
8337
- );
8338
- }
8339
-
8340
- const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
8341
- SliderPrimitive.Root,
8342
- {
8343
- ref,
8344
- className: cn("relative flex w-full touch-none select-none items-center", className),
8345
- ...props,
8346
- children: [
8347
- /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
8348
- /* @__PURE__ */ jsx(SliderPrimitive.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" })
8349
- ]
8350
- }
8351
- ));
8352
- Slider.displayName = SliderPrimitive.Root.displayName;
8353
-
8354
- const ZoomSlider = forwardRef(({ className, ...props }) => {
8355
- const { zoom } = useViewport();
8356
- const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
8357
- return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8358
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
8359
- /* @__PURE__ */ jsx(
8360
- Slider,
8361
- {
8362
- className: "w-[140px]",
8363
- value: [zoom],
8364
- min: 0.01,
8365
- max: 1,
8366
- step: 0.01,
8367
- onValueChange: (values) => {
8368
- zoomTo(values[0]);
8369
- }
8370
- }
8371
- ),
8372
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
8373
- /* @__PURE__ */ jsxs(Button$2, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8374
- (100 * zoom).toFixed(0),
8375
- "%"
8376
- ] }),
8377
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
8378
- ] });
8379
- });
8380
- ZoomSlider.displayName = "ZoomSlider";
8381
-
8382
- function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
8383
- const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8384
- stepGraph
8385
- });
8386
- const [isMounted, setIsMounted] = useState(false);
8387
- const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8388
- const [edges] = useEdgesState(initialEdges);
8389
- const { steps } = useCurrentRun();
8390
- const nodeTypes = {
8391
- "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
8392
- "condition-node": WorkflowConditionNode,
8393
- "after-node": WorkflowAfterNode,
8394
- "loop-result-node": WorkflowLoopResultNode,
8395
- "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
8396
- };
8397
- useEffect(() => {
8398
- if (open) {
8399
- setTimeout(() => {
8400
- setIsMounted(true);
8401
- }, 500);
8402
- }
8403
- }, [open]);
8404
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
8405
- ReactFlow,
8406
- {
8407
- nodes,
8408
- edges: edges.map((e) => ({
8409
- ...e,
8410
- style: {
8411
- ...e.style,
8412
- 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
8413
- }
8414
- })),
8415
- fitView: true,
8416
- fitViewOptions: {
8417
- maxZoom: 1
8418
- },
8419
- minZoom: 0.01,
8420
- maxZoom: 1,
8421
- nodeTypes,
8422
- onNodesChange,
8423
- children: [
8424
- /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
8425
- /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
8426
- ]
8427
- }
8428
- ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
8429
- }
8430
-
8431
8412
  const WorkflowNestedGraphContext = createContext(
8432
8413
  {}
8433
8414
  );
8434
8415
  function WorkflowNestedGraphProvider({ children }) {
8435
- const [stepGraph, setStepGraph] = useState(null);
8436
- const [parentStepGraphList, setParentStepGraphList] = useState([]);
8437
- const [openDialog, setOpenDialog] = useState(false);
8438
- const [label, setLabel] = useState("");
8439
- const [fullStep, setFullStep] = useState("");
8440
- const closeNestedGraph = () => {
8441
- if (parentStepGraphList.length) {
8442
- const lastStepGraph = parentStepGraphList[parentStepGraphList.length - 1];
8443
- setStepGraph(lastStepGraph.stepGraph);
8444
- setLabel(lastStepGraph.label);
8445
- setFullStep(lastStepGraph.fullStep);
8446
- setParentStepGraphList(parentStepGraphList.slice(0, -1));
8447
- } else {
8448
- setOpenDialog(false);
8449
- setStepGraph(null);
8450
- setLabel("");
8451
- setFullStep("");
8452
- }
8453
- };
8416
+ const { showNestedGraph: showNestedGraphInPanel, closeStepDetail } = useWorkflowStepDetail();
8454
8417
  const showNestedGraph = ({
8455
- label: newLabel,
8456
- stepGraph: newStepGraph,
8457
- fullStep: newFullStep
8418
+ label,
8419
+ stepGraph,
8420
+ fullStep
8458
8421
  }) => {
8459
- if (stepGraph) {
8460
- setParentStepGraphList([...parentStepGraphList, { stepGraph, label, fullStep }]);
8461
- }
8462
- setLabel(newLabel);
8463
- setFullStep(newFullStep);
8464
- setStepGraph(newStepGraph);
8465
- setOpenDialog(true);
8422
+ showNestedGraphInPanel({ label, stepGraph, fullStep });
8466
8423
  };
8467
- return /* @__PURE__ */ jsxs(
8424
+ const closeNestedGraph = () => {
8425
+ closeStepDetail();
8426
+ };
8427
+ return /* @__PURE__ */ jsx(
8468
8428
  WorkflowNestedGraphContext.Provider,
8469
8429
  {
8470
8430
  value: {
8471
8431
  showNestedGraph,
8472
8432
  closeNestedGraph
8473
8433
  },
8474
- children: [
8475
- children,
8476
- /* @__PURE__ */ jsx(Dialog, { open: openDialog, onOpenChange: closeNestedGraph, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[45rem] h-[45rem] max-w-[unset] bg-[#121212] p-[0.5rem]", children: [
8477
- /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-3 left-3 z-50", children: [
8478
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
8479
- /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
8480
- label,
8481
- " workflow"
8482
- ] })
8483
- ] }),
8484
- /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(WorkflowNestedGraph, { stepGraph, open: openDialog, workflowName: fullStep }) })
8485
- ] }) }) }, `${label}-${fullStep}`)
8486
- ]
8434
+ children
8487
8435
  }
8488
8436
  );
8489
8437
  }
@@ -8582,6 +8530,48 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8582
8530
  ] });
8583
8531
  }
8584
8532
 
8533
+ const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
8534
+ SliderPrimitive.Root,
8535
+ {
8536
+ ref,
8537
+ className: cn("relative flex w-full touch-none select-none items-center", className),
8538
+ ...props,
8539
+ children: [
8540
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
8541
+ /* @__PURE__ */ jsx(SliderPrimitive.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" })
8542
+ ]
8543
+ }
8544
+ ));
8545
+ Slider.displayName = SliderPrimitive.Root.displayName;
8546
+
8547
+ const ZoomSlider = forwardRef(({ className, ...props }) => {
8548
+ const { zoom } = useViewport();
8549
+ const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
8550
+ return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8551
+ /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
8552
+ /* @__PURE__ */ jsx(
8553
+ Slider,
8554
+ {
8555
+ className: "w-[140px]",
8556
+ value: [zoom],
8557
+ min: 0.01,
8558
+ max: 1,
8559
+ step: 0.01,
8560
+ onValueChange: (values) => {
8561
+ zoomTo(values[0]);
8562
+ }
8563
+ }
8564
+ ),
8565
+ /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
8566
+ /* @__PURE__ */ jsxs(Button$2, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8567
+ (100 * zoom).toFixed(0),
8568
+ "%"
8569
+ ] }),
8570
+ /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
8571
+ ] });
8572
+ });
8573
+ ZoomSlider.displayName = "ZoomSlider";
8574
+
8585
8575
  function WorkflowGraphInner({ workflow }) {
8586
8576
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
8587
8577
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
@@ -8790,11 +8780,11 @@ function WorkflowTrigger({
8790
8780
  setIsRunning(true);
8791
8781
  setCancelResponse(null);
8792
8782
  setResult(null);
8793
- const { runId } = await createWorkflowRun({ workflowId });
8794
- setRunId?.(runId);
8795
- setInnerRunId(runId);
8796
- setContextRunId(runId);
8797
- streamWorkflow({ workflowId, runId, inputData: data, requestContext });
8783
+ const run = await createWorkflowRun({ workflowId });
8784
+ setRunId?.(run.runId);
8785
+ setInnerRunId(run.runId);
8786
+ setContextRunId(run.runId);
8787
+ streamWorkflow({ workflowId, runId: run.runId, inputData: data, requestContext });
8798
8788
  } catch (err) {
8799
8789
  setIsRunning(false);
8800
8790
  toast$1.error("Error executing workflow");
@@ -8804,10 +8794,10 @@ function WorkflowTrigger({
8804
8794
  if (!workflow) return;
8805
8795
  setCancelResponse(null);
8806
8796
  const { stepId, runId: prevRunId, resumeData } = step;
8807
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
8797
+ const run = await createWorkflowRun({ workflowId, prevRunId });
8808
8798
  await resumeWorkflow({
8809
8799
  step: stepId,
8810
- runId,
8800
+ runId: run.runId,
8811
8801
  resumeData,
8812
8802
  workflowId,
8813
8803
  requestContext
@@ -8851,7 +8841,7 @@ function WorkflowTrigger({
8851
8841
  const workflowActivePaths = streamResultToUse?.steps ?? {};
8852
8842
  const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
8853
8843
  const doneStatuses = ["success", "failed", "canceled", "tripwire"];
8854
- return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 pb-12 overflow-y-auto", children: [
8844
+ return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 overflow-y-auto", children: [
8855
8845
  /* @__PURE__ */ jsxs("div", { className: "space-y-4 px-5 pb-5 border-b-sm border-border1", children: [
8856
8846
  isSuspendedSteps && isStreamingWorkflow && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
8857
8847
  /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
@@ -8934,12 +8924,16 @@ function WorkflowTrigger({
8934
8924
  const { status } = step;
8935
8925
  let output = void 0;
8936
8926
  let suspendOutput = void 0;
8927
+ let error = void 0;
8937
8928
  if (step.status === "suspended") {
8938
8929
  suspendOutput = step.suspendOutput;
8939
8930
  }
8940
8931
  if (step.status === "success") {
8941
8932
  output = step.output;
8942
8933
  }
8934
+ if (step.status === "failed") {
8935
+ error = step.error;
8936
+ }
8943
8937
  const tripwireInfo = step.status === "failed" && step.tripwire ? step.tripwire : streamResultToUse?.status === "tripwire" ? {
8944
8938
  reason: streamResultToUse?.tripwire?.reason,
8945
8939
  retry: streamResultToUse?.tripwire?.retry,
@@ -8952,7 +8946,7 @@ function WorkflowTrigger({
8952
8946
  {
8953
8947
  stepId,
8954
8948
  status: displayStatus,
8955
- result: output ?? suspendOutput ?? {},
8949
+ result: output ?? suspendOutput ?? error ?? {},
8956
8950
  tripwire: tripwireInfo
8957
8951
  },
8958
8952
  stepId
@@ -9521,14 +9515,28 @@ const PlaygroundTabs = ({
9521
9515
  const TabList$1 = ({ children, className }) => {
9522
9516
  return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsx(TabsList, { className: "border-b border-border1 flex min-w-full shrink-0", children }) });
9523
9517
  };
9524
- const Tab$1 = ({ children, value, onClick }) => {
9525
- return /* @__PURE__ */ jsx(
9518
+ const Tab$1 = ({ children, value, onClick, onClose }) => {
9519
+ return /* @__PURE__ */ jsxs(
9526
9520
  TabsTrigger,
9527
9521
  {
9528
9522
  value,
9529
- 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",
9523
+ 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",
9530
9524
  onClick,
9531
- children
9525
+ children: [
9526
+ children,
9527
+ onClose && /* @__PURE__ */ jsx(
9528
+ "button",
9529
+ {
9530
+ onClick: (e) => {
9531
+ e.stopPropagation();
9532
+ onClose();
9533
+ },
9534
+ className: "p-0.5 hover:bg-surface3 rounded transition-colors",
9535
+ "aria-label": "Close tab",
9536
+ children: /* @__PURE__ */ jsx(X, { className: "w-3 h-3" })
9537
+ }
9538
+ )
9539
+ ]
9532
9540
  }
9533
9541
  );
9534
9542
  };
@@ -9556,20 +9564,127 @@ const TracingRunOptions = () => {
9556
9564
  strValue = JSON.stringify(settings?.tracingOptions, null, 2);
9557
9565
  } catch {
9558
9566
  }
9559
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-5 py-2", children: [
9560
- /* @__PURE__ */ jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Tracing Options" }),
9561
- /* @__PURE__ */ jsx(
9562
- CodeMirror,
9563
- {
9564
- value: strValue,
9565
- onChange: handleChange,
9566
- theme,
9567
- extensions: [jsonLanguage],
9568
- className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9569
- }
9570
- )
9567
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-5 py-2", children: [
9568
+ /* @__PURE__ */ jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Tracing Options" }),
9569
+ /* @__PURE__ */ jsx(
9570
+ CodeMirror,
9571
+ {
9572
+ value: strValue,
9573
+ onChange: handleChange,
9574
+ theme,
9575
+ extensions: [jsonLanguage],
9576
+ className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9577
+ }
9578
+ )
9579
+ ] });
9580
+ };
9581
+
9582
+ function Spinner({ color = "#fff", className }) {
9583
+ return /* @__PURE__ */ jsx(
9584
+ "svg",
9585
+ {
9586
+ className: clsx("animate-spin duration-700", className),
9587
+ xmlns: "http://www.w3.org/2000/svg",
9588
+ width: "24",
9589
+ height: "24",
9590
+ viewBox: "0 0 24 24",
9591
+ fill: "none",
9592
+ stroke: "currentColor",
9593
+ strokeWidth: "2",
9594
+ strokeLinecap: "round",
9595
+ strokeLinejoin: "round",
9596
+ children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
9597
+ }
9598
+ );
9599
+ }
9600
+
9601
+ function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
9602
+ const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
9603
+ stepGraph
9604
+ });
9605
+ const [isMounted, setIsMounted] = useState(false);
9606
+ const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9607
+ const [edges] = useEdgesState(initialEdges);
9608
+ const { steps } = useCurrentRun();
9609
+ const nodeTypes = {
9610
+ "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
9611
+ "condition-node": WorkflowConditionNode,
9612
+ "after-node": WorkflowAfterNode,
9613
+ "loop-result-node": WorkflowLoopResultNode,
9614
+ "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
9615
+ };
9616
+ useEffect(() => {
9617
+ if (open) {
9618
+ setTimeout(() => {
9619
+ setIsMounted(true);
9620
+ }, 500);
9621
+ }
9622
+ }, [open]);
9623
+ return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
9624
+ ReactFlow,
9625
+ {
9626
+ nodes,
9627
+ edges: edges.map((e) => ({
9628
+ ...e,
9629
+ style: {
9630
+ ...e.style,
9631
+ 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
9632
+ }
9633
+ })),
9634
+ fitView: true,
9635
+ fitViewOptions: {
9636
+ maxZoom: 1
9637
+ },
9638
+ minZoom: 0.01,
9639
+ maxZoom: 1,
9640
+ nodeTypes,
9641
+ onNodesChange,
9642
+ children: [
9643
+ /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
9644
+ /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
9645
+ ]
9646
+ }
9647
+ ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
9648
+ }
9649
+
9650
+ function WorkflowStepDetailContent() {
9651
+ const { stepDetail, closeStepDetail } = useWorkflowStepDetail();
9652
+ if (!stepDetail) {
9653
+ return null;
9654
+ }
9655
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
9656
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b-sm border-border1 bg-surface1", children: [
9657
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9658
+ stepDetail.type === "map-config" && /* @__PURE__ */ jsx(List, { className: "w-4 h-4", style: { color: BADGE_COLORS.map } }),
9659
+ stepDetail.type === "nested-graph" && /* @__PURE__ */ jsx(WorkflowIcon, { className: "w-4 h-4", style: { color: BADGE_COLORS.workflow } }),
9660
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
9661
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 font-medium", children: stepDetail.type === "map-config" ? `${stepDetail.stepName} Config` : `${stepDetail.stepName} Workflow` }),
9662
+ stepDetail.type === "map-config" && stepDetail.stepId && stepDetail.stepId !== stepDetail.stepName && /* @__PURE__ */ jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: stepDetail.stepId })
9663
+ ] })
9664
+ ] }),
9665
+ /* @__PURE__ */ jsx(
9666
+ "button",
9667
+ {
9668
+ onClick: closeStepDetail,
9669
+ className: "p-1 hover:bg-surface3 rounded transition-colors",
9670
+ "aria-label": "Close",
9671
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-icon3" })
9672
+ }
9673
+ )
9674
+ ] }),
9675
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-auto", children: [
9676
+ stepDetail.type === "map-config" && stepDetail.mapConfig && /* @__PURE__ */ jsx(CodeDialogContent, { data: stepDetail.mapConfig }),
9677
+ stepDetail.type === "nested-graph" && stepDetail.nestedGraph && /* @__PURE__ */ jsx("div", { className: "h-full min-h-[400px]", children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
9678
+ WorkflowNestedGraph,
9679
+ {
9680
+ stepGraph: stepDetail.nestedGraph.stepGraph,
9681
+ open: true,
9682
+ workflowName: stepDetail.nestedGraph.fullStep
9683
+ }
9684
+ ) }) })
9685
+ ] })
9571
9686
  ] });
9572
- };
9687
+ }
9573
9688
 
9574
9689
  function WorkflowInformation({ workflowId, initialRunId }) {
9575
9690
  const { data: workflow, isLoading, error } = useWorkflow(workflowId);
@@ -9584,10 +9699,21 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9584
9699
  cancelWorkflowRun,
9585
9700
  isCancellingWorkflowRun
9586
9701
  } = useContext(WorkflowRunContext);
9702
+ const { stepDetail, closeStepDetail } = useWorkflowStepDetail();
9587
9703
  const [tab, setTab] = useState("current-run");
9588
9704
  const [runId, setRunId] = useState("");
9589
9705
  const { handleCopy } = useCopyToClipboard({ text: workflowId });
9590
9706
  const stepsCount = Object.keys(workflow?.steps ?? {}).length;
9707
+ const nodeDetailTabName = useMemo(() => {
9708
+ if (!stepDetail) return null;
9709
+ if (stepDetail.type === "map-config") {
9710
+ return "Map Config";
9711
+ }
9712
+ if (stepDetail.type === "nested-graph") {
9713
+ return "Nested Workflow";
9714
+ }
9715
+ return "Node";
9716
+ }, [stepDetail]);
9591
9717
  useEffect(() => {
9592
9718
  if (!runId && !initialRunId) {
9593
9719
  closeStreamsAndReset();
@@ -9599,6 +9725,19 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9599
9725
  toast.error(`Error loading workflow: ${errorMessage}`);
9600
9726
  }
9601
9727
  }, [error]);
9728
+ useEffect(() => {
9729
+ if (stepDetail) {
9730
+ setTab("node-details");
9731
+ } else if (tab === "node-details") {
9732
+ setTab("current-run");
9733
+ }
9734
+ }, [stepDetail]);
9735
+ const handleTabChange = (newTab) => {
9736
+ if (tab === "node-details" && newTab !== "node-details") {
9737
+ closeStepDetail();
9738
+ }
9739
+ setTab(newTab);
9740
+ };
9602
9741
  if (error) {
9603
9742
  return null;
9604
9743
  }
@@ -9615,10 +9754,24 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9615
9754
  ] }),
9616
9755
  workflow?.isProcessorWorkflow && /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx(Cpu, { className: "h-3 w-3" }), className: "bg-violet-500/20 text-violet-400", children: "Processor" })
9617
9756
  ] }) }),
9618
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "current-run", value: tab, onValueChange: setTab, children: [
9757
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "current-run", value: tab, onValueChange: handleTabChange, className: "h-full", children: [
9619
9758
  /* @__PURE__ */ jsxs(TabList$1, { children: [
9620
9759
  /* @__PURE__ */ jsx(Tab$1, { value: "current-run", children: "Current Run" }),
9621
- /* @__PURE__ */ jsx(Tab$1, { value: "run-options", children: "Run options" })
9760
+ /* @__PURE__ */ jsx(Tab$1, { value: "run-options", children: "Run Options" }),
9761
+ stepDetail && nodeDetailTabName && /* @__PURE__ */ jsxs(
9762
+ Tab$1,
9763
+ {
9764
+ value: "node-details",
9765
+ onClose: () => {
9766
+ closeStepDetail();
9767
+ setTab("current-run");
9768
+ },
9769
+ children: [
9770
+ nodeDetailTabName,
9771
+ " Details"
9772
+ ]
9773
+ }
9774
+ )
9622
9775
  ] }),
9623
9776
  /* @__PURE__ */ jsx(TabContent$1, { value: "current-run", children: workflowId ? initialRunId ? /* @__PURE__ */ jsx(
9624
9777
  WorkflowRunDetail,
@@ -9653,7 +9806,8 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9653
9806
  cancelWorkflowRun
9654
9807
  }
9655
9808
  ) : null }),
9656
- /* @__PURE__ */ jsx(TabContent$1, { value: "run-options", children: /* @__PURE__ */ jsx(TracingRunOptions, {}) })
9809
+ /* @__PURE__ */ jsx(TabContent$1, { value: "run-options", children: /* @__PURE__ */ jsx(TracingRunOptions, {}) }),
9810
+ stepDetail && /* @__PURE__ */ jsx(TabContent$1, { value: "node-details", children: /* @__PURE__ */ jsx(WorkflowStepDetailContent, {}) })
9657
9811
  ] }) })
9658
9812
  ] });
9659
9813
  }
@@ -9885,7 +10039,8 @@ const WorkflowBadge = ({
9885
10039
  isStreaming,
9886
10040
  metadata,
9887
10041
  toolCallId,
9888
- toolApprovalMetadata
10042
+ toolApprovalMetadata,
10043
+ suspendPayload
9889
10044
  }) => {
9890
10045
  const { runId, status } = result || {};
9891
10046
  const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(workflowId);
@@ -9897,6 +10052,7 @@ const WorkflowBadge = ({
9897
10052
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
9898
10053
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
9899
10054
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
10055
+ let suspendPayloadSlot = typeof suspendPayload === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: suspendPayload }) : /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: suspendPayload, "data-testid": "tool-suspend-payload" });
9900
10056
  if (isWorkflowLoading || !workflow) return /* @__PURE__ */ jsx(LoadingBadge, {});
9901
10057
  return /* @__PURE__ */ jsxs(
9902
10058
  BadgeWrapper,
@@ -9913,6 +10069,10 @@ const WorkflowBadge = ({
9913
10069
  }
9914
10070
  ),
9915
10071
  children: [
10072
+ suspendPayloadSlot !== void 0 && suspendPayload && /* @__PURE__ */ jsxs("div", { children: [
10073
+ /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool suspend payload" }),
10074
+ suspendPayloadSlot
10075
+ ] }),
9916
10076
  !isStreaming && !isLoading && /* @__PURE__ */ jsx(WorkflowRunProvider, { snapshot, workflowId, initialRunId: runId, withoutTimeTravel: true, children: /* @__PURE__ */ jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }) }),
9917
10077
  isStreaming && /* @__PURE__ */ jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }),
9918
10078
  /* @__PURE__ */ jsx(ToolApprovalButtons, { toolCalled: !!status, toolCallId, toolApprovalMetadata })
@@ -10048,7 +10208,9 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10048
10208
  const agentToolName = toolName.startsWith("agent-") ? toolName.substring("agent-".length) : toolName;
10049
10209
  const workflowToolName = toolName.startsWith("workflow-") ? toolName.substring("workflow-".length) : toolName;
10050
10210
  const requireApprovalMetadata = metadata?.mode === "stream" && metadata?.requireApprovalMetadata;
10051
- const toolApprovalMetadata = requireApprovalMetadata ? requireApprovalMetadata?.[toolCallId] : void 0;
10211
+ const suspendedTools = metadata?.mode === "stream" && metadata?.suspendedTools;
10212
+ const toolApprovalMetadata = requireApprovalMetadata ? requireApprovalMetadata?.[toolName] ?? requireApprovalMetadata?.[toolCallId] : void 0;
10213
+ const suspendedToolMetadata = suspendedTools ? suspendedTools?.[toolName] : void 0;
10052
10214
  useWorkflowStream(result);
10053
10215
  if (isAgent) {
10054
10216
  return /* @__PURE__ */ jsx(
@@ -10072,7 +10234,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10072
10234
  result,
10073
10235
  metadata,
10074
10236
  toolCallId,
10075
- toolApprovalMetadata
10237
+ toolApprovalMetadata,
10238
+ suspendPayload: suspendedToolMetadata?.suspendPayload
10076
10239
  }
10077
10240
  );
10078
10241
  }
@@ -10085,7 +10248,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
10085
10248
  toolOutput: result?.toolOutput || [],
10086
10249
  metadata,
10087
10250
  toolCallId,
10088
- toolApprovalMetadata
10251
+ toolApprovalMetadata,
10252
+ suspendPayload: suspendedToolMetadata?.suspendPayload
10089
10253
  }
10090
10254
  );
10091
10255
  };
@@ -11166,25 +11330,36 @@ const ThreadWelcome = ({ agentName }) => {
11166
11330
  };
11167
11331
  const Composer = ({ hasMemory, agentId }) => {
11168
11332
  const { setThreadInput } = useThreadInput();
11333
+ const textareaRef = useRef(null);
11169
11334
  return /* @__PURE__ */ jsx("div", { className: "mx-4", children: /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
11170
11335
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
11171
- /* @__PURE__ */ 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: [
11172
- /* @__PURE__ */ jsx(ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(
11173
- "textarea",
11174
- {
11175
- className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none outline-none",
11176
- autoFocus: document.activeElement === document.body,
11177
- placeholder: "Enter your message...",
11178
- name: "",
11179
- id: "",
11180
- onChange: (e) => setThreadInput?.(e.target.value)
11181
- }
11182
- ) }),
11183
- /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11184
- /* @__PURE__ */ jsx(SpeechInput, { agentId }),
11185
- /* @__PURE__ */ jsx(ComposerAction, {})
11186
- ] })
11187
- ] })
11336
+ /* @__PURE__ */ jsxs(
11337
+ "div",
11338
+ {
11339
+ 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",
11340
+ onClick: () => {
11341
+ textareaRef.current?.focus();
11342
+ },
11343
+ children: [
11344
+ /* @__PURE__ */ jsx(ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(
11345
+ "textarea",
11346
+ {
11347
+ ref: textareaRef,
11348
+ className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none outline-none",
11349
+ autoFocus: document.activeElement === document.body,
11350
+ placeholder: "Enter your message...",
11351
+ name: "",
11352
+ id: "",
11353
+ onChange: (e) => setThreadInput?.(e.target.value)
11354
+ }
11355
+ ) }),
11356
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11357
+ /* @__PURE__ */ jsx(SpeechInput, { agentId }),
11358
+ /* @__PURE__ */ jsx(ComposerAction, {})
11359
+ ] })
11360
+ ]
11361
+ }
11362
+ )
11188
11363
  ] }) });
11189
11364
  };
11190
11365
  const SpeechInput = ({ agentId }) => {
@@ -11522,34 +11697,33 @@ function useAgentSettingsState({ agentId, defaultSettings: defaultSettingsProp }
11522
11697
  useEffect(() => {
11523
11698
  try {
11524
11699
  const stored = localStorage.getItem(LOCAL_STORAGE_KEY);
11525
- if (stored) {
11526
- const parsed = JSON.parse(stored);
11527
- const settings2 = {
11528
- ...parsed,
11529
- modelSettings: {
11530
- ...defaultSettingsProp?.modelSettings ?? {},
11531
- ...parsed?.modelSettings ?? {}
11532
- }
11533
- };
11534
- setSettingsState(settings2 ?? void 0);
11535
- }
11700
+ const parsed = stored ? JSON.parse(stored) : {};
11701
+ const mergedSettings = {
11702
+ ...parsed,
11703
+ modelSettings: {
11704
+ ...defaultSettings.modelSettings,
11705
+ ...parsed?.modelSettings ?? {},
11706
+ ...defaultSettingsProp?.modelSettings ?? {}
11707
+ // Code defaults win
11708
+ }
11709
+ };
11710
+ setSettingsState(mergedSettings);
11536
11711
  } catch (e) {
11537
- console.error(e);
11538
11712
  }
11539
- }, [LOCAL_STORAGE_KEY]);
11713
+ }, [LOCAL_STORAGE_KEY, defaultSettingsProp]);
11540
11714
  const setSettings = (settingsValue) => {
11541
11715
  setSettingsState((prev) => ({ ...prev, ...settingsValue }));
11542
11716
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({ ...settingsValue, agentId }));
11543
11717
  };
11544
11718
  const resetAll = () => {
11545
- const settings2 = {
11719
+ const resetSettings = {
11546
11720
  modelSettings: {
11547
- ...defaultSettingsProp?.modelSettings ?? {},
11548
- ...defaultSettings.modelSettings
11721
+ ...defaultSettings.modelSettings,
11722
+ ...defaultSettingsProp?.modelSettings ?? {}
11549
11723
  }
11550
11724
  };
11551
- setSettingsState(settings2);
11552
- localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(settings2));
11725
+ setSettingsState(resetSettings);
11726
+ localStorage.removeItem(LOCAL_STORAGE_KEY);
11553
11727
  };
11554
11728
  return {
11555
11729
  settings,
@@ -11700,18 +11874,19 @@ const initializeMessageState = (initialMessages) => {
11700
11874
  };
11701
11875
  } else if (part.toolInvocation.state === "call") {
11702
11876
  const toolCallId = part.toolInvocation.toolCallId;
11877
+ const toolName = part.toolInvocation.toolName;
11703
11878
  const pendingToolApprovals = message.metadata?.pendingToolApprovals;
11704
11879
  const suspensionData = pendingToolApprovals?.[toolCallId];
11705
11880
  if (suspensionData) {
11706
11881
  return {
11707
11882
  type: "tool-call",
11708
11883
  toolCallId,
11709
- toolName: part.toolInvocation.toolName,
11884
+ toolName,
11710
11885
  args: part.toolInvocation.args,
11711
11886
  metadata: {
11712
11887
  mode: "stream",
11713
11888
  requireApprovalMetadata: {
11714
- [toolCallId]: suspensionData
11889
+ [toolName]: suspensionData
11715
11890
  }
11716
11891
  }
11717
11892
  };
@@ -11781,6 +11956,7 @@ function MastraRuntimeProvider({
11781
11956
  temperature,
11782
11957
  topK,
11783
11958
  topP,
11959
+ seed,
11784
11960
  chatWithGenerateLegacy,
11785
11961
  chatWithGenerate,
11786
11962
  chatWithNetwork,
@@ -11799,7 +11975,9 @@ function MastraRuntimeProvider({
11799
11975
  temperature,
11800
11976
  topK,
11801
11977
  topP,
11802
- maxTokens,
11978
+ seed,
11979
+ maxOutputTokens: maxTokens,
11980
+ // AI SDK v5 uses maxOutputTokens
11803
11981
  instructions,
11804
11982
  providerOptions,
11805
11983
  maxSteps,
@@ -11898,6 +12076,7 @@ function MastraRuntimeProvider({
11898
12076
  temperature,
11899
12077
  topK,
11900
12078
  topP,
12079
+ seed,
11901
12080
  instructions,
11902
12081
  requestContext: requestContextInstance,
11903
12082
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -12014,6 +12193,7 @@ function MastraRuntimeProvider({
12014
12193
  temperature,
12015
12194
  topK,
12016
12195
  topP,
12196
+ seed,
12017
12197
  instructions,
12018
12198
  requestContext: requestContextInstance,
12019
12199
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -12334,54 +12514,60 @@ const AgentAdvancedSettings = () => {
12334
12514
  ] }),
12335
12515
  /* @__PURE__ */ jsxs(CollapsibleContent, { className: collapsibleContentClassName, children: [
12336
12516
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12337
- /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "top-k", children: "Top K" }),
12517
+ /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "frequency-penalty", children: "Frequency Penalty" }),
12338
12518
  /* @__PURE__ */ jsx(
12339
12519
  Input,
12340
12520
  {
12341
- id: "top-k",
12521
+ id: "frequency-penalty",
12342
12522
  type: "number",
12343
- value: settings?.modelSettings?.topK || "",
12523
+ step: "0.1",
12524
+ min: "-1",
12525
+ max: "1",
12526
+ value: settings?.modelSettings?.frequencyPenalty ?? "",
12344
12527
  onChange: (e) => setSettings({
12345
12528
  ...settings,
12346
12529
  modelSettings: {
12347
12530
  ...settings?.modelSettings,
12348
- topK: e.target.value ? Number(e.target.value) : void 0
12531
+ frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12349
12532
  }
12350
12533
  })
12351
12534
  }
12352
12535
  )
12353
12536
  ] }),
12354
12537
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12355
- /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "frequency-penalty", children: "Frequency Penalty" }),
12538
+ /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "presence-penalty", children: "Presence Penalty" }),
12356
12539
  /* @__PURE__ */ jsx(
12357
12540
  Input,
12358
12541
  {
12359
- id: "frequency-penalty",
12542
+ id: "presence-penalty",
12360
12543
  type: "number",
12361
- value: settings?.modelSettings?.frequencyPenalty || "",
12544
+ step: "0.1",
12545
+ min: "-1",
12546
+ max: "1",
12547
+ value: settings?.modelSettings?.presencePenalty ?? "",
12362
12548
  onChange: (e) => setSettings({
12363
12549
  ...settings,
12364
12550
  modelSettings: {
12365
12551
  ...settings?.modelSettings,
12366
- frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12552
+ presencePenalty: e.target.value ? Number(e.target.value) : void 0
12367
12553
  }
12368
12554
  })
12369
12555
  }
12370
12556
  )
12371
12557
  ] }),
12372
12558
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12373
- /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "presence-penalty", children: "Presence Penalty" }),
12559
+ /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "top-k", children: "Top K" }),
12374
12560
  /* @__PURE__ */ jsx(
12375
12561
  Input,
12376
12562
  {
12377
- id: "presence-penalty",
12563
+ id: "top-k",
12378
12564
  type: "number",
12379
- value: settings?.modelSettings?.presencePenalty || "",
12565
+ value: settings?.modelSettings?.topK || "",
12380
12566
  onChange: (e) => setSettings({
12381
12567
  ...settings,
12382
12568
  modelSettings: {
12383
12569
  ...settings?.modelSettings,
12384
- presencePenalty: e.target.value ? Number(e.target.value) : void 0
12570
+ topK: e.target.value ? Number(e.target.value) : void 0
12385
12571
  }
12386
12572
  })
12387
12573
  }
@@ -12441,6 +12627,24 @@ const AgentAdvancedSettings = () => {
12441
12627
  }
12442
12628
  )
12443
12629
  ] }),
12630
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12631
+ /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "seed", children: "Seed" }),
12632
+ /* @__PURE__ */ jsx(
12633
+ Input,
12634
+ {
12635
+ id: "seed",
12636
+ type: "number",
12637
+ value: settings?.modelSettings?.seed || "",
12638
+ onChange: (e) => setSettings({
12639
+ ...settings,
12640
+ modelSettings: {
12641
+ ...settings?.modelSettings,
12642
+ seed: e.target.value ? Number(e.target.value) : void 0
12643
+ }
12644
+ })
12645
+ }
12646
+ )
12647
+ ] }),
12444
12648
  /* @__PURE__ */ jsxs("div", { className: "space-y-1 col-span-2", children: [
12445
12649
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
12446
12650
  /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "provider-options", children: "Provider Options" }),
@@ -15452,6 +15656,7 @@ const AgentMetadataModelList = ({
15452
15656
  }) => {
15453
15657
  const [modelConfigs, setModelConfigs] = useState(() => modelList);
15454
15658
  const hasMultipleModels = modelConfigs.length > 1;
15659
+ const enabledCount = modelConfigs.filter((m) => m.enabled !== false).length;
15455
15660
  const handleDragEnd = (result) => {
15456
15661
  if (!result.destination) {
15457
15662
  return;
@@ -15486,7 +15691,8 @@ const AgentMetadataModelList = ({
15486
15691
  modelConfig,
15487
15692
  updateModelInModelList: updateModel,
15488
15693
  showDragHandle: hasMultipleModels,
15489
- dragHandleProps: provided2.dragHandleProps
15694
+ dragHandleProps: provided2.dragHandleProps,
15695
+ isLastEnabled: modelConfig.enabled !== false && enabledCount === 1
15490
15696
  }
15491
15697
  ) }) }, modelConfig.id)),
15492
15698
  provided.placeholder
@@ -15496,7 +15702,8 @@ const AgentMetadataModelListItem = ({
15496
15702
  modelConfig,
15497
15703
  updateModelInModelList,
15498
15704
  showDragHandle,
15499
- dragHandleProps
15705
+ dragHandleProps,
15706
+ isLastEnabled
15500
15707
  }) => {
15501
15708
  const [enabled, setEnabled] = useState(() => modelConfig.enabled);
15502
15709
  return /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-background hover:bg-muted/50 transition-colors", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 p-2", children: [
@@ -15510,7 +15717,10 @@ const AgentMetadataModelListItem = ({
15510
15717
  autoSave: true
15511
15718
  }
15512
15719
  ) }),
15513
- /* @__PURE__ */ jsx(
15720
+ isLastEnabled ? /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
15721
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(Switch, { checked: enabled, disabled: true, className: "pointer-events-none" }) }) }),
15722
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "At least one model must be enabled" }) })
15723
+ ] }) }) : /* @__PURE__ */ jsx(
15514
15724
  Switch,
15515
15725
  {
15516
15726
  checked: enabled,
@@ -15528,7 +15738,14 @@ function usePromptEnhancer({ agentId }) {
15528
15738
  const client = useMastraClient();
15529
15739
  return useMutation({
15530
15740
  mutationFn: async ({ instructions, userComment }) => {
15531
- return await client.getAgent(agentId).enhanceInstructions(instructions, userComment);
15741
+ try {
15742
+ return await client.getAgent(agentId).enhanceInstructions(instructions, userComment);
15743
+ } catch (error) {
15744
+ const errorMessage = error instanceof Error ? error.message : "Error enhancing prompt";
15745
+ toast.error(errorMessage);
15746
+ console.error("Error enhancing prompt:", error);
15747
+ throw error;
15748
+ }
15532
15749
  }
15533
15750
  });
15534
15751
  }
@@ -15571,21 +15788,53 @@ const PromptEnhancer = ({ agentId }) => {
15571
15788
  const PromptEnhancerTextarea = ({ agentId }) => {
15572
15789
  const { prompt, setPrompt } = useAgentPromptExperiment();
15573
15790
  const { mutateAsync: enhancePrompt, isPending } = usePromptEnhancer({ agentId });
15791
+ const { data: agent, isLoading: isAgentLoading, isError: isAgentError } = useAgent(agentId);
15792
+ const { data: providersData, isLoading: isProvidersLoading } = useAgentsModelProviders();
15793
+ const providers = providersData?.providers || [];
15794
+ const isProviderConnected = (providerId) => {
15795
+ const cleanId = cleanProviderId(providerId);
15796
+ const provider = providers.find((p) => cleanProviderId(p.id) === cleanId);
15797
+ return provider?.connected === true;
15798
+ };
15799
+ const hasConnectedModel = () => {
15800
+ if (agent?.modelList && agent.modelList.length > 0) {
15801
+ return agent.modelList.some((m) => m.enabled !== false && isProviderConnected(m.model.provider));
15802
+ }
15803
+ return agent?.provider ? isProviderConnected(agent.provider) : false;
15804
+ };
15805
+ const isDataLoading = isAgentLoading || isProvidersLoading;
15806
+ const hasValidModel = !isDataLoading && !isAgentError && hasConnectedModel();
15574
15807
  const handleSubmit = async (e) => {
15575
15808
  e.preventDefault();
15576
15809
  const form = e.target;
15577
15810
  const formData = new FormData(form);
15578
15811
  const userComment = formData.get("userComment");
15579
- const result = await enhancePrompt({ instructions: prompt, userComment });
15580
- form.reset();
15581
- setPrompt(result.new_prompt);
15812
+ try {
15813
+ const result = await enhancePrompt({ instructions: prompt, userComment });
15814
+ form.reset();
15815
+ setPrompt(result.new_prompt);
15816
+ } catch {
15817
+ }
15582
15818
  };
15819
+ const isDisabled = isPending || !hasValidModel;
15820
+ const showWarning = !isDataLoading && !hasValidModel;
15583
15821
  return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
15584
- /* @__PURE__ */ jsx(Input, { name: "userComment", placeholder: "Enter your comment here...", className: "resize-none", disabled: isPending }),
15585
- /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(Button$1, { variant: "light", type: "submit", disabled: isPending, children: [
15586
- /* @__PURE__ */ jsx(Icon, { children: isPending ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(RefreshCcwIcon, {}) }),
15587
- "Enhance prompt"
15588
- ] }) })
15822
+ /* @__PURE__ */ jsx(
15823
+ Input,
15824
+ {
15825
+ name: "userComment",
15826
+ placeholder: "Enter your comment here...",
15827
+ className: "resize-none",
15828
+ disabled: isDisabled
15829
+ }
15830
+ ),
15831
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end items-center gap-2", children: [
15832
+ showWarning && /* @__PURE__ */ jsx("span", { className: "text-xs text-yellow-200", children: "No model with a configured API key found." }),
15833
+ /* @__PURE__ */ jsxs(Button$1, { variant: "light", type: "submit", disabled: isDisabled, children: [
15834
+ /* @__PURE__ */ jsx(Icon, { children: isPending ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(RefreshCcwIcon, {}) }),
15835
+ "Enhance prompt"
15836
+ ] })
15837
+ ] })
15589
15838
  ] });
15590
15839
  };
15591
15840
 
@@ -16359,13 +16608,16 @@ const AgentWorkingMemory = ({ agentId }) => {
16359
16608
  placeholder: "Enter working memory content..."
16360
16609
  }
16361
16610
  ),
16362
- /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
16611
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsx(Fragment, { children: !threadExists ? /* @__PURE__ */ jsxs(Tooltip, { children: [
16612
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { tabIndex: 0, children: /* @__PURE__ */ jsx(Button$2, { variant: "secondary", size: "sm", disabled: true, className: "text-xs pointer-events-none", children: "Edit Working Memory" }) }) }),
16613
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "Working memory will be available after the agent calls updateWorkingMemory" }) })
16614
+ ] }) : /* @__PURE__ */ jsx(
16363
16615
  Button$2,
16364
16616
  {
16365
16617
  variant: "secondary",
16366
16618
  size: "sm",
16367
16619
  onClick: () => setIsEditing(true),
16368
- disabled: !threadExists || isUpdating,
16620
+ disabled: isUpdating,
16369
16621
  className: "text-xs",
16370
16622
  children: "Edit Working Memory"
16371
16623
  }
@@ -16462,22 +16714,6 @@ const AgentMemoryConfig = ({ agentId }) => {
16462
16714
  ]
16463
16715
  });
16464
16716
  }
16465
- if (config.workingMemory) {
16466
- sections.push({
16467
- title: "Working Memory",
16468
- items: [
16469
- {
16470
- label: "Enabled",
16471
- value: config.workingMemory.enabled,
16472
- badge: config.workingMemory.enabled ? "success" : void 0
16473
- },
16474
- ...config.workingMemory.enabled ? [
16475
- { label: "Scope", value: config.workingMemory.scope || "resource" },
16476
- { label: "Template", value: config.workingMemory.template || "default" }
16477
- ] : []
16478
- ]
16479
- });
16480
- }
16481
16717
  return sections;
16482
16718
  }, [config]);
16483
16719
  const toggleSection = (title) => {
@@ -16537,7 +16773,7 @@ const AgentMemoryConfig = ({ agentId }) => {
16537
16773
  ),
16538
16774
  expandedSections.has(section.title) && /* @__PURE__ */ jsx("div", { className: "px-3 pb-2 space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1", children: [
16539
16775
  /* @__PURE__ */ jsx("span", { className: "text-xs text-icon3", children: item.label }),
16540
- renderValue(item.value || "", item.badge)
16776
+ renderValue(item.value ?? "", item.badge)
16541
16777
  ] }, `${section.title}-${item.label}`)) })
16542
16778
  ] }, section.title)) })
16543
16779
  ] });
@@ -18668,6 +18904,17 @@ const Tabs = Object.assign(TabsRoot, {
18668
18904
  Content: TabContent
18669
18905
  });
18670
18906
 
18907
+ function isTokenDetailsObject(value) {
18908
+ return typeof value === "object" && value !== null;
18909
+ }
18910
+ const detailKeyLabels = {
18911
+ text: "Text",
18912
+ cacheRead: "Cache Read",
18913
+ cacheWrite: "Cache Write",
18914
+ audio: "Audio",
18915
+ image: "Image",
18916
+ reasoning: "Reasoning"
18917
+ };
18671
18918
  function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18672
18919
  if (!traceUsage && !spanUsage) {
18673
18920
  console.warn("No usage data available");
@@ -18772,6 +19019,14 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18772
19019
  cachedInputTokens: {
18773
19020
  label: "Cached Input Tokens",
18774
19021
  icon: /* @__PURE__ */ jsx(ArrowRightToLineIcon, {})
19022
+ },
19023
+ inputDetails: {
19024
+ label: "Input Details",
19025
+ icon: /* @__PURE__ */ jsx(ArrowRightIcon, {})
19026
+ },
19027
+ outputDetails: {
19028
+ label: "Output Details",
19029
+ icon: /* @__PURE__ */ jsx(ArrowRightToLineIcon, {})
18775
19030
  }
18776
19031
  };
18777
19032
  const commonTokenPresentations = {
@@ -18787,47 +19042,79 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18787
19042
  };
18788
19043
  let usageKeyOrder = [];
18789
19044
  if (hasV5Format) {
18790
- usageKeyOrder = ["totalTokens", "inputTokens", "outputTokens", "reasoningTokens", "cachedInputTokens"];
19045
+ usageKeyOrder = [
19046
+ "totalTokens",
19047
+ "inputTokens",
19048
+ "outputTokens",
19049
+ "reasoningTokens",
19050
+ "cachedInputTokens",
19051
+ "inputDetails",
19052
+ "outputDetails"
19053
+ ];
18791
19054
  } else {
18792
19055
  usageKeyOrder = ["totalTokens", "promptTokens", "completionTokens"];
18793
19056
  }
18794
- const usageAsArray = Object.entries(traceUsage || spanUsage || {}).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
18795
- return /* @__PURE__ */ jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxs(
18796
- "div",
18797
- {
18798
- className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
18799
- "min-h-[5.5rem]": traceUsage
18800
- }),
18801
- children: [
18802
- /* @__PURE__ */ jsxs(
18803
- "div",
18804
- {
18805
- className: cn(
18806
- "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
18807
- "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
18808
- ),
18809
- children: [
18810
- tokenPresentations?.[key]?.icon,
18811
- /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
18812
- /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
18813
- ]
18814
- }
18815
- ),
18816
- tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxs(
18817
- "dl",
18818
- {
18819
- className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
18820
- children: [
18821
- /* @__PURE__ */ jsx("dt", { children: provider }),
18822
- /* @__PURE__ */ jsx("dd", { children: providerTokens?.[key] })
18823
- ]
18824
- },
18825
- provider
18826
- )) })
18827
- ]
18828
- },
18829
- key
18830
- )) });
19057
+ const usageAsArray = Object.entries(traceUsage || spanUsage || {}).filter((entry) => {
19058
+ const value = entry[1];
19059
+ return typeof value === "number" || isTokenDetailsObject(value);
19060
+ }).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
19061
+ return /* @__PURE__ */ jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => {
19062
+ const isObject = isTokenDetailsObject(value);
19063
+ return /* @__PURE__ */ jsxs(
19064
+ "div",
19065
+ {
19066
+ className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
19067
+ "min-h-[5.5rem]": traceUsage
19068
+ }),
19069
+ children: [
19070
+ /* @__PURE__ */ jsxs(
19071
+ "div",
19072
+ {
19073
+ className: cn(
19074
+ "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
19075
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
19076
+ ),
19077
+ children: [
19078
+ tokenPresentations?.[key]?.icon,
19079
+ /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
19080
+ !isObject && /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
19081
+ ]
19082
+ }
19083
+ ),
19084
+ isObject && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(value).map(([detailKey, detailValue]) => {
19085
+ if (typeof detailValue !== "number") return null;
19086
+ return /* @__PURE__ */ jsxs(
19087
+ "dl",
19088
+ {
19089
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
19090
+ children: [
19091
+ /* @__PURE__ */ jsx("dt", { children: detailKeyLabels[detailKey] || detailKey }),
19092
+ /* @__PURE__ */ jsx("dd", { children: detailValue })
19093
+ ]
19094
+ },
19095
+ detailKey
19096
+ );
19097
+ }) }),
19098
+ !isObject && tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => {
19099
+ const tokenValue = providerTokens?.[key];
19100
+ if (typeof tokenValue !== "number") return null;
19101
+ return /* @__PURE__ */ jsxs(
19102
+ "dl",
19103
+ {
19104
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
19105
+ children: [
19106
+ /* @__PURE__ */ jsx("dt", { children: provider }),
19107
+ /* @__PURE__ */ jsx("dd", { children: tokenValue })
19108
+ ]
19109
+ },
19110
+ provider
19111
+ );
19112
+ }) })
19113
+ ]
19114
+ },
19115
+ key
19116
+ );
19117
+ }) });
18831
19118
  }
18832
19119
 
18833
19120
  function isTokenLimitExceeded(span) {
@@ -18940,7 +19227,7 @@ function SpanTabs({
18940
19227
  SpanScoring,
18941
19228
  {
18942
19229
  traceId: trace?.traceId,
18943
- isTopLevelSpan: span?.parentSpanId === null,
19230
+ isTopLevelSpan: !Boolean(span?.parentSpanId),
18944
19231
  spanId: span?.spanId,
18945
19232
  entityType,
18946
19233
  scorers,
@@ -20100,14 +20387,6 @@ const MCPToolPanel = ({ toolId, serverId }) => {
20100
20387
  );
20101
20388
  };
20102
20389
 
20103
- const CodeMirrorBlock = (props) => {
20104
- const theme = useCodemirrorTheme$1();
20105
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4 relative", children: [
20106
- /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy code", content: props.value || "No content" }) }),
20107
- /* @__PURE__ */ jsx(CodeMirror, { extensions: [json()], theme, ...props })
20108
- ] });
20109
- };
20110
-
20111
20390
  const MCPDetail = ({ isLoading, server }) => {
20112
20391
  const [{ sseUrl, httpStreamUrl }, setUrls] = useState({
20113
20392
  sseUrl: "",
@@ -20129,112 +20408,45 @@ const MCPDetail = ({ isLoading, server }) => {
20129
20408
  if (isLoading) return null;
20130
20409
  if (!server)
20131
20410
  return /* @__PURE__ */ jsx(MainContentContent, { children: /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon3 font-medium py-20 text-center", children: "Server not found" }) });
20411
+ const commandLineConfig = `npx -y mcp-remote ${sseUrl}`;
20132
20412
  return /* @__PURE__ */ jsxs(MainContentContent, { isDivided: true, children: [
20133
- /* @__PURE__ */ jsxs("div", { className: "px-8 py-20 mx-auto max-w-[604px] w-full", children: [
20413
+ /* @__PURE__ */ jsxs("div", { className: "px-8 py-12 mx-auto max-w-2xl w-full", children: [
20134
20414
  /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon6 font-medium pb-4", children: server.name }),
20135
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
20136
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
20137
- /* @__PURE__ */ jsx(
20138
- Badge,
20139
- {
20140
- icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "SSE" }),
20141
- className: "!text-icon4",
20142
- children: sseUrl
20143
- }
20144
- ),
20145
- /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" })
20146
- ] }),
20147
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
20148
- /* @__PURE__ */ jsx(
20149
- Badge,
20150
- {
20151
- icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "HTTP" }),
20152
- className: "!text-icon4",
20153
- children: httpStreamUrl
20154
- }
20155
- ),
20156
- /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" })
20157
- ] })
20158
- ] }),
20159
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 pt-3 pb-9", children: [
20415
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 pb-6", children: [
20160
20416
  /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx(FolderIcon, { className: "text-icon6" }), className: "rounded-r-sm !text-icon4", children: "Version" }),
20161
20417
  /* @__PURE__ */ jsx(Badge, { className: "rounded-l-sm !text-icon4", children: server.version_detail.version })
20162
20418
  ] }),
20163
- /* @__PURE__ */ jsx(McpSetupTabs, { sseUrl, serverName: server.name })
20419
+ /* @__PURE__ */ 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." }),
20420
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
20421
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20422
+ /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "HTTP" }), children: "Regular HTTP Endpoint" }),
20423
+ /* @__PURE__ */ jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for stateless HTTP transport with streamable responses." }),
20424
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
20425
+ /* @__PURE__ */ jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: httpStreamUrl }),
20426
+ /* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" }) })
20427
+ ] })
20428
+ ] }),
20429
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20430
+ /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "SSE" }), children: "Server-Sent Events" }),
20431
+ /* @__PURE__ */ jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for real-time communication via SSE." }),
20432
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
20433
+ /* @__PURE__ */ jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: sseUrl }),
20434
+ /* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" }) })
20435
+ ] })
20436
+ ] }),
20437
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4", children: [
20438
+ /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 font-medium mr-1", children: "CLI" }), children: "Command Line" }),
20439
+ /* @__PURE__ */ jsx(Txt, { className: "text-icon3 pt-1 pb-2", children: "Use for local command-line access via npx and mcp-remote." }),
20440
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
20441
+ /* @__PURE__ */ jsx(Txt, { className: "px-2 py-1 bg-surface4 rounded-lg", children: commandLineConfig }),
20442
+ /* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy Command Line Config", content: commandLineConfig, iconSize: "sm" }) })
20443
+ ] })
20444
+ ] })
20445
+ ] })
20164
20446
  ] }),
20165
20447
  /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll border-l-sm border-border1", children: /* @__PURE__ */ jsx(McpToolList, { server }) })
20166
20448
  ] });
20167
20449
  };
20168
- const McpSetupTabs = ({ sseUrl, serverName }) => {
20169
- const { Link } = useLinkComponent();
20170
- return /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "cursor", children: [
20171
- /* @__PURE__ */ jsxs(TabList$1, { children: [
20172
- /* @__PURE__ */ jsx(Tab$1, { value: "cursor", children: "Cursor" }),
20173
- /* @__PURE__ */ jsx(Tab$1, { value: "windsurf", children: "Windsurf" })
20174
- ] }),
20175
- /* @__PURE__ */ jsxs(TabContent$1, { value: "cursor", children: [
20176
- /* @__PURE__ */ jsxs(Txt, { className: "text-icon3 pb-4", children: [
20177
- "Cursor comes with built-in MCP Support.",
20178
- " ",
20179
- /* @__PURE__ */ jsx(
20180
- Link,
20181
- {
20182
- href: "https://docs.cursor.com/context/model-context-protocol",
20183
- target: "_blank",
20184
- rel: "noopener noreferrer",
20185
- className: "underline hover:text-icon6",
20186
- children: "Following the documentation"
20187
- }
20188
- ),
20189
- ", you can register an MCP server using SSE with the following configuration."
20190
- ] }),
20191
- /* @__PURE__ */ jsx(
20192
- CodeMirrorBlock,
20193
- {
20194
- editable: false,
20195
- value: `{
20196
- "mcpServers": {
20197
- "${serverName}": {
20198
- "url": "${sseUrl}"
20199
- }
20200
- }
20201
- }`
20202
- }
20203
- )
20204
- ] }),
20205
- /* @__PURE__ */ jsxs(TabContent$1, { value: "windsurf", children: [
20206
- /* @__PURE__ */ jsxs(Txt, { className: "text-icon3 pb-4", children: [
20207
- "Windsurf comes with built-in MCP Support.",
20208
- " ",
20209
- /* @__PURE__ */ jsx(
20210
- Link,
20211
- {
20212
- href: "https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json",
20213
- target: "_blank",
20214
- rel: "noopener noreferrer",
20215
- className: "underline hover:text-icon6",
20216
- children: "Following the documentation"
20217
- }
20218
- ),
20219
- ", you can register an MCP server using SSE with the following configuration."
20220
- ] }),
20221
- /* @__PURE__ */ jsx(
20222
- CodeMirrorBlock,
20223
- {
20224
- editable: false,
20225
- value: `{
20226
- "mcpServers": {
20227
- "${serverName}": {
20228
- "command": "npx",
20229
- "args": ["-y", "mcp-remote", "${sseUrl}"]
20230
- }
20231
- }
20232
- }`
20233
- }
20234
- )
20235
- ] })
20236
- ] });
20237
- };
20238
20450
  const McpToolList = ({ server }) => {
20239
20451
  const { data: tools = {}, isLoading } = useMCPServerTools(server);
20240
20452
  if (isLoading) return null;
@@ -20481,5 +20693,5 @@ const PlaygroundConfigGuard = () => {
20481
20693
  ] }) });
20482
20694
  };
20483
20695
 
20484
- export { AgentChat, AgentCoinIcon, AgentCombobox, AgentEntityHeader, AgentIcon, AgentInformation, AgentInformationLayout, AgentInformationTabLayout, AgentMemory, AgentMetadata, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentPromptExperimentProvider, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentToolPanel, AgentsTable, AiIcon, Alert$1 as Alert, AlertDescription$1 as AlertDescription, AlertDialog, AlertTitle$1 as AlertTitle, ApiIcon, Badge, BranchIcon, Breadcrumb, Button$1 as Button, ButtonsGroup, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, CommitIcon, CrossIcon, Crumb, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EntryList, EntryListSkeleton, EnvIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LinkComponentProvider, LogoWithoutText, LogsIcon, MCPDetail, MCPServerCombobox, MCPTable, MCPToolPanel, MainContentContent, MainContentLayout, MainSidebar, MainSidebarProvider, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, Notification, OpenAIIcon, PageHeader, PlaygroundConfigGuard, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupItem, RepoIcon, RequestContext, RequestContextWrapper, Row, ScoreDialog, ScorerCombobox, ScorersTable, ScoresList, ScoresTools, SearchField, Searchbar, SearchbarWrapper, Section, Sections, SelectField, SettingsIcon, SideDialog, Skeleton, SlashIcon, SpanScoreList, SpanScoring, SpanTabs, StudioConfigContext, StudioConfigForm, StudioConfigProvider, Tab$1 as Tab, TabContent$1 as TabContent, TabList$1 as TabList, Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolCombobox, ToolFallback, ToolIconMap, ToolInformation, ToolPanel, ToolTable, ToolsIcon, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineSpan, TraceTimelineTools, TracesList, TracesTools, TracingSettingsContext, TracingSettingsProvider, TsIcon, Txt, TxtCell, VariablesIcon, WorkflowCoinIcon, WorkflowCombobox, WorkflowGraph, WorkflowIcon, WorkflowInformation, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowTable, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, convertWorkflowRunStateToStreamResult, extractPrompt, formatHierarchicalSpans, getColumnTemplate, getShortId, getSpanTypeUi, getToNextEntryFn, getToPreviousEntryFn, parseError, providerMapToIcon, scoresListColumns, spanTypePrefixes, toast, traceScoresListColumns, tracesListColumns, useAgent, useAgentInformationSettings, useAgentInformationTab, useAgentPromptExperiment, useAgentSettings, useAgents, useCancelWorkflowRun, useCurrentRun, useDeleteThread, useDeleteWorkflowRun, useExecuteAgentTool, useExecuteMCPTool, useExecuteTool, useExecuteWorkflow, useInView, useLinkComponent, useMCPServerTool, useMCPServerTools, useMCPServers, useMainSidebar, useMemory, useMemoryConfig, useMemorySearch, usePlaygroundStore, useReorderModelList, useResetAgentModel, useScorer, useScorers, useScoresByScorerId, useSpeechRecognition, useStreamWorkflow, useStudioConfig, useThreadInput, useThreads, useTool, useTools, useTraceSpanScores, useTracingSettings, useUpdateAgentModel, useUpdateModelInModelList, useWorkflow, useWorkflowRunExecutionResult, useWorkflowRuns, useWorkflows, useWorkingMemory };
20696
+ export { AgentChat, AgentCoinIcon, AgentCombobox, AgentEntityHeader, AgentIcon, AgentInformation, AgentInformationLayout, AgentInformationTabLayout, AgentMemory, AgentMetadata, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentPromptExperimentProvider, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentToolPanel, AgentsTable, AiIcon, Alert$1 as Alert, AlertDescription$1 as AlertDescription, AlertDialog, AlertTitle$1 as AlertTitle, ApiIcon, Badge, BranchIcon, Breadcrumb, Button$1 as Button, ButtonsGroup, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, CommitIcon, CrossIcon, Crumb, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EntryList, EntryListSkeleton, EnvIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LinkComponentProvider, LogoWithoutText, LogsIcon, MCPDetail, MCPServerCombobox, MCPTable, MCPToolPanel, MainContentContent, MainContentLayout, MainSidebar, MainSidebarProvider, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, Notification, OpenAIIcon, PageHeader, PlaygroundConfigGuard, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupItem, RepoIcon, RequestContext, RequestContextWrapper, Row, ScoreDialog, ScorerCombobox, ScorersTable, ScoresList, ScoresTools, SearchField, Searchbar, SearchbarWrapper, Section, Sections, SelectField, SettingsIcon, SideDialog, Skeleton, SlashIcon, SpanScoreList, SpanScoring, SpanTabs, StudioConfigContext, StudioConfigForm, StudioConfigProvider, Tab$1 as Tab, TabContent$1 as TabContent, TabList$1 as TabList, Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolCombobox, ToolFallback, ToolIconMap, ToolInformation, ToolPanel, ToolTable, ToolsIcon, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineSpan, TraceTimelineTools, TracesList, TracesTools, TracingSettingsContext, TracingSettingsProvider, TsIcon, Txt, TxtCell, VariablesIcon, WorkflowCoinIcon, WorkflowCombobox, WorkflowGraph, WorkflowIcon, WorkflowInformation, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowStepDetailContext, WorkflowStepDetailProvider, WorkflowTable, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, convertWorkflowRunStateToStreamResult, extractPrompt, formatHierarchicalSpans, getColumnTemplate, getShortId, getSpanTypeUi, getToNextEntryFn, getToPreviousEntryFn, parseError, providerMapToIcon, scoresListColumns, spanTypePrefixes, toast, traceScoresListColumns, tracesListColumns, useAgent, useAgentInformationSettings, useAgentInformationTab, useAgentPromptExperiment, useAgentSettings, useAgents, useCancelWorkflowRun, useCurrentRun, useDeleteThread, useDeleteWorkflowRun, useExecuteAgentTool, useExecuteMCPTool, useExecuteTool, useExecuteWorkflow, useInView, useLinkComponent, useMCPServerTool, useMCPServerTools, useMCPServers, useMainSidebar, useMemory, useMemoryConfig, useMemorySearch, usePlaygroundStore, useReorderModelList, useResetAgentModel, useScorer, useScorers, useScoresByScorerId, useSpeechRecognition, useStreamWorkflow, useStudioConfig, useThreadInput, useThreads, useTool, useTools, useTraceSpanScores, useTracingSettings, useUpdateAgentModel, useUpdateModelInModelList, useWorkflow, useWorkflowRunExecutionResult, useWorkflowRuns, useWorkflowStepDetail, useWorkflows, useWorkingMemory };
20485
20697
  //# sourceMappingURL=index.es.js.map