@mastra/playground-ui 7.0.0-beta.10 → 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
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useAssistantState, useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, useAttachment, ComposerPrimitive, AttachmentPrimitive, useComposer, ThreadPrimitive, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechSynthesisAdapter, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
3
- import { CheckIcon as CheckIcon$1, CopyIcon, InfoIcon as InfoIcon$1, AlertCircle, TriangleAlert, ChevronUpIcon, X, Share2, Check, PlayCircle, Workflow, Layers, List, Clock as Clock$1, CalendarClock, Timer, CornerDownRight, GitBranch, RefreshCw, Repeat, Repeat1, Network, CalendarIcon, ChevronDown, Braces, ChevronDownIcon, Brackets, PlusIcon, TrashIcon, Plus, Loader2, Circle, EyeOffIcon, EyeIcon, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Maximize, AlertCircleIcon, CirclePause, StopCircle, SearchIcon, ChevronsUpDown, Search, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, SaveIcon, ExternalLink, XIcon, TriangleAlertIcon, ChevronRightIcon, ArrowLeftIcon, ArrowRightIcon, ChevronsRightIcon, AlignLeftIcon, AlignJustifyIcon, ArrowUpIcon, ArrowDownIcon, CircleAlertIcon, PanelRightIcon, KeyboardIcon, GaugeIcon, ChevronsLeftRightEllipsisIcon, CalculatorIcon, HashIcon, FileInputIcon, FileOutputIcon, ReceiptText, Info, RotateCcw, GripVertical, RefreshCcwIcon, AlertTriangleIcon, ChevronRight, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, FrownIcon, CircleChevronUpIcon, CircleChevronDownIcon, FileIcon, ChevronsUpIcon, ChevronsDownIcon, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, CircleDashedIcon, ArrowRightToLineIcon, CoinsIcon, BracesIcon, CircleGaugeIcon, PanelTopIcon, ListTreeIcon, PanelLeftIcon, CircleSlash, Trash, Link2 } from 'lucide-react';
3
+ import { CheckIcon as CheckIcon$1, CopyIcon, ShieldAlert, ChevronDown, ChevronRight, RefreshCw, Tag, InfoIcon as InfoIcon$1, AlertCircle, TriangleAlert, ChevronUpIcon, X, Share2, Check, PlayCircle, Workflow, Layers, List, Clock as Clock$1, CalendarClock, Timer, CornerDownRight, GitBranch, Repeat, Repeat1, Network, CalendarIcon, Braces, ChevronDownIcon, Brackets, PlusIcon, TrashIcon, Plus, Loader2, Circle, EyeOffIcon, EyeIcon, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Maximize, AlertCircleIcon, CirclePause, StopCircle, Cpu, SearchIcon, ChevronsUpDown, Search, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, SaveIcon, ExternalLink, XIcon, TriangleAlertIcon, ChevronRightIcon, ArrowLeftIcon, ArrowRightIcon, ChevronsRightIcon, AlignLeftIcon, AlignJustifyIcon, ArrowUpIcon, ArrowDownIcon, CircleAlertIcon, PanelRightIcon, KeyboardIcon, GaugeIcon, ChevronsLeftRightEllipsisIcon, CalculatorIcon, HashIcon, FileInputIcon, FileOutputIcon, ReceiptText, Info, RotateCcw, GripVertical, RefreshCcwIcon, AlertTriangleIcon, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, FrownIcon, CircleChevronUpIcon, CircleChevronDownIcon, FileIcon, ChevronsUpIcon, ChevronsDownIcon, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, CircleDashedIcon, ArrowRightToLineIcon, CoinsIcon, BracesIcon, CircleGaugeIcon, PanelTopIcon, ListTreeIcon, PanelLeftIcon, CircleSlash, Trash, Link2 } from 'lucide-react';
4
4
  import * as React from 'react';
5
5
  import React__default, { forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, createContext, useContext, Fragment as Fragment$1, useId, Suspense, useLayoutEffect } from 'react';
6
6
  import { Slot } from '@radix-ui/react-slot';
@@ -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';
@@ -3430,6 +3431,55 @@ const defaultComponents = unstable_memoizeMarkdownComponents({
3430
3431
  img: ImageWithFallback
3431
3432
  });
3432
3433
 
3434
+ const TripwireNotice = ({ reason, tripwire }) => {
3435
+ const [isExpanded, setIsExpanded] = useState(false);
3436
+ const hasMetadata = tripwire && (tripwire.retry !== void 0 || tripwire.tripwirePayload || tripwire.processorId);
3437
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-amber-500/30 bg-amber-950/20 overflow-hidden", children: [
3438
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4", children: [
3439
+ /* @__PURE__ */ jsx(ShieldAlert, { className: "w-5 h-5 text-amber-400 mt-0.5 flex-shrink-0" }),
3440
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
3441
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-amber-200 mb-1", children: "Content Blocked" }),
3442
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-300/90", children: reason })
3443
+ ] })
3444
+ ] }),
3445
+ hasMetadata && /* @__PURE__ */ jsxs(Fragment, { children: [
3446
+ /* @__PURE__ */ jsxs(
3447
+ "button",
3448
+ {
3449
+ onClick: () => setIsExpanded(!isExpanded),
3450
+ className: "w-full flex items-center gap-2 px-4 py-2 text-xs text-amber-400/70 hover:text-amber-400 hover:bg-amber-900/20 transition-colors border-t border-amber-500/20",
3451
+ children: [
3452
+ isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3.5 h-3.5" }),
3453
+ /* @__PURE__ */ jsx("span", { children: "Details" })
3454
+ ]
3455
+ }
3456
+ ),
3457
+ isExpanded && /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-3 border-t border-amber-500/20 bg-amber-950/10", children: [
3458
+ tripwire.retry !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-3", children: [
3459
+ /* @__PURE__ */ jsx(RefreshCw, { className: "w-3.5 h-3.5 text-amber-400/60" }),
3460
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-amber-300/70", children: [
3461
+ "Retry:",
3462
+ " ",
3463
+ tripwire.retry ? /* @__PURE__ */ jsx("span", { className: "text-green-400", children: "Allowed" }) : /* @__PURE__ */ jsx("span", { className: "text-red-400", children: "Not allowed" })
3464
+ ] })
3465
+ ] }),
3466
+ tripwire.processorId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3467
+ /* @__PURE__ */ jsx(Tag, { className: "w-3.5 h-3.5 text-amber-400/60" }),
3468
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-amber-300/70", children: [
3469
+ "Processor:",
3470
+ " ",
3471
+ /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded bg-amber-900/30 text-amber-200 font-mono", children: tripwire.processorId })
3472
+ ] })
3473
+ ] }),
3474
+ tripwire.tripwirePayload !== void 0 && tripwire.tripwirePayload !== null && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
3475
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-400/60 mb-1.5", children: "Metadata:" }),
3476
+ /* @__PURE__ */ jsx("pre", { className: "text-xs text-amber-200/80 bg-amber-900/30 rounded p-2 overflow-x-auto font-mono", children: String(JSON.stringify(tripwire.tripwirePayload, null, 2)) })
3477
+ ] })
3478
+ ] })
3479
+ ] })
3480
+ ] });
3481
+ };
3482
+
3433
3483
  const AgentIcon = (props) => /* @__PURE__ */ jsxs("svg", { width: "17", height: "16", viewBox: "0 0 17 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [
3434
3484
  /* @__PURE__ */ jsx(
3435
3485
  "path",
@@ -4220,6 +4270,9 @@ const ErrorAwareText = () => {
4220
4270
  const part = useAssistantState(({ part: part2 }) => part2);
4221
4271
  const text = part.text || "";
4222
4272
  const metadata = part.metadata || {};
4273
+ if (metadata?.status === "tripwire") {
4274
+ return /* @__PURE__ */ jsx(TripwireNotice, { reason: text, tripwire: metadata.tripwire });
4275
+ }
4223
4276
  if (metadata?.status === "warning") {
4224
4277
  return /* @__PURE__ */ jsxs(Alert$1, { variant: "warning", children: [
4225
4278
  /* @__PURE__ */ jsx(AlertTitle$1, { as: "h5", children: "Warning" }),
@@ -4593,7 +4646,8 @@ const ToolBadge = ({
4593
4646
  metadata,
4594
4647
  toolOutput,
4595
4648
  toolCallId,
4596
- toolApprovalMetadata
4649
+ toolApprovalMetadata,
4650
+ suspendPayload
4597
4651
  }) => {
4598
4652
  let argSlot = null;
4599
4653
  try {
@@ -4603,6 +4657,7 @@ const ToolBadge = ({
4603
4657
  argSlot = /* @__PURE__ */ jsx("pre", { className: "whitespace-pre bg-surface4 p-4 rounded-md overflow-x-auto", children: args });
4604
4658
  }
4605
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" });
4606
4661
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
4607
4662
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
4608
4663
  const toolCalled = result || toolOutput.length > 0;
@@ -4619,12 +4674,16 @@ const ToolBadge = ({
4619
4674
  input: agentNetworkInput
4620
4675
  }
4621
4676
  ),
4622
- initialCollapsed: !!!toolApprovalMetadata,
4677
+ initialCollapsed: !!!(toolApprovalMetadata ?? suspendPayload),
4623
4678
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4624
4679
  /* @__PURE__ */ jsxs("div", { children: [
4625
4680
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4626
4681
  argSlot
4627
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
+ ] }),
4628
4687
  resultSlot !== void 0 && result && /* @__PURE__ */ jsxs("div", { children: [
4629
4688
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4630
4689
  resultSlot
@@ -4652,6 +4711,7 @@ function convertWorkflowRunStateToStreamResult(runState) {
4652
4711
  Object.entries(context).forEach(([stepId, stepResult]) => {
4653
4712
  if (stepId !== "input" && "status" in stepResult) {
4654
4713
  const result = stepResult;
4714
+ const hasTripwire = result.status === "failed" && result.tripwire !== void 0;
4655
4715
  steps[stepId] = {
4656
4716
  status: result.status,
4657
4717
  output: "output" in result ? result.output : void 0,
@@ -4659,7 +4719,9 @@ function convertWorkflowRunStateToStreamResult(runState) {
4659
4719
  suspendPayload: "suspendPayload" in result ? result.suspendPayload : void 0,
4660
4720
  suspendOutput: "suspendOutput" in result ? result.suspendOutput : void 0,
4661
4721
  resumePayload: "resumePayload" in result ? result.resumePayload : void 0,
4662
- error: "error" in result ? result.error : void 0,
4722
+ // Don't include error when tripwire is present - tripwire takes precedence
4723
+ error: hasTripwire ? void 0 : "error" in result ? result.error : void 0,
4724
+ tripwire: hasTripwire ? result.tripwire : void 0,
4663
4725
  startedAt: "startedAt" in result ? result.startedAt : Date.now(),
4664
4726
  endedAt: "endedAt" in result ? result.endedAt : void 0,
4665
4727
  suspendedAt: "suspendedAt" in result ? result.suspendedAt : void 0,
@@ -4684,7 +4746,15 @@ function convertWorkflowRunStateToStreamResult(runState) {
4684
4746
  status: runState.status,
4685
4747
  ...runState.status === "success" ? { result: runState.result } : {},
4686
4748
  ...runState.status === "failed" ? { error: runState.error } : {},
4687
- ...runState.status === "suspended" ? { suspended: suspendedStepIds, suspendPayload } : {}
4749
+ ...runState.status === "suspended" ? { suspended: suspendedStepIds, suspendPayload } : {},
4750
+ ...runState.status === "tripwire" && runState.tripwire ? {
4751
+ tripwire: {
4752
+ reason: runState.tripwire.reason,
4753
+ retry: runState.tripwire.retry,
4754
+ metadata: runState.tripwire.metadata,
4755
+ processorId: runState.tripwire.processorId
4756
+ }
4757
+ } : {}
4688
4758
  };
4689
4759
  }
4690
4760
 
@@ -4930,7 +5000,8 @@ const useExecuteWorkflow = () => {
4930
5000
  requestContext.set(key, value);
4931
5001
  });
4932
5002
  const workflow = client.getWorkflow(workflowId);
4933
- await workflow.start({ runId, inputData: input || {}, requestContext });
5003
+ const run = await workflow.createRun({ runId });
5004
+ await run.start({ inputData: input || {}, requestContext });
4934
5005
  } catch (error) {
4935
5006
  console.error("Error starting workflow run:", error);
4936
5007
  throw error;
@@ -4950,7 +5021,8 @@ const useExecuteWorkflow = () => {
4950
5021
  requestContext.set(key, value);
4951
5022
  });
4952
5023
  const workflow = client.getWorkflow(workflowId);
4953
- 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 });
4954
5026
  return result;
4955
5027
  } catch (error) {
4956
5028
  console.error("Error starting workflow run:", error);
@@ -5043,8 +5115,8 @@ const useStreamWorkflow = () => {
5043
5115
  requestContext.set(key, value);
5044
5116
  });
5045
5117
  const workflow = client.getWorkflow(workflowId);
5046
- const stream = await workflow.streamVNext({
5047
- runId,
5118
+ const run = await workflow.createRun({ runId });
5119
+ const stream = await run.streamVNext({
5048
5120
  inputData,
5049
5121
  requestContext,
5050
5122
  closeOnSuspend: true,
@@ -5106,7 +5178,8 @@ const useStreamWorkflow = () => {
5106
5178
  return;
5107
5179
  }
5108
5180
  const workflow = client.getWorkflow(workflowId);
5109
- const stream = await workflow.observeStreamVNext({ runId });
5181
+ const run = await workflow.createRun({ runId });
5182
+ const stream = await run.observeStreamVNext();
5110
5183
  if (!stream) {
5111
5184
  return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
5112
5185
  }
@@ -5164,8 +5237,8 @@ const useStreamWorkflow = () => {
5164
5237
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5165
5238
  requestContext.set(key, value);
5166
5239
  });
5167
- const stream = await workflow.resumeStreamVNext({
5168
- runId,
5240
+ const run = await workflow.createRun({ runId });
5241
+ const stream = await run.resumeStreamVNext({
5169
5242
  step,
5170
5243
  resumeData,
5171
5244
  requestContext,
@@ -5214,6 +5287,7 @@ const useStreamWorkflow = () => {
5214
5287
  mutationFn: async ({
5215
5288
  workflowId,
5216
5289
  requestContext: playgroundRequestContext,
5290
+ runId,
5217
5291
  ...params
5218
5292
  }) => {
5219
5293
  if (timeTravelStreamRef.current) {
@@ -5226,7 +5300,8 @@ const useStreamWorkflow = () => {
5226
5300
  Object.entries(playgroundRequestContext).forEach(([key, value]) => {
5227
5301
  requestContext.set(key, value);
5228
5302
  });
5229
- const stream = await workflow.timeTravelStream({
5303
+ const run = await workflow.createRun({ runId });
5304
+ const stream = await run.timeTravelStream({
5230
5305
  ...params,
5231
5306
  requestContext,
5232
5307
  tracingOptions: settings?.tracingOptions
@@ -5317,7 +5392,9 @@ const useCancelWorkflowRun = () => {
5317
5392
  const cancelWorkflowRun = useMutation({
5318
5393
  mutationFn: async ({ workflowId, runId }) => {
5319
5394
  try {
5320
- 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();
5321
5398
  return response;
5322
5399
  } catch (error) {
5323
5400
  console.error("Error canceling workflow run:", error);
@@ -5411,6 +5488,58 @@ const useDeleteWorkflowRun = (workflowId) => {
5411
5488
  });
5412
5489
  };
5413
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
+
5414
5543
  const WorkflowRunContext = createContext({});
5415
5544
  function WorkflowRunProvider({
5416
5545
  children,
@@ -5512,7 +5641,7 @@ function WorkflowRunProvider({
5512
5641
  isLoadingRunExecutionResult,
5513
5642
  withoutTimeTravel
5514
5643
  },
5515
- children
5644
+ children: /* @__PURE__ */ jsx(WorkflowStepDetailProvider, { children })
5516
5645
  }
5517
5646
  );
5518
5647
  }
@@ -6117,10 +6246,13 @@ const useCurrentRun = () => {
6117
6246
  const context = useContext(WorkflowRunContext);
6118
6247
  const workflowCurrentSteps = context.result?.steps ?? {};
6119
6248
  const steps = Object.entries(workflowCurrentSteps).reduce((acc, [key, value]) => {
6249
+ const hasTripwire = "tripwire" in value && value.tripwire;
6120
6250
  return {
6121
6251
  ...acc,
6122
6252
  [key]: {
6123
- error: "error" in value ? value.error : void 0,
6253
+ // Don't include error when tripwire is present - tripwire takes precedence
6254
+ error: hasTripwire ? void 0 : "error" in value ? value.error : void 0,
6255
+ tripwire: hasTripwire ? value.tripwire : void 0,
6124
6256
  startedAt: value.startedAt,
6125
6257
  endedAt: "endedAt" in value ? value.endedAt : void 0,
6126
6258
  status: value.status,
@@ -6168,26 +6300,46 @@ const SyntaxHighlighter$1 = ({ data }) => {
6168
6300
  return /* @__PURE__ */ jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] }) });
6169
6301
  };
6170
6302
 
6171
- const CodeDialogContent = ({ data }) => {
6303
+ const CodeDialogContent = ({
6304
+ data,
6305
+ language = "auto"
6306
+ }) => {
6172
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
+ };
6173
6325
  if (typeof data !== "string") {
6326
+ const content = JSON.stringify(data, null, 2);
6174
6327
  return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6175
- /* @__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) }) }),
6176
- /* @__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] }) })
6177
6330
  ] });
6178
6331
  }
6332
+ const extensions = getExtensions(data);
6333
+ let displayContent = data;
6179
6334
  try {
6180
6335
  const json = JSON.parse(data);
6181
- return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6182
- /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
6183
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: JSON.stringify(json, null, 2), theme, extensions: [jsonLanguage] }) })
6184
- ] });
6185
- } catch (error) {
6186
- return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
6187
- /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: data }) }),
6188
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-lg p-4", children: /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [] }) })
6189
- ] });
6336
+ displayContent = JSON.stringify(json, null, 2);
6337
+ } catch {
6190
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
+ ] });
6191
6343
  };
6192
6344
 
6193
6345
  const Form = React__default.forwardRef(({ children, ...props }, ref) => {
@@ -7169,12 +7321,23 @@ function inferFieldType(schema, fieldConfig) {
7169
7321
  if (schema instanceof z.ZodDiscriminatedUnion) {
7170
7322
  return "discriminated-union";
7171
7323
  }
7324
+ if (schema instanceof z.ZodLiteral) {
7325
+ const v4Values = schema._zod?.def?.values;
7326
+ const v3Value = schema._def?.value;
7327
+ const literalValue = v4Values !== void 0 ? Array.isArray(v4Values) ? v4Values[0] : v4Values : v3Value;
7328
+ if (typeof literalValue === "number") return "number";
7329
+ if (typeof literalValue === "boolean") return "boolean";
7330
+ return "string";
7331
+ }
7172
7332
  return "string";
7173
7333
  }
7174
7334
 
7175
7335
  function getDefaultValueInZodStack(schema) {
7176
7336
  if (schema instanceof z$2.core.$ZodDefault) {
7177
7337
  return schema._zod.def.defaultValue;
7338
+ } else if (schema instanceof z$2.core.$ZodLiteral) {
7339
+ const values = schema._zod.def.values;
7340
+ return Array.isArray(values) ? values[0] : values;
7178
7341
  } else if ("innerType" in schema._zod.def) {
7179
7342
  return getDefaultValueInZodStack(schema._zod.def.innerType);
7180
7343
  } else if ("shape" in schema._zod.def) {
@@ -7690,9 +7853,9 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7690
7853
  const parsedResume = resumeData.trim() ? JSON.parse(resumeData) : {};
7691
7854
  const parsedContext = contextValue.trim() ? JSON.parse(contextValue) : {};
7692
7855
  const parsedNestedContext = nestedContextValue.trim() ? JSON.parse(nestedContextValue) : {};
7693
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
7856
+ const run = await createWorkflowRun({ workflowId, prevRunId });
7694
7857
  const payload = {
7695
- runId,
7858
+ runId: run.runId,
7696
7859
  workflowId,
7697
7860
  step: stepKey,
7698
7861
  inputData: data,
@@ -7791,6 +7954,7 @@ const WorkflowStepActionBar = ({
7791
7954
  resumeData,
7792
7955
  suspendOutput,
7793
7956
  error,
7957
+ tripwire,
7794
7958
  mapConfig,
7795
7959
  stepName,
7796
7960
  stepId,
@@ -7802,25 +7966,44 @@ const WorkflowStepActionBar = ({
7802
7966
  const [isOutputOpen, setIsOutputOpen] = useState(false);
7803
7967
  const [isResumeDataOpen, setIsResumeDataOpen] = useState(false);
7804
7968
  const [isErrorOpen, setIsErrorOpen] = useState(false);
7805
- const [isMapConfigOpen, setIsMapConfigOpen] = useState(false);
7969
+ const [isTripwireOpen, setIsTripwireOpen] = useState(false);
7806
7970
  const [isTimeTravelOpen, setIsTimeTravelOpen] = useState(false);
7807
7971
  const { withoutTimeTravel } = useContext(WorkflowRunContext);
7972
+ const { showMapConfig, stepDetail, closeStepDetail } = useWorkflowStepDetail();
7808
7973
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7809
7974
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7810
7975
  const showTimeTravel = !withoutTimeTravel && stepKey && !mapConfig;
7811
- return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || mapConfig || resumeData || onShowNestedGraph || showTimeTravel) && /* @__PURE__ */ jsxs(
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
+ };
7993
+ return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || tripwire || mapConfig || resumeData || onShowNestedGraph || showTimeTravel) && /* @__PURE__ */ jsxs(
7812
7994
  "div",
7813
7995
  {
7814
7996
  className: cn(
7815
7997
  "flex flex-wrap items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2 rounded-b-lg",
7816
7998
  status === "success" && "bg-accent1Dark",
7817
7999
  status === "failed" && "bg-accent2Dark",
8000
+ status === "tripwire" && "bg-amber-900/40 border-amber-500/20",
7818
8001
  status === "suspended" && "bg-accent3Dark",
7819
8002
  status === "waiting" && "bg-accent5Dark",
7820
8003
  status === "running" && "bg-accent6Dark"
7821
8004
  ),
7822
8005
  children: [
7823
- 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" }),
7824
8007
  showTimeTravel && /* @__PURE__ */ jsxs(Fragment, { children: [
7825
8008
  /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsTimeTravelOpen(true), children: "Time travel" }),
7826
8009
  /* @__PURE__ */ jsx(Dialog, { open: isTimeTravelOpen, onOpenChange: setIsTimeTravelOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7831,19 +8014,7 @@ const WorkflowStepActionBar = ({
7831
8014
  /* @__PURE__ */ jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsx(WorkflowTimeTravelForm, { stepKey, closeModal: () => setIsTimeTravelOpen(false) }) })
7832
8015
  ] }) })
7833
8016
  ] }),
7834
- mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
7835
- /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
7836
- /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
7837
- /* @__PURE__ */ jsx(DialogTitle, { className: dialogTitleClass, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
7838
- /* @__PURE__ */ jsxs("div", { children: [
7839
- stepName,
7840
- " Map Config"
7841
- ] }),
7842
- stepId && stepId !== stepName && /* @__PURE__ */ jsx("div", { className: "text-xs text-icon3 font-normal", children: stepId })
7843
- ] }) }),
7844
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
7845
- ] }) })
7846
- ] }),
8017
+ mapConfig && /* @__PURE__ */ jsx(Button$1, { onClick: handleMapConfigClick, className: cn(isMapConfigOpen && activeButtonClass), children: "Map config" }),
7847
8018
  input && /* @__PURE__ */ jsxs(Fragment, { children: [
7848
8019
  /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsInputOpen(true), children: "Input" }),
7849
8020
  /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
@@ -7883,6 +8054,26 @@ const WorkflowStepActionBar = ({
7883
8054
  ] }),
7884
8055
  /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: error }) })
7885
8056
  ] }) })
8057
+ ] }),
8058
+ tripwire && /* @__PURE__ */ jsxs(Fragment, { children: [
8059
+ /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsTripwireOpen(true), className: "text-amber-400 hover:text-amber-300", children: "Tripwire" }),
8060
+ /* @__PURE__ */ jsx(Dialog, { open: isTripwireOpen, onOpenChange: setIsTripwireOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8061
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8062
+ stepName,
8063
+ " tripwire"
8064
+ ] }),
8065
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(
8066
+ CodeDialogContent,
8067
+ {
8068
+ data: {
8069
+ reason: tripwire.reason,
8070
+ retry: tripwire.retry,
8071
+ metadata: tripwire.metadata,
8072
+ processorId: tripwire.processorId
8073
+ }
8074
+ }
8075
+ ) })
8076
+ ] }) })
7886
8077
  ] })
7887
8078
  ]
7888
8079
  }
@@ -7898,6 +8089,8 @@ function WorkflowConditionNode({ data }) {
7898
8089
  const { steps } = useCurrentRun();
7899
8090
  const previousStep = steps[previousStepId];
7900
8091
  const nextStep = steps[nextStepId];
8092
+ const isPreviousTripwire = previousStep?.status === "failed" && previousStep?.tripwire !== void 0;
8093
+ const previousDisplayStatus = isPreviousTripwire ? "tripwire" : previousStep?.status;
7901
8094
  const { icon: IconComponent, color } = getConditionIconAndColor(type);
7902
8095
  return /* @__PURE__ */ jsxs(Fragment, { children: [
7903
8096
  !withoutTopHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: { visibility: "hidden" } }),
@@ -7905,12 +8098,13 @@ function WorkflowConditionNode({ data }) {
7905
8098
  "div",
7906
8099
  {
7907
8100
  "data-workflow-node": true,
7908
- "data-workflow-step-status": previousStep?.status,
8101
+ "data-workflow-step-status": previousDisplayStatus,
7909
8102
  "data-testid": "workflow-condition-node",
7910
8103
  className: cn(
7911
8104
  "bg-surface3 rounded-lg w-[300px] border-sm border-border1",
7912
- previousStep?.status === "success" && nextStep && "bg-accent1Darker",
7913
- previousStep?.status === "failed" && nextStep && "bg-accent2Darker",
8105
+ previousDisplayStatus === "success" && nextStep && "bg-accent1Darker",
8106
+ previousDisplayStatus === "failed" && nextStep && "bg-accent2Darker",
8107
+ previousDisplayStatus === "tripwire" && nextStep && "bg-amber-950/40 border-amber-500/30",
7914
8108
  !previousStep && Boolean(nextStep?.status) && "bg-accent1Darker"
7915
8109
  ),
7916
8110
  children: [
@@ -7962,10 +8156,11 @@ function WorkflowConditionNode({ data }) {
7962
8156
  "pre",
7963
8157
  {
7964
8158
  className: cn(
7965
- "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",
7966
8160
  className,
7967
- previousStep?.status === "success" && nextStep && "!bg-accent1Dark",
7968
- previousStep?.status === "failed" && nextStep && "!bg-accent2Dark"
8161
+ previousDisplayStatus === "success" && nextStep && "!bg-accent1Dark",
8162
+ previousDisplayStatus === "failed" && nextStep && "!bg-accent2Dark",
8163
+ previousDisplayStatus === "tripwire" && nextStep && "!bg-amber-900/40"
7969
8164
  ),
7970
8165
  onClick: () => setOpenDialog(true),
7971
8166
  style,
@@ -8021,7 +8216,8 @@ function WorkflowConditionNode({ data }) {
8021
8216
  stepName: nextStepId,
8022
8217
  input: previousStep?.output,
8023
8218
  mapConfig: data.mapConfig,
8024
- status: nextStep ? previousStep?.status : void 0
8219
+ tripwire: isPreviousTripwire ? previousStep?.tripwire : void 0,
8220
+ status: nextStep ? previousDisplayStatus : void 0
8025
8221
  }
8026
8222
  )
8027
8223
  ]
@@ -8067,6 +8263,8 @@ function WorkflowDefaultNode({ data, parentWorkflowName }) {
8067
8263
  } = data;
8068
8264
  const stepKey = parentWorkflowName ? `${parentWorkflowName}.${stepId || label}` : stepId || label;
8069
8265
  const step = steps[stepKey];
8266
+ const isTripwire = step?.status === "failed" && step?.tripwire !== void 0;
8267
+ const displayStatus = isTripwire ? "tripwire" : step?.status;
8070
8268
  const { isSleepNode, isForEachNode, isMapNode, hasSpecialBadge } = getNodeBadgeInfo({
8071
8269
  duration,
8072
8270
  date,
@@ -8081,16 +8279,17 @@ function WorkflowDefaultNode({ data, parentWorkflowName }) {
8081
8279
  "div",
8082
8280
  {
8083
8281
  "data-workflow-node": true,
8084
- "data-workflow-step-status": step?.status ?? "idle",
8282
+ "data-workflow-step-status": displayStatus ?? "idle",
8085
8283
  "data-testid": "workflow-default-node",
8086
8284
  className: cn(
8087
8285
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1",
8088
8286
  hasSpecialBadge ? "pt-0" : "pt-2",
8089
- step?.status === "success" && "bg-accent1Darker",
8090
- step?.status === "failed" && "bg-accent2Darker",
8091
- step?.status === "suspended" && "bg-accent3Darker",
8092
- step?.status === "waiting" && "bg-accent5Darker",
8093
- step?.status === "running" && "bg-accent6Darker"
8287
+ displayStatus === "success" && "bg-accent1Darker",
8288
+ displayStatus === "failed" && "bg-accent2Darker",
8289
+ displayStatus === "tripwire" && "bg-amber-950/40 border-amber-500/30",
8290
+ displayStatus === "suspended" && "bg-accent3Darker",
8291
+ displayStatus === "waiting" && "bg-accent5Darker",
8292
+ displayStatus === "running" && "bg-accent6Darker"
8094
8293
  ),
8095
8294
  children: [
8096
8295
  hasSpecialBadge && /* @__PURE__ */ jsxs("div", { className: "px-3 pt-2 pb-1 flex gap-1.5 flex-wrap", children: [
@@ -8108,11 +8307,12 @@ function WorkflowDefaultNode({ data, parentWorkflowName }) {
8108
8307
  ] }),
8109
8308
  /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
8110
8309
  /* @__PURE__ */ jsxs(Icon, { children: [
8111
- step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8112
- step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8113
- step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-accent3" }),
8114
- step?.status === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
8115
- step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" }),
8310
+ displayStatus === "tripwire" && /* @__PURE__ */ jsx(ShieldAlert, { className: "text-amber-400" }),
8311
+ displayStatus === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8312
+ displayStatus === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8313
+ displayStatus === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-accent3" }),
8314
+ displayStatus === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
8315
+ displayStatus === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" }),
8116
8316
  !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
8117
8317
  ] }),
8118
8318
  /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
@@ -8142,9 +8342,10 @@ function WorkflowDefaultNode({ data, parentWorkflowName }) {
8142
8342
  resumeData: step?.resumeData,
8143
8343
  output: step?.output,
8144
8344
  suspendOutput: step?.suspendOutput,
8145
- error: step?.error,
8345
+ error: isTripwire ? void 0 : step?.error,
8346
+ tripwire: isTripwire ? step?.tripwire : void 0,
8146
8347
  mapConfig,
8147
- status: step?.status,
8348
+ status: displayStatus,
8148
8349
  stepKey
8149
8350
  }
8150
8351
  )
@@ -8208,172 +8409,29 @@ function WorkflowLoopResultNode({ data }) {
8208
8409
  );
8209
8410
  }
8210
8411
 
8211
- function Spinner({ color = "#fff", className }) {
8212
- return /* @__PURE__ */ jsx(
8213
- "svg",
8214
- {
8215
- className: clsx("animate-spin duration-700", className),
8216
- xmlns: "http://www.w3.org/2000/svg",
8217
- width: "24",
8218
- height: "24",
8219
- viewBox: "0 0 24 24",
8220
- fill: "none",
8221
- stroke: "currentColor",
8222
- strokeWidth: "2",
8223
- strokeLinecap: "round",
8224
- strokeLinejoin: "round",
8225
- children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
8226
- }
8227
- );
8228
- }
8229
-
8230
- const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
8231
- SliderPrimitive.Root,
8232
- {
8233
- ref,
8234
- className: cn("relative flex w-full touch-none select-none items-center", className),
8235
- ...props,
8236
- children: [
8237
- /* @__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" }) }),
8238
- /* @__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" })
8239
- ]
8240
- }
8241
- ));
8242
- Slider.displayName = SliderPrimitive.Root.displayName;
8243
-
8244
- const ZoomSlider = forwardRef(({ className, ...props }) => {
8245
- const { zoom } = useViewport();
8246
- const { zoomTo, zoomIn, zoomOut, fitView } = useReactFlow();
8247
- return /* @__PURE__ */ jsxs(Panel, { className: cn("flex gap-1 rounded-md bg-primary-foreground p-1 text-foreground", className), ...props, children: [
8248
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomOut({ duration: 300 }), children: /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4" }) }),
8249
- /* @__PURE__ */ jsx(
8250
- Slider,
8251
- {
8252
- className: "w-[140px]",
8253
- value: [zoom],
8254
- min: 0.01,
8255
- max: 1,
8256
- step: 0.01,
8257
- onValueChange: (values) => {
8258
- zoomTo(values[0]);
8259
- }
8260
- }
8261
- ),
8262
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => zoomIn({ duration: 300 }), children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }) }),
8263
- /* @__PURE__ */ jsxs(Button$2, { className: "min-w-20 tabular-nums", variant: "ghost", onClick: () => zoomTo(1, { duration: 300 }), children: [
8264
- (100 * zoom).toFixed(0),
8265
- "%"
8266
- ] }),
8267
- /* @__PURE__ */ jsx(Button$2, { variant: "ghost", size: "icon", onClick: () => fitView({ duration: 300, maxZoom: 1 }), children: /* @__PURE__ */ jsx(Maximize, { className: "h-4 w-4" }) })
8268
- ] });
8269
- });
8270
- ZoomSlider.displayName = "ZoomSlider";
8271
-
8272
- function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
8273
- const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges({
8274
- stepGraph
8275
- });
8276
- const [isMounted, setIsMounted] = useState(false);
8277
- const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8278
- const [edges] = useEdgesState(initialEdges);
8279
- const { steps } = useCurrentRun();
8280
- const nodeTypes = {
8281
- "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
8282
- "condition-node": WorkflowConditionNode,
8283
- "after-node": WorkflowAfterNode,
8284
- "loop-result-node": WorkflowLoopResultNode,
8285
- "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
8286
- };
8287
- useEffect(() => {
8288
- if (open) {
8289
- setTimeout(() => {
8290
- setIsMounted(true);
8291
- }, 500);
8292
- }
8293
- }, [open]);
8294
- return /* @__PURE__ */ jsx("div", { className: "w-full h-full relative bg-surface1", children: isMounted ? /* @__PURE__ */ jsxs(
8295
- ReactFlow,
8296
- {
8297
- nodes,
8298
- edges: edges.map((e) => ({
8299
- ...e,
8300
- style: {
8301
- ...e.style,
8302
- 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
8303
- }
8304
- })),
8305
- fitView: true,
8306
- fitViewOptions: {
8307
- maxZoom: 1
8308
- },
8309
- minZoom: 0.01,
8310
- maxZoom: 1,
8311
- nodeTypes,
8312
- onNodesChange,
8313
- children: [
8314
- /* @__PURE__ */ jsx(ZoomSlider, { position: "bottom-left" }),
8315
- /* @__PURE__ */ jsx(Background, { variant: BackgroundVariant.Lines, gap: 12, size: 0.5 })
8316
- ]
8317
- }
8318
- ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) });
8319
- }
8320
-
8321
8412
  const WorkflowNestedGraphContext = createContext(
8322
8413
  {}
8323
8414
  );
8324
8415
  function WorkflowNestedGraphProvider({ children }) {
8325
- const [stepGraph, setStepGraph] = useState(null);
8326
- const [parentStepGraphList, setParentStepGraphList] = useState([]);
8327
- const [openDialog, setOpenDialog] = useState(false);
8328
- const [label, setLabel] = useState("");
8329
- const [fullStep, setFullStep] = useState("");
8330
- const closeNestedGraph = () => {
8331
- if (parentStepGraphList.length) {
8332
- const lastStepGraph = parentStepGraphList[parentStepGraphList.length - 1];
8333
- setStepGraph(lastStepGraph.stepGraph);
8334
- setLabel(lastStepGraph.label);
8335
- setFullStep(lastStepGraph.fullStep);
8336
- setParentStepGraphList(parentStepGraphList.slice(0, -1));
8337
- } else {
8338
- setOpenDialog(false);
8339
- setStepGraph(null);
8340
- setLabel("");
8341
- setFullStep("");
8342
- }
8343
- };
8416
+ const { showNestedGraph: showNestedGraphInPanel, closeStepDetail } = useWorkflowStepDetail();
8344
8417
  const showNestedGraph = ({
8345
- label: newLabel,
8346
- stepGraph: newStepGraph,
8347
- fullStep: newFullStep
8418
+ label,
8419
+ stepGraph,
8420
+ fullStep
8348
8421
  }) => {
8349
- if (stepGraph) {
8350
- setParentStepGraphList([...parentStepGraphList, { stepGraph, label, fullStep }]);
8351
- }
8352
- setLabel(newLabel);
8353
- setFullStep(newFullStep);
8354
- setStepGraph(newStepGraph);
8355
- setOpenDialog(true);
8422
+ showNestedGraphInPanel({ label, stepGraph, fullStep });
8356
8423
  };
8357
- return /* @__PURE__ */ jsxs(
8424
+ const closeNestedGraph = () => {
8425
+ closeStepDetail();
8426
+ };
8427
+ return /* @__PURE__ */ jsx(
8358
8428
  WorkflowNestedGraphContext.Provider,
8359
8429
  {
8360
8430
  value: {
8361
8431
  showNestedGraph,
8362
8432
  closeNestedGraph
8363
8433
  },
8364
- children: [
8365
- children,
8366
- /* @__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: [
8367
- /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-1.5 absolute top-3 left-3 z-50", children: [
8368
- /* @__PURE__ */ jsx(Workflow, { className: "text-current w-4 h-4" }),
8369
- /* @__PURE__ */ jsxs(Text, { size: "xs", weight: "medium", className: "text-mastra-el-6 capitalize", children: [
8370
- label,
8371
- " workflow"
8372
- ] })
8373
- ] }),
8374
- /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(WorkflowNestedGraph, { stepGraph, open: openDialog, workflowName: fullStep }) })
8375
- ] }) }) }, `${label}-${fullStep}`)
8376
- ]
8434
+ children
8377
8435
  }
8378
8436
  );
8379
8437
  }
@@ -8396,6 +8454,8 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8396
8454
  const fullLabel = parentWorkflowName ? `${parentWorkflowName}.${label}` : label;
8397
8455
  const stepKey = parentWorkflowName ? `${parentWorkflowName}.${stepId || label}` : stepId || label;
8398
8456
  const step = steps[stepKey];
8457
+ const isTripwire = step?.status === "failed" && step?.tripwire !== void 0;
8458
+ const displayStatus = isTripwire ? "tripwire" : step?.status;
8399
8459
  const { isForEachNode, isMapNode, isNestedWorkflow, hasSpecialBadge } = getNodeBadgeInfo({
8400
8460
  isForEach,
8401
8461
  mapConfig,
@@ -8410,15 +8470,16 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8410
8470
  {
8411
8471
  "data-testid": "workflow-nested-node",
8412
8472
  "data-workflow-node": true,
8413
- "data-workflow-step-status": step?.status,
8473
+ "data-workflow-step-status": displayStatus,
8414
8474
  className: cn(
8415
8475
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1",
8416
8476
  hasSpecialBadge ? "pt-0" : "pt-2",
8417
- step?.status === "success" && "bg-accent1Darker",
8418
- step?.status === "failed" && "bg-accent2Darker",
8419
- step?.status === "suspended" && "bg-accent3Darker",
8420
- step?.status === "waiting" && "bg-accent5Darker",
8421
- step?.status === "running" && "bg-accent6Darker"
8477
+ displayStatus === "success" && "bg-accent1Darker",
8478
+ displayStatus === "failed" && "bg-accent2Darker",
8479
+ displayStatus === "tripwire" && "bg-amber-950/40 border-amber-500/30",
8480
+ displayStatus === "suspended" && "bg-accent3Darker",
8481
+ displayStatus === "waiting" && "bg-accent5Darker",
8482
+ displayStatus === "running" && "bg-accent6Darker"
8422
8483
  ),
8423
8484
  children: [
8424
8485
  hasSpecialBadge && /* @__PURE__ */ jsxs("div", { className: "px-3 pt-2 pb-1 flex gap-1.5 flex-wrap", children: [
@@ -8430,11 +8491,12 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8430
8491
  ] }),
8431
8492
  /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
8432
8493
  /* @__PURE__ */ jsxs(Icon, { children: [
8433
- step?.status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8434
- step?.status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8435
- step?.status === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-accent3" }),
8436
- step?.status === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
8437
- step?.status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" }),
8494
+ displayStatus === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8495
+ displayStatus === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8496
+ displayStatus === "tripwire" && /* @__PURE__ */ jsx(ShieldAlert, { className: "text-amber-400" }),
8497
+ displayStatus === "suspended" && /* @__PURE__ */ jsx(PauseIcon, { className: "text-accent3" }),
8498
+ displayStatus === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
8499
+ displayStatus === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" }),
8438
8500
  !step && /* @__PURE__ */ jsx(CircleDashed, { className: "text-icon2" })
8439
8501
  ] }),
8440
8502
  /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "text-icon6 font-medium inline-flex items-center gap-1 justify-between w-full", children: [
@@ -8454,9 +8516,10 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8454
8516
  output: step?.output,
8455
8517
  suspendOutput: step?.suspendOutput,
8456
8518
  error: step?.error,
8519
+ tripwire: isTripwire ? step?.tripwire : void 0,
8457
8520
  mapConfig,
8458
8521
  onShowNestedGraph: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }),
8459
- status: step?.status,
8522
+ status: displayStatus,
8460
8523
  stepKey
8461
8524
  }
8462
8525
  )
@@ -8467,6 +8530,48 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8467
8530
  ] });
8468
8531
  }
8469
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
+
8470
8575
  function WorkflowGraphInner({ workflow }) {
8471
8576
  const { nodes: initialNodes, edges: initialEdges } = constructNodesAndEdges(workflow);
8472
8577
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
@@ -8562,7 +8667,12 @@ const WorkflowCard = ({ header, children, footer }) => {
8562
8667
  ] });
8563
8668
  };
8564
8669
 
8565
- const WorkflowStatus = ({ stepId, status, result }) => {
8670
+ const WorkflowStatus = ({ stepId, status, result, tripwire }) => {
8671
+ const [isTripwireExpanded, setIsTripwireExpanded] = useState(false);
8672
+ const isTripwire = status === "tripwire";
8673
+ const hasTripwireMetadata = Boolean(
8674
+ tripwire && (tripwire.retry !== void 0 || tripwire.metadata !== void 0 || tripwire.processorId !== void 0)
8675
+ );
8566
8676
  return /* @__PURE__ */ jsx(
8567
8677
  WorkflowCard,
8568
8678
  {
@@ -8570,19 +8680,74 @@ const WorkflowStatus = ({ stepId, status, result }) => {
8570
8680
  /* @__PURE__ */ jsxs(Icon, { children: [
8571
8681
  status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
8572
8682
  status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
8683
+ status === "tripwire" && /* @__PURE__ */ jsx(ShieldAlert, { className: "text-amber-400" }),
8573
8684
  status === "suspended" && /* @__PURE__ */ jsx(CirclePause, { className: "text-accent3" }),
8574
8685
  status === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
8575
8686
  status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" })
8576
8687
  ] }),
8577
8688
  /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-lg", className: "text-icon6 font-medium", children: stepId.charAt(0).toUpperCase() + stepId.slice(1) })
8578
8689
  ] }),
8579
- children: /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-surface4 p-1 font-mono relative", children: [
8690
+ children: isTripwire && tripwire ? /* @__PURE__ */ jsx(
8691
+ TripwireDetails,
8692
+ {
8693
+ tripwire,
8694
+ isExpanded: isTripwireExpanded,
8695
+ onToggleExpand: () => setIsTripwireExpanded(!isTripwireExpanded),
8696
+ hasMetadata: hasTripwireMetadata
8697
+ }
8698
+ ) : /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-surface4 p-1 font-mono relative", children: [
8580
8699
  /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(result, null, 2), className: "absolute top-2 right-2 z-10" }),
8581
8700
  /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: result })
8582
8701
  ] })
8583
8702
  }
8584
8703
  );
8585
8704
  };
8705
+ const TripwireDetails = ({ tripwire, isExpanded, onToggleExpand, hasMetadata }) => {
8706
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-amber-500/30 bg-amber-950/20 overflow-hidden", children: [
8707
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4", children: [
8708
+ /* @__PURE__ */ jsx(ShieldAlert, { className: "w-5 h-5 text-amber-400 mt-0.5 flex-shrink-0" }),
8709
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
8710
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-amber-200 mb-1", children: "Content Blocked" }),
8711
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-300/90", children: tripwire.reason || "Tripwire triggered" })
8712
+ ] })
8713
+ ] }),
8714
+ hasMetadata && /* @__PURE__ */ jsxs(Fragment, { children: [
8715
+ /* @__PURE__ */ jsxs(
8716
+ "button",
8717
+ {
8718
+ onClick: onToggleExpand,
8719
+ className: "w-full flex items-center gap-2 px-4 py-2 text-xs text-amber-400/70 hover:text-amber-400 hover:bg-amber-900/20 transition-colors border-t border-amber-500/20",
8720
+ children: [
8721
+ isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3.5 h-3.5" }),
8722
+ /* @__PURE__ */ jsx("span", { children: "Details" })
8723
+ ]
8724
+ }
8725
+ ),
8726
+ isExpanded && /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-3 border-t border-amber-500/20 bg-amber-950/10", children: [
8727
+ tripwire.retry !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-3", children: [
8728
+ /* @__PURE__ */ jsx(RefreshCw, { className: "w-3.5 h-3.5 text-amber-400/60" }),
8729
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-amber-300/70", children: [
8730
+ "Retry:",
8731
+ " ",
8732
+ tripwire.retry ? /* @__PURE__ */ jsx("span", { className: "text-green-400", children: "Allowed" }) : /* @__PURE__ */ jsx("span", { className: "text-red-400", children: "Not allowed" })
8733
+ ] })
8734
+ ] }),
8735
+ tripwire.processorId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8736
+ /* @__PURE__ */ jsx(Tag, { className: "w-3.5 h-3.5 text-amber-400/60" }),
8737
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-amber-300/70", children: [
8738
+ "Processor:",
8739
+ " ",
8740
+ /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded bg-amber-900/30 text-amber-200 font-mono", children: tripwire.processorId })
8741
+ ] })
8742
+ ] }),
8743
+ tripwire.metadata !== void 0 && tripwire.metadata !== null && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
8744
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-400/60 mb-1.5", children: "Metadata:" }),
8745
+ /* @__PURE__ */ jsx("pre", { className: "text-xs text-amber-200/80 bg-amber-900/30 rounded p-2 overflow-x-auto font-mono", children: String(JSON.stringify(tripwire.metadata, null, 2)) })
8746
+ ] })
8747
+ ] })
8748
+ ] })
8749
+ ] });
8750
+ };
8586
8751
 
8587
8752
  const isObjectEmpty = (objectName) => {
8588
8753
  return objectName && Object.keys(objectName).length === 0 && objectName.constructor === Object;
@@ -8615,11 +8780,11 @@ function WorkflowTrigger({
8615
8780
  setIsRunning(true);
8616
8781
  setCancelResponse(null);
8617
8782
  setResult(null);
8618
- const { runId } = await createWorkflowRun({ workflowId });
8619
- setRunId?.(runId);
8620
- setInnerRunId(runId);
8621
- setContextRunId(runId);
8622
- 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 });
8623
8788
  } catch (err) {
8624
8789
  setIsRunning(false);
8625
8790
  toast$1.error("Error executing workflow");
@@ -8629,10 +8794,10 @@ function WorkflowTrigger({
8629
8794
  if (!workflow) return;
8630
8795
  setCancelResponse(null);
8631
8796
  const { stepId, runId: prevRunId, resumeData } = step;
8632
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
8797
+ const run = await createWorkflowRun({ workflowId, prevRunId });
8633
8798
  await resumeWorkflow({
8634
8799
  step: stepId,
8635
- runId,
8800
+ runId: run.runId,
8636
8801
  resumeData,
8637
8802
  workflowId,
8638
8803
  requestContext
@@ -8675,8 +8840,8 @@ function WorkflowTrigger({
8675
8840
  const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
8676
8841
  const workflowActivePaths = streamResultToUse?.steps ?? {};
8677
8842
  const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
8678
- const doneStatuses = ["success", "failed", "canceled"];
8679
- return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 pb-12 overflow-y-auto", children: [
8843
+ const doneStatuses = ["success", "failed", "canceled", "tripwire"];
8844
+ return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 overflow-y-auto", children: [
8680
8845
  /* @__PURE__ */ jsxs("div", { className: "space-y-4 px-5 pb-5 border-b-sm border-border1", children: [
8681
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: [
8682
8847
  /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
@@ -8759,18 +8924,30 @@ function WorkflowTrigger({
8759
8924
  const { status } = step;
8760
8925
  let output = void 0;
8761
8926
  let suspendOutput = void 0;
8927
+ let error = void 0;
8762
8928
  if (step.status === "suspended") {
8763
8929
  suspendOutput = step.suspendOutput;
8764
8930
  }
8765
8931
  if (step.status === "success") {
8766
8932
  output = step.output;
8767
8933
  }
8934
+ if (step.status === "failed") {
8935
+ error = step.error;
8936
+ }
8937
+ const tripwireInfo = step.status === "failed" && step.tripwire ? step.tripwire : streamResultToUse?.status === "tripwire" ? {
8938
+ reason: streamResultToUse?.tripwire?.reason,
8939
+ retry: streamResultToUse?.tripwire?.retry,
8940
+ metadata: streamResultToUse?.tripwire?.metadata,
8941
+ processorId: streamResultToUse?.tripwire?.processorId
8942
+ } : void 0;
8943
+ const displayStatus = step.status === "failed" && step.tripwire ? "tripwire" : status;
8768
8944
  return /* @__PURE__ */ jsx(
8769
8945
  WorkflowStatus,
8770
8946
  {
8771
8947
  stepId,
8772
- status,
8773
- result: output ?? suspendOutput ?? {}
8948
+ status: displayStatus,
8949
+ result: output ?? suspendOutput ?? error ?? {},
8950
+ tripwire: tripwireInfo
8774
8951
  },
8775
8952
  stepId
8776
8953
  );
@@ -9119,10 +9296,14 @@ const columns$4 = [
9119
9296
  header: "Name",
9120
9297
  cell: ({ row }) => {
9121
9298
  const { Link, paths } = useLinkComponent();
9299
+ const workflow = row.original;
9122
9300
  return /* @__PURE__ */ jsx(
9123
9301
  EntryCell,
9124
9302
  {
9125
- name: /* @__PURE__ */ jsx(Link, { href: paths.workflowLink(row.original.id), children: row.original.name }),
9303
+ name: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9304
+ /* @__PURE__ */ jsx(Link, { href: paths.workflowLink(row.original.id), children: row.original.name }),
9305
+ workflow.isProcessorWorkflow && /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx(Cpu, { className: "h-3 w-3" }), className: "!h-badge-sm bg-violet-500/20 text-violet-400", children: "Processor" })
9306
+ ] }),
9126
9307
  description: void 0,
9127
9308
  meta: void 0
9128
9309
  }
@@ -9334,19 +9515,33 @@ const PlaygroundTabs = ({
9334
9515
  const TabList$1 = ({ children, className }) => {
9335
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 }) });
9336
9517
  };
9337
- const Tab$1 = ({ children, value, onClick }) => {
9338
- return /* @__PURE__ */ jsx(
9518
+ const Tab$1 = ({ children, value, onClick, onClose }) => {
9519
+ return /* @__PURE__ */ jsxs(
9339
9520
  TabsTrigger,
9340
9521
  {
9341
9522
  value,
9342
- 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",
9343
9524
  onClick,
9344
- 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
+ ]
9345
9540
  }
9346
9541
  );
9347
9542
  };
9348
9543
  const TabContent$1 = ({ children, value }) => {
9349
- return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-hidden flex flex-col", children });
9544
+ return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-auto flex flex-col", children });
9350
9545
  };
9351
9546
 
9352
9547
  const TracingRunOptions = () => {
@@ -9369,20 +9564,127 @@ const TracingRunOptions = () => {
9369
9564
  strValue = JSON.stringify(settings?.tracingOptions, null, 2);
9370
9565
  } catch {
9371
9566
  }
9372
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-5 py-2", children: [
9373
- /* @__PURE__ */ jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Tracing Options" }),
9374
- /* @__PURE__ */ jsx(
9375
- CodeMirror,
9376
- {
9377
- value: strValue,
9378
- onChange: handleChange,
9379
- theme,
9380
- extensions: [jsonLanguage],
9381
- className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9382
- }
9383
- )
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
+ ] })
9384
9686
  ] });
9385
- };
9687
+ }
9386
9688
 
9387
9689
  function WorkflowInformation({ workflowId, initialRunId }) {
9388
9690
  const { data: workflow, isLoading, error } = useWorkflow(workflowId);
@@ -9397,10 +9699,21 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9397
9699
  cancelWorkflowRun,
9398
9700
  isCancellingWorkflowRun
9399
9701
  } = useContext(WorkflowRunContext);
9702
+ const { stepDetail, closeStepDetail } = useWorkflowStepDetail();
9400
9703
  const [tab, setTab] = useState("current-run");
9401
9704
  const [runId, setRunId] = useState("");
9402
9705
  const { handleCopy } = useCopyToClipboard({ text: workflowId });
9403
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]);
9404
9717
  useEffect(() => {
9405
9718
  if (!runId && !initialRunId) {
9406
9719
  closeStreamsAndReset();
@@ -9412,6 +9725,19 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9412
9725
  toast.error(`Error loading workflow: ${errorMessage}`);
9413
9726
  }
9414
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
+ };
9415
9741
  if (error) {
9416
9742
  return null;
9417
9743
  }
@@ -9425,12 +9751,27 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9425
9751
  stepsCount,
9426
9752
  " step",
9427
9753
  stepsCount > 1 ? "s" : ""
9428
- ] })
9754
+ ] }),
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" })
9429
9756
  ] }) }),
9430
- /* @__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: [
9431
9758
  /* @__PURE__ */ jsxs(TabList$1, { children: [
9432
9759
  /* @__PURE__ */ jsx(Tab$1, { value: "current-run", children: "Current Run" }),
9433
- /* @__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
+ )
9434
9775
  ] }),
9435
9776
  /* @__PURE__ */ jsx(TabContent$1, { value: "current-run", children: workflowId ? initialRunId ? /* @__PURE__ */ jsx(
9436
9777
  WorkflowRunDetail,
@@ -9465,7 +9806,8 @@ function WorkflowInformation({ workflowId, initialRunId }) {
9465
9806
  cancelWorkflowRun
9466
9807
  }
9467
9808
  ) : null }),
9468
- /* @__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, {}) })
9469
9811
  ] }) })
9470
9812
  ] });
9471
9813
  }
@@ -9697,7 +10039,8 @@ const WorkflowBadge = ({
9697
10039
  isStreaming,
9698
10040
  metadata,
9699
10041
  toolCallId,
9700
- toolApprovalMetadata
10042
+ toolApprovalMetadata,
10043
+ suspendPayload
9701
10044
  }) => {
9702
10045
  const { runId, status } = result || {};
9703
10046
  const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(workflowId);
@@ -9709,6 +10052,7 @@ const WorkflowBadge = ({
9709
10052
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
9710
10053
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
9711
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" });
9712
10056
  if (isWorkflowLoading || !workflow) return /* @__PURE__ */ jsx(LoadingBadge, {});
9713
10057
  return /* @__PURE__ */ jsxs(
9714
10058
  BadgeWrapper,
@@ -9725,6 +10069,10 @@ const WorkflowBadge = ({
9725
10069
  }
9726
10070
  ),
9727
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
+ ] }),
9728
10076
  !isStreaming && !isLoading && /* @__PURE__ */ jsx(WorkflowRunProvider, { snapshot, workflowId, initialRunId: runId, withoutTimeTravel: true, children: /* @__PURE__ */ jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }) }),
9729
10077
  isStreaming && /* @__PURE__ */ jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }),
9730
10078
  /* @__PURE__ */ jsx(ToolApprovalButtons, { toolCalled: !!status, toolCallId, toolApprovalMetadata })
@@ -9860,7 +10208,9 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
9860
10208
  const agentToolName = toolName.startsWith("agent-") ? toolName.substring("agent-".length) : toolName;
9861
10209
  const workflowToolName = toolName.startsWith("workflow-") ? toolName.substring("workflow-".length) : toolName;
9862
10210
  const requireApprovalMetadata = metadata?.mode === "stream" && metadata?.requireApprovalMetadata;
9863
- 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;
9864
10214
  useWorkflowStream(result);
9865
10215
  if (isAgent) {
9866
10216
  return /* @__PURE__ */ jsx(
@@ -9884,7 +10234,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
9884
10234
  result,
9885
10235
  metadata,
9886
10236
  toolCallId,
9887
- toolApprovalMetadata
10237
+ toolApprovalMetadata,
10238
+ suspendPayload: suspendedToolMetadata?.suspendPayload
9888
10239
  }
9889
10240
  );
9890
10241
  }
@@ -9897,7 +10248,8 @@ const ToolFallbackInner = ({ toolName, result, args, metadata, toolCallId, ...pr
9897
10248
  toolOutput: result?.toolOutput || [],
9898
10249
  metadata,
9899
10250
  toolCallId,
9900
- toolApprovalMetadata
10251
+ toolApprovalMetadata,
10252
+ suspendPayload: suspendedToolMetadata?.suspendPayload
9901
10253
  }
9902
10254
  );
9903
10255
  };
@@ -10978,25 +11330,36 @@ const ThreadWelcome = ({ agentName }) => {
10978
11330
  };
10979
11331
  const Composer = ({ hasMemory, agentId }) => {
10980
11332
  const { setThreadInput } = useThreadInput();
11333
+ const textareaRef = useRef(null);
10981
11334
  return /* @__PURE__ */ jsx("div", { className: "mx-4", children: /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
10982
11335
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
10983
- /* @__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: [
10984
- /* @__PURE__ */ jsx(ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(
10985
- "textarea",
10986
- {
10987
- className: "text-ui-lg leading-ui-lg placeholder:text-icon3 text-icon6 bg-transparent focus:outline-none resize-none outline-none",
10988
- autoFocus: document.activeElement === document.body,
10989
- placeholder: "Enter your message...",
10990
- name: "",
10991
- id: "",
10992
- onChange: (e) => setThreadInput?.(e.target.value)
10993
- }
10994
- ) }),
10995
- /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10996
- /* @__PURE__ */ jsx(SpeechInput, { agentId }),
10997
- /* @__PURE__ */ jsx(ComposerAction, {})
10998
- ] })
10999
- ] })
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
+ )
11000
11363
  ] }) });
11001
11364
  };
11002
11365
  const SpeechInput = ({ agentId }) => {
@@ -11334,34 +11697,33 @@ function useAgentSettingsState({ agentId, defaultSettings: defaultSettingsProp }
11334
11697
  useEffect(() => {
11335
11698
  try {
11336
11699
  const stored = localStorage.getItem(LOCAL_STORAGE_KEY);
11337
- if (stored) {
11338
- const parsed = JSON.parse(stored);
11339
- const settings2 = {
11340
- ...parsed,
11341
- modelSettings: {
11342
- ...defaultSettingsProp?.modelSettings ?? {},
11343
- ...parsed?.modelSettings ?? {}
11344
- }
11345
- };
11346
- setSettingsState(settings2 ?? void 0);
11347
- }
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);
11348
11711
  } catch (e) {
11349
- console.error(e);
11350
11712
  }
11351
- }, [LOCAL_STORAGE_KEY]);
11713
+ }, [LOCAL_STORAGE_KEY, defaultSettingsProp]);
11352
11714
  const setSettings = (settingsValue) => {
11353
11715
  setSettingsState((prev) => ({ ...prev, ...settingsValue }));
11354
11716
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({ ...settingsValue, agentId }));
11355
11717
  };
11356
11718
  const resetAll = () => {
11357
- const settings2 = {
11719
+ const resetSettings = {
11358
11720
  modelSettings: {
11359
- ...defaultSettingsProp?.modelSettings ?? {},
11360
- ...defaultSettings.modelSettings
11721
+ ...defaultSettings.modelSettings,
11722
+ ...defaultSettingsProp?.modelSettings ?? {}
11361
11723
  }
11362
11724
  };
11363
- setSettingsState(settings2);
11364
- localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(settings2));
11725
+ setSettingsState(resetSettings);
11726
+ localStorage.removeItem(LOCAL_STORAGE_KEY);
11365
11727
  };
11366
11728
  return {
11367
11729
  settings,
@@ -11512,18 +11874,19 @@ const initializeMessageState = (initialMessages) => {
11512
11874
  };
11513
11875
  } else if (part.toolInvocation.state === "call") {
11514
11876
  const toolCallId = part.toolInvocation.toolCallId;
11877
+ const toolName = part.toolInvocation.toolName;
11515
11878
  const pendingToolApprovals = message.metadata?.pendingToolApprovals;
11516
11879
  const suspensionData = pendingToolApprovals?.[toolCallId];
11517
11880
  if (suspensionData) {
11518
11881
  return {
11519
11882
  type: "tool-call",
11520
11883
  toolCallId,
11521
- toolName: part.toolInvocation.toolName,
11884
+ toolName,
11522
11885
  args: part.toolInvocation.args,
11523
11886
  metadata: {
11524
11887
  mode: "stream",
11525
11888
  requireApprovalMetadata: {
11526
- [toolCallId]: suspensionData
11889
+ [toolName]: suspensionData
11527
11890
  }
11528
11891
  }
11529
11892
  };
@@ -11593,6 +11956,7 @@ function MastraRuntimeProvider({
11593
11956
  temperature,
11594
11957
  topK,
11595
11958
  topP,
11959
+ seed,
11596
11960
  chatWithGenerateLegacy,
11597
11961
  chatWithGenerate,
11598
11962
  chatWithNetwork,
@@ -11611,7 +11975,9 @@ function MastraRuntimeProvider({
11611
11975
  temperature,
11612
11976
  topK,
11613
11977
  topP,
11614
- maxTokens,
11978
+ seed,
11979
+ maxOutputTokens: maxTokens,
11980
+ // AI SDK v5 uses maxOutputTokens
11615
11981
  instructions,
11616
11982
  providerOptions,
11617
11983
  maxSteps,
@@ -11710,6 +12076,7 @@ function MastraRuntimeProvider({
11710
12076
  temperature,
11711
12077
  topK,
11712
12078
  topP,
12079
+ seed,
11713
12080
  instructions,
11714
12081
  requestContext: requestContextInstance,
11715
12082
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -11826,6 +12193,7 @@ function MastraRuntimeProvider({
11826
12193
  temperature,
11827
12194
  topK,
11828
12195
  topP,
12196
+ seed,
11829
12197
  instructions,
11830
12198
  requestContext: requestContextInstance,
11831
12199
  ...memory ? { threadId, resourceId: agentId } : {},
@@ -12146,54 +12514,60 @@ const AgentAdvancedSettings = () => {
12146
12514
  ] }),
12147
12515
  /* @__PURE__ */ jsxs(CollapsibleContent, { className: collapsibleContentClassName, children: [
12148
12516
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12149
- /* @__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" }),
12150
12518
  /* @__PURE__ */ jsx(
12151
12519
  Input,
12152
12520
  {
12153
- id: "top-k",
12521
+ id: "frequency-penalty",
12154
12522
  type: "number",
12155
- value: settings?.modelSettings?.topK || "",
12523
+ step: "0.1",
12524
+ min: "-1",
12525
+ max: "1",
12526
+ value: settings?.modelSettings?.frequencyPenalty ?? "",
12156
12527
  onChange: (e) => setSettings({
12157
12528
  ...settings,
12158
12529
  modelSettings: {
12159
12530
  ...settings?.modelSettings,
12160
- topK: e.target.value ? Number(e.target.value) : void 0
12531
+ frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12161
12532
  }
12162
12533
  })
12163
12534
  }
12164
12535
  )
12165
12536
  ] }),
12166
12537
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12167
- /* @__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" }),
12168
12539
  /* @__PURE__ */ jsx(
12169
12540
  Input,
12170
12541
  {
12171
- id: "frequency-penalty",
12542
+ id: "presence-penalty",
12172
12543
  type: "number",
12173
- value: settings?.modelSettings?.frequencyPenalty || "",
12544
+ step: "0.1",
12545
+ min: "-1",
12546
+ max: "1",
12547
+ value: settings?.modelSettings?.presencePenalty ?? "",
12174
12548
  onChange: (e) => setSettings({
12175
12549
  ...settings,
12176
12550
  modelSettings: {
12177
12551
  ...settings?.modelSettings,
12178
- frequencyPenalty: e.target.value ? Number(e.target.value) : void 0
12552
+ presencePenalty: e.target.value ? Number(e.target.value) : void 0
12179
12553
  }
12180
12554
  })
12181
12555
  }
12182
12556
  )
12183
12557
  ] }),
12184
12558
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
12185
- /* @__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" }),
12186
12560
  /* @__PURE__ */ jsx(
12187
12561
  Input,
12188
12562
  {
12189
- id: "presence-penalty",
12563
+ id: "top-k",
12190
12564
  type: "number",
12191
- value: settings?.modelSettings?.presencePenalty || "",
12565
+ value: settings?.modelSettings?.topK || "",
12192
12566
  onChange: (e) => setSettings({
12193
12567
  ...settings,
12194
12568
  modelSettings: {
12195
12569
  ...settings?.modelSettings,
12196
- presencePenalty: e.target.value ? Number(e.target.value) : void 0
12570
+ topK: e.target.value ? Number(e.target.value) : void 0
12197
12571
  }
12198
12572
  })
12199
12573
  }
@@ -12253,6 +12627,24 @@ const AgentAdvancedSettings = () => {
12253
12627
  }
12254
12628
  )
12255
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
+ ] }),
12256
12648
  /* @__PURE__ */ jsxs("div", { className: "space-y-1 col-span-2", children: [
12257
12649
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
12258
12650
  /* @__PURE__ */ jsx(Txt, { as: "label", className: "text-icon3", variant: "ui-sm", htmlFor: "provider-options", children: "Provider Options" }),
@@ -15264,6 +15656,7 @@ const AgentMetadataModelList = ({
15264
15656
  }) => {
15265
15657
  const [modelConfigs, setModelConfigs] = useState(() => modelList);
15266
15658
  const hasMultipleModels = modelConfigs.length > 1;
15659
+ const enabledCount = modelConfigs.filter((m) => m.enabled !== false).length;
15267
15660
  const handleDragEnd = (result) => {
15268
15661
  if (!result.destination) {
15269
15662
  return;
@@ -15298,7 +15691,8 @@ const AgentMetadataModelList = ({
15298
15691
  modelConfig,
15299
15692
  updateModelInModelList: updateModel,
15300
15693
  showDragHandle: hasMultipleModels,
15301
- dragHandleProps: provided2.dragHandleProps
15694
+ dragHandleProps: provided2.dragHandleProps,
15695
+ isLastEnabled: modelConfig.enabled !== false && enabledCount === 1
15302
15696
  }
15303
15697
  ) }) }, modelConfig.id)),
15304
15698
  provided.placeholder
@@ -15308,7 +15702,8 @@ const AgentMetadataModelListItem = ({
15308
15702
  modelConfig,
15309
15703
  updateModelInModelList,
15310
15704
  showDragHandle,
15311
- dragHandleProps
15705
+ dragHandleProps,
15706
+ isLastEnabled
15312
15707
  }) => {
15313
15708
  const [enabled, setEnabled] = useState(() => modelConfig.enabled);
15314
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: [
@@ -15322,7 +15717,10 @@ const AgentMetadataModelListItem = ({
15322
15717
  autoSave: true
15323
15718
  }
15324
15719
  ) }),
15325
- /* @__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(
15326
15724
  Switch,
15327
15725
  {
15328
15726
  checked: enabled,
@@ -15340,7 +15738,14 @@ function usePromptEnhancer({ agentId }) {
15340
15738
  const client = useMastraClient();
15341
15739
  return useMutation({
15342
15740
  mutationFn: async ({ instructions, userComment }) => {
15343
- 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
+ }
15344
15749
  }
15345
15750
  });
15346
15751
  }
@@ -15383,21 +15788,53 @@ const PromptEnhancer = ({ agentId }) => {
15383
15788
  const PromptEnhancerTextarea = ({ agentId }) => {
15384
15789
  const { prompt, setPrompt } = useAgentPromptExperiment();
15385
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();
15386
15807
  const handleSubmit = async (e) => {
15387
15808
  e.preventDefault();
15388
15809
  const form = e.target;
15389
15810
  const formData = new FormData(form);
15390
15811
  const userComment = formData.get("userComment");
15391
- const result = await enhancePrompt({ instructions: prompt, userComment });
15392
- form.reset();
15393
- 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
+ }
15394
15818
  };
15819
+ const isDisabled = isPending || !hasValidModel;
15820
+ const showWarning = !isDataLoading && !hasValidModel;
15395
15821
  return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
15396
- /* @__PURE__ */ jsx(Input, { name: "userComment", placeholder: "Enter your comment here...", className: "resize-none", disabled: isPending }),
15397
- /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(Button$1, { variant: "light", type: "submit", disabled: isPending, children: [
15398
- /* @__PURE__ */ jsx(Icon, { children: isPending ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(RefreshCcwIcon, {}) }),
15399
- "Enhance prompt"
15400
- ] }) })
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
+ ] })
15401
15838
  ] });
15402
15839
  };
15403
15840
 
@@ -16171,13 +16608,16 @@ const AgentWorkingMemory = ({ agentId }) => {
16171
16608
  placeholder: "Enter working memory content..."
16172
16609
  }
16173
16610
  ),
16174
- /* @__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(
16175
16615
  Button$2,
16176
16616
  {
16177
16617
  variant: "secondary",
16178
16618
  size: "sm",
16179
16619
  onClick: () => setIsEditing(true),
16180
- disabled: !threadExists || isUpdating,
16620
+ disabled: isUpdating,
16181
16621
  className: "text-xs",
16182
16622
  children: "Edit Working Memory"
16183
16623
  }
@@ -16274,22 +16714,6 @@ const AgentMemoryConfig = ({ agentId }) => {
16274
16714
  ]
16275
16715
  });
16276
16716
  }
16277
- if (config.workingMemory) {
16278
- sections.push({
16279
- title: "Working Memory",
16280
- items: [
16281
- {
16282
- label: "Enabled",
16283
- value: config.workingMemory.enabled,
16284
- badge: config.workingMemory.enabled ? "success" : void 0
16285
- },
16286
- ...config.workingMemory.enabled ? [
16287
- { label: "Scope", value: config.workingMemory.scope || "resource" },
16288
- { label: "Template", value: config.workingMemory.template || "default" }
16289
- ] : []
16290
- ]
16291
- });
16292
- }
16293
16717
  return sections;
16294
16718
  }, [config]);
16295
16719
  const toggleSection = (title) => {
@@ -16349,7 +16773,7 @@ const AgentMemoryConfig = ({ agentId }) => {
16349
16773
  ),
16350
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: [
16351
16775
  /* @__PURE__ */ jsx("span", { className: "text-xs text-icon3", children: item.label }),
16352
- renderValue(item.value || "", item.badge)
16776
+ renderValue(item.value ?? "", item.badge)
16353
16777
  ] }, `${section.title}-${item.label}`)) })
16354
16778
  ] }, section.title)) })
16355
16779
  ] });
@@ -18480,6 +18904,17 @@ const Tabs = Object.assign(TabsRoot, {
18480
18904
  Content: TabContent
18481
18905
  });
18482
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
+ };
18483
18918
  function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18484
18919
  if (!traceUsage && !spanUsage) {
18485
18920
  console.warn("No usage data available");
@@ -18584,6 +19019,14 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18584
19019
  cachedInputTokens: {
18585
19020
  label: "Cached Input Tokens",
18586
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, {})
18587
19030
  }
18588
19031
  };
18589
19032
  const commonTokenPresentations = {
@@ -18599,47 +19042,79 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18599
19042
  };
18600
19043
  let usageKeyOrder = [];
18601
19044
  if (hasV5Format) {
18602
- usageKeyOrder = ["totalTokens", "inputTokens", "outputTokens", "reasoningTokens", "cachedInputTokens"];
19045
+ usageKeyOrder = [
19046
+ "totalTokens",
19047
+ "inputTokens",
19048
+ "outputTokens",
19049
+ "reasoningTokens",
19050
+ "cachedInputTokens",
19051
+ "inputDetails",
19052
+ "outputDetails"
19053
+ ];
18603
19054
  } else {
18604
19055
  usageKeyOrder = ["totalTokens", "promptTokens", "completionTokens"];
18605
19056
  }
18606
- const usageAsArray = Object.entries(traceUsage || spanUsage || {}).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
18607
- return /* @__PURE__ */ jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxs(
18608
- "div",
18609
- {
18610
- className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
18611
- "min-h-[5.5rem]": traceUsage
18612
- }),
18613
- children: [
18614
- /* @__PURE__ */ jsxs(
18615
- "div",
18616
- {
18617
- className: cn(
18618
- "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
18619
- "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
18620
- ),
18621
- children: [
18622
- tokenPresentations?.[key]?.icon,
18623
- /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
18624
- /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
18625
- ]
18626
- }
18627
- ),
18628
- tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxs(
18629
- "dl",
18630
- {
18631
- className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
18632
- children: [
18633
- /* @__PURE__ */ jsx("dt", { children: provider }),
18634
- /* @__PURE__ */ jsx("dd", { children: providerTokens?.[key] })
18635
- ]
18636
- },
18637
- provider
18638
- )) })
18639
- ]
18640
- },
18641
- key
18642
- )) });
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
+ }) });
18643
19118
  }
18644
19119
 
18645
19120
  function isTokenLimitExceeded(span) {
@@ -18752,7 +19227,7 @@ function SpanTabs({
18752
19227
  SpanScoring,
18753
19228
  {
18754
19229
  traceId: trace?.traceId,
18755
- isTopLevelSpan: span?.parentSpanId === null,
19230
+ isTopLevelSpan: !Boolean(span?.parentSpanId),
18756
19231
  spanId: span?.spanId,
18757
19232
  entityType,
18758
19233
  scorers,
@@ -19912,14 +20387,6 @@ const MCPToolPanel = ({ toolId, serverId }) => {
19912
20387
  );
19913
20388
  };
19914
20389
 
19915
- const CodeMirrorBlock = (props) => {
19916
- const theme = useCodemirrorTheme$1();
19917
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4 relative", children: [
19918
- /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy code", content: props.value || "No content" }) }),
19919
- /* @__PURE__ */ jsx(CodeMirror, { extensions: [json()], theme, ...props })
19920
- ] });
19921
- };
19922
-
19923
20390
  const MCPDetail = ({ isLoading, server }) => {
19924
20391
  const [{ sseUrl, httpStreamUrl }, setUrls] = useState({
19925
20392
  sseUrl: "",
@@ -19941,112 +20408,45 @@ const MCPDetail = ({ isLoading, server }) => {
19941
20408
  if (isLoading) return null;
19942
20409
  if (!server)
19943
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}`;
19944
20412
  return /* @__PURE__ */ jsxs(MainContentContent, { isDivided: true, children: [
19945
- /* @__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: [
19946
20414
  /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon6 font-medium pb-4", children: server.name }),
19947
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
19948
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
19949
- /* @__PURE__ */ jsx(
19950
- Badge,
19951
- {
19952
- icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "SSE" }),
19953
- className: "!text-icon4",
19954
- children: sseUrl
19955
- }
19956
- ),
19957
- /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" })
19958
- ] }),
19959
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
19960
- /* @__PURE__ */ jsx(
19961
- Badge,
19962
- {
19963
- icon: /* @__PURE__ */ jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "HTTP" }),
19964
- className: "!text-icon4",
19965
- children: httpStreamUrl
19966
- }
19967
- ),
19968
- /* @__PURE__ */ jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" })
19969
- ] })
19970
- ] }),
19971
- /* @__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: [
19972
20416
  /* @__PURE__ */ jsx(Badge, { icon: /* @__PURE__ */ jsx(FolderIcon, { className: "text-icon6" }), className: "rounded-r-sm !text-icon4", children: "Version" }),
19973
20417
  /* @__PURE__ */ jsx(Badge, { className: "rounded-l-sm !text-icon4", children: server.version_detail.version })
19974
20418
  ] }),
19975
- /* @__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
+ ] })
19976
20446
  ] }),
19977
20447
  /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll border-l-sm border-border1", children: /* @__PURE__ */ jsx(McpToolList, { server }) })
19978
20448
  ] });
19979
20449
  };
19980
- const McpSetupTabs = ({ sseUrl, serverName }) => {
19981
- const { Link } = useLinkComponent();
19982
- return /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "cursor", children: [
19983
- /* @__PURE__ */ jsxs(TabList$1, { children: [
19984
- /* @__PURE__ */ jsx(Tab$1, { value: "cursor", children: "Cursor" }),
19985
- /* @__PURE__ */ jsx(Tab$1, { value: "windsurf", children: "Windsurf" })
19986
- ] }),
19987
- /* @__PURE__ */ jsxs(TabContent$1, { value: "cursor", children: [
19988
- /* @__PURE__ */ jsxs(Txt, { className: "text-icon3 pb-4", children: [
19989
- "Cursor comes with built-in MCP Support.",
19990
- " ",
19991
- /* @__PURE__ */ jsx(
19992
- Link,
19993
- {
19994
- href: "https://docs.cursor.com/context/model-context-protocol",
19995
- target: "_blank",
19996
- rel: "noopener noreferrer",
19997
- className: "underline hover:text-icon6",
19998
- children: "Following the documentation"
19999
- }
20000
- ),
20001
- ", you can register an MCP server using SSE with the following configuration."
20002
- ] }),
20003
- /* @__PURE__ */ jsx(
20004
- CodeMirrorBlock,
20005
- {
20006
- editable: false,
20007
- value: `{
20008
- "mcpServers": {
20009
- "${serverName}": {
20010
- "url": "${sseUrl}"
20011
- }
20012
- }
20013
- }`
20014
- }
20015
- )
20016
- ] }),
20017
- /* @__PURE__ */ jsxs(TabContent$1, { value: "windsurf", children: [
20018
- /* @__PURE__ */ jsxs(Txt, { className: "text-icon3 pb-4", children: [
20019
- "Windsurf comes with built-in MCP Support.",
20020
- " ",
20021
- /* @__PURE__ */ jsx(
20022
- Link,
20023
- {
20024
- href: "https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json",
20025
- target: "_blank",
20026
- rel: "noopener noreferrer",
20027
- className: "underline hover:text-icon6",
20028
- children: "Following the documentation"
20029
- }
20030
- ),
20031
- ", you can register an MCP server using SSE with the following configuration."
20032
- ] }),
20033
- /* @__PURE__ */ jsx(
20034
- CodeMirrorBlock,
20035
- {
20036
- editable: false,
20037
- value: `{
20038
- "mcpServers": {
20039
- "${serverName}": {
20040
- "command": "npx",
20041
- "args": ["-y", "mcp-remote", "${sseUrl}"]
20042
- }
20043
- }
20044
- }`
20045
- }
20046
- )
20047
- ] })
20048
- ] });
20049
- };
20050
20450
  const McpToolList = ({ server }) => {
20051
20451
  const { data: tools = {}, isLoading } = useMCPServerTools(server);
20052
20452
  if (isLoading) return null;
@@ -20293,5 +20693,5 @@ const PlaygroundConfigGuard = () => {
20293
20693
  ] }) });
20294
20694
  };
20295
20695
 
20296
- 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 };
20297
20697
  //# sourceMappingURL=index.es.js.map