@mastra/playground-ui 6.5.2-alpha.0 → 6.6.0-alpha.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @mastra/playground-ui
2
2
 
3
+ ## 6.6.0-alpha.1
4
+
5
+ ### Minor Changes
6
+
7
+ - Update peer dependencies to match core package version bump (0.21.2) ([#9021](https://github.com/mastra-ai/mastra/pull/9021))
8
+
9
+ ### Patch Changes
10
+
11
+ - Handle nested optional objects in dynamic form ([#9059](https://github.com/mastra-ai/mastra/pull/9059))
12
+
13
+ - Move "Playground" to "Studio" in UI only ([#9052](https://github.com/mastra-ai/mastra/pull/9052))
14
+
15
+ - Show agent tool output better in playground ([#9021](https://github.com/mastra-ai/mastra/pull/9021))
16
+
17
+ - Update peerdeps to 0.23.0-0 ([#9043](https://github.com/mastra-ai/mastra/pull/9043))
18
+
19
+ - Updated dependencies [[`efb5ed9`](https://github.com/mastra-ai/mastra/commit/efb5ed946ae7f410bc68c9430beb4b010afd25ec), [`8ea07b4`](https://github.com/mastra-ai/mastra/commit/8ea07b4bdc73e4218437dbb6dcb0f4b23e745a44), [`ba201b8`](https://github.com/mastra-ai/mastra/commit/ba201b8f8feac4c72350f2dbd52c13c7297ba7b0), [`1f058c6`](https://github.com/mastra-ai/mastra/commit/1f058c63ccb88d718b9876490d17e112cc026467), [`4fc4136`](https://github.com/mastra-ai/mastra/commit/4fc413652866a8d2240694fddb2562e9edbb70df), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`d10baf5`](https://github.com/mastra-ai/mastra/commit/d10baf5a3c924f2a6654e23a3e318ed03f189b76), [`038c55a`](https://github.com/mastra-ai/mastra/commit/038c55a7090fc1b1513a966386d3072617f836ac), [`5ea29c6`](https://github.com/mastra-ai/mastra/commit/5ea29c6a72dc3a6c837076fd37ee54ebae77a02a), [`182f045`](https://github.com/mastra-ai/mastra/commit/182f0458f25bd70aa774e64fd923c8a483eddbf1), [`7620d2b`](https://github.com/mastra-ai/mastra/commit/7620d2bddeb4fae4c3c0a0b4e672969795fca11a), [`b2365f0`](https://github.com/mastra-ai/mastra/commit/b2365f038dd4c5f06400428b224af963f399ad50), [`9029ba3`](https://github.com/mastra-ai/mastra/commit/9029ba34459c8859fed4c6b73efd8e2d0021e7ba), [`426cc56`](https://github.com/mastra-ai/mastra/commit/426cc561c85ae76a112ded2385532a91f9f9f074), [`00931fb`](https://github.com/mastra-ai/mastra/commit/00931fb1a21aa42c4fbc20c2c40dd62466b8fc8f), [`e473bfe`](https://github.com/mastra-ai/mastra/commit/e473bfe416c0b8e876973c2b6a6f13c394b7a93f), [`b78e04d`](https://github.com/mastra-ai/mastra/commit/b78e04d935a16ecb1e59c5c96e564903527edddd), [`648e2ca`](https://github.com/mastra-ai/mastra/commit/648e2ca42da54838c6ccbdaadc6fadd808fa6b86), [`b65c5e0`](https://github.com/mastra-ai/mastra/commit/b65c5e0fe6f3c390a9a8bbcf69304d972c3a4afb)]:
20
+ - @mastra/core@0.22.0-alpha.1
21
+ - @mastra/react@0.0.8-alpha.1
22
+ - @mastra/client-js@0.16.2-alpha.1
23
+
3
24
  ## 6.5.2-alpha.0
4
25
 
5
26
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -4385,11 +4385,12 @@ const useCodemirrorTheme$2 = () => {
4385
4385
  };
4386
4386
  const SyntaxHighlighter$2 = ({
4387
4387
  data,
4388
- className
4388
+ className,
4389
+ ...props
4389
4390
  }) => {
4390
4391
  const formattedCode = JSON.stringify(data, null, 2);
4391
4392
  const theme = useCodemirrorTheme$2();
4392
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), children: [
4393
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), ...props, children: [
4393
4394
  /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: formattedCode, className: "absolute top-2 right-2 z-20" }),
4394
4395
  /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: formattedCode, theme, extensions: [langJson.jsonLanguage] })
4395
4396
  ] });
@@ -4550,11 +4551,11 @@ const ToolBadge = ({ toolName, args, result, metadata, toolOutput }) => {
4550
4551
  let argSlot = null;
4551
4552
  try {
4552
4553
  const { __mastraMetadata: _, ...formattedArgs } = typeof args === "object" ? args : JSON.parse(args);
4553
- argSlot = /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: formattedArgs });
4554
+ argSlot = /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: formattedArgs, "data-testid": "tool-args" });
4554
4555
  } catch {
4555
4556
  argSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: args });
4556
4557
  }
4557
- let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap bg-surface4 p-4 rounded-md", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result });
4558
+ let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap bg-surface4 p-4 rounded-md", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result, "data-testid": "tool-result" });
4558
4559
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
4559
4560
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
4560
4561
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -4581,7 +4582,7 @@ const ToolBadge = ({ toolName, args, result, metadata, toolOutput }) => {
4581
4582
  ] }),
4582
4583
  toolOutput.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4583
4584
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool output" }),
4584
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-40 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: toolOutput }) })
4585
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-40 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: toolOutput, "data-testid": "tool-output" }) })
4585
4586
  ] })
4586
4587
  ] })
4587
4588
  }
@@ -6641,12 +6642,16 @@ const SelectField$1 = ({ field, inputProps, error, id, value }) => {
6641
6642
 
6642
6643
  const ObjectWrapper = ({ label, children }) => {
6643
6644
  const hasLabel = label !== "​" && label !== "";
6645
+ const [isOpen, setIsOpen] = React.useState(false);
6644
6646
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "", children: [
6645
- hasLabel && /* @__PURE__ */ jsxRuntime.jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 flex items-center gap-1 pb-2", children: [
6646
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Braces, {}) }),
6647
- label
6647
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
6648
+ hasLabel && /* @__PURE__ */ jsxRuntime.jsxs(Txt, { as: "h3", variant: "ui-sm", className: "text-icon3 flex items-center gap-1 pb-2", children: [
6649
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Braces, {}) }),
6650
+ label
6651
+ ] }),
6652
+ /* @__PURE__ */ jsxRuntime.jsx(Button$1, { onClick: () => setIsOpen(!isOpen), type: "button", className: "ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("transition-all", isOpen ? "rotate-180" : "rotate-0") }) }) })
6648
6653
  ] }),
6649
- /* @__PURE__ */ jsxRuntime.jsx(
6654
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
6650
6655
  "div",
6651
6656
  {
6652
6657
  className: hasLabel ? "flex flex-col gap-1 [&>*]:border-dashed [&>*]:border-l [&>*]:border-l-border1 [&>*]:pl-4" : "",
@@ -7792,7 +7797,46 @@ const EmptyWorkflowsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { classN
7792
7797
  }
7793
7798
  ) });
7794
7799
 
7795
- const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming, metadata }) => {
7800
+ const LoadingBadge = () => {
7801
+ return /* @__PURE__ */ jsxRuntime.jsx(
7802
+ BadgeWrapper,
7803
+ {
7804
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { color: colors.IconColors.icon3 }),
7805
+ title: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "ml-2 w-12 h-2" }),
7806
+ collapsible: false
7807
+ }
7808
+ );
7809
+ };
7810
+
7811
+ const useInView = () => {
7812
+ const [inView, setInView] = React.useState(false);
7813
+ const setRef = React.useCallback((node) => {
7814
+ if (node) {
7815
+ const observer = new IntersectionObserver(([entry]) => {
7816
+ setInView(entry.isIntersecting);
7817
+ });
7818
+ observer.observe(node);
7819
+ return () => observer.disconnect();
7820
+ }
7821
+ }, []);
7822
+ return { inView, setRef };
7823
+ };
7824
+
7825
+ const useWorkflow = (workflowId) => {
7826
+ const client = react$3.useMastraClient();
7827
+ const { runtimeContext } = usePlaygroundStore();
7828
+ return reactQuery.useQuery({
7829
+ queryKey: ["workflow", workflowId],
7830
+ queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
7831
+ enabled: Boolean(workflowId),
7832
+ retry: false,
7833
+ refetchOnWindowFocus: false,
7834
+ throwOnError: false
7835
+ });
7836
+ };
7837
+
7838
+ const WorkflowBadge = ({ runId, workflowId, isStreaming, metadata }) => {
7839
+ const { data: workflow, isLoading: isWorkflowLoading } = useWorkflow(workflowId);
7796
7840
  const { data: runs, isLoading: isRunsLoading } = useWorkflowRuns(workflowId, {
7797
7841
  enabled: Boolean(runId) && !isStreaming
7798
7842
  });
@@ -7801,6 +7845,7 @@ const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming, metadata }) =
7801
7845
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
7802
7846
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
7803
7847
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
7848
+ if (isWorkflowLoading || !workflow) return /* @__PURE__ */ jsxRuntime.jsx(LoadingBadge, {});
7804
7849
  return /* @__PURE__ */ jsxRuntime.jsxs(
7805
7850
  BadgeWrapper,
7806
7851
  {
@@ -7827,7 +7872,7 @@ const WorkflowBadgeExtended = ({ workflowId, workflow, runId }) => {
7827
7872
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7828
7873
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pb-2", children: [
7829
7874
  /* @__PURE__ */ jsxRuntime.jsx(Button$1, { as: Link, href: `/workflows/${workflowId}/graph`, children: "Go to workflow" }),
7830
- /* @__PURE__ */ jsxRuntime.jsx(Button$1, { as: Link, href: `/workflows/${workflowId}/graph/${runId}`, children: "See run" })
7875
+ runId && /* @__PURE__ */ jsxRuntime.jsx(Button$1, { as: Link, href: `/workflows/${workflowId}/graph/${runId}`, children: "See run" })
7831
7876
  ] }),
7832
7877
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md overflow-hidden h-[60vh] w-full", children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowGraph, { workflowId, workflow }) })
7833
7878
  ] });
@@ -7840,30 +7885,6 @@ const useWorkflowStream = (workflowFullState) => {
7840
7885
  }, [workflowFullState]);
7841
7886
  };
7842
7887
 
7843
- const useWorkflow = (workflowId) => {
7844
- const client = react$3.useMastraClient();
7845
- const { runtimeContext } = usePlaygroundStore();
7846
- return reactQuery.useQuery({
7847
- queryKey: ["workflow", workflowId],
7848
- queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
7849
- enabled: Boolean(workflowId),
7850
- retry: false,
7851
- refetchOnWindowFocus: false,
7852
- throwOnError: false
7853
- });
7854
- };
7855
-
7856
- const LoadingBadge = () => {
7857
- return /* @__PURE__ */ jsxRuntime.jsx(
7858
- BadgeWrapper,
7859
- {
7860
- icon: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { color: colors.IconColors.icon3 }),
7861
- title: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "ml-2 w-12 h-2" }),
7862
- collapsible: false
7863
- }
7864
- );
7865
- };
7866
-
7867
7888
  const AgentBadge = ({ agentId, messages = [], metadata }) => {
7868
7889
  const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
7869
7890
  const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
@@ -7908,25 +7929,51 @@ const AgentBadge = ({ agentId, messages = [], metadata }) => {
7908
7929
  );
7909
7930
  };
7910
7931
 
7932
+ const useAgentMessages = ({
7933
+ threadId,
7934
+ agentId,
7935
+ memory
7936
+ }) => {
7937
+ const client = react$3.useMastraClient();
7938
+ return reactQuery.useQuery({
7939
+ queryKey: ["memory", "messages", threadId, agentId],
7940
+ queryFn: () => client.getThreadMessages(threadId, { agentId }),
7941
+ enabled: memory && Boolean(threadId),
7942
+ staleTime: 0,
7943
+ gcTime: 0,
7944
+ retry: false,
7945
+ refetchOnWindowFocus: false
7946
+ });
7947
+ };
7948
+
7949
+ const AgentBadgeWrapper = ({ agentId, result, metadata }) => {
7950
+ const { data: memoryMessages } = useAgentMessages({
7951
+ threadId: result?.subAgentThreadId ?? "",
7952
+ agentId,
7953
+ memory: true
7954
+ });
7955
+ const childMessages = result?.childMessages ?? react$3.resolveToChildMessages(memoryMessages?.uiMessages ?? []);
7956
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentBadge, { agentId, messages: childMessages, metadata });
7957
+ };
7958
+
7911
7959
  const ToolFallback = ({ toolName, result, args, ...props }) => {
7912
7960
  return /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolFallbackInner, { toolName, result, args, ...props }) });
7913
7961
  };
7914
7962
  const ToolFallbackInner = ({ toolName, result, args, metadata, ...props }) => {
7963
+ const isAgent = metadata?.mode === "network" && metadata.from === "AGENT" || toolName.startsWith("agent-");
7964
+ const isWorkflow = metadata?.mode === "network" && metadata.from === "WORKFLOW" || toolName.startsWith("workflow-");
7965
+ const agentToolName = toolName.startsWith("agent-") ? toolName.substring("agent-".length) : toolName;
7966
+ const workflowToolName = toolName.startsWith("workflow-") ? toolName.substring("workflow-".length) : toolName;
7915
7967
  useWorkflowStream(result);
7916
- const { data: workflow, isLoading } = useWorkflow(toolName);
7917
- const isAgent = metadata?.mode === "network" && metadata.from === "AGENT";
7918
7968
  if (isAgent) {
7919
- const messages = result?.childMessages ?? [];
7920
- return /* @__PURE__ */ jsxRuntime.jsx(AgentBadge, { agentId: toolName, messages, metadata });
7969
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentBadgeWrapper, { agentId: agentToolName, result, metadata });
7921
7970
  }
7922
- if (isLoading) return /* @__PURE__ */ jsxRuntime.jsx(LoadingBadge, {});
7923
- if (workflow) {
7971
+ if (isWorkflow) {
7924
7972
  const isStreaming = metadata?.mode === "stream" || metadata?.mode === "network";
7925
7973
  return /* @__PURE__ */ jsxRuntime.jsx(
7926
7974
  WorkflowBadge,
7927
7975
  {
7928
- workflowId: toolName,
7929
- workflow,
7976
+ workflowId: workflowToolName,
7930
7977
  isStreaming,
7931
7978
  runId: result?.runId,
7932
7979
  metadata
@@ -10103,15 +10150,36 @@ const AgentChat = ({
10103
10150
  agentId,
10104
10151
  agentName,
10105
10152
  threadId,
10106
- initialMessages,
10107
- initialLegacyMessages,
10108
10153
  memory,
10109
10154
  refreshThreadList,
10110
10155
  modelVersion,
10111
- modelList
10156
+ modelList,
10157
+ messageId
10112
10158
  }) => {
10113
10159
  const { settings } = useAgentSettings();
10114
10160
  const { runtimeContext } = usePlaygroundStore();
10161
+ const { data: messages, isLoading: isMessagesLoading } = useAgentMessages({
10162
+ agentId,
10163
+ threadId: threadId ?? "",
10164
+ memory: memory ?? false
10165
+ });
10166
+ React.useEffect(() => {
10167
+ if (messageId && messages && !isMessagesLoading) {
10168
+ setTimeout(() => {
10169
+ const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
10170
+ if (messageElement) {
10171
+ messageElement.scrollIntoView({ behavior: "smooth", block: "center" });
10172
+ messageElement.classList.add("bg-surface4");
10173
+ setTimeout(() => {
10174
+ messageElement.classList.remove("bg-surface4");
10175
+ }, 2e3);
10176
+ }
10177
+ }, 100);
10178
+ }
10179
+ }, [messageId, messages, isMessagesLoading]);
10180
+ if (isMessagesLoading) {
10181
+ return null;
10182
+ }
10115
10183
  return /* @__PURE__ */ jsxRuntime.jsx(
10116
10184
  MastraRuntimeProvider,
10117
10185
  {
@@ -10119,8 +10187,8 @@ const AgentChat = ({
10119
10187
  agentName,
10120
10188
  modelVersion,
10121
10189
  threadId,
10122
- initialMessages,
10123
- initialLegacyMessages,
10190
+ initialMessages: messages?.uiMessages || [],
10191
+ initialLegacyMessages: messages?.legacyMessages || [],
10124
10192
  memory,
10125
10193
  refreshThreadList,
10126
10194
  settings,
@@ -17354,20 +17422,6 @@ function usePolling({
17354
17422
  };
17355
17423
  }
17356
17424
 
17357
- const useInView = () => {
17358
- const [inView, setInView] = React.useState(false);
17359
- const setRef = React.useCallback((node) => {
17360
- if (node) {
17361
- const observer = new IntersectionObserver(([entry]) => {
17362
- setInView(entry.isIntersecting);
17363
- });
17364
- observer.observe(node);
17365
- return () => observer.disconnect();
17366
- }
17367
- }, []);
17368
- return { inView, setRef };
17369
- };
17370
-
17371
17425
  const PlaygroundQueryClient = ({ children }) => {
17372
17426
  const queryClient = new reactQuery.QueryClient();
17373
17427
  return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });