@mastra/playground-ui 5.1.11-alpha.2 → 5.1.11-alpha.4

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 (23) hide show
  1. package/LICENSE.md +11 -42
  2. package/dist/index.cjs.js +309 -170
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +312 -173
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/src/components/assistant-ui/attachments/attachment-preview-dialog.d.ts +31 -0
  7. package/dist/src/components/assistant-ui/attachments/attachment.d.ts +2 -0
  8. package/dist/src/components/assistant-ui/hooks/use-attachment-src.d.ts +1 -0
  9. package/dist/src/components/assistant-ui/hooks/use-file-src.d.ts +1 -0
  10. package/dist/src/components/assistant-ui/hooks/use-load-browser-file.d.ts +4 -0
  11. package/dist/src/components/assistant-ui/messages/assistant-message.d.ts +6 -0
  12. package/dist/src/components/assistant-ui/messages/markdown-text.d.ts +2 -0
  13. package/dist/src/components/assistant-ui/messages/user-messages.d.ts +9 -0
  14. package/package.json +5 -5
  15. package/dist/src/components/assistant-ui/assistant-message.d.ts +0 -6
  16. package/dist/src/components/assistant-ui/assistant-modal.d.ts +0 -1
  17. package/dist/src/components/assistant-ui/attachment.d.ts +0 -5
  18. package/dist/src/components/assistant-ui/image-with-fallback.d.ts +0 -3
  19. package/dist/src/components/assistant-ui/markdown-text.d.ts +0 -2
  20. package/dist/src/components/assistant-ui/user-message.d.ts +0 -1
  21. /package/dist/src/components/assistant-ui/{attachment-adapters → attachments}/pdfs-adapter.d.ts +0 -0
  22. /package/dist/src/components/assistant-ui/{use-has-attachments.d.ts → hooks/use-has-attachments.d.ts} +0 -0
  23. /package/dist/src/components/assistant-ui/{tool-fallback.d.ts → tools/tool-fallback.d.ts} +0 -0
package/dist/index.es.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { createContext, useContext, forwardRef, useState, useEffect, memo, useRef, useCallback, useMemo, Suspense, Fragment as Fragment$1 } from 'react';
3
+ import React__default, { createContext, useContext, forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, 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, SimpleTextAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, FileText, FileIcon, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, ChevronUp, ChevronDown, Circle, RefreshCw, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Braces, Loader2, Network, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Brackets, TrashIcon, CirclePause, StopCircle } from 'lucide-react';
5
+ import { useMessage, MessagePrimitive, ActionBarPrimitive, useAttachment, AttachmentPrimitive, useComposerRuntime, ComposerPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
+ import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, FileText, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, ChevronUp, ChevronDown, Circle, RefreshCw, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Braces, Loader2, Network, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Brackets, TrashIcon, CirclePause, StopCircle } 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';
@@ -18,8 +18,8 @@ import { tags } from '@lezer/highlight';
18
18
  import { draculaInit } from '@uiw/codemirror-theme-dracula';
19
19
  import CodeMirror from '@uiw/react-codemirror';
20
20
  import { toast } from 'sonner';
21
- import * as DialogPrimitive from '@radix-ui/react-dialog';
22
21
  import { useShallow } from 'zustand/shallow';
22
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
23
23
  import { RuntimeContext } from '@mastra/core/di';
24
24
  import { create } from 'zustand';
25
25
  import { persist } from 'zustand/middleware';
@@ -3166,46 +3166,6 @@ const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => /* @__
3166
3166
  ));
3167
3167
  AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
3168
3168
 
3169
- const ImageWithFallback = ({ alt, src, ...rest }) => {
3170
- const [error, setError] = useState(false);
3171
- useEffect(() => {
3172
- setError(false);
3173
- }, [src]);
3174
- return error || !src ? /* @__PURE__ */ jsxs("div", { children: [
3175
- /* @__PURE__ */ jsx(
3176
- "svg",
3177
- {
3178
- xmlns: "http://www.w3.org/2000/svg",
3179
- fill: "none",
3180
- viewBox: "0 0 24 24",
3181
- strokeWidth: "1.5",
3182
- stroke: "currentColor",
3183
- width: "150",
3184
- height: "150",
3185
- children: /* @__PURE__ */ jsx(
3186
- "path",
3187
- {
3188
- strokeLinecap: "round",
3189
- strokeLinejoin: "round",
3190
- d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
3191
- }
3192
- )
3193
- }
3194
- ),
3195
- /* @__PURE__ */ jsx("p", { className: "text-xs italic text-muted-foreground -mt-[0.625rem] mb-[0.625rem]", children: "Image link is broken" })
3196
- ] }) : /* @__PURE__ */ jsx(
3197
- "img",
3198
- {
3199
- src,
3200
- alt,
3201
- ...rest,
3202
- onError: () => {
3203
- setError(true);
3204
- }
3205
- }
3206
- );
3207
- };
3208
-
3209
3169
  const SyntaxHighlighter$3 = makePrismAsyncSyntaxHighlighter({
3210
3170
  style: coldarkDark,
3211
3171
  customStyle: {
@@ -3278,6 +3238,45 @@ const useCopyToClipboard$1 = ({
3278
3238
  };
3279
3239
  return { isCopied, copyToClipboard };
3280
3240
  };
3241
+ const ImageWithFallback = ({ alt, src, ...rest }) => {
3242
+ const [error, setError] = useState(false);
3243
+ useEffect(() => {
3244
+ setError(false);
3245
+ }, [src]);
3246
+ return error || !src ? /* @__PURE__ */ jsxs("div", { children: [
3247
+ /* @__PURE__ */ jsx(
3248
+ "svg",
3249
+ {
3250
+ xmlns: "http://www.w3.org/2000/svg",
3251
+ fill: "none",
3252
+ viewBox: "0 0 24 24",
3253
+ strokeWidth: "1.5",
3254
+ stroke: "currentColor",
3255
+ width: "150",
3256
+ height: "150",
3257
+ children: /* @__PURE__ */ jsx(
3258
+ "path",
3259
+ {
3260
+ strokeLinecap: "round",
3261
+ strokeLinejoin: "round",
3262
+ d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
3263
+ }
3264
+ )
3265
+ }
3266
+ ),
3267
+ /* @__PURE__ */ jsx("p", { className: "text-xs italic text-muted-foreground -mt-[0.625rem] mb-[0.625rem]", children: "Image link is broken" })
3268
+ ] }) : /* @__PURE__ */ jsx(
3269
+ "img",
3270
+ {
3271
+ src,
3272
+ alt,
3273
+ ...rest,
3274
+ onError: () => {
3275
+ setError(true);
3276
+ }
3277
+ }
3278
+ );
3279
+ };
3281
3280
  const defaultComponents = unstable_memoizeMarkdownComponents({
3282
3281
  h1: ({ className, ...props }) => /* @__PURE__ */ jsx(
3283
3282
  "h1",
@@ -4353,9 +4352,7 @@ const ToolFallback$1 = ({ toolName, argsText, result }) => {
4353
4352
  ] });
4354
4353
  };
4355
4354
 
4356
- const AssistantMessage = ({
4357
- ToolFallback: ToolFallbackCustom
4358
- }) => {
4355
+ const AssistantMessage = ({ ToolFallback: ToolFallbackCustom }) => {
4359
4356
  const data = useMessage();
4360
4357
  const isSolelyToolCall = data.content.length === 1 && data.content[0].type === "tool-call";
4361
4358
  return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "max-w-full", children: [
@@ -4387,8 +4384,36 @@ const AssistantActionBar$1 = () => {
4387
4384
  );
4388
4385
  };
4389
4386
 
4387
+ const useFileSrc = (file) => {
4388
+ const [src, setSrc] = useState(void 0);
4389
+ useEffect(() => {
4390
+ if (!file) {
4391
+ setSrc(void 0);
4392
+ return;
4393
+ }
4394
+ const objectUrl = URL.createObjectURL(file);
4395
+ setSrc(objectUrl);
4396
+ return () => {
4397
+ URL.revokeObjectURL(objectUrl);
4398
+ };
4399
+ }, [file]);
4400
+ return src;
4401
+ };
4402
+
4403
+ const useAttachmentSrc = () => {
4404
+ const { file, src } = useAttachment(
4405
+ useShallow((a) => {
4406
+ if (a.type !== "image") return {};
4407
+ if (a.file) return { file: a.file };
4408
+ const src2 = a.content?.filter((c) => c.type === "image")[0]?.image;
4409
+ if (!src2) return {};
4410
+ return { src: src2 };
4411
+ })
4412
+ );
4413
+ return useFileSrc(file) ?? src;
4414
+ };
4415
+
4390
4416
  const Dialog = DialogPrimitive.Root;
4391
- const DialogTrigger = DialogPrimitive.Trigger;
4392
4417
  const DialogPortal = DialogPrimitive.Portal;
4393
4418
  const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4394
4419
  DialogPrimitive.Overlay,
@@ -4436,107 +4461,137 @@ DialogTitle.displayName = DialogPrimitive.Title.displayName;
4436
4461
  const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
4437
4462
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
4438
4463
 
4439
- const useHasAttachments = () => {
4440
- const composer = useComposerRuntime();
4441
- const [hasAttachments, setHasAttachments] = useState(false);
4442
- useEffect(() => {
4443
- composer.subscribe(() => {
4444
- const attachments = composer.getState().attachments;
4445
- setHasAttachments(attachments.length > 0);
4446
- });
4447
- }, [composer]);
4448
- return hasAttachments;
4464
+ const PdfEntry = ({ data }) => {
4465
+ const [open, setOpen] = useState(false);
4466
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4467
+ /* @__PURE__ */ jsx("button", { onClick: () => setOpen(true), className: "h-full w-full flex items-center justify-center", type: "button", children: /* @__PURE__ */ jsx(FileText, { className: "text-accent2" }) }),
4468
+ /* @__PURE__ */ jsx(PdfPreviewDialog, { data, open, onOpenChange: setOpen })
4469
+ ] });
4449
4470
  };
4450
-
4451
- const useFileSrc = (file) => {
4452
- const [src, setSrc] = useState(void 0);
4453
- useEffect(() => {
4454
- if (!file) {
4455
- setSrc(void 0);
4456
- return;
4457
- }
4458
- const objectUrl = URL.createObjectURL(file);
4459
- setSrc(objectUrl);
4460
- return () => {
4461
- URL.revokeObjectURL(objectUrl);
4462
- };
4463
- }, [file]);
4464
- return src;
4471
+ const PdfPreviewDialog = ({ data, open, onOpenChange }) => {
4472
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { className: "max-w-4xl bg-surface2", children: /* @__PURE__ */ jsxs("div", { className: "h-full w-full", children: [
4473
+ /* @__PURE__ */ jsx(DialogTitle, { className: "pb-4", children: "PDF preview" }),
4474
+ open && /* @__PURE__ */ jsx("iframe", { src: data, width: "100%", height: "600px" })
4475
+ ] }) }) });
4465
4476
  };
4466
- const useAttachmentSrc = () => {
4467
- const { file, src } = useAttachment(
4468
- useShallow((a) => {
4469
- if (a.type !== "image") return {};
4470
- if (a.file) return { file: a.file };
4471
- const src2 = a.content?.filter((c) => c.type === "image")[0]?.image;
4472
- if (!src2) return {};
4473
- return { src: src2 };
4474
- })
4475
- );
4476
- return useFileSrc(file) ?? src;
4477
+ const ImageEntry = ({ src }) => {
4478
+ const [open, setOpen] = useState(false);
4479
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4480
+ /* @__PURE__ */ jsx("button", { onClick: () => setOpen(true), type: "button", className: "h-full w-full flex items-center justify-center", children: /* @__PURE__ */ jsx("img", { src, className: "object-cover aspect-ratio max-h-[140px] max-w-[320px]", alt: "Preview" }) }),
4481
+ /* @__PURE__ */ jsx(ImagePreviewDialog, { src, open, onOpenChange: setOpen })
4482
+ ] });
4477
4483
  };
4478
- const AttachmentPreview = ({ src }) => {
4479
- return /* @__PURE__ */ jsx("div", { className: "overflow-hidden w-full", children: /* @__PURE__ */ jsx("img", { src, className: "object-contain aspect-ratio h-full w-full", alt: "Preview" }) });
4484
+ const ImagePreviewDialog = ({ src, open, onOpenChange }) => {
4485
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { className: "max-w-4xl bg-surface2", children: /* @__PURE__ */ jsxs("div", { className: "h-full w-full", children: [
4486
+ /* @__PURE__ */ jsx(DialogTitle, { className: "pb-4", children: "Image preview" }),
4487
+ open && /* @__PURE__ */ jsx("img", { src, alt: "Image" })
4488
+ ] }) }) });
4480
4489
  };
4481
- const AttachmentPreviewDialog = ({ children }) => {
4482
- const src = useAttachmentSrc();
4483
- if (!src) return children;
4484
- return /* @__PURE__ */ jsxs(Dialog, { children: [
4485
- /* @__PURE__ */ jsx(DialogTrigger, { className: "hover:bg-accent/50 cursor-pointer transition-colors", asChild: true, children }),
4486
- /* @__PURE__ */ jsxs(DialogPortal, { children: [
4487
- /* @__PURE__ */ jsx(DialogOverlay, {}),
4488
- /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-5xl w-full max-h-[80%]", children: [
4489
- /* @__PURE__ */ jsx(DialogTitle, { className: "aui-sr-only", children: "Image Attachment Preview" }),
4490
- /* @__PURE__ */ jsx(AttachmentPreview, { src })
4491
- ] })
4492
- ] })
4490
+ const TxtEntry = ({ data }) => {
4491
+ const [open, setOpen] = useState(false);
4492
+ const formattedContent = data.replace(/<attachment[^>]*>/, "").replace(/<\/attachment>/g, "");
4493
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4494
+ /* @__PURE__ */ jsx("button", { onClick: () => setOpen(true), className: "h-full w-full flex items-center justify-center", type: "button", children: /* @__PURE__ */ jsx(FileText, { className: "text-icon3" }) }),
4495
+ /* @__PURE__ */ jsx(TxtPreviewDialog, { data: formattedContent, open, onOpenChange: setOpen })
4493
4496
  ] });
4494
4497
  };
4495
- const AttachmentThumbnail = () => {
4496
- const isImage = useAttachment((a) => a.type === "image");
4497
- const document = useAttachment((a) => a.type === "document" ? a : void 0);
4498
- const src = useAttachmentSrc();
4499
- const canRemove = useAttachment((a) => a.source !== "message");
4500
- return /* @__PURE__ */ jsx(TooltipProvider$1, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
4501
- /* @__PURE__ */ jsxs(AttachmentPrimitive.Root, { className: "relative", children: [
4502
- /* @__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" }) }) }) }) }),
4503
- canRemove && /* @__PURE__ */ jsx(AttachmentRemove, {})
4504
- ] }),
4505
- /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}) })
4506
- ] }) });
4498
+ const TxtPreviewDialog = ({ data, open, onOpenChange }) => {
4499
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { className: "max-w-4xl bg-surface2 h-[80vh] overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "h-full w-full", children: [
4500
+ /* @__PURE__ */ jsx(DialogTitle, { className: "pb-4", children: "Text preview" }),
4501
+ open && /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap", children: data })
4502
+ ] }) }) });
4507
4503
  };
4508
- const AttachmentRemove = () => {
4509
- return /* @__PURE__ */ jsx(AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsx(
4510
- TooltipIconButton,
4504
+
4505
+ const InMessageContextWrapper = () => {
4506
+ return /* @__PURE__ */ jsx(AttachmentPrimitive.Root, { className: "pt-4", children: /* @__PURE__ */ jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsx(InMessageAttachmentWrapper, {}) }) });
4507
+ };
4508
+ const InMessageAttachmentWrapper = () => {
4509
+ const src = useAttachmentSrc();
4510
+ const attachment = useAttachment((a) => a);
4511
+ if (attachment.type === "image") {
4512
+ return /* @__PURE__ */ jsx(
4513
+ InMessageAttachment,
4514
+ {
4515
+ type: "image",
4516
+ contentType: void 0,
4517
+ nameSlot: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}),
4518
+ src,
4519
+ data: void 0
4520
+ }
4521
+ );
4522
+ }
4523
+ if (attachment.contentType === "application/pdf") {
4524
+ const pdfText = attachment.content?.[0]?.text;
4525
+ return /* @__PURE__ */ jsx(
4526
+ InMessageAttachment,
4527
+ {
4528
+ type: "document",
4529
+ contentType: attachment.contentType,
4530
+ nameSlot: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}),
4531
+ src,
4532
+ data: `data:application/pdf;base64,${pdfText}`
4533
+ }
4534
+ );
4535
+ }
4536
+ return /* @__PURE__ */ jsx(
4537
+ InMessageAttachment,
4511
4538
  {
4512
- tooltip: "Remove file",
4513
- className: "absolute -right-3 -top-3 hover:bg-transparent rounded-full bg-surface1 rounded-full p-1",
4514
- side: "top",
4515
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CircleXIcon, {}) })
4539
+ type: attachment.type,
4540
+ contentType: attachment.contentType,
4541
+ nameSlot: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}),
4542
+ src,
4543
+ data: attachment.content?.[0]?.text
4516
4544
  }
4517
- ) });
4518
- };
4519
- const UserMessageAttachments = () => {
4520
- return /* @__PURE__ */ jsx(MessagePrimitive.Attachments, { components: { Attachment: InMessageAttachment } });
4545
+ );
4521
4546
  };
4522
- const InMessageAttachment = () => {
4523
- const isImage = useAttachment((a) => a.type === "image");
4524
- const document = useAttachment((a) => a.type === "document" ? a : void 0);
4525
- const src = useAttachmentSrc();
4547
+ const InMessageAttachment = ({ type, contentType, nameSlot, src, data }) => {
4526
4548
  return /* @__PURE__ */ jsx(TooltipProvider$1, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
4527
- /* @__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" }) }) }) }) }) }),
4528
- /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}) })
4549
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full overflow-hidden rounded-lg", children: type === "image" ? /* @__PURE__ */ jsx(ImageEntry, { src: src ?? "" }) : type === "document" && contentType === "application/pdf" ? /* @__PURE__ */ jsx(PdfEntry, { data: data ?? "" }) : /* @__PURE__ */ jsx(TxtEntry, { data: data ?? "" }) }) }),
4550
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: nameSlot })
4529
4551
  ] }) });
4530
4552
  };
4531
- const ComposerAttachments = () => {
4532
- const hasAttachments = useHasAttachments();
4533
- if (!hasAttachments) return null;
4534
- return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-row items-center gap-4 h-24", children: /* @__PURE__ */ jsx(ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4553
+ const UserMessageAttachments = () => {
4554
+ return /* @__PURE__ */ jsx(MessagePrimitive.Attachments, { components: { Attachment: InMessageContextWrapper } });
4535
4555
  };
4536
-
4537
4556
  const UserMessage = () => {
4538
4557
  return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", children: [
4539
- /* @__PURE__ */ jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsx(MessagePrimitive.Content, {}) }),
4558
+ /* @__PURE__ */ jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsx(
4559
+ MessagePrimitive.Content,
4560
+ {
4561
+ components: {
4562
+ File: (p) => {
4563
+ return /* @__PURE__ */ jsx(
4564
+ InMessageAttachment,
4565
+ {
4566
+ type: "document",
4567
+ contentType: p.mimeType,
4568
+ nameSlot: "Unknown filename",
4569
+ src: void 0,
4570
+ data: p.image
4571
+ }
4572
+ );
4573
+ },
4574
+ Image: (p) => {
4575
+ return /* @__PURE__ */ jsx(InMessageAttachment, { type: "image", nameSlot: "Unknown filename", src: p.image });
4576
+ },
4577
+ Text: (p) => {
4578
+ if (p.text.includes("<attachment name=")) {
4579
+ return /* @__PURE__ */ jsx(
4580
+ InMessageAttachment,
4581
+ {
4582
+ type: "document",
4583
+ contentType: "text/plain",
4584
+ nameSlot: "Unknown filename",
4585
+ src: void 0,
4586
+ data: p.text
4587
+ }
4588
+ );
4589
+ }
4590
+ return p.text;
4591
+ }
4592
+ }
4593
+ }
4594
+ ) }),
4540
4595
  /* @__PURE__ */ jsx(UserMessageAttachments, {})
4541
4596
  ] });
4542
4597
  };
@@ -4643,6 +4698,123 @@ const useSpeechRecognition = ({ language = "en-US" } = {}) => {
4643
4698
  };
4644
4699
  };
4645
4700
 
4701
+ const useHasAttachments = () => {
4702
+ const composer = useComposerRuntime();
4703
+ const [hasAttachments, setHasAttachments] = useState(false);
4704
+ useEffect(() => {
4705
+ composer.subscribe(() => {
4706
+ const attachments = composer.getState().attachments;
4707
+ setHasAttachments(attachments.length > 0);
4708
+ });
4709
+ }, [composer]);
4710
+ return hasAttachments;
4711
+ };
4712
+
4713
+ function Spinner({ color = "#fff", className }) {
4714
+ return /* @__PURE__ */ jsx(
4715
+ "svg",
4716
+ {
4717
+ className: cn("animate-spin duration-700", className),
4718
+ xmlns: "http://www.w3.org/2000/svg",
4719
+ width: "24",
4720
+ height: "24",
4721
+ viewBox: "0 0 24 24",
4722
+ fill: "none",
4723
+ stroke: "currentColor",
4724
+ strokeWidth: "2",
4725
+ strokeLinecap: "round",
4726
+ strokeLinejoin: "round",
4727
+ children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
4728
+ }
4729
+ );
4730
+ }
4731
+
4732
+ const useLoadBrowserFile = (file) => {
4733
+ const [state, setState] = useState({ isLoading: false, text: "" });
4734
+ useEffect(() => {
4735
+ if (!file) return;
4736
+ const run = async () => {
4737
+ setState((s) => ({ ...s, isLoading: true }));
4738
+ const text = await file.text();
4739
+ setState((s) => ({ ...s, isLoading: false, text }));
4740
+ };
4741
+ run();
4742
+ }, [file]);
4743
+ return state;
4744
+ };
4745
+
4746
+ const fileToBase64 = async (file) => {
4747
+ return new Promise((resolve, reject) => {
4748
+ const reader = new FileReader();
4749
+ reader.onload = () => {
4750
+ const result = reader.result;
4751
+ if (typeof result === "string") {
4752
+ resolve(result);
4753
+ } else {
4754
+ reject(new Error("Failed to convert file to base64."));
4755
+ }
4756
+ };
4757
+ reader.onerror = (error) => {
4758
+ reject(error);
4759
+ };
4760
+ reader.readAsDataURL(file);
4761
+ });
4762
+ };
4763
+
4764
+ const ComposerTxtAttachment = ({ document }) => {
4765
+ const { isLoading, text } = useLoadBrowserFile(document.file);
4766
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full w-full", children: isLoading ? /* @__PURE__ */ jsx(Spinner, { className: "animate-spin" }) : /* @__PURE__ */ jsx(TxtEntry, { data: text }) });
4767
+ };
4768
+ const ComposerPdfAttachment = ({ document }) => {
4769
+ const [state, setState] = useState({ isLoading: false, text: "" });
4770
+ useEffect(() => {
4771
+ let isCanceled = false;
4772
+ const run = async () => {
4773
+ if (!document.file) return;
4774
+ setState((s) => ({ ...s, isLoading: true }));
4775
+ const text = await fileToBase64(document.file);
4776
+ if (isCanceled) {
4777
+ return;
4778
+ }
4779
+ setState((s) => ({ ...s, isLoading: false, text }));
4780
+ };
4781
+ run();
4782
+ return () => {
4783
+ isCanceled = true;
4784
+ };
4785
+ }, [document]);
4786
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full w-full", children: state.isLoading ? /* @__PURE__ */ jsx(Spinner, { className: "animate-spin" }) : /* @__PURE__ */ jsx(PdfEntry, { data: state.text }) });
4787
+ };
4788
+ const AttachmentThumbnail = () => {
4789
+ const isImage = useAttachment((a) => a.type === "image");
4790
+ const document = useAttachment((a) => a.type === "document" ? a : void 0);
4791
+ const src = useAttachmentSrc();
4792
+ const canRemove = useAttachment((a) => a.source !== "message");
4793
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
4794
+ /* @__PURE__ */ jsx(TooltipProvider$1, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
4795
+ /* @__PURE__ */ jsx(AttachmentPrimitive.Root, { children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden size-16 rounded-lg bg-surface3 border-sm border-border1 ", children: isImage ? /* @__PURE__ */ jsx(ImageEntry, { src: src ?? "" }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsx(ComposerPdfAttachment, { document }) : document ? /* @__PURE__ */ jsx(ComposerTxtAttachment, { document }) : null }) }) }),
4796
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx(AttachmentPrimitive.Name, {}) })
4797
+ ] }) }),
4798
+ canRemove && /* @__PURE__ */ jsx(AttachmentRemove, {})
4799
+ ] }) });
4800
+ };
4801
+ const AttachmentRemove = () => {
4802
+ return /* @__PURE__ */ jsx(AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsx(
4803
+ TooltipIconButton,
4804
+ {
4805
+ tooltip: "Remove file",
4806
+ className: "absolute -right-3 -top-3 text-icon3 hover:text-icon6 rounded-full bg-surface1 hover:bg-surface2 rounded-full p-1",
4807
+ side: "top",
4808
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CircleXIcon, {}) })
4809
+ }
4810
+ ) });
4811
+ };
4812
+ const ComposerAttachments = () => {
4813
+ const hasAttachments = useHasAttachments();
4814
+ if (!hasAttachments) return null;
4815
+ return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-row items-center gap-4 pb-2", children: /* @__PURE__ */ jsx(ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4816
+ };
4817
+
4646
4818
  const Thread = ({ ToolFallback, agentName, hasMemory, showFileSupport }) => {
4647
4819
  const areaRef = useRef(null);
4648
4820
  useAutoscroll(areaRef, { enabled: true });
@@ -4689,7 +4861,7 @@ const ThreadWelcome$1 = ({ agentName }) => {
4689
4861
  const Composer$1 = ({ hasMemory, showFileSupport }) => {
4690
4862
  return /* @__PURE__ */ jsxs("div", { className: "mx-4", children: [
4691
4863
  /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
4692
- /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto px-2 py-3", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
4864
+ /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
4693
4865
  /* @__PURE__ */ jsxs("div", { className: "bg-surface3 rounded-lg border-sm border-border1 py-4 mt-auto max-w-[568px] w-full mx-auto px-4", children: [
4694
4866
  /* @__PURE__ */ jsx(ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(
4695
4867
  "textarea",
@@ -4760,24 +4932,6 @@ const CircleStopIcon$1 = () => {
4760
4932
  return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", width: "16", height: "16", children: /* @__PURE__ */ jsx("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" }) });
4761
4933
  };
4762
4934
 
4763
- const fileToBase64 = async (file) => {
4764
- return new Promise((resolve, reject) => {
4765
- const reader = new FileReader();
4766
- reader.onload = () => {
4767
- const result = reader.result;
4768
- if (typeof result === "string") {
4769
- resolve(result);
4770
- } else {
4771
- reject(new Error("Failed to convert file to base64."));
4772
- }
4773
- };
4774
- reader.onerror = (error) => {
4775
- reject(error);
4776
- };
4777
- reader.readAsDataURL(file);
4778
- });
4779
- };
4780
-
4781
4935
  class PDFAttachmentAdapter {
4782
4936
  accept = "application/pdf";
4783
4937
  async add({ file }) {
@@ -4844,13 +4998,13 @@ const convertToAIAttachments = async (attachments) => {
4844
4998
  const promises = attachments.filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
4845
4999
  if (attachment.type === "document") {
4846
5000
  if (attachment.contentType === "application/pdf") {
5001
+ const pdfText = attachment.content?.[0]?.text || "";
4847
5002
  return {
4848
5003
  role: "user",
4849
5004
  content: [
4850
5005
  {
4851
5006
  type: "file",
4852
- // @ts-expect-error - TODO: fix this type issue somehow
4853
- data: attachment.content?.[0]?.text || "",
5007
+ data: `data:application/pdf;base64,${pdfText}`,
4854
5008
  mimeType: attachment.contentType,
4855
5009
  filename: attachment.name
4856
5010
  }
@@ -5236,6 +5390,10 @@ function useAgentModelSettingsState({ agentId }) {
5236
5390
  const resetAll = () => {
5237
5391
  setModelSettingsState(defaultModelSettings$1);
5238
5392
  setChatWithGenerate(false);
5393
+ localStorage.setItem(
5394
+ LOCAL_STORAGE_KEY,
5395
+ JSON.stringify({ modelSettings: defaultModelSettings$1, chatWithGenerate: false, agentId })
5396
+ );
5239
5397
  };
5240
5398
  return {
5241
5399
  modelSettings,
@@ -7172,25 +7330,6 @@ const useVNextNetworkChat = () => {
7172
7330
  return context;
7173
7331
  };
7174
7332
 
7175
- function Spinner({ color = "#fff", className }) {
7176
- return /* @__PURE__ */ jsx(
7177
- "svg",
7178
- {
7179
- className: cn("animate-spin duration-700", className),
7180
- xmlns: "http://www.w3.org/2000/svg",
7181
- width: "24",
7182
- height: "24",
7183
- viewBox: "0 0 24 24",
7184
- fill: "none",
7185
- stroke: "currentColor",
7186
- strokeWidth: "2",
7187
- strokeLinecap: "round",
7188
- strokeLinejoin: "round",
7189
- children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
7190
- }
7191
- );
7192
- }
7193
-
7194
7333
  const Clock = ({ startedAt, endedAt }) => {
7195
7334
  const [time, setTime] = useState(startedAt);
7196
7335
  useEffect(() => {