@mastra/playground-ui 5.1.2-alpha.4 → 5.1.2-alpha.6

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
@@ -2,8 +2,8 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { createContext, useContext, forwardRef, useState, useEffect, memo, useMemo, useRef, useCallback, Suspense, Fragment as Fragment$1 } from 'react';
4
4
  import { MastraClient } from '@mastra/client-js';
5
- import { useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, ComposerPrimitive, useAttachment, AttachmentPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { CheckIcon as CheckIcon$1, CopyIcon, ChevronUpIcon, X, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Copy, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Check, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Network, PauseIcon, Loader2, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon, Plus, Minus, Maximize, CirclePause } from 'lucide-react';
5
+ import { useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, ComposerPrimitive, useAttachment, AttachmentPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
+ import { CheckIcon as CheckIcon$1, CopyIcon, ChevronUpIcon, X, FileText, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Copy, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Check, ChevronUp, ChevronDown, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Network, PauseIcon, Loader2, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Braces, Brackets, TrashIcon, Plus, Minus, Maximize, CirclePause } from 'lucide-react';
7
7
  import { Slot } from '@radix-ui/react-slot';
8
8
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
9
  import { TooltipProvider as TooltipProvider$1 } from '@radix-ui/react-tooltip';
@@ -22,7 +22,7 @@ import { useShallow } from 'zustand/shallow';
22
22
  import { RuntimeContext } from '@mastra/core/di';
23
23
  import { create } from 'zustand';
24
24
  import { persist } from 'zustand/middleware';
25
- import { format, formatDistanceToNow, isValid } from 'date-fns';
25
+ import { format, formatDistanceToNow, isValid, formatDate } from 'date-fns';
26
26
  import * as TabsPrimitive from '@radix-ui/react-tabs';
27
27
  import { toast } from 'sonner';
28
28
  import { AnimatePresence } from 'motion/react';
@@ -4202,11 +4202,12 @@ const AttachmentPreviewDialog = ({ children }) => {
4202
4202
  };
4203
4203
  const AttachmentThumbnail = () => {
4204
4204
  const isImage = useAttachment((a) => a.type === "image");
4205
+ const document = useAttachment((a) => a.type === "document" ? a : void 0);
4205
4206
  const src = useAttachmentSrc();
4206
4207
  const canRemove = useAttachment((a) => a.source !== "message");
4207
4208
  return /* @__PURE__ */ jsx(TooltipProvider$1, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
4208
4209
  /* @__PURE__ */ jsxs(AttachmentPrimitive.Root, { className: "relative", children: [
4209
- /* @__PURE__ */ jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsx("img", { src, className: "object-cover aspect-ratio size-16", alt: "Preview", height: 64, width: 64 }) }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileIcon, { className: "text-icon3" }) }) }) }) }),
4210
+ /* @__PURE__ */ jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsx("img", { src, className: "object-cover aspect-ratio size-16", alt: "Preview", height: 64, width: 64 }) }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileText, { className: "text-accent2" }) }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileIcon, { className: "text-icon3" }) }) }) }) }),
4210
4211
  canRemove && /* @__PURE__ */ jsx(AttachmentRemove, {})
4211
4212
  ] }),
4212
4213
  /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}) })
@@ -4228,9 +4229,10 @@ const UserMessageAttachments = () => {
4228
4229
  };
4229
4230
  const InMessageAttachment = () => {
4230
4231
  const isImage = useAttachment((a) => a.type === "image");
4232
+ const document = useAttachment((a) => a.type === "document" ? a : void 0);
4231
4233
  const src = useAttachmentSrc();
4232
4234
  return /* @__PURE__ */ jsx(TooltipProvider$1, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
4233
- /* @__PURE__ */ jsx(AttachmentPrimitive.Root, { className: "relative pt-4", children: /* @__PURE__ */ jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsx("img", { src, className: "object-cover aspect-ratio max-h-[140px] max-w-[320px]", alt: "Preview" }) }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileIcon, { className: "text-icon3" }) }) }) }) }) }),
4235
+ /* @__PURE__ */ jsx(AttachmentPrimitive.Root, { className: "relative pt-4", children: /* @__PURE__ */ jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsx("img", { src, className: "object-cover aspect-ratio max-h-[140px] max-w-[320px]", alt: "Preview" }) }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center p-4", children: /* @__PURE__ */ jsx(FileText, { className: "text-accent2" }) }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center p-4", children: /* @__PURE__ */ jsx(FileIcon, { className: "text-icon3" }) }) }) }) }) }),
4234
4236
  /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}) })
4235
4237
  ] }) });
4236
4238
  };
@@ -4496,20 +4498,96 @@ const fileToBase64 = async (file) => {
4496
4498
  });
4497
4499
  };
4498
4500
 
4501
+ class PDFAttachmentAdapter {
4502
+ accept = "application/pdf";
4503
+ async add({ file }) {
4504
+ const maxSize = 20 * 1024 * 1024;
4505
+ if (file.size > maxSize) {
4506
+ throw new Error("PDF size exceeds 20MB limit");
4507
+ }
4508
+ return {
4509
+ id: crypto.randomUUID(),
4510
+ type: "document",
4511
+ name: file.name,
4512
+ file,
4513
+ status: {
4514
+ type: "running",
4515
+ reason: "uploading",
4516
+ progress: 0
4517
+ },
4518
+ contentType: "application/pdf"
4519
+ };
4520
+ }
4521
+ async send(attachment) {
4522
+ const base64Data = await this.fileToBase64(attachment.file);
4523
+ return {
4524
+ id: attachment.id,
4525
+ type: "document",
4526
+ name: attachment.name,
4527
+ content: [
4528
+ {
4529
+ type: "text",
4530
+ text: base64Data
4531
+ }
4532
+ ],
4533
+ status: { type: "complete" },
4534
+ contentType: "application/pdf"
4535
+ };
4536
+ }
4537
+ async remove(attachment) {
4538
+ }
4539
+ async fileToBase64(file) {
4540
+ const arrayBuffer = await file.arrayBuffer();
4541
+ const bytes = new Uint8Array(arrayBuffer);
4542
+ let binary = "";
4543
+ bytes.forEach((byte) => {
4544
+ binary += String.fromCharCode(byte);
4545
+ });
4546
+ return btoa(binary);
4547
+ }
4548
+ // Optional: Extract text from PDF using a library like pdf.js
4549
+ async extractTextFromPDF(file) {
4550
+ return "Extracted PDF text content";
4551
+ }
4552
+ }
4553
+
4499
4554
  const convertMessage$1 = (message) => {
4500
4555
  return message;
4501
4556
  };
4502
4557
  const convertToAIAttachments = async (attachments) => {
4503
- const promises = attachments.filter((attachment) => attachment.file).map(async (attachment) => ({
4504
- role: "user",
4505
- content: [
4506
- {
4507
- type: "image",
4508
- image: await fileToBase64(attachment.file),
4509
- mimeType: attachment.file.type
4558
+ const promises = attachments.filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
4559
+ if (attachment.type === "document") {
4560
+ if (attachment.contentType === "application/pdf") {
4561
+ return {
4562
+ role: "user",
4563
+ content: [
4564
+ {
4565
+ type: "file",
4566
+ // @ts-expect-error - TODO: fix this type issue somehow
4567
+ data: attachment.content?.[0]?.text || "",
4568
+ mimeType: attachment.contentType,
4569
+ filename: attachment.name
4570
+ }
4571
+ ]
4572
+ };
4510
4573
  }
4511
- ]
4512
- }));
4574
+ return {
4575
+ role: "user",
4576
+ // @ts-expect-error - TODO: fix this type issue somehow
4577
+ content: attachment.content[0]?.text || ""
4578
+ };
4579
+ }
4580
+ return {
4581
+ role: "user",
4582
+ content: [
4583
+ {
4584
+ type: "image",
4585
+ image: await fileToBase64(attachment.file),
4586
+ mimeType: attachment.file.type
4587
+ }
4588
+ ]
4589
+ };
4590
+ });
4513
4591
  return Promise.all(promises);
4514
4592
  };
4515
4593
  function MastraRuntimeProvider({
@@ -4811,7 +4889,11 @@ function MastraRuntimeProvider({
4811
4889
  convertMessage: convertMessage$1,
4812
4890
  onNew,
4813
4891
  adapters: {
4814
- attachments: new CompositeAttachmentAdapter([new SimpleImageAttachmentAdapter()])
4892
+ attachments: new CompositeAttachmentAdapter([
4893
+ new SimpleImageAttachmentAdapter(),
4894
+ new SimpleTextAttachmentAdapter(),
4895
+ new PDFAttachmentAdapter()
4896
+ ])
4815
4897
  }
4816
4898
  });
4817
4899
  return /* @__PURE__ */ jsxs(AssistantRuntimeProvider, { runtime, children: [
@@ -6025,42 +6107,6 @@ function transformKey(key) {
6025
6107
  const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
6026
6108
  return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
6027
6109
  }
6028
- const refineTraces = (traces, isWorkflow = false) => {
6029
- const listOfSpanIds = /* @__PURE__ */ new Set();
6030
- const newName = (name) => {
6031
- if (name?.startsWith("workflow.") && isWorkflow) {
6032
- return name?.split(".")?.slice(2)?.join(".");
6033
- }
6034
- if (name?.startsWith("agent.") && !isWorkflow) {
6035
- return name?.split(".")?.slice(1)?.join(".");
6036
- }
6037
- return name;
6038
- };
6039
- const groupedTraces = traces?.reduce((acc, curr) => {
6040
- const newCurr = { ...curr, name: newName(curr.name), duration: curr.endTime - curr.startTime };
6041
- listOfSpanIds.add(curr.id);
6042
- return { ...acc, [curr.traceId]: [...acc[curr.traceId] || [], newCurr] };
6043
- }, {});
6044
- const tracesData = Object.entries(groupedTraces).map(([key, value]) => {
6045
- const parentSpan = value.find((span) => !span.parentSpanId || !listOfSpanIds.has(span.parentSpanId));
6046
- const enrichedSpans = value.map((span) => ({
6047
- ...span,
6048
- parentSpanId: parentSpan?.id === span.id ? null : span?.parentSpanId
6049
- }));
6050
- const failedStatus = value.find((span) => span.status.code !== 0)?.status;
6051
- const runId = value?.[0]?.attributes?.runId;
6052
- return {
6053
- traceId: key,
6054
- serviceName: parentSpan?.name || key,
6055
- duration: parentSpan?.duration || value.reduce((acc, curr) => acc + curr.duration, 0),
6056
- status: failedStatus || parentSpan?.status || value[0].status,
6057
- started: value[0].startTime,
6058
- trace: enrichedSpans,
6059
- runId: runId ? String(runId) : void 0
6060
- };
6061
- });
6062
- return tracesData;
6063
- };
6064
6110
 
6065
6111
  function SpanDetail() {
6066
6112
  const { span, setSpan, trace, setIsOpen } = useContext(TraceContext);
@@ -9747,6 +9793,28 @@ function WorkflowTrigger({ workflowId, setRunId }) {
9747
9793
  ] }) });
9748
9794
  }
9749
9795
 
9796
+ const WorkflowRuns = ({ workflowId, runId, isLoading, runs, onPressRun }) => {
9797
+ if (isLoading) {
9798
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[600px]" }) });
9799
+ }
9800
+ if (runs.length === 0) {
9801
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 text-center", children: "No previous run" }) });
9802
+ }
9803
+ return /* @__PURE__ */ jsx("ol", { className: "pb-10", children: runs.map((run) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
9804
+ "button",
9805
+ {
9806
+ onClick: () => onPressRun({ workflowId, runId: run.runId }),
9807
+ className: clsx("px-3 py-2 border-b-sm border-border1 block w-full hover:bg-surface4 text-left", {
9808
+ "bg-surface4": run.runId === runId
9809
+ }),
9810
+ children: [
9811
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-lg", className: "font-medium text-icon6 truncate", as: "p", children: run.runId }),
9812
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "font-medium text-icon3 truncate", as: "p", children: typeof run?.snapshot === "string" ? "" : run?.snapshot?.timestamp ? formatDate(run?.snapshot?.timestamp, "MMM d, yyyy h:mm a") : "" })
9813
+ ]
9814
+ }
9815
+ ) }, run.runId)) });
9816
+ };
9817
+
9750
9818
  const DataTable = ({
9751
9819
  columns,
9752
9820
  data,
@@ -9794,7 +9862,7 @@ const DataTable = ({
9794
9862
  const rows = table.getRowModel().rows;
9795
9863
  return /* @__PURE__ */ jsxs("div", { children: [
9796
9864
  /* @__PURE__ */ jsxs(Table, { children: [
9797
- /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => {
9865
+ /* @__PURE__ */ jsx(Thead, { className: "sticky top-0 bg-surface2", children: ths.headers.map((header) => {
9798
9866
  const size = header.column.getSize();
9799
9867
  const meta = header.column.columnDef.meta;
9800
9868
  return /* @__PURE__ */ jsx(Th, { style: { width: meta?.width || size || "auto" }, children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id);
@@ -10102,47 +10170,5 @@ function usePolling({
10102
10170
  };
10103
10171
  }
10104
10172
 
10105
- const useTraces = (componentName, isWorkflow = false) => {
10106
- const [traces, setTraces] = useState([]);
10107
- const client = useMemo(() => useMastraClient(), []);
10108
- const fetchFn = useCallback(async () => {
10109
- try {
10110
- const res = await client.getTelemetry({
10111
- attribute: {
10112
- componentName
10113
- }
10114
- });
10115
- if (!res.traces) {
10116
- throw new Error("Error fetching traces");
10117
- }
10118
- const refinedTraces = refineTraces(res?.traces || [], isWorkflow);
10119
- return refinedTraces;
10120
- } catch (error2) {
10121
- throw error2;
10122
- }
10123
- }, [client, componentName, isWorkflow]);
10124
- const onSuccess = useCallback((newTraces) => {
10125
- if (newTraces.length > 0) {
10126
- setTraces(() => newTraces);
10127
- }
10128
- }, []);
10129
- const onError = useCallback((error2) => {
10130
- console.log(`error, onError`, error2);
10131
- toast.error(error2.message);
10132
- }, []);
10133
- const shouldContinue = useCallback(() => {
10134
- return true;
10135
- }, []);
10136
- const { firstCallLoading, error } = usePolling({
10137
- fetchFn,
10138
- interval: 3e3,
10139
- onSuccess,
10140
- onError,
10141
- shouldContinue,
10142
- enabled: true
10143
- });
10144
- return { traces, firstCallLoading, error };
10145
- };
10146
-
10147
- export { AgentChat, AgentCoinIcon, AgentContext, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentProvider, AgentTraces, AiIcon, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityIcon, EntityName, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LogsIcon, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, NetworkChat, NetworkContext, NetworkProvider, OpenAIIcon, PromptIcon, RepoIcon, Row, ScoreIcon, SettingsIcon, SlashIcon, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolsIcon, TraceIcon, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowTraces, WorkflowTrigger, refineTraces, useCurrentRun, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition, useTraces };
10173
+ export { AgentChat, AgentCoinIcon, AgentContext, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentProvider, AgentTraces, AiIcon, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityIcon, EntityName, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LogsIcon, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, NetworkChat, NetworkContext, NetworkProvider, OpenAIIcon, PromptIcon, RepoIcon, Row, ScoreIcon, SettingsIcon, SlashIcon, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolsIcon, TraceIcon, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTraces, WorkflowTrigger, useCurrentRun, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition };
10148
10174
  //# sourceMappingURL=index.es.js.map