@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/LICENSE.md CHANGED
@@ -1,46 +1,15 @@
1
- # Elastic License 2.0 (ELv2)
1
+ # Apache License 2.0
2
2
 
3
- Copyright (c) 2025 Mastra AI, Inc.
3
+ Copyright (c) 2025 Kepler Software, Inc.
4
4
 
5
- **Acceptance**
6
- By using the software, you agree to all of the terms and conditions below.
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
7
8
 
8
- **Copyright License**
9
- The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
10
 
11
- **Limitations**
12
- You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
13
-
14
- You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key.
15
-
16
- You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
17
-
18
- **Patents**
19
- The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
20
-
21
- **Notices**
22
- You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
23
-
24
- If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
25
-
26
- **No Other Rights**
27
- These terms do not imply any licenses other than those expressly granted in these terms.
28
-
29
- **Termination**
30
- If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
31
-
32
- **No Liability**
33
- As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
34
-
35
- **Definitions**
36
- The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it.
37
-
38
- _you_ refers to the individual or entity agreeing to these terms.
39
-
40
- _your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
41
-
42
- _your licenses_ are all the licenses granted to you for the software under these terms.
43
-
44
- _use_ means anything you do with the software requiring one of your licenses.
45
-
46
- _trademark_ means trademarks, service marks, and similar rights.
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/dist/index.cjs.js CHANGED
@@ -20,8 +20,8 @@ const highlight$1 = require('@lezer/highlight');
20
20
  const codemirrorThemeDracula = require('@uiw/codemirror-theme-dracula');
21
21
  const CodeMirror = require('@uiw/react-codemirror');
22
22
  const sonner = require('sonner');
23
- const DialogPrimitive = require('@radix-ui/react-dialog');
24
23
  const shallow = require('zustand/shallow');
24
+ const DialogPrimitive = require('@radix-ui/react-dialog');
25
25
  const di = require('@mastra/core/di');
26
26
  const zustand = require('zustand');
27
27
  const middleware = require('zustand/middleware');
@@ -3199,46 +3199,6 @@ const AvatarFallback = React__namespace.forwardRef(({ className, ...props }, ref
3199
3199
  ));
3200
3200
  AvatarFallback.displayName = AvatarPrimitive__namespace.Fallback.displayName;
3201
3201
 
3202
- const ImageWithFallback = ({ alt, src, ...rest }) => {
3203
- const [error, setError] = React.useState(false);
3204
- React.useEffect(() => {
3205
- setError(false);
3206
- }, [src]);
3207
- return error || !src ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3208
- /* @__PURE__ */ jsxRuntime.jsx(
3209
- "svg",
3210
- {
3211
- xmlns: "http://www.w3.org/2000/svg",
3212
- fill: "none",
3213
- viewBox: "0 0 24 24",
3214
- strokeWidth: "1.5",
3215
- stroke: "currentColor",
3216
- width: "150",
3217
- height: "150",
3218
- children: /* @__PURE__ */ jsxRuntime.jsx(
3219
- "path",
3220
- {
3221
- strokeLinecap: "round",
3222
- strokeLinejoin: "round",
3223
- 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"
3224
- }
3225
- )
3226
- }
3227
- ),
3228
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs italic text-muted-foreground -mt-[0.625rem] mb-[0.625rem]", children: "Image link is broken" })
3229
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3230
- "img",
3231
- {
3232
- src,
3233
- alt,
3234
- ...rest,
3235
- onError: () => {
3236
- setError(true);
3237
- }
3238
- }
3239
- );
3240
- };
3241
-
3242
3202
  const SyntaxHighlighter$3 = reactSyntaxHighlighter.makePrismAsyncSyntaxHighlighter({
3243
3203
  style: prism.coldarkDark,
3244
3204
  customStyle: {
@@ -3311,6 +3271,45 @@ const useCopyToClipboard$1 = ({
3311
3271
  };
3312
3272
  return { isCopied, copyToClipboard };
3313
3273
  };
3274
+ const ImageWithFallback = ({ alt, src, ...rest }) => {
3275
+ const [error, setError] = React.useState(false);
3276
+ React.useEffect(() => {
3277
+ setError(false);
3278
+ }, [src]);
3279
+ return error || !src ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3280
+ /* @__PURE__ */ jsxRuntime.jsx(
3281
+ "svg",
3282
+ {
3283
+ xmlns: "http://www.w3.org/2000/svg",
3284
+ fill: "none",
3285
+ viewBox: "0 0 24 24",
3286
+ strokeWidth: "1.5",
3287
+ stroke: "currentColor",
3288
+ width: "150",
3289
+ height: "150",
3290
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3291
+ "path",
3292
+ {
3293
+ strokeLinecap: "round",
3294
+ strokeLinejoin: "round",
3295
+ 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"
3296
+ }
3297
+ )
3298
+ }
3299
+ ),
3300
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs italic text-muted-foreground -mt-[0.625rem] mb-[0.625rem]", children: "Image link is broken" })
3301
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3302
+ "img",
3303
+ {
3304
+ src,
3305
+ alt,
3306
+ ...rest,
3307
+ onError: () => {
3308
+ setError(true);
3309
+ }
3310
+ }
3311
+ );
3312
+ };
3314
3313
  const defaultComponents = reactMarkdown.unstable_memoizeMarkdownComponents({
3315
3314
  h1: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
3316
3315
  "h1",
@@ -4386,9 +4385,7 @@ const ToolFallback$1 = ({ toolName, argsText, result }) => {
4386
4385
  ] });
4387
4386
  };
4388
4387
 
4389
- const AssistantMessage = ({
4390
- ToolFallback: ToolFallbackCustom
4391
- }) => {
4388
+ const AssistantMessage = ({ ToolFallback: ToolFallbackCustom }) => {
4392
4389
  const data = react.useMessage();
4393
4390
  const isSolelyToolCall = data.content.length === 1 && data.content[0].type === "tool-call";
4394
4391
  return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "max-w-full", children: [
@@ -4420,8 +4417,36 @@ const AssistantActionBar$1 = () => {
4420
4417
  );
4421
4418
  };
4422
4419
 
4420
+ const useFileSrc = (file) => {
4421
+ const [src, setSrc] = React.useState(void 0);
4422
+ React.useEffect(() => {
4423
+ if (!file) {
4424
+ setSrc(void 0);
4425
+ return;
4426
+ }
4427
+ const objectUrl = URL.createObjectURL(file);
4428
+ setSrc(objectUrl);
4429
+ return () => {
4430
+ URL.revokeObjectURL(objectUrl);
4431
+ };
4432
+ }, [file]);
4433
+ return src;
4434
+ };
4435
+
4436
+ const useAttachmentSrc = () => {
4437
+ const { file, src } = react.useAttachment(
4438
+ shallow.useShallow((a) => {
4439
+ if (a.type !== "image") return {};
4440
+ if (a.file) return { file: a.file };
4441
+ const src2 = a.content?.filter((c) => c.type === "image")[0]?.image;
4442
+ if (!src2) return {};
4443
+ return { src: src2 };
4444
+ })
4445
+ );
4446
+ return useFileSrc(file) ?? src;
4447
+ };
4448
+
4423
4449
  const Dialog = DialogPrimitive__namespace.Root;
4424
- const DialogTrigger = DialogPrimitive__namespace.Trigger;
4425
4450
  const DialogPortal = DialogPrimitive__namespace.Portal;
4426
4451
  const DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4427
4452
  DialogPrimitive__namespace.Overlay,
@@ -4469,107 +4494,137 @@ DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
4469
4494
  const DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
4470
4495
  DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
4471
4496
 
4472
- const useHasAttachments = () => {
4473
- const composer = react.useComposerRuntime();
4474
- const [hasAttachments, setHasAttachments] = React.useState(false);
4475
- React.useEffect(() => {
4476
- composer.subscribe(() => {
4477
- const attachments = composer.getState().attachments;
4478
- setHasAttachments(attachments.length > 0);
4479
- });
4480
- }, [composer]);
4481
- return hasAttachments;
4497
+ const PdfEntry = ({ data }) => {
4498
+ const [open, setOpen] = React.useState(false);
4499
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4500
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setOpen(true), className: "h-full w-full flex items-center justify-center", type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "text-accent2" }) }),
4501
+ /* @__PURE__ */ jsxRuntime.jsx(PdfPreviewDialog, { data, open, onOpenChange: setOpen })
4502
+ ] });
4482
4503
  };
4483
-
4484
- const useFileSrc = (file) => {
4485
- const [src, setSrc] = React.useState(void 0);
4486
- React.useEffect(() => {
4487
- if (!file) {
4488
- setSrc(void 0);
4489
- return;
4490
- }
4491
- const objectUrl = URL.createObjectURL(file);
4492
- setSrc(objectUrl);
4493
- return () => {
4494
- URL.revokeObjectURL(objectUrl);
4495
- };
4496
- }, [file]);
4497
- return src;
4504
+ const PdfPreviewDialog = ({ data, open, onOpenChange }) => {
4505
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { className: "max-w-4xl bg-surface2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full w-full", children: [
4506
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "pb-4", children: "PDF preview" }),
4507
+ open && /* @__PURE__ */ jsxRuntime.jsx("iframe", { src: data, width: "100%", height: "600px" })
4508
+ ] }) }) });
4498
4509
  };
4499
- const useAttachmentSrc = () => {
4500
- const { file, src } = react.useAttachment(
4501
- shallow.useShallow((a) => {
4502
- if (a.type !== "image") return {};
4503
- if (a.file) return { file: a.file };
4504
- const src2 = a.content?.filter((c) => c.type === "image")[0]?.image;
4505
- if (!src2) return {};
4506
- return { src: src2 };
4507
- })
4508
- );
4509
- return useFileSrc(file) ?? src;
4510
+ const ImageEntry = ({ src }) => {
4511
+ const [open, setOpen] = React.useState(false);
4512
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4513
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setOpen(true), type: "button", className: "h-full w-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, className: "object-cover aspect-ratio max-h-[140px] max-w-[320px]", alt: "Preview" }) }),
4514
+ /* @__PURE__ */ jsxRuntime.jsx(ImagePreviewDialog, { src, open, onOpenChange: setOpen })
4515
+ ] });
4510
4516
  };
4511
- const AttachmentPreview = ({ src }) => {
4512
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden w-full", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, className: "object-contain aspect-ratio h-full w-full", alt: "Preview" }) });
4517
+ const ImagePreviewDialog = ({ src, open, onOpenChange }) => {
4518
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { className: "max-w-4xl bg-surface2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full w-full", children: [
4519
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "pb-4", children: "Image preview" }),
4520
+ open && /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: "Image" })
4521
+ ] }) }) });
4513
4522
  };
4514
- const AttachmentPreviewDialog = ({ children }) => {
4515
- const src = useAttachmentSrc();
4516
- if (!src) return children;
4517
- return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { children: [
4518
- /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { className: "hover:bg-accent/50 cursor-pointer transition-colors", asChild: true, children }),
4519
- /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
4520
- /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
4521
- /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "max-w-5xl w-full max-h-[80%]", children: [
4522
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "aui-sr-only", children: "Image Attachment Preview" }),
4523
- /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, { src })
4524
- ] })
4525
- ] })
4523
+ const TxtEntry = ({ data }) => {
4524
+ const [open, setOpen] = React.useState(false);
4525
+ const formattedContent = data.replace(/<attachment[^>]*>/, "").replace(/<\/attachment>/g, "");
4526
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4527
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setOpen(true), className: "h-full w-full flex items-center justify-center", type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "text-icon3" }) }),
4528
+ /* @__PURE__ */ jsxRuntime.jsx(TxtPreviewDialog, { data: formattedContent, open, onOpenChange: setOpen })
4526
4529
  ] });
4527
4530
  };
4528
- const AttachmentThumbnail = () => {
4529
- const isImage = react.useAttachment((a) => a.type === "image");
4530
- const document = react.useAttachment((a) => a.type === "document" ? a : void 0);
4531
- const src = useAttachmentSrc();
4532
- const canRemove = react.useAttachment((a) => a.source !== "message");
4533
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
4534
- /* @__PURE__ */ jsxRuntime.jsxs(react.AttachmentPrimitive.Root, { className: "relative", children: [
4535
- /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, className: "object-cover aspect-ratio size-16", alt: "Preview", height: 64, width: 64 }) }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "text-accent2" }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileIcon, { className: "text-icon3" }) }) }) }) }),
4536
- canRemove && /* @__PURE__ */ jsxRuntime.jsx(AttachmentRemove, {})
4537
- ] }),
4538
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}) })
4539
- ] }) });
4531
+ const TxtPreviewDialog = ({ data, open, onOpenChange }) => {
4532
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { className: "max-w-4xl bg-surface2 h-[80vh] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full w-full", children: [
4533
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "pb-4", children: "Text preview" }),
4534
+ open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap", children: data })
4535
+ ] }) }) });
4540
4536
  };
4541
- const AttachmentRemove = () => {
4542
- return /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4543
- TooltipIconButton,
4537
+
4538
+ const InMessageContextWrapper = () => {
4539
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Root, { className: "pt-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsxRuntime.jsx(InMessageAttachmentWrapper, {}) }) });
4540
+ };
4541
+ const InMessageAttachmentWrapper = () => {
4542
+ const src = useAttachmentSrc();
4543
+ const attachment = react.useAttachment((a) => a);
4544
+ if (attachment.type === "image") {
4545
+ return /* @__PURE__ */ jsxRuntime.jsx(
4546
+ InMessageAttachment,
4547
+ {
4548
+ type: "image",
4549
+ contentType: void 0,
4550
+ nameSlot: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}),
4551
+ src,
4552
+ data: void 0
4553
+ }
4554
+ );
4555
+ }
4556
+ if (attachment.contentType === "application/pdf") {
4557
+ const pdfText = attachment.content?.[0]?.text;
4558
+ return /* @__PURE__ */ jsxRuntime.jsx(
4559
+ InMessageAttachment,
4560
+ {
4561
+ type: "document",
4562
+ contentType: attachment.contentType,
4563
+ nameSlot: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}),
4564
+ src,
4565
+ data: `data:application/pdf;base64,${pdfText}`
4566
+ }
4567
+ );
4568
+ }
4569
+ return /* @__PURE__ */ jsxRuntime.jsx(
4570
+ InMessageAttachment,
4544
4571
  {
4545
- tooltip: "Remove file",
4546
- className: "absolute -right-3 -top-3 hover:bg-transparent rounded-full bg-surface1 rounded-full p-1",
4547
- side: "top",
4548
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleXIcon, {}) })
4572
+ type: attachment.type,
4573
+ contentType: attachment.contentType,
4574
+ nameSlot: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}),
4575
+ src,
4576
+ data: attachment.content?.[0]?.text
4549
4577
  }
4550
- ) });
4551
- };
4552
- const UserMessageAttachments = () => {
4553
- return /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Attachments, { components: { Attachment: InMessageAttachment } });
4578
+ );
4554
4579
  };
4555
- const InMessageAttachment = () => {
4556
- const isImage = react.useAttachment((a) => a.type === "image");
4557
- const document = react.useAttachment((a) => a.type === "document" ? a : void 0);
4558
- const src = useAttachmentSrc();
4580
+ const InMessageAttachment = ({ type, contentType, nameSlot, src, data }) => {
4559
4581
  return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
4560
- /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Root, { className: "relative pt-4", children: /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreviewDialog, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full aspect-ratio overflow-hidden rounded-lg", children: isImage ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, className: "object-cover aspect-ratio max-h-[140px] max-w-[320px]", alt: "Preview" }) }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "text-accent2" }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border-sm border-border1 flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileIcon, { className: "text-icon3" }) }) }) }) }) }),
4561
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}) })
4582
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full overflow-hidden rounded-lg", children: type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(ImageEntry, { src: src ?? "" }) : type === "document" && contentType === "application/pdf" ? /* @__PURE__ */ jsxRuntime.jsx(PdfEntry, { data: data ?? "" }) : /* @__PURE__ */ jsxRuntime.jsx(TxtEntry, { data: data ?? "" }) }) }),
4583
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: nameSlot })
4562
4584
  ] }) });
4563
4585
  };
4564
- const ComposerAttachments = () => {
4565
- const hasAttachments = useHasAttachments();
4566
- if (!hasAttachments) return null;
4567
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-row items-center gap-4 h-24", children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4586
+ const UserMessageAttachments = () => {
4587
+ return /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Attachments, { components: { Attachment: InMessageContextWrapper } });
4568
4588
  };
4569
-
4570
4589
  const UserMessage = () => {
4571
4590
  return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", children: [
4572
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Content, {}) }),
4591
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsxRuntime.jsx(
4592
+ react.MessagePrimitive.Content,
4593
+ {
4594
+ components: {
4595
+ File: (p) => {
4596
+ return /* @__PURE__ */ jsxRuntime.jsx(
4597
+ InMessageAttachment,
4598
+ {
4599
+ type: "document",
4600
+ contentType: p.mimeType,
4601
+ nameSlot: "Unknown filename",
4602
+ src: void 0,
4603
+ data: p.image
4604
+ }
4605
+ );
4606
+ },
4607
+ Image: (p) => {
4608
+ return /* @__PURE__ */ jsxRuntime.jsx(InMessageAttachment, { type: "image", nameSlot: "Unknown filename", src: p.image });
4609
+ },
4610
+ Text: (p) => {
4611
+ if (p.text.includes("<attachment name=")) {
4612
+ return /* @__PURE__ */ jsxRuntime.jsx(
4613
+ InMessageAttachment,
4614
+ {
4615
+ type: "document",
4616
+ contentType: "text/plain",
4617
+ nameSlot: "Unknown filename",
4618
+ src: void 0,
4619
+ data: p.text
4620
+ }
4621
+ );
4622
+ }
4623
+ return p.text;
4624
+ }
4625
+ }
4626
+ }
4627
+ ) }),
4573
4628
  /* @__PURE__ */ jsxRuntime.jsx(UserMessageAttachments, {})
4574
4629
  ] });
4575
4630
  };
@@ -4676,6 +4731,123 @@ const useSpeechRecognition = ({ language = "en-US" } = {}) => {
4676
4731
  };
4677
4732
  };
4678
4733
 
4734
+ const useHasAttachments = () => {
4735
+ const composer = react.useComposerRuntime();
4736
+ const [hasAttachments, setHasAttachments] = React.useState(false);
4737
+ React.useEffect(() => {
4738
+ composer.subscribe(() => {
4739
+ const attachments = composer.getState().attachments;
4740
+ setHasAttachments(attachments.length > 0);
4741
+ });
4742
+ }, [composer]);
4743
+ return hasAttachments;
4744
+ };
4745
+
4746
+ function Spinner({ color = "#fff", className }) {
4747
+ return /* @__PURE__ */ jsxRuntime.jsx(
4748
+ "svg",
4749
+ {
4750
+ className: cn("animate-spin duration-700", className),
4751
+ xmlns: "http://www.w3.org/2000/svg",
4752
+ width: "24",
4753
+ height: "24",
4754
+ viewBox: "0 0 24 24",
4755
+ fill: "none",
4756
+ stroke: "currentColor",
4757
+ strokeWidth: "2",
4758
+ strokeLinecap: "round",
4759
+ strokeLinejoin: "round",
4760
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
4761
+ }
4762
+ );
4763
+ }
4764
+
4765
+ const useLoadBrowserFile = (file) => {
4766
+ const [state, setState] = React.useState({ isLoading: false, text: "" });
4767
+ React.useEffect(() => {
4768
+ if (!file) return;
4769
+ const run = async () => {
4770
+ setState((s) => ({ ...s, isLoading: true }));
4771
+ const text = await file.text();
4772
+ setState((s) => ({ ...s, isLoading: false, text }));
4773
+ };
4774
+ run();
4775
+ }, [file]);
4776
+ return state;
4777
+ };
4778
+
4779
+ const fileToBase64 = async (file) => {
4780
+ return new Promise((resolve, reject) => {
4781
+ const reader = new FileReader();
4782
+ reader.onload = () => {
4783
+ const result = reader.result;
4784
+ if (typeof result === "string") {
4785
+ resolve(result);
4786
+ } else {
4787
+ reject(new Error("Failed to convert file to base64."));
4788
+ }
4789
+ };
4790
+ reader.onerror = (error) => {
4791
+ reject(error);
4792
+ };
4793
+ reader.readAsDataURL(file);
4794
+ });
4795
+ };
4796
+
4797
+ const ComposerTxtAttachment = ({ document }) => {
4798
+ const { isLoading, text } = useLoadBrowserFile(document.file);
4799
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full w-full", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(TxtEntry, { data: text }) });
4800
+ };
4801
+ const ComposerPdfAttachment = ({ document }) => {
4802
+ const [state, setState] = React.useState({ isLoading: false, text: "" });
4803
+ React.useEffect(() => {
4804
+ let isCanceled = false;
4805
+ const run = async () => {
4806
+ if (!document.file) return;
4807
+ setState((s) => ({ ...s, isLoading: true }));
4808
+ const text = await fileToBase64(document.file);
4809
+ if (isCanceled) {
4810
+ return;
4811
+ }
4812
+ setState((s) => ({ ...s, isLoading: false, text }));
4813
+ };
4814
+ run();
4815
+ return () => {
4816
+ isCanceled = true;
4817
+ };
4818
+ }, [document]);
4819
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full w-full", children: state.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(PdfEntry, { data: state.text }) });
4820
+ };
4821
+ const AttachmentThumbnail = () => {
4822
+ const isImage = react.useAttachment((a) => a.type === "image");
4823
+ const document = react.useAttachment((a) => a.type === "document" ? a : void 0);
4824
+ const src = useAttachmentSrc();
4825
+ const canRemove = react.useAttachment((a) => a.source !== "message");
4826
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
4827
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
4828
+ /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden size-16 rounded-lg bg-surface3 border-sm border-border1 ", children: isImage ? /* @__PURE__ */ jsxRuntime.jsx(ImageEntry, { src: src ?? "" }) : document?.contentType === "application/pdf" ? /* @__PURE__ */ jsxRuntime.jsx(ComposerPdfAttachment, { document }) : document ? /* @__PURE__ */ jsxRuntime.jsx(ComposerTxtAttachment, { document }) : null }) }) }),
4829
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}) })
4830
+ ] }) }),
4831
+ canRemove && /* @__PURE__ */ jsxRuntime.jsx(AttachmentRemove, {})
4832
+ ] }) });
4833
+ };
4834
+ const AttachmentRemove = () => {
4835
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4836
+ TooltipIconButton,
4837
+ {
4838
+ tooltip: "Remove file",
4839
+ className: "absolute -right-3 -top-3 text-icon3 hover:text-icon6 rounded-full bg-surface1 hover:bg-surface2 rounded-full p-1",
4840
+ side: "top",
4841
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleXIcon, {}) })
4842
+ }
4843
+ ) });
4844
+ };
4845
+ const ComposerAttachments = () => {
4846
+ const hasAttachments = useHasAttachments();
4847
+ if (!hasAttachments) return null;
4848
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-row items-center gap-4 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4849
+ };
4850
+
4679
4851
  const Thread = ({ ToolFallback, agentName, hasMemory, showFileSupport }) => {
4680
4852
  const areaRef = React.useRef(null);
4681
4853
  useAutoscroll(areaRef, { enabled: true });
@@ -4722,7 +4894,7 @@ const ThreadWelcome$1 = ({ agentName }) => {
4722
4894
  const Composer$1 = ({ hasMemory, showFileSupport }) => {
4723
4895
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4", children: [
4724
4896
  /* @__PURE__ */ jsxRuntime.jsxs(react.ComposerPrimitive.Root, { children: [
4725
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[568px] w-full mx-auto px-2 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(ComposerAttachments, {}) }),
4897
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ComposerAttachments, {}) }),
4726
4898
  /* @__PURE__ */ jsxRuntime.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: [
4727
4899
  /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Input, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
4728
4900
  "textarea",
@@ -4793,24 +4965,6 @@ const CircleStopIcon$1 = () => {
4793
4965
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", width: "16", height: "16", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" }) });
4794
4966
  };
4795
4967
 
4796
- const fileToBase64 = async (file) => {
4797
- return new Promise((resolve, reject) => {
4798
- const reader = new FileReader();
4799
- reader.onload = () => {
4800
- const result = reader.result;
4801
- if (typeof result === "string") {
4802
- resolve(result);
4803
- } else {
4804
- reject(new Error("Failed to convert file to base64."));
4805
- }
4806
- };
4807
- reader.onerror = (error) => {
4808
- reject(error);
4809
- };
4810
- reader.readAsDataURL(file);
4811
- });
4812
- };
4813
-
4814
4968
  class PDFAttachmentAdapter {
4815
4969
  accept = "application/pdf";
4816
4970
  async add({ file }) {
@@ -4877,13 +5031,13 @@ const convertToAIAttachments = async (attachments) => {
4877
5031
  const promises = attachments.filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
4878
5032
  if (attachment.type === "document") {
4879
5033
  if (attachment.contentType === "application/pdf") {
5034
+ const pdfText = attachment.content?.[0]?.text || "";
4880
5035
  return {
4881
5036
  role: "user",
4882
5037
  content: [
4883
5038
  {
4884
5039
  type: "file",
4885
- // @ts-expect-error - TODO: fix this type issue somehow
4886
- data: attachment.content?.[0]?.text || "",
5040
+ data: `data:application/pdf;base64,${pdfText}`,
4887
5041
  mimeType: attachment.contentType,
4888
5042
  filename: attachment.name
4889
5043
  }
@@ -5269,6 +5423,10 @@ function useAgentModelSettingsState({ agentId }) {
5269
5423
  const resetAll = () => {
5270
5424
  setModelSettingsState(defaultModelSettings$1);
5271
5425
  setChatWithGenerate(false);
5426
+ localStorage.setItem(
5427
+ LOCAL_STORAGE_KEY,
5428
+ JSON.stringify({ modelSettings: defaultModelSettings$1, chatWithGenerate: false, agentId })
5429
+ );
5272
5430
  };
5273
5431
  return {
5274
5432
  modelSettings,
@@ -7205,25 +7363,6 @@ const useVNextNetworkChat = () => {
7205
7363
  return context;
7206
7364
  };
7207
7365
 
7208
- function Spinner({ color = "#fff", className }) {
7209
- return /* @__PURE__ */ jsxRuntime.jsx(
7210
- "svg",
7211
- {
7212
- className: cn("animate-spin duration-700", className),
7213
- xmlns: "http://www.w3.org/2000/svg",
7214
- width: "24",
7215
- height: "24",
7216
- viewBox: "0 0 24 24",
7217
- fill: "none",
7218
- stroke: "currentColor",
7219
- strokeWidth: "2",
7220
- strokeLinecap: "round",
7221
- strokeLinejoin: "round",
7222
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", stroke: color })
7223
- }
7224
- );
7225
- }
7226
-
7227
7366
  const Clock = ({ startedAt, endedAt }) => {
7228
7367
  const [time, setTime] = React.useState(startedAt);
7229
7368
  React.useEffect(() => {