@mastra/playground-ui 7.0.0-beta.14 → 7.0.0-beta.15

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/index.cjs.js +835 -180
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +831 -183
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/src/components/ui/containers/MainContent.d.ts +7 -0
  7. package/dist/src/domains/agents/components/agent-layout.d.ts +7 -0
  8. package/dist/src/domains/agents/index.d.ts +1 -0
  9. package/dist/src/domains/configuration/components/mastra-version-footer.d.ts +17 -0
  10. package/dist/src/domains/configuration/hooks/use-mastra-packages.d.ts +1 -0
  11. package/dist/src/domains/configuration/hooks/use-package-updates.d.ts +18 -0
  12. package/dist/src/domains/configuration/index.d.ts +3 -0
  13. package/dist/src/domains/observability/components/helpers.d.ts +11 -3
  14. package/dist/src/domains/observability/components/span-dialog.d.ts +2 -1
  15. package/dist/src/domains/observability/components/span-score-list.d.ts +1 -1
  16. package/dist/src/domains/observability/components/span-tabs.d.ts +2 -1
  17. package/dist/src/domains/observability/components/trace-span-usage.d.ts +1 -1
  18. package/dist/src/domains/observability/components/traces-list.d.ts +1 -1
  19. package/dist/src/domains/observability/context/tracing-settings-context.d.ts +1 -0
  20. package/dist/src/domains/observability/hooks/use-tracing-settings-state.d.ts +1 -0
  21. package/dist/src/domains/scores/components/score-dialog.d.ts +2 -2
  22. package/dist/src/domains/scores/hooks/use-trace-span-scores.d.ts +41 -1
  23. package/dist/src/domains/workflows/components/workflow-layout.d.ts +7 -0
  24. package/dist/src/domains/workflows/context/workflow-run-context.d.ts +3 -1
  25. package/dist/src/domains/workflows/hooks/use-workflows-actions.d.ts +6 -2
  26. package/dist/src/domains/workflows/index.d.ts +1 -0
  27. package/dist/src/domains/workflows/workflow/workflow-default-node.d.ts +2 -1
  28. package/dist/src/domains/workflows/workflow/workflow-nested-node.d.ts +2 -1
  29. package/dist/src/domains/workflows/workflow/workflow-run-options.d.ts +1 -0
  30. package/dist/src/domains/workflows/workflow/workflow-step-action-bar.d.ts +4 -2
  31. package/dist/src/domains/workflows/workflow/workflow-time-travel-form.d.ts +5 -1
  32. package/dist/src/domains/workflows/workflow/workflow-trigger.d.ts +4 -2
  33. package/dist/src/lib/resize/collapsible-panel.d.ts +5 -0
  34. package/dist/src/lib/resize/separator.d.ts +1 -0
  35. package/package.json +13 -11
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, 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';
3
+ import { CheckIcon as CheckIcon$1, CopyIcon, ShieldAlert, ChevronDown, ChevronRight, RefreshCw, Tag, InfoIcon as InfoIcon$1, AlertCircle, TriangleAlert, ChevronUpIcon, X, Share2, Check, Clock as Clock$1, PlayCircle, Workflow, Layers, List, 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, ArrowRight, ArrowLeft, 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, MoveRight, Copy } 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';
@@ -19,7 +19,7 @@ import CodeMirror, { EditorView as EditorView$1 } from '@uiw/react-codemirror';
19
19
  import { toast as toast$1 } from 'sonner';
20
20
  import './index.css';export { Toaster } from 'sonner';
21
21
  import * as DialogPrimitive from '@radix-ui/react-dialog';
22
- import { useQuery, useMutation, useInfiniteQuery, useQueryClient, QueryClient, QueryClientProvider } from '@tanstack/react-query';
22
+ import { useQuery, useMutation, useInfiniteQuery, useQueryClient, QueryClient, QueryClientProvider, useQueries } from '@tanstack/react-query';
23
23
  export * from '@tanstack/react-query';
24
24
  import { useMastraClient, mapWorkflowStreamChunkToWatchResult, resolveToChildMessages, useChat, toAssistantUIMessage } from '@mastra/react';
25
25
  import { create } from 'zustand';
@@ -74,6 +74,8 @@ import { languages } from '@codemirror/language-data';
74
74
  import { githubDarkInit } from '@uiw/codemirror-theme-github';
75
75
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
76
76
  import * as TabsPrimitive from '@radix-ui/react-tabs';
77
+ import { Separator, usePanelRef, Panel as Panel$1, useDefaultLayout, Group } from 'react-resizable-panels';
78
+ import semver from 'semver';
77
79
 
78
80
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
79
81
 
@@ -4457,6 +4459,7 @@ const BadgeWrapper = ({
4457
4459
  };
4458
4460
 
4459
4461
  const Dialog = DialogPrimitive.Root;
4462
+ const DialogTrigger = DialogPrimitive.Trigger;
4460
4463
  const DialogPortal = DialogPrimitive.Portal;
4461
4464
  const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4462
4465
  DialogPrimitive.Overlay,
@@ -4954,7 +4957,8 @@ function useTracingSettingsState({ entityId, entityType }) {
4954
4957
  return {
4955
4958
  settings,
4956
4959
  setSettings,
4957
- resetAll
4960
+ resetAll,
4961
+ entityType
4958
4962
  };
4959
4963
  }
4960
4964
 
@@ -4963,7 +4967,8 @@ const TracingSettingsContext = createContext({
4963
4967
  },
4964
4968
  resetAll: () => {
4965
4969
  },
4966
- settings: void 0
4970
+ settings: void 0,
4971
+ entityType: void 0
4967
4972
  });
4968
4973
  const TracingSettingsProvider = ({ children, entityId, entityType }) => {
4969
4974
  const state = useTracingSettingsState({ entityId, entityType });
@@ -5036,7 +5041,7 @@ const useExecuteWorkflow = () => {
5036
5041
  startAsyncWorkflowRun
5037
5042
  };
5038
5043
  };
5039
- const useStreamWorkflow = () => {
5044
+ const useStreamWorkflow = ({ debugMode }) => {
5040
5045
  const client = useMastraClient();
5041
5046
  const { settings } = useTracingSettings();
5042
5047
  const [streamResult, setStreamResult] = useState({});
@@ -5092,6 +5097,10 @@ const useStreamWorkflow = () => {
5092
5097
  if (value.type === "workflow-finish") {
5093
5098
  const streamStatus = value.payload?.workflowStatus;
5094
5099
  const metadata = value.payload?.metadata;
5100
+ setStreamResult((prev) => ({
5101
+ ...prev,
5102
+ status: streamStatus
5103
+ }));
5095
5104
  if (streamStatus === "failed") {
5096
5105
  throw new Error(metadata?.errorMessage || "Workflow execution failed");
5097
5106
  }
@@ -5102,7 +5111,8 @@ const useStreamWorkflow = () => {
5102
5111
  workflowId,
5103
5112
  runId,
5104
5113
  inputData,
5105
- requestContext: playgroundRequestContext
5114
+ requestContext: playgroundRequestContext,
5115
+ perStep
5106
5116
  }) => {
5107
5117
  if (readerRef.current) {
5108
5118
  readerRef.current.releaseLock();
@@ -5120,7 +5130,8 @@ const useStreamWorkflow = () => {
5120
5130
  inputData,
5121
5131
  requestContext,
5122
5132
  closeOnSuspend: true,
5123
- tracingOptions: settings?.tracingOptions
5133
+ tracingOptions: settings?.tracingOptions,
5134
+ perStep: perStep ?? debugMode
5124
5135
  });
5125
5136
  if (!stream) {
5126
5137
  return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
@@ -5225,7 +5236,8 @@ const useStreamWorkflow = () => {
5225
5236
  runId,
5226
5237
  step,
5227
5238
  resumeData,
5228
- requestContext: playgroundRequestContext
5239
+ requestContext: playgroundRequestContext,
5240
+ perStep
5229
5241
  }) => {
5230
5242
  if (resumeStreamRef.current) {
5231
5243
  resumeStreamRef.current.releaseLock();
@@ -5242,7 +5254,8 @@ const useStreamWorkflow = () => {
5242
5254
  step,
5243
5255
  resumeData,
5244
5256
  requestContext,
5245
- tracingOptions: settings?.tracingOptions
5257
+ tracingOptions: settings?.tracingOptions,
5258
+ perStep: perStep ?? debugMode
5246
5259
  });
5247
5260
  if (!stream) {
5248
5261
  return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
@@ -5288,6 +5301,7 @@ const useStreamWorkflow = () => {
5288
5301
  workflowId,
5289
5302
  requestContext: playgroundRequestContext,
5290
5303
  runId,
5304
+ perStep,
5291
5305
  ...params
5292
5306
  }) => {
5293
5307
  if (timeTravelStreamRef.current) {
@@ -5303,6 +5317,7 @@ const useStreamWorkflow = () => {
5303
5317
  const run = await workflow.createRun({ runId });
5304
5318
  const stream = await run.timeTravelStream({
5305
5319
  ...params,
5320
+ perStep: perStep ?? debugMode,
5306
5321
  requestContext,
5307
5322
  tracingOptions: settings?.tracingOptions
5308
5323
  });
@@ -5554,6 +5569,7 @@ function WorkflowRunProvider({
5554
5569
  const [payload, setPayload] = useState(() => snapshot?.context?.input ?? null);
5555
5570
  const [runId, setRunId] = useState(() => initialRunId ?? "");
5556
5571
  const [isRunning, setIsRunning] = useState(false);
5572
+ const [debugMode, setDebugMode] = useState(false);
5557
5573
  const refetchExecResultInterval = isRunning ? void 0 : ["success", "failed", "canceled", "bailed"].includes(result?.status ?? "") ? void 0 : 5e3;
5558
5574
  const { isLoading: isLoadingRunExecutionResult, data: runExecutionResult } = useWorkflowRunExecutionResult(
5559
5575
  workflowId,
@@ -5583,7 +5599,7 @@ function WorkflowRunProvider({
5583
5599
  closeStreamsAndReset,
5584
5600
  resumeWorkflowStream,
5585
5601
  timeTravelWorkflowStream
5586
- } = useStreamWorkflow();
5602
+ } = useStreamWorkflow({ debugMode });
5587
5603
  const { mutateAsync: cancelWorkflowRun, isPending: isCancellingWorkflowRun } = useCancelWorkflowRun();
5588
5604
  const clearData = () => {
5589
5605
  setResult(null);
@@ -5639,7 +5655,9 @@ function WorkflowRunProvider({
5639
5655
  },
5640
5656
  runSnapshot,
5641
5657
  isLoadingRunExecutionResult,
5642
- withoutTimeTravel
5658
+ withoutTimeTravel,
5659
+ debugMode,
5660
+ setDebugMode
5643
5661
  },
5644
5662
  children: /* @__PURE__ */ jsx(WorkflowStepDetailProvider, { children })
5645
5663
  }
@@ -7817,17 +7835,24 @@ const JsonField = ({
7817
7835
  ] })
7818
7836
  ] });
7819
7837
  };
7820
- const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7838
+ const WorkflowTimeTravelForm = ({
7839
+ stepKey,
7840
+ closeModal,
7841
+ isPerStepRun,
7842
+ isContinueRun,
7843
+ buttonText = "Start time travel",
7844
+ inputData
7845
+ }) => {
7821
7846
  const {
7822
7847
  result,
7823
7848
  workflow,
7824
7849
  timeTravelWorkflowStream,
7825
- createWorkflowRun,
7826
7850
  runId: prevRunId,
7827
- workflowId
7851
+ workflowId,
7852
+ setDebugMode
7828
7853
  } = useContext(WorkflowRunContext);
7829
7854
  const { requestContext } = usePlaygroundStore();
7830
- const stepResult = result?.steps?.[stepKey];
7855
+ const stepResult = inputData ? { payload: inputData } : result?.steps?.[stepKey];
7831
7856
  const [resumeData, setResumeData] = useState(() => "{}");
7832
7857
  const [contextValue, setContextValue] = useState(() => "{}");
7833
7858
  const [nestedContextValue, setNestedContextValue] = useState(() => "{}");
@@ -7853,17 +7878,20 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7853
7878
  const parsedResume = resumeData.trim() ? JSON.parse(resumeData) : {};
7854
7879
  const parsedContext = contextValue.trim() ? JSON.parse(contextValue) : {};
7855
7880
  const parsedNestedContext = nestedContextValue.trim() ? JSON.parse(nestedContextValue) : {};
7856
- const run = await createWorkflowRun({ workflowId, prevRunId });
7857
7881
  const payload = {
7858
- runId: run.runId,
7882
+ runId: prevRunId,
7859
7883
  workflowId,
7860
7884
  step: stepKey,
7861
7885
  inputData: data,
7862
7886
  resumeData: Object.keys(parsedResume)?.length > 0 ? parsedResume : void 0,
7863
7887
  context: Object.keys(parsedContext)?.length > 0 ? parsedContext : void 0,
7864
7888
  nestedStepsContext: Object.keys(parsedNestedContext)?.length > 0 ? parsedNestedContext : void 0,
7865
- requestContext
7889
+ requestContext,
7890
+ ...isContinueRun ? { perStep: false } : {}
7866
7891
  };
7892
+ if (isContinueRun) {
7893
+ setDebugMode(false);
7894
+ }
7867
7895
  timeTravelWorkflowStream(payload);
7868
7896
  closeModal();
7869
7897
  } catch (error) {
@@ -7887,47 +7915,27 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7887
7915
  schema: stepSchema,
7888
7916
  defaultValues: stepResult?.payload,
7889
7917
  isSubmitLoading: isSubmitting,
7890
- submitButtonLabel: "Start time travel",
7918
+ submitButtonLabel: buttonText,
7891
7919
  onSubmit: handleSubmit,
7892
7920
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-4 pb-4", children: [
7893
- /* @__PURE__ */ jsx(
7894
- JsonField,
7895
- {
7896
- label: "Resume Data (JSON)",
7897
- value: resumeData,
7898
- onChange: setResumeData,
7899
- helperText: "Provide any resume payloads that should be passed to the step."
7900
- }
7901
- ),
7902
- /* @__PURE__ */ jsx(
7903
- JsonField,
7904
- {
7905
- label: "Context (JSON)",
7906
- value: contextValue,
7907
- onChange: setContextValue,
7908
- helperText: "Only include top level steps (no nested workflow steps) that are required in the time travel execution.",
7909
- exampleCode: prettyJson({
7910
- stepId: {
7911
- status: "success",
7912
- payload: {
7913
- value: "test value"
7914
- },
7915
- output: {
7916
- value: "test output"
7917
- }
7918
- }
7919
- })
7920
- }
7921
- ),
7922
- /* @__PURE__ */ jsx(
7923
- JsonField,
7924
- {
7925
- label: "Nested Step Context (JSON)",
7926
- value: nestedContextValue,
7927
- onChange: setNestedContextValue,
7928
- helperText: "Includes nested workflow steps that are required in the time travel execution.",
7929
- exampleCode: prettyJson({
7930
- nestedWorkflowId: {
7921
+ isPerStepRun || isContinueRun ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
7922
+ /* @__PURE__ */ jsx(
7923
+ JsonField,
7924
+ {
7925
+ label: "Resume Data (JSON)",
7926
+ value: resumeData,
7927
+ onChange: setResumeData,
7928
+ helperText: "Provide any resume payloads that should be passed to the step."
7929
+ }
7930
+ ),
7931
+ /* @__PURE__ */ jsx(
7932
+ JsonField,
7933
+ {
7934
+ label: "Context (JSON)",
7935
+ value: contextValue,
7936
+ onChange: setContextValue,
7937
+ helperText: "Only include top level steps (no nested workflow steps) that are required in the time travel execution.",
7938
+ exampleCode: prettyJson({
7931
7939
  stepId: {
7932
7940
  status: "success",
7933
7941
  payload: {
@@ -7937,10 +7945,32 @@ const WorkflowTimeTravelForm = ({ stepKey, closeModal }) => {
7937
7945
  value: "test output"
7938
7946
  }
7939
7947
  }
7940
- }
7941
- })
7942
- }
7943
- ),
7948
+ })
7949
+ }
7950
+ ),
7951
+ /* @__PURE__ */ jsx(
7952
+ JsonField,
7953
+ {
7954
+ label: "Nested Step Context (JSON)",
7955
+ value: nestedContextValue,
7956
+ onChange: setNestedContextValue,
7957
+ helperText: "Includes nested workflow steps that are required in the time travel execution.",
7958
+ exampleCode: prettyJson({
7959
+ nestedWorkflowId: {
7960
+ stepId: {
7961
+ status: "success",
7962
+ payload: {
7963
+ value: "test value"
7964
+ },
7965
+ output: {
7966
+ value: "test output"
7967
+ }
7968
+ }
7969
+ }
7970
+ })
7971
+ }
7972
+ )
7973
+ ] }),
7944
7974
  formError && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-accent2", children: formError })
7945
7975
  ] })
7946
7976
  }
@@ -7960,7 +7990,8 @@ const WorkflowStepActionBar = ({
7960
7990
  stepId,
7961
7991
  onShowNestedGraph,
7962
7992
  status,
7963
- stepKey
7993
+ stepKey,
7994
+ stepsFlow
7964
7995
  }) => {
7965
7996
  const [isInputOpen, setIsInputOpen] = useState(false);
7966
7997
  const [isOutputOpen, setIsOutputOpen] = useState(false);
@@ -7968,11 +7999,53 @@ const WorkflowStepActionBar = ({
7968
7999
  const [isErrorOpen, setIsErrorOpen] = useState(false);
7969
8000
  const [isTripwireOpen, setIsTripwireOpen] = useState(false);
7970
8001
  const [isTimeTravelOpen, setIsTimeTravelOpen] = useState(false);
7971
- const { withoutTimeTravel } = useContext(WorkflowRunContext);
8002
+ const [isContinueRunOpen, setIsContinueRunOpen] = useState(false);
8003
+ const [isPerStepRunOpen, setIsPerStepRunOpen] = useState(false);
8004
+ const {
8005
+ withoutTimeTravel,
8006
+ debugMode,
8007
+ result,
8008
+ runSnapshot,
8009
+ timeTravelWorkflowStream,
8010
+ runId: prevRunId,
8011
+ workflowId,
8012
+ setDebugMode
8013
+ } = useContext(WorkflowRunContext);
7972
8014
  const { showMapConfig, stepDetail, closeStepDetail } = useWorkflowStepDetail();
8015
+ const { requestContext } = usePlaygroundStore();
8016
+ const workflowStatus = result?.status ?? runSnapshot?.status;
7973
8017
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
7974
8018
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
7975
- const showTimeTravel = !withoutTimeTravel && stepKey && !mapConfig;
8019
+ const showTimeTravel = !withoutTimeTravel && stepKey && !mapConfig && workflowStatus !== "running" && workflowStatus !== "paused";
8020
+ const inDebugMode = stepKey && debugMode && workflowStatus === "paused";
8021
+ const stepPayload = useMemo(() => {
8022
+ if (!stepKey || !inDebugMode) return void 0;
8023
+ const previousSteps = stepsFlow?.[stepKey] ?? [];
8024
+ if (previousSteps.length === 0) return void 0;
8025
+ if (previousSteps.length > 1) {
8026
+ return {
8027
+ hasMultiSteps: true,
8028
+ input: previousSteps.reduce(
8029
+ (acc, stepId2) => {
8030
+ if (result?.steps?.[stepId2]?.status === "success") {
8031
+ acc[stepId2] = result?.steps?.[stepId2].output;
8032
+ }
8033
+ return acc;
8034
+ },
8035
+ {}
8036
+ )
8037
+ };
8038
+ }
8039
+ const prevStepId = previousSteps[0];
8040
+ if (result?.steps?.[prevStepId]?.status === "success") {
8041
+ return {
8042
+ hasMultiSteps: false,
8043
+ input: result?.steps?.[prevStepId].output
8044
+ };
8045
+ }
8046
+ return void 0;
8047
+ }, [stepKey, stepsFlow, inDebugMode, result]);
8048
+ const showDebugMode = inDebugMode && stepPayload && !result?.steps[stepKey];
7976
8049
  const isMapConfigOpen = stepDetail?.type === "map-config" && stepDetail?.stepName === stepName;
7977
8050
  const isNestedGraphOpen = stepDetail?.type === "nested-graph" && stepDetail?.stepName === stepName;
7978
8051
  const activeButtonClass = "ring-2 ring-accent1 ring-offset-1 ring-offset-transparent";
@@ -7990,7 +8063,32 @@ const WorkflowStepActionBar = ({
7990
8063
  onShowNestedGraph?.();
7991
8064
  }
7992
8065
  };
7993
- return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || tripwire || mapConfig || resumeData || onShowNestedGraph || showTimeTravel) && /* @__PURE__ */ jsxs(
8066
+ const handleRunMapStep = (isContinueRun) => {
8067
+ const payload = {
8068
+ runId: prevRunId,
8069
+ workflowId,
8070
+ step: stepKey,
8071
+ inputData: stepPayload?.hasMultiSteps ? void 0 : stepPayload?.input,
8072
+ requestContext,
8073
+ ...isContinueRun ? { perStep: false } : {},
8074
+ ...stepPayload?.hasMultiSteps ? {
8075
+ context: Object.keys(stepPayload.input)?.reduce(
8076
+ (acc, stepId2) => {
8077
+ acc[stepId2] = {
8078
+ output: stepPayload.input[stepId2]
8079
+ };
8080
+ return acc;
8081
+ },
8082
+ {}
8083
+ )
8084
+ } : {}
8085
+ };
8086
+ if (isContinueRun) {
8087
+ setDebugMode(false);
8088
+ }
8089
+ timeTravelWorkflowStream(payload);
8090
+ };
8091
+ return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || tripwire || mapConfig || resumeData || onShowNestedGraph || showTimeTravel || showDebugMode) && /* @__PURE__ */ jsxs(
7994
8092
  "div",
7995
8093
  {
7996
8094
  className: cn(
@@ -8014,6 +8112,66 @@ const WorkflowStepActionBar = ({
8014
8112
  /* @__PURE__ */ jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsx(WorkflowTimeTravelForm, { stepKey, closeModal: () => setIsTimeTravelOpen(false) }) })
8015
8113
  ] }) })
8016
8114
  ] }),
8115
+ showDebugMode && /* @__PURE__ */ jsxs(Fragment, { children: [
8116
+ /* @__PURE__ */ jsx(
8117
+ Button$1,
8118
+ {
8119
+ onClick: () => {
8120
+ if (mapConfig) {
8121
+ handleRunMapStep();
8122
+ } else {
8123
+ setIsPerStepRunOpen(true);
8124
+ }
8125
+ },
8126
+ children: "Run step"
8127
+ }
8128
+ ),
8129
+ /* @__PURE__ */ jsx(Dialog, { open: isPerStepRunOpen, onOpenChange: setIsPerStepRunOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8130
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8131
+ "Run step ",
8132
+ stepKey
8133
+ ] }),
8134
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsx(
8135
+ WorkflowTimeTravelForm,
8136
+ {
8137
+ stepKey,
8138
+ closeModal: () => setIsPerStepRunOpen(false),
8139
+ isPerStepRun: true,
8140
+ buttonText: "Run step",
8141
+ inputData: stepPayload?.input
8142
+ }
8143
+ ) })
8144
+ ] }) }),
8145
+ /* @__PURE__ */ jsx(
8146
+ Button$1,
8147
+ {
8148
+ onClick: () => {
8149
+ if (mapConfig) {
8150
+ handleRunMapStep(true);
8151
+ } else {
8152
+ setIsContinueRunOpen(true);
8153
+ }
8154
+ },
8155
+ children: "Continue run"
8156
+ }
8157
+ ),
8158
+ /* @__PURE__ */ jsx(Dialog, { open: isContinueRunOpen, onOpenChange: setIsContinueRunOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
8159
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
8160
+ "Continue run ",
8161
+ stepKey
8162
+ ] }),
8163
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-scroll max-h-[600px]", children: /* @__PURE__ */ jsx(
8164
+ WorkflowTimeTravelForm,
8165
+ {
8166
+ stepKey,
8167
+ closeModal: () => setIsContinueRunOpen(false),
8168
+ isContinueRun: true,
8169
+ buttonText: "Continue run",
8170
+ inputData: stepPayload?.input
8171
+ }
8172
+ ) })
8173
+ ] }) })
8174
+ ] }),
8017
8175
  mapConfig && /* @__PURE__ */ jsx(Button$1, { onClick: handleMapConfigClick, className: cn(isMapConfigOpen && activeButtonClass), children: "Map config" }),
8018
8176
  input && /* @__PURE__ */ jsxs(Fragment, { children: [
8019
8177
  /* @__PURE__ */ jsx(Button$1, { onClick: () => setIsInputOpen(true), children: "Input" }),
@@ -8246,7 +8404,11 @@ const Clock = ({ startedAt, endedAt }) => {
8246
8404
  ] });
8247
8405
  };
8248
8406
 
8249
- function WorkflowDefaultNode({ data, parentWorkflowName }) {
8407
+ function WorkflowDefaultNode({
8408
+ data,
8409
+ parentWorkflowName,
8410
+ stepsFlow
8411
+ }) {
8250
8412
  const { steps } = useCurrentRun();
8251
8413
  const {
8252
8414
  label,
@@ -8346,7 +8508,8 @@ function WorkflowDefaultNode({ data, parentWorkflowName }) {
8346
8508
  tripwire: isTripwire ? step?.tripwire : void 0,
8347
8509
  mapConfig,
8348
8510
  status: displayStatus,
8349
- stepKey
8511
+ stepKey,
8512
+ stepsFlow
8350
8513
  }
8351
8514
  )
8352
8515
  ]
@@ -8409,36 +8572,13 @@ function WorkflowLoopResultNode({ data }) {
8409
8572
  );
8410
8573
  }
8411
8574
 
8412
- const WorkflowNestedGraphContext = createContext(
8413
- {}
8414
- );
8415
- function WorkflowNestedGraphProvider({ children }) {
8416
- const { showNestedGraph: showNestedGraphInPanel, closeStepDetail } = useWorkflowStepDetail();
8417
- const showNestedGraph = ({
8418
- label,
8419
- stepGraph,
8420
- fullStep
8421
- }) => {
8422
- showNestedGraphInPanel({ label, stepGraph, fullStep });
8423
- };
8424
- const closeNestedGraph = () => {
8425
- closeStepDetail();
8426
- };
8427
- return /* @__PURE__ */ jsx(
8428
- WorkflowNestedGraphContext.Provider,
8429
- {
8430
- value: {
8431
- showNestedGraph,
8432
- closeNestedGraph
8433
- },
8434
- children
8435
- }
8436
- );
8437
- }
8438
-
8439
- function WorkflowNestedNode({ data, parentWorkflowName }) {
8575
+ function WorkflowNestedNode({
8576
+ data,
8577
+ parentWorkflowName,
8578
+ stepsFlow
8579
+ }) {
8440
8580
  const { steps } = useCurrentRun();
8441
- const { showNestedGraph } = useContext(WorkflowNestedGraphContext);
8581
+ const { showNestedGraph } = useWorkflowStepDetail();
8442
8582
  const {
8443
8583
  label,
8444
8584
  stepId,
@@ -8520,7 +8660,8 @@ function WorkflowNestedNode({ data, parentWorkflowName }) {
8520
8660
  mapConfig,
8521
8661
  onShowNestedGraph: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }),
8522
8662
  status: displayStatus,
8523
- stepKey
8663
+ stepKey,
8664
+ stepsFlow
8524
8665
  }
8525
8666
  )
8526
8667
  ]
@@ -8577,12 +8718,28 @@ function WorkflowGraphInner({ workflow }) {
8577
8718
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
8578
8719
  const [edges] = useEdgesState(initialEdges);
8579
8720
  const { steps } = useCurrentRun();
8721
+ const stepsFlow = useMemo(() => {
8722
+ return initialEdges.reduce(
8723
+ (acc, edge) => {
8724
+ if (edge.data) {
8725
+ const stepId = edge.data.nextStepId;
8726
+ const prevStepId = edge.data.previousStepId;
8727
+ return {
8728
+ ...acc,
8729
+ [stepId]: [.../* @__PURE__ */ new Set([...acc[stepId] || [], prevStepId])]
8730
+ };
8731
+ }
8732
+ return acc;
8733
+ },
8734
+ {}
8735
+ );
8736
+ }, [initialEdges]);
8580
8737
  const nodeTypes = {
8581
- "default-node": WorkflowDefaultNode,
8738
+ "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { ...props, stepsFlow }),
8582
8739
  "condition-node": WorkflowConditionNode,
8583
8740
  "after-node": WorkflowAfterNode,
8584
8741
  "loop-result-node": WorkflowLoopResultNode,
8585
- "nested-node": WorkflowNestedNode
8742
+ "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { ...props, stepsFlow })
8586
8743
  };
8587
8744
  return /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface1", children: /* @__PURE__ */ jsxs(
8588
8745
  ReactFlow,
@@ -8611,6 +8768,33 @@ function WorkflowGraphInner({ workflow }) {
8611
8768
  ) });
8612
8769
  }
8613
8770
 
8771
+ const WorkflowNestedGraphContext = createContext(
8772
+ {}
8773
+ );
8774
+ function WorkflowNestedGraphProvider({ children }) {
8775
+ const { showNestedGraph: showNestedGraphInPanel, closeStepDetail } = useWorkflowStepDetail();
8776
+ const showNestedGraph = ({
8777
+ label,
8778
+ stepGraph,
8779
+ fullStep
8780
+ }) => {
8781
+ showNestedGraphInPanel({ label, stepGraph, fullStep });
8782
+ };
8783
+ const closeNestedGraph = () => {
8784
+ closeStepDetail();
8785
+ };
8786
+ return /* @__PURE__ */ jsx(
8787
+ WorkflowNestedGraphContext.Provider,
8788
+ {
8789
+ value: {
8790
+ showNestedGraph,
8791
+ closeNestedGraph
8792
+ },
8793
+ children
8794
+ }
8795
+ );
8796
+ }
8797
+
8614
8798
  function WorkflowGraph({ workflowId, workflow, isLoading }) {
8615
8799
  const { snapshot } = useContext(WorkflowRunContext);
8616
8800
  if (isLoading) {
@@ -9499,7 +9683,7 @@ const PlaygroundTabs = ({
9499
9683
  setInternalTab(typedValue);
9500
9684
  }
9501
9685
  };
9502
- return /* @__PURE__ */ jsx(Tabs$1, { value: currentTab, onValueChange: handleTabChange, className: cn("h-full", className), children });
9686
+ return /* @__PURE__ */ jsx(Tabs$1, { value: currentTab, onValueChange: handleTabChange, className: cn("h-full overflow-x-auto", className), children });
9503
9687
  };
9504
9688
  const TabList$1 = ({ children, className }) => {
9505
9689
  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 }) });
@@ -9533,9 +9717,17 @@ const TabContent$1 = ({ children, value }) => {
9533
9717
  return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-auto flex flex-col", children });
9534
9718
  };
9535
9719
 
9720
+ const WorkflowRunOptions = () => {
9721
+ const { debugMode, setDebugMode } = useContext(WorkflowRunContext);
9722
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9723
+ /* @__PURE__ */ jsx(Txt, { as: "h3", variant: "ui-md", className: "text-icon3", children: "Debug Mode" }),
9724
+ /* @__PURE__ */ jsx(Checkbox, { checked: debugMode, onCheckedChange: (value) => setDebugMode(value) })
9725
+ ] });
9726
+ };
9727
+
9536
9728
  const TracingRunOptions = () => {
9537
9729
  const theme = useCodemirrorTheme$1();
9538
- const { settings, setSettings } = useTracingSettings();
9730
+ const { settings, setSettings, entityType } = useTracingSettings();
9539
9731
  const handleChange = (value) => {
9540
9732
  if (!value) {
9541
9733
  return setSettings({ ...settings, tracingOptions: void 0 });
@@ -9564,7 +9756,8 @@ const TracingRunOptions = () => {
9564
9756
  extensions: [jsonLanguage],
9565
9757
  className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
9566
9758
  }
9567
- )
9759
+ ),
9760
+ entityType === "workflow" && /* @__PURE__ */ jsx(WorkflowRunOptions, {})
9568
9761
  ] });
9569
9762
  };
9570
9763
 
@@ -9595,12 +9788,28 @@ function WorkflowNestedGraph({ stepGraph, open, workflowName }) {
9595
9788
  const [nodes, _, onNodesChange] = useNodesState(initialNodes);
9596
9789
  const [edges] = useEdgesState(initialEdges);
9597
9790
  const { steps } = useCurrentRun();
9791
+ const stepsFlow = useMemo(() => {
9792
+ return initialEdges.reduce(
9793
+ (acc, edge) => {
9794
+ if (edge.data) {
9795
+ const stepId = edge.data.nextStepId;
9796
+ const prevStepId = edge.data.previousStepId;
9797
+ return {
9798
+ ...acc,
9799
+ [stepId]: [.../* @__PURE__ */ new Set([...acc[stepId] || [], prevStepId])]
9800
+ };
9801
+ }
9802
+ return acc;
9803
+ },
9804
+ {}
9805
+ );
9806
+ }, [initialEdges]);
9598
9807
  const nodeTypes = {
9599
- "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props }),
9808
+ "default-node": (props) => /* @__PURE__ */ jsx(WorkflowDefaultNode, { parentWorkflowName: workflowName, ...props, stepsFlow }),
9600
9809
  "condition-node": WorkflowConditionNode,
9601
9810
  "after-node": WorkflowAfterNode,
9602
9811
  "loop-result-node": WorkflowLoopResultNode,
9603
- "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props })
9812
+ "nested-node": (props) => /* @__PURE__ */ jsx(WorkflowNestedNode, { parentWorkflowName: workflowName, ...props, stepsFlow })
9604
9813
  };
9605
9814
  useEffect(() => {
9606
9815
  if (open) {
@@ -9670,7 +9879,7 @@ function WorkflowStepDetailContent() {
9670
9879
  open: true,
9671
9880
  workflowName: stepDetail.nestedGraph.fullStep
9672
9881
  }
9673
- ) }) })
9882
+ ) }, stepDetail.nestedGraph.fullStep) })
9674
9883
  ] })
9675
9884
  ] });
9676
9885
  }
@@ -10011,6 +10220,162 @@ function WorkflowCombobox({
10011
10220
  );
10012
10221
  }
10013
10222
 
10223
+ function MainContentLayout({
10224
+ children,
10225
+ className,
10226
+ style
10227
+ }) {
10228
+ const devStyleRequested = devUIStyleRequested("MainContentLayout");
10229
+ return /* @__PURE__ */ jsx(
10230
+ "main",
10231
+ {
10232
+ className: cn(`grid grid-rows-[auto_1fr] h-full items-start content-start`, className),
10233
+ style: { ...style, ...devStyleRequested ? { border: "3px dotted red" } : {} },
10234
+ children
10235
+ }
10236
+ );
10237
+ }
10238
+ function MainContentContent({
10239
+ children,
10240
+ className,
10241
+ isCentered = false,
10242
+ isDivided = false,
10243
+ hasLeftServiceColumn = false,
10244
+ style
10245
+ }) {
10246
+ const devStyleRequested = devUIStyleRequested("MainContentContent");
10247
+ const contentClassName = getMainContentContentClassName({ isCentered, isDivided, hasLeftServiceColumn, className });
10248
+ return /* @__PURE__ */ jsx(
10249
+ "div",
10250
+ {
10251
+ className: contentClassName,
10252
+ style: { ...style, ...devStyleRequested ? { border: "3px dotted orange" } : {} },
10253
+ children
10254
+ }
10255
+ );
10256
+ }
10257
+ const getMainContentContentClassName = ({
10258
+ isCentered,
10259
+ isDivided,
10260
+ hasLeftServiceColumn,
10261
+ className
10262
+ }) => {
10263
+ return cn(
10264
+ `grid overflow-y-auto h-full `,
10265
+ `overflow-x-auto min-w-[min-content]`,
10266
+ {
10267
+ "items-start content-start": !isCentered && !isDivided && !hasLeftServiceColumn,
10268
+ "grid place-items-center": isCentered,
10269
+ "grid-cols-[1fr_1fr]": isDivided && !hasLeftServiceColumn,
10270
+ "grid-cols-[12rem_1fr_1fr]": isDivided && hasLeftServiceColumn,
10271
+ "grid-cols-[auto_1fr]": !isDivided && hasLeftServiceColumn
10272
+ },
10273
+ className
10274
+ );
10275
+ };
10276
+ function devUIStyleRequested(name) {
10277
+ try {
10278
+ const raw = localStorage.getItem("add-dev-style-to-components");
10279
+ if (!raw) return false;
10280
+ const components = raw.split(",").map((c) => c.trim()).filter(Boolean);
10281
+ return components.includes(name);
10282
+ } catch (error) {
10283
+ console.error("Error reading or parsing localStorage:", error);
10284
+ return false;
10285
+ }
10286
+ }
10287
+
10288
+ const PanelSeparator = () => {
10289
+ return /* @__PURE__ */ jsx(
10290
+ Separator,
10291
+ {
10292
+ className: clsx(
10293
+ "w-1.5 bg-surface3",
10294
+ "[&[data-separator='hover']]:!bg-surface4",
10295
+ "[&[data-separator='active']]:!bg-surface5",
10296
+ "focus:outline-none"
10297
+ )
10298
+ }
10299
+ );
10300
+ };
10301
+
10302
+ const CollapsiblePanel = ({ collapsedSize, children, direction, ...props }) => {
10303
+ const [collapsed, setCollapsed] = useState(false);
10304
+ const panelRef = usePanelRef();
10305
+ const expand = () => {
10306
+ if (!panelRef.current) return;
10307
+ panelRef.current.expand();
10308
+ };
10309
+ return /* @__PURE__ */ jsx(
10310
+ Panel$1,
10311
+ {
10312
+ panelRef,
10313
+ collapsedSize,
10314
+ ...props,
10315
+ onResize: (size) => {
10316
+ if (!collapsedSize) return;
10317
+ if (typeof collapsedSize !== "number") return;
10318
+ if (size.inPixels <= collapsedSize) {
10319
+ setCollapsed(true);
10320
+ } else if (collapsed) {
10321
+ setCollapsed(false);
10322
+ }
10323
+ },
10324
+ children: collapsed ? /* @__PURE__ */ jsxs(Tooltip, { children: [
10325
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button$1, { onClick: expand, className: "!h-48 border-none", children: /* @__PURE__ */ jsx(Icon, { children: direction === "left" ? /* @__PURE__ */ jsx(ArrowRight, {}) : /* @__PURE__ */ jsx(ArrowLeft, {}) }) }) }) }),
10326
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Expand" })
10327
+ ] }) : children
10328
+ }
10329
+ );
10330
+ };
10331
+
10332
+ const WorkflowLayout = ({ workflowId, children, leftSlot, rightSlot }) => {
10333
+ const { defaultLayout, onLayoutChange } = useDefaultLayout({
10334
+ id: `workflow-layout-${workflowId}`,
10335
+ storage: localStorage
10336
+ });
10337
+ const computedClassName = getMainContentContentClassName({
10338
+ isCentered: false,
10339
+ isDivided: true,
10340
+ hasLeftServiceColumn: Boolean(leftSlot)
10341
+ });
10342
+ return /* @__PURE__ */ jsxs(Group, { className: computedClassName, defaultLayout, onLayoutChange, children: [
10343
+ leftSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
10344
+ /* @__PURE__ */ jsx(
10345
+ CollapsiblePanel,
10346
+ {
10347
+ direction: "left",
10348
+ id: "left-slot",
10349
+ minSize: 200,
10350
+ maxSize: "30%",
10351
+ defaultSize: 200,
10352
+ collapsedSize: 60,
10353
+ collapsible: true,
10354
+ children: leftSlot
10355
+ }
10356
+ ),
10357
+ /* @__PURE__ */ jsx(PanelSeparator, {})
10358
+ ] }),
10359
+ /* @__PURE__ */ jsx(Panel$1, { id: "main-slot", children }),
10360
+ rightSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
10361
+ /* @__PURE__ */ jsx(PanelSeparator, {}),
10362
+ /* @__PURE__ */ jsx(
10363
+ CollapsiblePanel,
10364
+ {
10365
+ direction: "right",
10366
+ id: "right-slot",
10367
+ minSize: 300,
10368
+ maxSize: "50%",
10369
+ defaultSize: 300,
10370
+ collapsedSize: 60,
10371
+ collapsible: true,
10372
+ children: rightSlot
10373
+ }
10374
+ )
10375
+ ] })
10376
+ ] });
10377
+ };
10378
+
10014
10379
  const LoadingBadge = () => {
10015
10380
  return /* @__PURE__ */ jsx(
10016
10381
  BadgeWrapper,
@@ -13708,62 +14073,6 @@ const CombinedButtons = ({ className, children }) => {
13708
14073
  );
13709
14074
  };
13710
14075
 
13711
- function MainContentLayout({
13712
- children,
13713
- className,
13714
- style
13715
- }) {
13716
- const devStyleRequested = devUIStyleRequested("MainContentLayout");
13717
- return /* @__PURE__ */ jsx(
13718
- "main",
13719
- {
13720
- className: cn(`grid grid-rows-[auto_1fr] h-full items-start content-start`, className),
13721
- style: { ...style, ...devStyleRequested ? { border: "3px dotted red" } : {} },
13722
- children
13723
- }
13724
- );
13725
- }
13726
- function MainContentContent({
13727
- children,
13728
- className,
13729
- isCentered = false,
13730
- isDivided = false,
13731
- hasLeftServiceColumn = false,
13732
- style
13733
- }) {
13734
- const devStyleRequested = devUIStyleRequested("MainContentContent");
13735
- return /* @__PURE__ */ jsx(
13736
- "div",
13737
- {
13738
- className: cn(
13739
- `grid overflow-y-auto h-full `,
13740
- `overflow-x-auto min-w-[min-content]`,
13741
- {
13742
- "items-start content-start": !isCentered && !isDivided && !hasLeftServiceColumn,
13743
- "grid place-items-center": isCentered,
13744
- "grid-cols-[1fr_1fr]": isDivided && !hasLeftServiceColumn,
13745
- "grid-cols-[12rem_1fr_1fr]": isDivided && hasLeftServiceColumn,
13746
- "grid-cols-[auto_1fr]": !isDivided && hasLeftServiceColumn
13747
- },
13748
- className
13749
- ),
13750
- style: { ...style, ...devStyleRequested ? { border: "3px dotted orange" } : {} },
13751
- children
13752
- }
13753
- );
13754
- }
13755
- function devUIStyleRequested(name) {
13756
- try {
13757
- const raw = localStorage.getItem("add-dev-style-to-components");
13758
- if (!raw) return false;
13759
- const components = raw.split(",").map((c) => c.trim()).filter(Boolean);
13760
- return components.includes(name);
13761
- } catch (error) {
13762
- console.error("Error reading or parsing localStorage:", error);
13763
- return false;
13764
- }
13765
- }
13766
-
13767
14076
  function ButtonsGroup({ children, className }) {
13768
14077
  return /* @__PURE__ */ jsx("div", { className: cn(`flex gap-2 items-center`, "[&>button]:flex-grow", className), children });
13769
14078
  }
@@ -16057,7 +16366,7 @@ const AgentEntityHeader = ({ agentId }) => {
16057
16366
  };
16058
16367
 
16059
16368
  const Threads = ({ children }) => {
16060
- return /* @__PURE__ */ jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
16369
+ return /* @__PURE__ */ jsx("nav", { className: "bg-surface2 min-h-full overflow-hidden", children });
16061
16370
  };
16062
16371
  const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
16063
16372
  return /* @__PURE__ */ jsx(
@@ -17171,7 +17480,7 @@ const useAgentInformationSettings = ({ modelId }) => {
17171
17480
  const AgentInformationLayout = ({ children, agentId }) => {
17172
17481
  const { data: agent } = useAgent(agentId);
17173
17482
  useAgentInformationSettings({ modelId: agent?.modelId || "" });
17174
- return /* @__PURE__ */ jsx("div", { className: "grid grid-rows-[auto_1fr] h-full items-start overflow-y-auto border-l-sm border-border1", children });
17483
+ return /* @__PURE__ */ jsx("div", { className: "grid grid-rows-[auto_1fr] h-full items-start overflow-y-auto", children });
17175
17484
  };
17176
17485
  const AgentInformationTabLayout = ({ children, agentId }) => {
17177
17486
  const { data: memory, isLoading: isMemoryLoading } = useMemory(agentId);
@@ -17183,6 +17492,53 @@ const AgentInformationTabLayout = ({ children, agentId }) => {
17183
17492
  return /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsx(PlaygroundTabs, { defaultTab: "overview", value: selectedTab, onValueChange: handleTabChange, children }) });
17184
17493
  };
17185
17494
 
17495
+ const AgentLayout = ({ agentId, children, leftSlot, rightSlot }) => {
17496
+ const { defaultLayout, onLayoutChange } = useDefaultLayout({
17497
+ id: `agent-layout-${agentId}`,
17498
+ storage: localStorage
17499
+ });
17500
+ const computedClassName = getMainContentContentClassName({
17501
+ isCentered: false,
17502
+ isDivided: true,
17503
+ hasLeftServiceColumn: Boolean(leftSlot)
17504
+ });
17505
+ return /* @__PURE__ */ jsxs(Group, { className: computedClassName, defaultLayout, onLayoutChange, children: [
17506
+ leftSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
17507
+ /* @__PURE__ */ jsx(
17508
+ CollapsiblePanel,
17509
+ {
17510
+ direction: "left",
17511
+ id: "left-slot",
17512
+ minSize: 200,
17513
+ maxSize: "30%",
17514
+ defaultSize: 200,
17515
+ collapsedSize: 60,
17516
+ collapsible: true,
17517
+ children: leftSlot
17518
+ }
17519
+ ),
17520
+ /* @__PURE__ */ jsx(PanelSeparator, {})
17521
+ ] }),
17522
+ /* @__PURE__ */ jsx(Panel$1, { id: "main-slot", className: "grid overflow-y-auto relative bg-surface1 py-4", children }),
17523
+ rightSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
17524
+ /* @__PURE__ */ jsx(PanelSeparator, {}),
17525
+ /* @__PURE__ */ jsx(
17526
+ CollapsiblePanel,
17527
+ {
17528
+ direction: "right",
17529
+ id: "right-slot",
17530
+ minSize: 300,
17531
+ maxSize: "50%",
17532
+ defaultSize: 300,
17533
+ collapsedSize: 60,
17534
+ collapsible: true,
17535
+ children: rightSlot
17536
+ }
17537
+ )
17538
+ ] })
17539
+ ] });
17540
+ };
17541
+
17186
17542
  const NameCell$1 = ({ row }) => {
17187
17543
  const { Link, paths } = useLinkComponent();
17188
17544
  const tool = row.original;
@@ -18150,7 +18506,7 @@ const formatHierarchicalSpans = (spans) => {
18150
18506
  });
18151
18507
  spans.forEach((spanRecord) => {
18152
18508
  const uiSpan = spanMap.get(spanRecord.spanId);
18153
- if (spanRecord?.parentSpanId === null) {
18509
+ if (spanRecord?.parentSpanId == null) {
18154
18510
  if (overallEndDate && uiSpan.endTime && overallEndDate > new Date(uiSpan.endTime)) {
18155
18511
  uiSpan.endTime = overallEndDate.toISOString();
18156
18512
  const overallEndTime = new Date(overallEndDate).getTime();
@@ -18745,17 +19101,21 @@ function useTraceInfo(trace) {
18745
19101
  }
18746
19102
  const agentsLink = paths.agentsLink();
18747
19103
  const workflowsLink = paths.workflowsLink();
18748
- const agentLink = paths.agentLink(trace?.metadata?.resourceId);
18749
- const workflowLink = paths.workflowLink(trace?.attributes?.workflowId);
19104
+ const entityId = trace.entityId;
19105
+ const entityType = trace.entityType;
19106
+ const entityName = trace.entityName;
19107
+ const isAgent = entityType === "agent";
19108
+ const isWorkflow = entityType === "workflow_run";
19109
+ const entityLink = isAgent && entityId ? paths.agentLink(entityId) : isWorkflow && entityId ? paths.workflowLink(entityId) : void 0;
18750
19110
  return [
18751
19111
  {
18752
19112
  key: "entityId",
18753
19113
  label: "Entity Id",
18754
19114
  value: [
18755
19115
  {
18756
- id: trace?.metadata?.resourceId,
18757
- name: trace?.attributes?.agentId || trace?.attributes?.workflowId || "-",
18758
- path: trace?.attributes?.agentId ? agentLink : trace?.attributes?.workflowId ? workflowLink : void 0
19116
+ id: entityId ?? "unknown",
19117
+ name: entityName || entityId || "-",
19118
+ path: entityLink
18759
19119
  }
18760
19120
  ]
18761
19121
  },
@@ -18764,9 +19124,9 @@ function useTraceInfo(trace) {
18764
19124
  label: "Entity Type",
18765
19125
  value: [
18766
19126
  {
18767
- id: trace?.attributes?.agentId || trace?.attributes?.workflowId,
18768
- name: trace?.attributes?.agentId ? "Agent" : trace?.attributes?.workflowId ? "Workflow" : "-",
18769
- path: trace?.attributes?.agentId ? agentsLink : trace?.attributes?.workflowId ? workflowsLink : void 0
19127
+ id: entityType ?? "unknown",
19128
+ name: entityType ?? "-",
19129
+ path: isAgent ? agentsLink : isWorkflow ? workflowsLink : void 0
18770
19130
  }
18771
19131
  ]
18772
19132
  },
@@ -18808,11 +19168,12 @@ function getSpanInfo({ span }) {
18808
19168
  value: span?.endedAt ? format(new Date(span.endedAt), "MMM dd, h:mm:ss.SSS aaa") : "-"
18809
19169
  }
18810
19170
  ];
18811
- if (span?.attributes?.finishReason) {
19171
+ const finishReason = span?.attributes?.finishReason;
19172
+ if (finishReason) {
18812
19173
  baseInfo.push({
18813
19174
  key: "finishReason",
18814
19175
  label: "Finish Reason",
18815
- value: span.attributes.finishReason
19176
+ value: finishReason
18816
19177
  });
18817
19178
  }
18818
19179
  return baseInfo;
@@ -18915,9 +19276,10 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18915
19276
  return null;
18916
19277
  }
18917
19278
  const generationSpans = traceSpans.filter((span) => span.spanType === "model_generation");
18918
- const hasV5Format = generationSpans.some(
18919
- (span) => span.attributes?.usage?.inputTokens !== void 0 || span.attributes?.usage?.outputTokens !== void 0
18920
- );
19279
+ const hasV5Format = generationSpans.some((span) => {
19280
+ const usage = span.attributes?.usage;
19281
+ return usage && "inputTokens" in usage;
19282
+ });
18921
19283
  const tokensByProvider = generationSpans.reduce(
18922
19284
  (acc, span) => {
18923
19285
  const spanUsage2 = span.attributes?.usage || {};
@@ -18945,8 +19307,8 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
18945
19307
  const v5Acc = acc[spanModelProvider];
18946
19308
  v5Acc.inputTokens += inputTokens;
18947
19309
  v5Acc.outputTokens += outputTokens;
18948
- v5Acc.reasoningTokens += reasoningTokens;
18949
- v5Acc.cachedInputTokens += cachedInputTokens;
19310
+ v5Acc.reasoningTokens = (v5Acc.reasoningTokens ?? 0) + reasoningTokens;
19311
+ v5Acc.cachedInputTokens = (v5Acc.cachedInputTokens ?? 0) + cachedInputTokens;
18950
19312
  v5Acc.totalTokens += spanUsage2.totalTokens || inputTokens + outputTokens;
18951
19313
  } else if ("promptTokens" in acc[spanModelProvider] && !hasV5Format) {
18952
19314
  const promptTokens = spanUsage2.promptTokens ?? 0;
@@ -19203,7 +19565,7 @@ function SpanTabs({
19203
19565
  ] })
19204
19566
  ] }),
19205
19567
  /* @__PURE__ */ jsx(Tabs.Content, { value: "details", children: /* @__PURE__ */ jsxs(Sections, { children: [
19206
- span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage }),
19568
+ span?.attributes?.usage ? /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage }) : null,
19207
19569
  /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link }),
19208
19570
  /* @__PURE__ */ jsx(SpanDetails, { span })
19209
19571
  ] }) }),
@@ -19737,7 +20099,7 @@ function TracesList({
19737
20099
  date: isTodayDate ? "Today" : format(createdAtDate, "MMM dd"),
19738
20100
  time: format(createdAtDate, "h:mm:ss aaa"),
19739
20101
  name: trace?.name,
19740
- entityId: trace?.attributes?.agentId || trace?.attributes?.workflowId,
20102
+ entityId: trace?.entityName || trace?.entityId || trace?.attributes?.agentId || trace?.attributes?.workflowId,
19741
20103
  status: trace?.attributes?.status
19742
20104
  };
19743
20105
  return /* @__PURE__ */ jsx(
@@ -19843,7 +20205,7 @@ function SpanScoreList({
19843
20205
  entry,
19844
20206
  children: traceScoresListColumns.map((col) => {
19845
20207
  const key = `col-${col.name}`;
19846
- return /* @__PURE__ */ jsx(EntryList.EntryText, { children: entry?.[col.name] }, key);
20208
+ return /* @__PURE__ */ jsx(EntryList.EntryText, { children: String(entry?.[col.name] ?? "") }, key);
19847
20209
  })
19848
20210
  },
19849
20211
  score.id
@@ -20685,6 +21047,292 @@ const StudioConfigForm = ({ initialConfig }) => {
20685
21047
  ] });
20686
21048
  };
20687
21049
 
21050
+ const useMastraPackages = () => {
21051
+ const client = useMastraClient();
21052
+ return useQuery({
21053
+ queryKey: ["mastra-packages"],
21054
+ queryFn: () => {
21055
+ return client.getSystemPackages();
21056
+ }
21057
+ });
21058
+ };
21059
+
21060
+ async function fetchPackageInfo(packageName, installedVersion) {
21061
+ const prereleaseComponents = semver.prerelease(installedVersion);
21062
+ const prereleaseTag = prereleaseComponents ? String(prereleaseComponents[0]) : null;
21063
+ try {
21064
+ const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`);
21065
+ if (!response.ok) {
21066
+ return {
21067
+ name: packageName,
21068
+ version: installedVersion,
21069
+ latestVersion: null,
21070
+ isOutdated: false,
21071
+ isDeprecated: false,
21072
+ prereleaseTag,
21073
+ targetPrereleaseTag: null
21074
+ };
21075
+ }
21076
+ const data = await response.json();
21077
+ const latestVersion = data["dist-tags"]?.latest ?? null;
21078
+ const versionInfo = data.versions?.[installedVersion];
21079
+ const deprecationMessage = versionInfo?.deprecated;
21080
+ const targetPrereleaseComponents = latestVersion ? semver.prerelease(latestVersion) : null;
21081
+ const targetPrereleaseTag = targetPrereleaseComponents ? String(targetPrereleaseComponents[0]) : null;
21082
+ let isOutdated = false;
21083
+ if (latestVersion !== null && semver.valid(installedVersion) && semver.valid(latestVersion)) {
21084
+ isOutdated = semver.gt(latestVersion, installedVersion);
21085
+ }
21086
+ return {
21087
+ name: packageName,
21088
+ version: installedVersion,
21089
+ latestVersion,
21090
+ isOutdated,
21091
+ isDeprecated: !!deprecationMessage,
21092
+ prereleaseTag,
21093
+ targetPrereleaseTag,
21094
+ deprecationMessage
21095
+ };
21096
+ } catch {
21097
+ return {
21098
+ name: packageName,
21099
+ version: installedVersion,
21100
+ latestVersion: null,
21101
+ isOutdated: false,
21102
+ isDeprecated: false,
21103
+ prereleaseTag,
21104
+ targetPrereleaseTag: null
21105
+ };
21106
+ }
21107
+ }
21108
+ function usePackageUpdates(packages) {
21109
+ const queries = useQueries({
21110
+ queries: packages.map((pkg) => ({
21111
+ queryKey: ["package-update", pkg.name, pkg.version],
21112
+ queryFn: () => fetchPackageInfo(pkg.name, pkg.version),
21113
+ staleTime: 1e3 * 60 * 60,
21114
+ // 1 hour - latest versions don't change often
21115
+ gcTime: 1e3 * 60 * 60 * 24
21116
+ // 24 hours
21117
+ }))
21118
+ });
21119
+ const isLoading = queries.some((q) => q.isLoading);
21120
+ const packageUpdates = queries.map((q) => q.data).filter((p) => p !== void 0);
21121
+ const allComplete = !isLoading && packageUpdates.length === packages.length;
21122
+ const outdatedCount = allComplete ? packageUpdates.filter((p) => p.isOutdated && !p.isDeprecated).length : 0;
21123
+ const deprecatedCount = allComplete ? packageUpdates.filter((p) => p.isDeprecated).length : 0;
21124
+ return {
21125
+ packages: packageUpdates,
21126
+ isLoading,
21127
+ outdatedCount,
21128
+ deprecatedCount
21129
+ };
21130
+ }
21131
+
21132
+ const packageManagerCommands = {
21133
+ pnpm: "pnpm add",
21134
+ npm: "npm install",
21135
+ yarn: "yarn add",
21136
+ bun: "bun add"
21137
+ };
21138
+ const MastraVersionFooter = ({ collapsed }) => {
21139
+ const { data, isLoading: isLoadingPackages } = useMastraPackages();
21140
+ const installedPackages = data?.packages ?? [];
21141
+ const {
21142
+ packages: packageUpdates,
21143
+ isLoading: isLoadingUpdates,
21144
+ outdatedCount,
21145
+ deprecatedCount
21146
+ } = usePackageUpdates(installedPackages);
21147
+ const [packageManager, setPackageManager] = useState("pnpm");
21148
+ if (collapsed) {
21149
+ return null;
21150
+ }
21151
+ if (isLoadingPackages) {
21152
+ return /* @__PURE__ */ jsx("div", { className: "px-3 py-2", children: /* @__PURE__ */ jsx("div", { className: "animate-pulse h-4 bg-surface2 rounded w-16" }) });
21153
+ }
21154
+ const mastraCorePackage = installedPackages.find((pkg) => pkg.name === "@mastra/core");
21155
+ if (!mastraCorePackage && installedPackages.length === 0) {
21156
+ return null;
21157
+ }
21158
+ const mainVersion = mastraCorePackage?.version ?? installedPackages[0]?.version ?? "";
21159
+ const updateCommand = generateUpdateCommand(packageUpdates, packageManager);
21160
+ return /* @__PURE__ */ jsxs(Dialog, { children: [
21161
+ /* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("button", { className: "px-3 py-2 hover:bg-surface2 transition-colors rounded w-full text-left", children: [
21162
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-accent1 font-mono", children: "mastra version:" }) }),
21163
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
21164
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-icon3 font-mono", children: mainVersion }),
21165
+ isLoadingUpdates && /* @__PURE__ */ jsx(Spinner, { className: "w-3 h-3", color: "currentColor" }),
21166
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center -space-x-1.5", children: [
21167
+ outdatedCount > 0 && /* @__PURE__ */ jsx(CountBadge, { count: outdatedCount, variant: "warning" }),
21168
+ deprecatedCount > 0 && /* @__PURE__ */ jsx(CountBadge, { count: deprecatedCount, variant: "error" })
21169
+ ] })
21170
+ ] })
21171
+ ] }) }),
21172
+ /* @__PURE__ */ jsx(
21173
+ PackagesModalContent,
21174
+ {
21175
+ packages: packageUpdates,
21176
+ isLoadingUpdates,
21177
+ outdatedCount,
21178
+ deprecatedCount,
21179
+ updateCommand,
21180
+ packageManager,
21181
+ onPackageManagerChange: setPackageManager
21182
+ }
21183
+ )
21184
+ ] });
21185
+ };
21186
+ function generateUpdateCommand(packages, packageManager) {
21187
+ const outdatedPackages = packages.filter((p) => p.isOutdated || p.isDeprecated);
21188
+ if (outdatedPackages.length === 0) return null;
21189
+ const command = packageManagerCommands[packageManager];
21190
+ const packageArgs = outdatedPackages.map((p) => `${p.name}@${p.targetPrereleaseTag ?? "latest"}`).join(" ");
21191
+ return `${command} ${packageArgs}`;
21192
+ }
21193
+ function CountBadge({ count, variant }) {
21194
+ return /* @__PURE__ */ jsx(
21195
+ "span",
21196
+ {
21197
+ className: cn(
21198
+ "inline-flex items-center justify-center min-w-[1.125rem] h-[1.125rem] px-1 rounded-full text-[0.625rem] font-bold text-black",
21199
+ variant === "error" ? "bg-red-700" : "bg-yellow-700"
21200
+ ),
21201
+ children: count
21202
+ }
21203
+ );
21204
+ }
21205
+ function StatusBadge({ value, variant }) {
21206
+ return /* @__PURE__ */ jsx(
21207
+ "span",
21208
+ {
21209
+ className: cn(
21210
+ "inline-flex font-bold rounded-md px-1.5 py-0.5 items-center justify-center text-black text-xs min-w-[1.25rem]",
21211
+ variant === "error" ? "bg-red-700" : "bg-yellow-700"
21212
+ ),
21213
+ children: value
21214
+ }
21215
+ );
21216
+ }
21217
+ const PackagesModalContent = ({
21218
+ packages,
21219
+ isLoadingUpdates,
21220
+ outdatedCount,
21221
+ deprecatedCount,
21222
+ updateCommand,
21223
+ packageManager,
21224
+ onPackageManagerChange
21225
+ }) => {
21226
+ const hasUpdates = outdatedCount > 0 || deprecatedCount > 0;
21227
+ const packagesText = packages.map((pkg) => `${pkg.name}@${pkg.version}`).join("\n");
21228
+ const { isCopied: isCopiedAll, handleCopy: handleCopyAll } = useCopyToClipboard({
21229
+ text: packagesText,
21230
+ copyMessage: "Copied package versions!"
21231
+ });
21232
+ const { isCopied: isCopiedCommand, handleCopy: handleCopyCommand } = useCopyToClipboard({
21233
+ text: updateCommand ?? "",
21234
+ copyMessage: "Copied update command!"
21235
+ });
21236
+ return /* @__PURE__ */ jsxs(DialogContent, { className: "bg-surface1 border-border1 max-w-2xl", children: [
21237
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-text1", children: "Installed Mastra Packages" }) }),
21238
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-icon3 py-2", children: isLoadingUpdates ? /* @__PURE__ */ jsx("span", { className: "text-icon3", children: "Checking for updates..." }) : !hasUpdates ? /* @__PURE__ */ jsx("span", { className: "text-accent1", children: "✓ All packages are up to date" }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
21239
+ outdatedCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
21240
+ /* @__PURE__ */ jsx(StatusBadge, { value: outdatedCount, variant: "warning" }),
21241
+ /* @__PURE__ */ jsxs("span", { children: [
21242
+ "package",
21243
+ outdatedCount !== 1 ? "s" : "",
21244
+ " outdated"
21245
+ ] })
21246
+ ] }),
21247
+ deprecatedCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
21248
+ /* @__PURE__ */ jsx(StatusBadge, { value: deprecatedCount, variant: "error" }),
21249
+ /* @__PURE__ */ jsxs("span", { children: [
21250
+ "package",
21251
+ deprecatedCount !== 1 ? "s" : "",
21252
+ " deprecated"
21253
+ ] })
21254
+ ] })
21255
+ ] }) }),
21256
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto border border-border1 rounded-md", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[1fr_auto_auto] text-sm", children: packages.map((pkg, index) => /* @__PURE__ */ jsxs("div", { className: cn("contents", index > 0 && "[&>div]:border-t [&>div]:border-border1"), children: [
21257
+ /* @__PURE__ */ jsx("div", { className: "py-2 px-3 font-mono text-text1 truncate min-w-0", children: /* @__PURE__ */ jsxs(
21258
+ "a",
21259
+ {
21260
+ href: `https://www.npmjs.com/package/${pkg.name}`,
21261
+ target: "_blank",
21262
+ rel: "noopener noreferrer",
21263
+ className: "hover:text-accent1 hover:underline inline-flex items-center gap-1 group",
21264
+ children: [
21265
+ pkg.name,
21266
+ /* @__PURE__ */ jsx(ExternalLink, { className: "w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" })
21267
+ ]
21268
+ }
21269
+ ) }),
21270
+ /* @__PURE__ */ jsx("div", { className: "py-2 px-3 font-mono text-icon3 flex items-center gap-1.5", children: pkg.isOutdated || pkg.isDeprecated ? /* @__PURE__ */ jsxs(Tooltip, { children: [
21271
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
21272
+ "span",
21273
+ {
21274
+ className: cn(
21275
+ "cursor-help",
21276
+ pkg.isDeprecated ? "text-red-500" : pkg.isOutdated ? "text-yellow-500" : ""
21277
+ ),
21278
+ children: pkg.version
21279
+ }
21280
+ ) }),
21281
+ /* @__PURE__ */ jsx(TooltipContent, { children: pkg.isDeprecated ? pkg.deprecationMessage || "This version is deprecated" : "Newer version available" })
21282
+ ] }) : /* @__PURE__ */ jsx("span", { children: pkg.version }) }),
21283
+ /* @__PURE__ */ jsx("div", { className: "py-2 px-3 font-mono text-icon3 flex items-center", children: (pkg.isOutdated || pkg.isDeprecated) && pkg.latestVersion && /* @__PURE__ */ jsxs(Fragment, { children: [
21284
+ /* @__PURE__ */ jsx(MoveRight, { className: "w-4 h-4 mx-2 text-icon3" }),
21285
+ /* @__PURE__ */ jsx("span", { className: "text-accent1", children: pkg.latestVersion })
21286
+ ] }) })
21287
+ ] }, pkg.name)) }) }),
21288
+ /* @__PURE__ */ jsxs(
21289
+ "button",
21290
+ {
21291
+ onClick: handleCopyAll,
21292
+ className: "flex items-center justify-center gap-2 w-full py-2 px-3 rounded bg-surface2 hover:bg-surface3 text-icon3 hover:text-icon1 transition-colors",
21293
+ children: [
21294
+ isCopiedAll ? /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-accent1" }) : /* @__PURE__ */ jsx(Copy, { className: "w-4 h-4" }),
21295
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", children: isCopiedAll ? "Copied!" : "Copy current versions" })
21296
+ ]
21297
+ }
21298
+ ),
21299
+ hasUpdates && updateCommand && /* @__PURE__ */ jsxs("div", { className: "space-y-3 pt-2 border-t border-border1", children: [
21300
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-icon3 pt-3", children: [
21301
+ /* @__PURE__ */ jsx(Info, { className: "w-4 h-4" }),
21302
+ /* @__PURE__ */ jsx("span", { children: "Use the command below to update your packages" })
21303
+ ] }),
21304
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
21305
+ /* @__PURE__ */ jsx(
21306
+ SelectField,
21307
+ {
21308
+ value: packageManager,
21309
+ onValueChange: (value) => onPackageManagerChange(value),
21310
+ options: [
21311
+ { label: "pnpm", value: "pnpm" },
21312
+ { label: "npm", value: "npm" },
21313
+ { label: "yarn", value: "yarn" },
21314
+ { label: "bun", value: "bun" }
21315
+ ]
21316
+ }
21317
+ ),
21318
+ /* @__PURE__ */ jsx("pre", { className: "flex-1 text-sm text-icon3 bg-surface2 rounded-md px-3 py-1.5 overflow-x-auto whitespace-pre-wrap break-all", children: updateCommand })
21319
+ ] }),
21320
+ /* @__PURE__ */ jsxs(
21321
+ "button",
21322
+ {
21323
+ onClick: handleCopyCommand,
21324
+ className: "flex items-center justify-center gap-2 w-full py-2 px-3 rounded bg-surface2 hover:bg-surface3 text-icon3 hover:text-icon1 transition-colors",
21325
+ children: [
21326
+ isCopiedCommand ? /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-accent1" }) : /* @__PURE__ */ jsx(Copy, { className: "w-4 h-4" }),
21327
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", children: isCopiedCommand ? "Copied!" : "Copy command" })
21328
+ ]
21329
+ }
21330
+ )
21331
+ ] })
21332
+ ] });
21333
+ };
21334
+ const MastraPackagesInfo = MastraVersionFooter;
21335
+
20688
21336
  const PlaygroundConfigGuard = () => {
20689
21337
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col h-screen w-full items-center justify-center bg-surface1", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md w-full mx-auto px-4 pt-4", children: [
20690
21338
  /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center pb-4", children: /* @__PURE__ */ jsx(LogoWithoutText, { className: "size-32" }) }),
@@ -20692,5 +21340,5 @@ const PlaygroundConfigGuard = () => {
20692
21340
  ] }) });
20693
21341
  };
20694
21342
 
20695
- 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 };
21343
+ export { AgentChat, AgentCoinIcon, AgentCombobox, AgentEntityHeader, AgentIcon, AgentInformation, AgentInformationLayout, AgentInformationTabLayout, AgentLayout, 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, MastraPackagesInfo, MastraVersionFooter, 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, WorkflowLayout, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowStepDetailContext, WorkflowStepDetailProvider, WorkflowTable, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, convertWorkflowRunStateToStreamResult, extractPrompt, formatHierarchicalSpans, getColumnTemplate, getMainContentContentClassName, 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, useMastraPackages, useMemory, useMemoryConfig, useMemorySearch, usePackageUpdates, usePlaygroundStore, useReorderModelList, useResetAgentModel, useScorer, useScorers, useScoresByScorerId, useSpeechRecognition, useStreamWorkflow, useStudioConfig, useThreadInput, useThreads, useTool, useTools, useTraceSpanScores, useTracingSettings, useUpdateAgentModel, useUpdateModelInModelList, useWorkflow, useWorkflowRunExecutionResult, useWorkflowRuns, useWorkflowStepDetail, useWorkflows, useWorkingMemory };
20696
21344
  //# sourceMappingURL=index.es.js.map