@assistant-ui/mcp-docs-server 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/store-example.md +554 -0
- package/.docs/organized/code-examples/with-ag-ui.md +582 -32
- package/.docs/organized/code-examples/with-ai-sdk-v5.md +549 -47
- package/.docs/organized/code-examples/with-assistant-transport.md +547 -46
- package/.docs/organized/code-examples/with-cloud.md +634 -39
- package/.docs/organized/code-examples/with-external-store.md +581 -31
- package/.docs/organized/code-examples/with-ffmpeg.md +581 -47
- package/.docs/organized/code-examples/with-langgraph.md +633 -50
- package/.docs/organized/code-examples/with-parent-id-grouping.md +581 -31
- package/.docs/organized/code-examples/with-react-hook-form.md +582 -70
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -1
- package/.docs/raw/docs/cli.mdx +396 -0
- package/.docs/raw/docs/getting-started.mdx +31 -37
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +891 -0
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +1 -1
- package/package.json +13 -5
|
@@ -274,6 +274,247 @@ export default function Home() {
|
|
|
274
274
|
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
+
## components/assistant-ui/attachment.tsx
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
"use client";
|
|
281
|
+
|
|
282
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
283
|
+
import Image from "next/image";
|
|
284
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
285
|
+
import {
|
|
286
|
+
AttachmentPrimitive,
|
|
287
|
+
ComposerPrimitive,
|
|
288
|
+
MessagePrimitive,
|
|
289
|
+
useAssistantState,
|
|
290
|
+
useAssistantApi,
|
|
291
|
+
} from "@assistant-ui/react";
|
|
292
|
+
import { useShallow } from "zustand/shallow";
|
|
293
|
+
import {
|
|
294
|
+
Tooltip,
|
|
295
|
+
TooltipContent,
|
|
296
|
+
TooltipTrigger,
|
|
297
|
+
} from "@/components/ui/tooltip";
|
|
298
|
+
import {
|
|
299
|
+
Dialog,
|
|
300
|
+
DialogTitle,
|
|
301
|
+
DialogContent,
|
|
302
|
+
DialogTrigger,
|
|
303
|
+
} from "@/components/ui/dialog";
|
|
304
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
305
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
306
|
+
import { cn } from "@/lib/utils";
|
|
307
|
+
|
|
308
|
+
const useFileSrc = (file: File | undefined) => {
|
|
309
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
310
|
+
|
|
311
|
+
useEffect(() => {
|
|
312
|
+
if (!file) {
|
|
313
|
+
setSrc(undefined);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const objectUrl = URL.createObjectURL(file);
|
|
318
|
+
setSrc(objectUrl);
|
|
319
|
+
|
|
320
|
+
return () => {
|
|
321
|
+
URL.revokeObjectURL(objectUrl);
|
|
322
|
+
};
|
|
323
|
+
}, [file]);
|
|
324
|
+
|
|
325
|
+
return src;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const useAttachmentSrc = () => {
|
|
329
|
+
const { file, src } = useAssistantState(
|
|
330
|
+
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
331
|
+
if (attachment.type !== "image") return {};
|
|
332
|
+
if (attachment.file) return { file: attachment.file };
|
|
333
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
334
|
+
?.image;
|
|
335
|
+
if (!src) return {};
|
|
336
|
+
return { src };
|
|
337
|
+
}),
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
return useFileSrc(file) ?? src;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
type AttachmentPreviewProps = {
|
|
344
|
+
src: string;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
348
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
349
|
+
return (
|
|
350
|
+
<Image
|
|
351
|
+
src={src}
|
|
352
|
+
alt="Image Preview"
|
|
353
|
+
width={1}
|
|
354
|
+
height={1}
|
|
355
|
+
className={
|
|
356
|
+
isLoaded
|
|
357
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
358
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
359
|
+
}
|
|
360
|
+
onLoadingComplete={() => setIsLoaded(true)}
|
|
361
|
+
priority={false}
|
|
362
|
+
/>
|
|
363
|
+
);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
367
|
+
const src = useAttachmentSrc();
|
|
368
|
+
|
|
369
|
+
if (!src) return children;
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<Dialog>
|
|
373
|
+
<DialogTrigger
|
|
374
|
+
className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
|
|
375
|
+
asChild
|
|
376
|
+
>
|
|
377
|
+
{children}
|
|
378
|
+
</DialogTrigger>
|
|
379
|
+
<DialogContent className="aui-attachment-preview-dialog-content [&_svg]:text-background [&>button]:bg-foreground/60 [&>button]:hover:[&_svg]:text-destructive p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:p-1 [&>button]:opacity-100 [&>button]:!ring-0">
|
|
380
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
381
|
+
Image Attachment Preview
|
|
382
|
+
</DialogTitle>
|
|
383
|
+
<div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
|
|
384
|
+
<AttachmentPreview src={src} />
|
|
385
|
+
</div>
|
|
386
|
+
</DialogContent>
|
|
387
|
+
</Dialog>
|
|
388
|
+
);
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
const AttachmentThumb: FC = () => {
|
|
392
|
+
const isImage = useAssistantState(
|
|
393
|
+
({ attachment }) => attachment.type === "image",
|
|
394
|
+
);
|
|
395
|
+
const src = useAttachmentSrc();
|
|
396
|
+
|
|
397
|
+
return (
|
|
398
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
399
|
+
<AvatarImage
|
|
400
|
+
src={src}
|
|
401
|
+
alt="Attachment preview"
|
|
402
|
+
className="aui-attachment-tile-image object-cover"
|
|
403
|
+
/>
|
|
404
|
+
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
405
|
+
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
|
|
406
|
+
</AvatarFallback>
|
|
407
|
+
</Avatar>
|
|
408
|
+
);
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
const AttachmentUI: FC = () => {
|
|
412
|
+
const api = useAssistantApi();
|
|
413
|
+
const isComposer = api.attachment.source === "composer";
|
|
414
|
+
|
|
415
|
+
const isImage = useAssistantState(
|
|
416
|
+
({ attachment }) => attachment.type === "image",
|
|
417
|
+
);
|
|
418
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
419
|
+
const type = attachment.type;
|
|
420
|
+
switch (type) {
|
|
421
|
+
case "image":
|
|
422
|
+
return "Image";
|
|
423
|
+
case "document":
|
|
424
|
+
return "Document";
|
|
425
|
+
case "file":
|
|
426
|
+
return "File";
|
|
427
|
+
default:
|
|
428
|
+
const _exhaustiveCheck: never = type;
|
|
429
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
return (
|
|
434
|
+
<Tooltip>
|
|
435
|
+
<AttachmentPrimitive.Root
|
|
436
|
+
className={cn(
|
|
437
|
+
"aui-attachment-root relative",
|
|
438
|
+
isImage &&
|
|
439
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
440
|
+
)}
|
|
441
|
+
>
|
|
442
|
+
<AttachmentPreviewDialog>
|
|
443
|
+
<TooltipTrigger asChild>
|
|
444
|
+
<div
|
|
445
|
+
className={cn(
|
|
446
|
+
"aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
|
|
447
|
+
isComposer &&
|
|
448
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
449
|
+
)}
|
|
450
|
+
role="button"
|
|
451
|
+
id="attachment-tile"
|
|
452
|
+
aria-label={`${typeLabel} attachment`}
|
|
453
|
+
>
|
|
454
|
+
<AttachmentThumb />
|
|
455
|
+
</div>
|
|
456
|
+
</TooltipTrigger>
|
|
457
|
+
</AttachmentPreviewDialog>
|
|
458
|
+
{isComposer && <AttachmentRemove />}
|
|
459
|
+
</AttachmentPrimitive.Root>
|
|
460
|
+
<TooltipContent side="top">
|
|
461
|
+
<AttachmentPrimitive.Name />
|
|
462
|
+
</TooltipContent>
|
|
463
|
+
</Tooltip>
|
|
464
|
+
);
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const AttachmentRemove: FC = () => {
|
|
468
|
+
return (
|
|
469
|
+
<AttachmentPrimitive.Remove asChild>
|
|
470
|
+
<TooltipIconButton
|
|
471
|
+
tooltip="Remove file"
|
|
472
|
+
className="aui-attachment-tile-remove text-muted-foreground hover:[&_svg]:text-destructive absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white opacity-100 shadow-sm hover:!bg-white [&_svg]:text-black"
|
|
473
|
+
side="top"
|
|
474
|
+
>
|
|
475
|
+
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
476
|
+
</TooltipIconButton>
|
|
477
|
+
</AttachmentPrimitive.Remove>
|
|
478
|
+
);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export const UserMessageAttachments: FC = () => {
|
|
482
|
+
return (
|
|
483
|
+
<div className="aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2">
|
|
484
|
+
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
485
|
+
</div>
|
|
486
|
+
);
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
export const ComposerAttachments: FC = () => {
|
|
490
|
+
return (
|
|
491
|
+
<div className="aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden">
|
|
492
|
+
<ComposerPrimitive.Attachments
|
|
493
|
+
components={{ Attachment: AttachmentUI }}
|
|
494
|
+
/>
|
|
495
|
+
</div>
|
|
496
|
+
);
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
export const ComposerAddAttachment: FC = () => {
|
|
500
|
+
return (
|
|
501
|
+
<ComposerPrimitive.AddAttachment asChild>
|
|
502
|
+
<TooltipIconButton
|
|
503
|
+
tooltip="Add Attachment"
|
|
504
|
+
side="bottom"
|
|
505
|
+
variant="ghost"
|
|
506
|
+
size="icon"
|
|
507
|
+
className="aui-composer-add-attachment hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30 size-[34px] rounded-full p-1 text-xs font-semibold"
|
|
508
|
+
aria-label="Add Attachment"
|
|
509
|
+
>
|
|
510
|
+
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
511
|
+
</TooltipIconButton>
|
|
512
|
+
</ComposerPrimitive.AddAttachment>
|
|
513
|
+
);
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
```
|
|
517
|
+
|
|
277
518
|
## components/assistant-ui/markdown-text.tsx
|
|
278
519
|
|
|
279
520
|
```tsx
|
|
@@ -282,13 +523,13 @@ export default function Home() {
|
|
|
282
523
|
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
283
524
|
|
|
284
525
|
import {
|
|
285
|
-
CodeHeaderProps,
|
|
526
|
+
type CodeHeaderProps,
|
|
286
527
|
MarkdownTextPrimitive,
|
|
287
528
|
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
288
529
|
useIsMarkdownCodeBlock,
|
|
289
530
|
} from "@assistant-ui/react-markdown";
|
|
290
531
|
import remarkGfm from "remark-gfm";
|
|
291
|
-
import { FC, memo, useState } from "react";
|
|
532
|
+
import { type FC, memo, useState } from "react";
|
|
292
533
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
293
534
|
|
|
294
535
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
@@ -314,8 +555,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
|
|
|
314
555
|
};
|
|
315
556
|
|
|
316
557
|
return (
|
|
317
|
-
<div className="flex items-center justify-between gap-4 rounded-t-lg
|
|
318
|
-
<span className="lowercase [&>span]:text-xs">
|
|
558
|
+
<div className="aui-code-header-root bg-muted-foreground/15 text-foreground dark:bg-muted-foreground/20 mt-4 flex items-center justify-between gap-4 rounded-t-lg px-4 py-2 text-sm font-semibold">
|
|
559
|
+
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
560
|
+
{language}
|
|
561
|
+
</span>
|
|
319
562
|
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
320
563
|
{!isCopied && <CopyIcon />}
|
|
321
564
|
{isCopied && <CheckIcon />}
|
|
@@ -347,7 +590,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
347
590
|
h1: ({ className, ...props }) => (
|
|
348
591
|
<h1
|
|
349
592
|
className={cn(
|
|
350
|
-
"mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
593
|
+
"aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
351
594
|
className,
|
|
352
595
|
)}
|
|
353
596
|
{...props}
|
|
@@ -356,7 +599,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
356
599
|
h2: ({ className, ...props }) => (
|
|
357
600
|
<h2
|
|
358
601
|
className={cn(
|
|
359
|
-
"mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
602
|
+
"aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
360
603
|
className,
|
|
361
604
|
)}
|
|
362
605
|
{...props}
|
|
@@ -365,7 +608,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
365
608
|
h3: ({ className, ...props }) => (
|
|
366
609
|
<h3
|
|
367
610
|
className={cn(
|
|
368
|
-
"mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
611
|
+
"aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
369
612
|
className,
|
|
370
613
|
)}
|
|
371
614
|
{...props}
|
|
@@ -374,7 +617,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
374
617
|
h4: ({ className, ...props }) => (
|
|
375
618
|
<h4
|
|
376
619
|
className={cn(
|
|
377
|
-
"mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
620
|
+
"aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
378
621
|
className,
|
|
379
622
|
)}
|
|
380
623
|
{...props}
|
|
@@ -383,7 +626,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
383
626
|
h5: ({ className, ...props }) => (
|
|
384
627
|
<h5
|
|
385
628
|
className={cn(
|
|
386
|
-
"my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
629
|
+
"aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
387
630
|
className,
|
|
388
631
|
)}
|
|
389
632
|
{...props}
|
|
@@ -391,20 +634,26 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
391
634
|
),
|
|
392
635
|
h6: ({ className, ...props }) => (
|
|
393
636
|
<h6
|
|
394
|
-
className={cn(
|
|
637
|
+
className={cn(
|
|
638
|
+
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
639
|
+
className,
|
|
640
|
+
)}
|
|
395
641
|
{...props}
|
|
396
642
|
/>
|
|
397
643
|
),
|
|
398
644
|
p: ({ className, ...props }) => (
|
|
399
645
|
<p
|
|
400
|
-
className={cn(
|
|
646
|
+
className={cn(
|
|
647
|
+
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
648
|
+
className,
|
|
649
|
+
)}
|
|
401
650
|
{...props}
|
|
402
651
|
/>
|
|
403
652
|
),
|
|
404
653
|
a: ({ className, ...props }) => (
|
|
405
654
|
<a
|
|
406
655
|
className={cn(
|
|
407
|
-
"text-primary font-medium underline underline-offset-4",
|
|
656
|
+
"aui-md-a text-primary font-medium underline underline-offset-4",
|
|
408
657
|
className,
|
|
409
658
|
)}
|
|
410
659
|
{...props}
|
|
@@ -412,29 +661,29 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
412
661
|
),
|
|
413
662
|
blockquote: ({ className, ...props }) => (
|
|
414
663
|
<blockquote
|
|
415
|
-
className={cn("border-l-2 pl-6 italic", className)}
|
|
664
|
+
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
416
665
|
{...props}
|
|
417
666
|
/>
|
|
418
667
|
),
|
|
419
668
|
ul: ({ className, ...props }) => (
|
|
420
669
|
<ul
|
|
421
|
-
className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
670
|
+
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
422
671
|
{...props}
|
|
423
672
|
/>
|
|
424
673
|
),
|
|
425
674
|
ol: ({ className, ...props }) => (
|
|
426
675
|
<ol
|
|
427
|
-
className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
676
|
+
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
428
677
|
{...props}
|
|
429
678
|
/>
|
|
430
679
|
),
|
|
431
680
|
hr: ({ className, ...props }) => (
|
|
432
|
-
<hr className={cn("my-5 border-b", className)} {...props} />
|
|
681
|
+
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
433
682
|
),
|
|
434
683
|
table: ({ className, ...props }) => (
|
|
435
684
|
<table
|
|
436
685
|
className={cn(
|
|
437
|
-
"my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
686
|
+
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
438
687
|
className,
|
|
439
688
|
)}
|
|
440
689
|
{...props}
|
|
@@ -443,7 +692,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
443
692
|
th: ({ className, ...props }) => (
|
|
444
693
|
<th
|
|
445
694
|
className={cn(
|
|
446
|
-
"bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
695
|
+
"aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
447
696
|
className,
|
|
448
697
|
)}
|
|
449
698
|
{...props}
|
|
@@ -452,7 +701,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
452
701
|
td: ({ className, ...props }) => (
|
|
453
702
|
<td
|
|
454
703
|
className={cn(
|
|
455
|
-
"border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
704
|
+
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
456
705
|
className,
|
|
457
706
|
)}
|
|
458
707
|
{...props}
|
|
@@ -461,7 +710,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
461
710
|
tr: ({ className, ...props }) => (
|
|
462
711
|
<tr
|
|
463
712
|
className={cn(
|
|
464
|
-
"m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
713
|
+
"aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
465
714
|
className,
|
|
466
715
|
)}
|
|
467
716
|
{...props}
|
|
@@ -469,14 +718,14 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
469
718
|
),
|
|
470
719
|
sup: ({ className, ...props }) => (
|
|
471
720
|
<sup
|
|
472
|
-
className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
|
|
721
|
+
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
473
722
|
{...props}
|
|
474
723
|
/>
|
|
475
724
|
),
|
|
476
725
|
pre: ({ className, ...props }) => (
|
|
477
726
|
<pre
|
|
478
727
|
className={cn(
|
|
479
|
-
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
|
|
728
|
+
"aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
|
|
480
729
|
className,
|
|
481
730
|
)}
|
|
482
731
|
{...props}
|
|
@@ -487,7 +736,8 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
487
736
|
return (
|
|
488
737
|
<code
|
|
489
738
|
className={cn(
|
|
490
|
-
!isCodeBlock &&
|
|
739
|
+
!isCodeBlock &&
|
|
740
|
+
"aui-md-inline-code bg-muted rounded border font-semibold",
|
|
491
741
|
className,
|
|
492
742
|
)}
|
|
493
743
|
{...props}
|
|
@@ -506,15 +756,17 @@ import type { FC } from "react";
|
|
|
506
756
|
import {
|
|
507
757
|
ThreadListItemPrimitive,
|
|
508
758
|
ThreadListPrimitive,
|
|
759
|
+
useAssistantState,
|
|
509
760
|
} from "@assistant-ui/react";
|
|
510
761
|
import { ArchiveIcon, PlusIcon } from "lucide-react";
|
|
511
762
|
|
|
512
763
|
import { Button } from "@/components/ui/button";
|
|
513
764
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
765
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
514
766
|
|
|
515
767
|
export const ThreadList: FC = () => {
|
|
516
768
|
return (
|
|
517
|
-
<ThreadListPrimitive.Root className="flex flex-col items-stretch gap-1.5">
|
|
769
|
+
<ThreadListPrimitive.Root className="aui-root aui-thread-list-root flex flex-col items-stretch gap-1.5">
|
|
518
770
|
<ThreadListNew />
|
|
519
771
|
<ThreadListItems />
|
|
520
772
|
</ThreadListPrimitive.Root>
|
|
@@ -525,7 +777,7 @@ const ThreadListNew: FC = () => {
|
|
|
525
777
|
return (
|
|
526
778
|
<ThreadListPrimitive.New asChild>
|
|
527
779
|
<Button
|
|
528
|
-
className="
|
|
780
|
+
className="aui-thread-list-new hover:bg-muted data-active:bg-muted flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start"
|
|
529
781
|
variant="ghost"
|
|
530
782
|
>
|
|
531
783
|
<PlusIcon />
|
|
@@ -536,13 +788,37 @@ const ThreadListNew: FC = () => {
|
|
|
536
788
|
};
|
|
537
789
|
|
|
538
790
|
const ThreadListItems: FC = () => {
|
|
791
|
+
const isLoading = useAssistantState(({ threads }) => threads.isLoading);
|
|
792
|
+
|
|
793
|
+
if (isLoading) {
|
|
794
|
+
return <ThreadListSkeleton />;
|
|
795
|
+
}
|
|
796
|
+
|
|
539
797
|
return <ThreadListPrimitive.Items components={{ ThreadListItem }} />;
|
|
540
798
|
};
|
|
541
799
|
|
|
800
|
+
const ThreadListSkeleton: FC = () => {
|
|
801
|
+
return (
|
|
802
|
+
<>
|
|
803
|
+
{Array.from({ length: 5 }, (_, i) => (
|
|
804
|
+
<div
|
|
805
|
+
key={i}
|
|
806
|
+
role="status"
|
|
807
|
+
aria-label="Loading threads"
|
|
808
|
+
aria-live="polite"
|
|
809
|
+
className="aui-thread-list-skeleton-wrapper flex items-center gap-2 rounded-md px-3 py-2"
|
|
810
|
+
>
|
|
811
|
+
<Skeleton className="aui-thread-list-skeleton h-[22px] flex-grow" />
|
|
812
|
+
</div>
|
|
813
|
+
))}
|
|
814
|
+
</>
|
|
815
|
+
);
|
|
816
|
+
};
|
|
817
|
+
|
|
542
818
|
const ThreadListItem: FC = () => {
|
|
543
819
|
return (
|
|
544
|
-
<ThreadListItemPrimitive.Root className="
|
|
545
|
-
<ThreadListItemPrimitive.Trigger className="flex-grow px-3 py-2 text-start">
|
|
820
|
+
<ThreadListItemPrimitive.Root className="aui-thread-list-item hover:bg-muted focus-visible:bg-muted focus-visible:ring-ring data-active:bg-muted flex items-center gap-2 rounded-lg transition-all focus-visible:ring-2 focus-visible:outline-none">
|
|
821
|
+
<ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger flex-grow px-3 py-2 text-start">
|
|
546
822
|
<ThreadListItemTitle />
|
|
547
823
|
</ThreadListItemPrimitive.Trigger>
|
|
548
824
|
<ThreadListItemArchive />
|
|
@@ -552,9 +828,9 @@ const ThreadListItem: FC = () => {
|
|
|
552
828
|
|
|
553
829
|
const ThreadListItemTitle: FC = () => {
|
|
554
830
|
return (
|
|
555
|
-
<
|
|
831
|
+
<span className="aui-thread-list-item-title text-sm">
|
|
556
832
|
<ThreadListItemPrimitive.Title fallback="New Chat" />
|
|
557
|
-
</
|
|
833
|
+
</span>
|
|
558
834
|
);
|
|
559
835
|
};
|
|
560
836
|
|
|
@@ -562,7 +838,7 @@ const ThreadListItemArchive: FC = () => {
|
|
|
562
838
|
return (
|
|
563
839
|
<ThreadListItemPrimitive.Archive asChild>
|
|
564
840
|
<TooltipIconButton
|
|
565
|
-
className="hover:text-primary
|
|
841
|
+
className="aui-thread-list-item-archive text-foreground hover:text-primary mr-3 ml-auto size-4 p-0"
|
|
566
842
|
variant="ghost"
|
|
567
843
|
tooltip="Archive thread"
|
|
568
844
|
>
|
|
@@ -864,12 +1140,111 @@ const CircleStopIcon = () => {
|
|
|
864
1140
|
|
|
865
1141
|
```
|
|
866
1142
|
|
|
1143
|
+
## components/assistant-ui/tool-fallback.tsx
|
|
1144
|
+
|
|
1145
|
+
```tsx
|
|
1146
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
1147
|
+
import {
|
|
1148
|
+
CheckIcon,
|
|
1149
|
+
ChevronDownIcon,
|
|
1150
|
+
ChevronUpIcon,
|
|
1151
|
+
XCircleIcon,
|
|
1152
|
+
} from "lucide-react";
|
|
1153
|
+
import { useState } from "react";
|
|
1154
|
+
import { Button } from "@/components/ui/button";
|
|
1155
|
+
import { cn } from "@/lib/utils";
|
|
1156
|
+
|
|
1157
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
1158
|
+
toolName,
|
|
1159
|
+
argsText,
|
|
1160
|
+
result,
|
|
1161
|
+
status,
|
|
1162
|
+
}) => {
|
|
1163
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
1164
|
+
|
|
1165
|
+
const isCancelled =
|
|
1166
|
+
status?.type === "incomplete" && status.reason === "cancelled";
|
|
1167
|
+
const cancelledReason =
|
|
1168
|
+
isCancelled && status.error
|
|
1169
|
+
? typeof status.error === "string"
|
|
1170
|
+
? status.error
|
|
1171
|
+
: JSON.stringify(status.error)
|
|
1172
|
+
: null;
|
|
1173
|
+
|
|
1174
|
+
return (
|
|
1175
|
+
<div
|
|
1176
|
+
className={cn(
|
|
1177
|
+
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
1178
|
+
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
1179
|
+
)}
|
|
1180
|
+
>
|
|
1181
|
+
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
1182
|
+
{isCancelled ? (
|
|
1183
|
+
<XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
|
|
1184
|
+
) : (
|
|
1185
|
+
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
1186
|
+
)}
|
|
1187
|
+
<p
|
|
1188
|
+
className={cn(
|
|
1189
|
+
"aui-tool-fallback-title grow",
|
|
1190
|
+
isCancelled && "text-muted-foreground line-through",
|
|
1191
|
+
)}
|
|
1192
|
+
>
|
|
1193
|
+
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
1194
|
+
<b>{toolName}</b>
|
|
1195
|
+
</p>
|
|
1196
|
+
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
1197
|
+
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
1198
|
+
</Button>
|
|
1199
|
+
</div>
|
|
1200
|
+
{!isCollapsed && (
|
|
1201
|
+
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
1202
|
+
{cancelledReason && (
|
|
1203
|
+
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
1204
|
+
<p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
|
|
1205
|
+
Cancelled reason:
|
|
1206
|
+
</p>
|
|
1207
|
+
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
1208
|
+
{cancelledReason}
|
|
1209
|
+
</p>
|
|
1210
|
+
</div>
|
|
1211
|
+
)}
|
|
1212
|
+
<div
|
|
1213
|
+
className={cn(
|
|
1214
|
+
"aui-tool-fallback-args-root px-4",
|
|
1215
|
+
isCancelled && "opacity-60",
|
|
1216
|
+
)}
|
|
1217
|
+
>
|
|
1218
|
+
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
1219
|
+
{argsText}
|
|
1220
|
+
</pre>
|
|
1221
|
+
</div>
|
|
1222
|
+
{!isCancelled && result !== undefined && (
|
|
1223
|
+
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
1224
|
+
<p className="aui-tool-fallback-result-header font-semibold">
|
|
1225
|
+
Result:
|
|
1226
|
+
</p>
|
|
1227
|
+
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
1228
|
+
{typeof result === "string"
|
|
1229
|
+
? result
|
|
1230
|
+
: JSON.stringify(result, null, 2)}
|
|
1231
|
+
</pre>
|
|
1232
|
+
</div>
|
|
1233
|
+
)}
|
|
1234
|
+
</div>
|
|
1235
|
+
)}
|
|
1236
|
+
</div>
|
|
1237
|
+
);
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
```
|
|
1241
|
+
|
|
867
1242
|
## components/assistant-ui/tooltip-icon-button.tsx
|
|
868
1243
|
|
|
869
1244
|
```tsx
|
|
870
1245
|
"use client";
|
|
871
1246
|
|
|
872
|
-
import {
|
|
1247
|
+
import { ComponentPropsWithRef, forwardRef } from "react";
|
|
873
1248
|
import { Slottable } from "@radix-ui/react-slot";
|
|
874
1249
|
|
|
875
1250
|
import {
|
|
@@ -880,7 +1255,7 @@ import {
|
|
|
880
1255
|
import { Button } from "@/components/ui/button";
|
|
881
1256
|
import { cn } from "@/lib/utils";
|
|
882
1257
|
|
|
883
|
-
export type TooltipIconButtonProps =
|
|
1258
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
884
1259
|
tooltip: string;
|
|
885
1260
|
side?: "top" | "bottom" | "left" | "right";
|
|
886
1261
|
};
|
|
@@ -896,11 +1271,11 @@ export const TooltipIconButton = forwardRef<
|
|
|
896
1271
|
variant="ghost"
|
|
897
1272
|
size="icon"
|
|
898
1273
|
{...rest}
|
|
899
|
-
className={cn("size-6 p-1", className)}
|
|
1274
|
+
className={cn("aui-button-icon size-6 p-1", className)}
|
|
900
1275
|
ref={ref}
|
|
901
1276
|
>
|
|
902
1277
|
<Slottable>{children}</Slottable>
|
|
903
|
-
<span className="sr-only">{tooltip}</span>
|
|
1278
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
904
1279
|
</Button>
|
|
905
1280
|
</TooltipTrigger>
|
|
906
1281
|
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
@@ -912,6 +1287,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
|
|
|
912
1287
|
|
|
913
1288
|
```
|
|
914
1289
|
|
|
1290
|
+
## components/ui/avatar.tsx
|
|
1291
|
+
|
|
1292
|
+
```tsx
|
|
1293
|
+
"use client";
|
|
1294
|
+
|
|
1295
|
+
import * as React from "react";
|
|
1296
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
1297
|
+
|
|
1298
|
+
import { cn } from "@/lib/utils";
|
|
1299
|
+
|
|
1300
|
+
const Avatar = React.forwardRef<
|
|
1301
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
1302
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
1303
|
+
>(({ className, ...props }, ref) => (
|
|
1304
|
+
<AvatarPrimitive.Root
|
|
1305
|
+
ref={ref}
|
|
1306
|
+
className={cn(
|
|
1307
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
1308
|
+
className,
|
|
1309
|
+
)}
|
|
1310
|
+
{...props}
|
|
1311
|
+
/>
|
|
1312
|
+
));
|
|
1313
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1314
|
+
|
|
1315
|
+
const AvatarImage = React.forwardRef<
|
|
1316
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
1317
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
1318
|
+
>(({ className, ...props }, ref) => (
|
|
1319
|
+
<AvatarPrimitive.Image
|
|
1320
|
+
ref={ref}
|
|
1321
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
1322
|
+
{...props}
|
|
1323
|
+
/>
|
|
1324
|
+
));
|
|
1325
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
1326
|
+
|
|
1327
|
+
const AvatarFallback = React.forwardRef<
|
|
1328
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
1329
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
1330
|
+
>(({ className, ...props }, ref) => (
|
|
1331
|
+
<AvatarPrimitive.Fallback
|
|
1332
|
+
ref={ref}
|
|
1333
|
+
className={cn(
|
|
1334
|
+
"bg-muted flex h-full w-full items-center justify-center rounded-full",
|
|
1335
|
+
className,
|
|
1336
|
+
)}
|
|
1337
|
+
{...props}
|
|
1338
|
+
/>
|
|
1339
|
+
));
|
|
1340
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
1341
|
+
|
|
1342
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
1343
|
+
|
|
1344
|
+
```
|
|
1345
|
+
|
|
915
1346
|
## components/ui/button.tsx
|
|
916
1347
|
|
|
917
1348
|
```tsx
|
|
@@ -977,6 +1408,166 @@ export { Button, buttonVariants };
|
|
|
977
1408
|
|
|
978
1409
|
```
|
|
979
1410
|
|
|
1411
|
+
## components/ui/dialog.tsx
|
|
1412
|
+
|
|
1413
|
+
```tsx
|
|
1414
|
+
"use client";
|
|
1415
|
+
|
|
1416
|
+
import * as React from "react";
|
|
1417
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1418
|
+
import { XIcon } from "lucide-react";
|
|
1419
|
+
|
|
1420
|
+
import { cn } from "@/lib/utils";
|
|
1421
|
+
|
|
1422
|
+
function Dialog({
|
|
1423
|
+
...props
|
|
1424
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
1425
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
function DialogTrigger({
|
|
1429
|
+
...props
|
|
1430
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
1431
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
function DialogPortal({
|
|
1435
|
+
...props
|
|
1436
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
1437
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
function DialogClose({
|
|
1441
|
+
...props
|
|
1442
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
1443
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
function DialogOverlay({
|
|
1447
|
+
className,
|
|
1448
|
+
...props
|
|
1449
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
1450
|
+
return (
|
|
1451
|
+
<DialogPrimitive.Overlay
|
|
1452
|
+
data-slot="dialog-overlay"
|
|
1453
|
+
className={cn(
|
|
1454
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
|
|
1455
|
+
className,
|
|
1456
|
+
)}
|
|
1457
|
+
{...props}
|
|
1458
|
+
/>
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
function DialogContent({
|
|
1463
|
+
className,
|
|
1464
|
+
children,
|
|
1465
|
+
...props
|
|
1466
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
|
|
1467
|
+
return (
|
|
1468
|
+
<DialogPortal data-slot="dialog-portal">
|
|
1469
|
+
<DialogOverlay />
|
|
1470
|
+
<DialogPrimitive.Content
|
|
1471
|
+
data-slot="dialog-content"
|
|
1472
|
+
className={cn(
|
|
1473
|
+
"bg-background data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
1474
|
+
className,
|
|
1475
|
+
)}
|
|
1476
|
+
{...props}
|
|
1477
|
+
>
|
|
1478
|
+
{children}
|
|
1479
|
+
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
|
|
1480
|
+
<XIcon />
|
|
1481
|
+
<span className="sr-only">Close</span>
|
|
1482
|
+
</DialogPrimitive.Close>
|
|
1483
|
+
</DialogPrimitive.Content>
|
|
1484
|
+
</DialogPortal>
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
1489
|
+
return (
|
|
1490
|
+
<div
|
|
1491
|
+
data-slot="dialog-header"
|
|
1492
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
1493
|
+
{...props}
|
|
1494
|
+
/>
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
1499
|
+
return (
|
|
1500
|
+
<div
|
|
1501
|
+
data-slot="dialog-footer"
|
|
1502
|
+
className={cn(
|
|
1503
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1504
|
+
className,
|
|
1505
|
+
)}
|
|
1506
|
+
{...props}
|
|
1507
|
+
/>
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
function DialogTitle({
|
|
1512
|
+
className,
|
|
1513
|
+
...props
|
|
1514
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
1515
|
+
return (
|
|
1516
|
+
<DialogPrimitive.Title
|
|
1517
|
+
data-slot="dialog-title"
|
|
1518
|
+
className={cn("text-lg leading-none font-semibold", className)}
|
|
1519
|
+
{...props}
|
|
1520
|
+
/>
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
function DialogDescription({
|
|
1525
|
+
className,
|
|
1526
|
+
...props
|
|
1527
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
1528
|
+
return (
|
|
1529
|
+
<DialogPrimitive.Description
|
|
1530
|
+
data-slot="dialog-description"
|
|
1531
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
1532
|
+
{...props}
|
|
1533
|
+
/>
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
export {
|
|
1538
|
+
Dialog,
|
|
1539
|
+
DialogClose,
|
|
1540
|
+
DialogContent,
|
|
1541
|
+
DialogDescription,
|
|
1542
|
+
DialogFooter,
|
|
1543
|
+
DialogHeader,
|
|
1544
|
+
DialogOverlay,
|
|
1545
|
+
DialogPortal,
|
|
1546
|
+
DialogTitle,
|
|
1547
|
+
DialogTrigger,
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1550
|
+
```
|
|
1551
|
+
|
|
1552
|
+
## components/ui/skeleton.tsx
|
|
1553
|
+
|
|
1554
|
+
```tsx
|
|
1555
|
+
import { cn } from "@/lib/utils";
|
|
1556
|
+
|
|
1557
|
+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
|
|
1558
|
+
return (
|
|
1559
|
+
<div
|
|
1560
|
+
data-slot="skeleton"
|
|
1561
|
+
className={cn("bg-accent animate-pulse rounded-md", className)}
|
|
1562
|
+
{...props}
|
|
1563
|
+
/>
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
export { Skeleton };
|
|
1568
|
+
|
|
1569
|
+
```
|
|
1570
|
+
|
|
980
1571
|
## components/ui/tooltip.tsx
|
|
981
1572
|
|
|
982
1573
|
```tsx
|
|
@@ -1083,24 +1674,28 @@ export default nextConfig;
|
|
|
1083
1674
|
"lint": "eslint ."
|
|
1084
1675
|
},
|
|
1085
1676
|
"dependencies": {
|
|
1086
|
-
"@ai-sdk/openai": "^2.0.
|
|
1677
|
+
"@ai-sdk/openai": "^2.0.73",
|
|
1087
1678
|
"@assistant-ui/react": "workspace:*",
|
|
1088
1679
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1089
1680
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1681
|
+
"@radix-ui/react-avatar": "^1.1.4",
|
|
1682
|
+
"@radix-ui/react-dialog": "^1.1.7",
|
|
1090
1683
|
"@radix-ui/react-slot": "^1.2.4",
|
|
1091
1684
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1092
|
-
"ai": "^5.0.
|
|
1685
|
+
"ai": "^5.0.102",
|
|
1093
1686
|
"class-variance-authority": "^0.7.1",
|
|
1094
1687
|
"clsx": "^2.1.1",
|
|
1095
1688
|
"jsonwebtoken": "^9.0.2",
|
|
1096
|
-
"lucide-react": "^0.
|
|
1689
|
+
"lucide-react": "^0.555.0",
|
|
1690
|
+
"motion": "^11.18.2",
|
|
1097
1691
|
"nanoid": "5.1.6",
|
|
1098
|
-
"next": "16.0.
|
|
1692
|
+
"next": "16.0.4",
|
|
1099
1693
|
"react": "19.2.0",
|
|
1100
1694
|
"react-dom": "19.2.0",
|
|
1101
1695
|
"remark-gfm": "^4.0.1",
|
|
1102
1696
|
"tailwind-merge": "^3.4.0",
|
|
1103
|
-
"tw-animate-css": "^1.4.0"
|
|
1697
|
+
"tw-animate-css": "^1.4.0",
|
|
1698
|
+
"zustand": "^5.0.8"
|
|
1104
1699
|
},
|
|
1105
1700
|
"devDependencies": {
|
|
1106
1701
|
"@assistant-ui/x-buildutils": "workspace:*",
|