@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
|
@@ -421,6 +421,247 @@ export default function Home() {
|
|
|
421
421
|
|
|
422
422
|
```
|
|
423
423
|
|
|
424
|
+
## components/assistant-ui/attachment.tsx
|
|
425
|
+
|
|
426
|
+
```tsx
|
|
427
|
+
"use client";
|
|
428
|
+
|
|
429
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
430
|
+
import Image from "next/image";
|
|
431
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
432
|
+
import {
|
|
433
|
+
AttachmentPrimitive,
|
|
434
|
+
ComposerPrimitive,
|
|
435
|
+
MessagePrimitive,
|
|
436
|
+
useAssistantState,
|
|
437
|
+
useAssistantApi,
|
|
438
|
+
} from "@assistant-ui/react";
|
|
439
|
+
import { useShallow } from "zustand/shallow";
|
|
440
|
+
import {
|
|
441
|
+
Tooltip,
|
|
442
|
+
TooltipContent,
|
|
443
|
+
TooltipTrigger,
|
|
444
|
+
} from "@/components/ui/tooltip";
|
|
445
|
+
import {
|
|
446
|
+
Dialog,
|
|
447
|
+
DialogTitle,
|
|
448
|
+
DialogContent,
|
|
449
|
+
DialogTrigger,
|
|
450
|
+
} from "@/components/ui/dialog";
|
|
451
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
452
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
453
|
+
import { cn } from "@/lib/utils";
|
|
454
|
+
|
|
455
|
+
const useFileSrc = (file: File | undefined) => {
|
|
456
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
457
|
+
|
|
458
|
+
useEffect(() => {
|
|
459
|
+
if (!file) {
|
|
460
|
+
setSrc(undefined);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const objectUrl = URL.createObjectURL(file);
|
|
465
|
+
setSrc(objectUrl);
|
|
466
|
+
|
|
467
|
+
return () => {
|
|
468
|
+
URL.revokeObjectURL(objectUrl);
|
|
469
|
+
};
|
|
470
|
+
}, [file]);
|
|
471
|
+
|
|
472
|
+
return src;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
const useAttachmentSrc = () => {
|
|
476
|
+
const { file, src } = useAssistantState(
|
|
477
|
+
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
478
|
+
if (attachment.type !== "image") return {};
|
|
479
|
+
if (attachment.file) return { file: attachment.file };
|
|
480
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
481
|
+
?.image;
|
|
482
|
+
if (!src) return {};
|
|
483
|
+
return { src };
|
|
484
|
+
}),
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
return useFileSrc(file) ?? src;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
type AttachmentPreviewProps = {
|
|
491
|
+
src: string;
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
495
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
496
|
+
return (
|
|
497
|
+
<Image
|
|
498
|
+
src={src}
|
|
499
|
+
alt="Image Preview"
|
|
500
|
+
width={1}
|
|
501
|
+
height={1}
|
|
502
|
+
className={
|
|
503
|
+
isLoaded
|
|
504
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
505
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
506
|
+
}
|
|
507
|
+
onLoadingComplete={() => setIsLoaded(true)}
|
|
508
|
+
priority={false}
|
|
509
|
+
/>
|
|
510
|
+
);
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
514
|
+
const src = useAttachmentSrc();
|
|
515
|
+
|
|
516
|
+
if (!src) return children;
|
|
517
|
+
|
|
518
|
+
return (
|
|
519
|
+
<Dialog>
|
|
520
|
+
<DialogTrigger
|
|
521
|
+
className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
|
|
522
|
+
asChild
|
|
523
|
+
>
|
|
524
|
+
{children}
|
|
525
|
+
</DialogTrigger>
|
|
526
|
+
<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">
|
|
527
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
528
|
+
Image Attachment Preview
|
|
529
|
+
</DialogTitle>
|
|
530
|
+
<div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
|
|
531
|
+
<AttachmentPreview src={src} />
|
|
532
|
+
</div>
|
|
533
|
+
</DialogContent>
|
|
534
|
+
</Dialog>
|
|
535
|
+
);
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
const AttachmentThumb: FC = () => {
|
|
539
|
+
const isImage = useAssistantState(
|
|
540
|
+
({ attachment }) => attachment.type === "image",
|
|
541
|
+
);
|
|
542
|
+
const src = useAttachmentSrc();
|
|
543
|
+
|
|
544
|
+
return (
|
|
545
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
546
|
+
<AvatarImage
|
|
547
|
+
src={src}
|
|
548
|
+
alt="Attachment preview"
|
|
549
|
+
className="aui-attachment-tile-image object-cover"
|
|
550
|
+
/>
|
|
551
|
+
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
552
|
+
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
|
|
553
|
+
</AvatarFallback>
|
|
554
|
+
</Avatar>
|
|
555
|
+
);
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
const AttachmentUI: FC = () => {
|
|
559
|
+
const api = useAssistantApi();
|
|
560
|
+
const isComposer = api.attachment.source === "composer";
|
|
561
|
+
|
|
562
|
+
const isImage = useAssistantState(
|
|
563
|
+
({ attachment }) => attachment.type === "image",
|
|
564
|
+
);
|
|
565
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
566
|
+
const type = attachment.type;
|
|
567
|
+
switch (type) {
|
|
568
|
+
case "image":
|
|
569
|
+
return "Image";
|
|
570
|
+
case "document":
|
|
571
|
+
return "Document";
|
|
572
|
+
case "file":
|
|
573
|
+
return "File";
|
|
574
|
+
default:
|
|
575
|
+
const _exhaustiveCheck: never = type;
|
|
576
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
return (
|
|
581
|
+
<Tooltip>
|
|
582
|
+
<AttachmentPrimitive.Root
|
|
583
|
+
className={cn(
|
|
584
|
+
"aui-attachment-root relative",
|
|
585
|
+
isImage &&
|
|
586
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
587
|
+
)}
|
|
588
|
+
>
|
|
589
|
+
<AttachmentPreviewDialog>
|
|
590
|
+
<TooltipTrigger asChild>
|
|
591
|
+
<div
|
|
592
|
+
className={cn(
|
|
593
|
+
"aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
|
|
594
|
+
isComposer &&
|
|
595
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
596
|
+
)}
|
|
597
|
+
role="button"
|
|
598
|
+
id="attachment-tile"
|
|
599
|
+
aria-label={`${typeLabel} attachment`}
|
|
600
|
+
>
|
|
601
|
+
<AttachmentThumb />
|
|
602
|
+
</div>
|
|
603
|
+
</TooltipTrigger>
|
|
604
|
+
</AttachmentPreviewDialog>
|
|
605
|
+
{isComposer && <AttachmentRemove />}
|
|
606
|
+
</AttachmentPrimitive.Root>
|
|
607
|
+
<TooltipContent side="top">
|
|
608
|
+
<AttachmentPrimitive.Name />
|
|
609
|
+
</TooltipContent>
|
|
610
|
+
</Tooltip>
|
|
611
|
+
);
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
const AttachmentRemove: FC = () => {
|
|
615
|
+
return (
|
|
616
|
+
<AttachmentPrimitive.Remove asChild>
|
|
617
|
+
<TooltipIconButton
|
|
618
|
+
tooltip="Remove file"
|
|
619
|
+
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"
|
|
620
|
+
side="top"
|
|
621
|
+
>
|
|
622
|
+
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
623
|
+
</TooltipIconButton>
|
|
624
|
+
</AttachmentPrimitive.Remove>
|
|
625
|
+
);
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
export const UserMessageAttachments: FC = () => {
|
|
629
|
+
return (
|
|
630
|
+
<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">
|
|
631
|
+
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
632
|
+
</div>
|
|
633
|
+
);
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
export const ComposerAttachments: FC = () => {
|
|
637
|
+
return (
|
|
638
|
+
<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">
|
|
639
|
+
<ComposerPrimitive.Attachments
|
|
640
|
+
components={{ Attachment: AttachmentUI }}
|
|
641
|
+
/>
|
|
642
|
+
</div>
|
|
643
|
+
);
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
export const ComposerAddAttachment: FC = () => {
|
|
647
|
+
return (
|
|
648
|
+
<ComposerPrimitive.AddAttachment asChild>
|
|
649
|
+
<TooltipIconButton
|
|
650
|
+
tooltip="Add Attachment"
|
|
651
|
+
side="bottom"
|
|
652
|
+
variant="ghost"
|
|
653
|
+
size="icon"
|
|
654
|
+
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"
|
|
655
|
+
aria-label="Add Attachment"
|
|
656
|
+
>
|
|
657
|
+
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
658
|
+
</TooltipIconButton>
|
|
659
|
+
</ComposerPrimitive.AddAttachment>
|
|
660
|
+
);
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
```
|
|
664
|
+
|
|
424
665
|
## components/assistant-ui/markdown-text.tsx
|
|
425
666
|
|
|
426
667
|
```tsx
|
|
@@ -429,13 +670,13 @@ export default function Home() {
|
|
|
429
670
|
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
430
671
|
|
|
431
672
|
import {
|
|
432
|
-
CodeHeaderProps,
|
|
673
|
+
type CodeHeaderProps,
|
|
433
674
|
MarkdownTextPrimitive,
|
|
434
675
|
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
435
676
|
useIsMarkdownCodeBlock,
|
|
436
677
|
} from "@assistant-ui/react-markdown";
|
|
437
678
|
import remarkGfm from "remark-gfm";
|
|
438
|
-
import { FC, memo, useState } from "react";
|
|
679
|
+
import { type FC, memo, useState } from "react";
|
|
439
680
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
440
681
|
|
|
441
682
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
@@ -461,8 +702,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
|
|
|
461
702
|
};
|
|
462
703
|
|
|
463
704
|
return (
|
|
464
|
-
<div className="flex items-center justify-between gap-4 rounded-t-lg
|
|
465
|
-
<span className="lowercase [&>span]:text-xs">
|
|
705
|
+
<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">
|
|
706
|
+
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
707
|
+
{language}
|
|
708
|
+
</span>
|
|
466
709
|
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
467
710
|
{!isCopied && <CopyIcon />}
|
|
468
711
|
{isCopied && <CheckIcon />}
|
|
@@ -494,7 +737,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
494
737
|
h1: ({ className, ...props }) => (
|
|
495
738
|
<h1
|
|
496
739
|
className={cn(
|
|
497
|
-
"mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
740
|
+
"aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
498
741
|
className,
|
|
499
742
|
)}
|
|
500
743
|
{...props}
|
|
@@ -503,7 +746,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
503
746
|
h2: ({ className, ...props }) => (
|
|
504
747
|
<h2
|
|
505
748
|
className={cn(
|
|
506
|
-
"mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
749
|
+
"aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
507
750
|
className,
|
|
508
751
|
)}
|
|
509
752
|
{...props}
|
|
@@ -512,7 +755,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
512
755
|
h3: ({ className, ...props }) => (
|
|
513
756
|
<h3
|
|
514
757
|
className={cn(
|
|
515
|
-
"mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
758
|
+
"aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
516
759
|
className,
|
|
517
760
|
)}
|
|
518
761
|
{...props}
|
|
@@ -521,7 +764,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
521
764
|
h4: ({ className, ...props }) => (
|
|
522
765
|
<h4
|
|
523
766
|
className={cn(
|
|
524
|
-
"mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
767
|
+
"aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
525
768
|
className,
|
|
526
769
|
)}
|
|
527
770
|
{...props}
|
|
@@ -530,7 +773,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
530
773
|
h5: ({ className, ...props }) => (
|
|
531
774
|
<h5
|
|
532
775
|
className={cn(
|
|
533
|
-
"my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
776
|
+
"aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
534
777
|
className,
|
|
535
778
|
)}
|
|
536
779
|
{...props}
|
|
@@ -538,20 +781,26 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
538
781
|
),
|
|
539
782
|
h6: ({ className, ...props }) => (
|
|
540
783
|
<h6
|
|
541
|
-
className={cn(
|
|
784
|
+
className={cn(
|
|
785
|
+
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
786
|
+
className,
|
|
787
|
+
)}
|
|
542
788
|
{...props}
|
|
543
789
|
/>
|
|
544
790
|
),
|
|
545
791
|
p: ({ className, ...props }) => (
|
|
546
792
|
<p
|
|
547
|
-
className={cn(
|
|
793
|
+
className={cn(
|
|
794
|
+
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
795
|
+
className,
|
|
796
|
+
)}
|
|
548
797
|
{...props}
|
|
549
798
|
/>
|
|
550
799
|
),
|
|
551
800
|
a: ({ className, ...props }) => (
|
|
552
801
|
<a
|
|
553
802
|
className={cn(
|
|
554
|
-
"text-primary font-medium underline underline-offset-4",
|
|
803
|
+
"aui-md-a text-primary font-medium underline underline-offset-4",
|
|
555
804
|
className,
|
|
556
805
|
)}
|
|
557
806
|
{...props}
|
|
@@ -559,29 +808,29 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
559
808
|
),
|
|
560
809
|
blockquote: ({ className, ...props }) => (
|
|
561
810
|
<blockquote
|
|
562
|
-
className={cn("border-l-2 pl-6 italic", className)}
|
|
811
|
+
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
563
812
|
{...props}
|
|
564
813
|
/>
|
|
565
814
|
),
|
|
566
815
|
ul: ({ className, ...props }) => (
|
|
567
816
|
<ul
|
|
568
|
-
className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
817
|
+
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
569
818
|
{...props}
|
|
570
819
|
/>
|
|
571
820
|
),
|
|
572
821
|
ol: ({ className, ...props }) => (
|
|
573
822
|
<ol
|
|
574
|
-
className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
823
|
+
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
575
824
|
{...props}
|
|
576
825
|
/>
|
|
577
826
|
),
|
|
578
827
|
hr: ({ className, ...props }) => (
|
|
579
|
-
<hr className={cn("my-5 border-b", className)} {...props} />
|
|
828
|
+
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
580
829
|
),
|
|
581
830
|
table: ({ className, ...props }) => (
|
|
582
831
|
<table
|
|
583
832
|
className={cn(
|
|
584
|
-
"my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
833
|
+
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
585
834
|
className,
|
|
586
835
|
)}
|
|
587
836
|
{...props}
|
|
@@ -590,7 +839,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
590
839
|
th: ({ className, ...props }) => (
|
|
591
840
|
<th
|
|
592
841
|
className={cn(
|
|
593
|
-
"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",
|
|
842
|
+
"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",
|
|
594
843
|
className,
|
|
595
844
|
)}
|
|
596
845
|
{...props}
|
|
@@ -599,7 +848,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
599
848
|
td: ({ className, ...props }) => (
|
|
600
849
|
<td
|
|
601
850
|
className={cn(
|
|
602
|
-
"border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
851
|
+
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
603
852
|
className,
|
|
604
853
|
)}
|
|
605
854
|
{...props}
|
|
@@ -608,7 +857,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
608
857
|
tr: ({ className, ...props }) => (
|
|
609
858
|
<tr
|
|
610
859
|
className={cn(
|
|
611
|
-
"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",
|
|
860
|
+
"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",
|
|
612
861
|
className,
|
|
613
862
|
)}
|
|
614
863
|
{...props}
|
|
@@ -616,14 +865,14 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
616
865
|
),
|
|
617
866
|
sup: ({ className, ...props }) => (
|
|
618
867
|
<sup
|
|
619
|
-
className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
|
|
868
|
+
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
620
869
|
{...props}
|
|
621
870
|
/>
|
|
622
871
|
),
|
|
623
872
|
pre: ({ className, ...props }) => (
|
|
624
873
|
<pre
|
|
625
874
|
className={cn(
|
|
626
|
-
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
|
|
875
|
+
"aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
|
|
627
876
|
className,
|
|
628
877
|
)}
|
|
629
878
|
{...props}
|
|
@@ -634,7 +883,8 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
634
883
|
return (
|
|
635
884
|
<code
|
|
636
885
|
className={cn(
|
|
637
|
-
!isCodeBlock &&
|
|
886
|
+
!isCodeBlock &&
|
|
887
|
+
"aui-md-inline-code bg-muted rounded border font-semibold",
|
|
638
888
|
className,
|
|
639
889
|
)}
|
|
640
890
|
{...props}
|
|
@@ -1022,12 +1272,111 @@ const CircleStopIcon = () => {
|
|
|
1022
1272
|
|
|
1023
1273
|
```
|
|
1024
1274
|
|
|
1275
|
+
## components/assistant-ui/tool-fallback.tsx
|
|
1276
|
+
|
|
1277
|
+
```tsx
|
|
1278
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
1279
|
+
import {
|
|
1280
|
+
CheckIcon,
|
|
1281
|
+
ChevronDownIcon,
|
|
1282
|
+
ChevronUpIcon,
|
|
1283
|
+
XCircleIcon,
|
|
1284
|
+
} from "lucide-react";
|
|
1285
|
+
import { useState } from "react";
|
|
1286
|
+
import { Button } from "@/components/ui/button";
|
|
1287
|
+
import { cn } from "@/lib/utils";
|
|
1288
|
+
|
|
1289
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
1290
|
+
toolName,
|
|
1291
|
+
argsText,
|
|
1292
|
+
result,
|
|
1293
|
+
status,
|
|
1294
|
+
}) => {
|
|
1295
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
1296
|
+
|
|
1297
|
+
const isCancelled =
|
|
1298
|
+
status?.type === "incomplete" && status.reason === "cancelled";
|
|
1299
|
+
const cancelledReason =
|
|
1300
|
+
isCancelled && status.error
|
|
1301
|
+
? typeof status.error === "string"
|
|
1302
|
+
? status.error
|
|
1303
|
+
: JSON.stringify(status.error)
|
|
1304
|
+
: null;
|
|
1305
|
+
|
|
1306
|
+
return (
|
|
1307
|
+
<div
|
|
1308
|
+
className={cn(
|
|
1309
|
+
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
1310
|
+
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
1311
|
+
)}
|
|
1312
|
+
>
|
|
1313
|
+
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
1314
|
+
{isCancelled ? (
|
|
1315
|
+
<XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
|
|
1316
|
+
) : (
|
|
1317
|
+
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
1318
|
+
)}
|
|
1319
|
+
<p
|
|
1320
|
+
className={cn(
|
|
1321
|
+
"aui-tool-fallback-title grow",
|
|
1322
|
+
isCancelled && "text-muted-foreground line-through",
|
|
1323
|
+
)}
|
|
1324
|
+
>
|
|
1325
|
+
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
1326
|
+
<b>{toolName}</b>
|
|
1327
|
+
</p>
|
|
1328
|
+
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
1329
|
+
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
1330
|
+
</Button>
|
|
1331
|
+
</div>
|
|
1332
|
+
{!isCollapsed && (
|
|
1333
|
+
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
1334
|
+
{cancelledReason && (
|
|
1335
|
+
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
1336
|
+
<p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
|
|
1337
|
+
Cancelled reason:
|
|
1338
|
+
</p>
|
|
1339
|
+
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
1340
|
+
{cancelledReason}
|
|
1341
|
+
</p>
|
|
1342
|
+
</div>
|
|
1343
|
+
)}
|
|
1344
|
+
<div
|
|
1345
|
+
className={cn(
|
|
1346
|
+
"aui-tool-fallback-args-root px-4",
|
|
1347
|
+
isCancelled && "opacity-60",
|
|
1348
|
+
)}
|
|
1349
|
+
>
|
|
1350
|
+
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
1351
|
+
{argsText}
|
|
1352
|
+
</pre>
|
|
1353
|
+
</div>
|
|
1354
|
+
{!isCancelled && result !== undefined && (
|
|
1355
|
+
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
1356
|
+
<p className="aui-tool-fallback-result-header font-semibold">
|
|
1357
|
+
Result:
|
|
1358
|
+
</p>
|
|
1359
|
+
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
1360
|
+
{typeof result === "string"
|
|
1361
|
+
? result
|
|
1362
|
+
: JSON.stringify(result, null, 2)}
|
|
1363
|
+
</pre>
|
|
1364
|
+
</div>
|
|
1365
|
+
)}
|
|
1366
|
+
</div>
|
|
1367
|
+
)}
|
|
1368
|
+
</div>
|
|
1369
|
+
);
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1372
|
+
```
|
|
1373
|
+
|
|
1025
1374
|
## components/assistant-ui/tooltip-icon-button.tsx
|
|
1026
1375
|
|
|
1027
1376
|
```tsx
|
|
1028
1377
|
"use client";
|
|
1029
1378
|
|
|
1030
|
-
import {
|
|
1379
|
+
import { ComponentPropsWithRef, forwardRef } from "react";
|
|
1031
1380
|
import { Slottable } from "@radix-ui/react-slot";
|
|
1032
1381
|
|
|
1033
1382
|
import {
|
|
@@ -1038,7 +1387,7 @@ import {
|
|
|
1038
1387
|
import { Button } from "@/components/ui/button";
|
|
1039
1388
|
import { cn } from "@/lib/utils";
|
|
1040
1389
|
|
|
1041
|
-
export type TooltipIconButtonProps =
|
|
1390
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
1042
1391
|
tooltip: string;
|
|
1043
1392
|
side?: "top" | "bottom" | "left" | "right";
|
|
1044
1393
|
};
|
|
@@ -1054,11 +1403,11 @@ export const TooltipIconButton = forwardRef<
|
|
|
1054
1403
|
variant="ghost"
|
|
1055
1404
|
size="icon"
|
|
1056
1405
|
{...rest}
|
|
1057
|
-
className={cn("size-6 p-1", className)}
|
|
1406
|
+
className={cn("aui-button-icon size-6 p-1", className)}
|
|
1058
1407
|
ref={ref}
|
|
1059
1408
|
>
|
|
1060
1409
|
<Slottable>{children}</Slottable>
|
|
1061
|
-
<span className="sr-only">{tooltip}</span>
|
|
1410
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
1062
1411
|
</Button>
|
|
1063
1412
|
</TooltipTrigger>
|
|
1064
1413
|
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
@@ -1070,6 +1419,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
|
|
|
1070
1419
|
|
|
1071
1420
|
```
|
|
1072
1421
|
|
|
1422
|
+
## components/ui/avatar.tsx
|
|
1423
|
+
|
|
1424
|
+
```tsx
|
|
1425
|
+
"use client";
|
|
1426
|
+
|
|
1427
|
+
import * as React from "react";
|
|
1428
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
1429
|
+
|
|
1430
|
+
import { cn } from "@/lib/utils";
|
|
1431
|
+
|
|
1432
|
+
const Avatar = React.forwardRef<
|
|
1433
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
1434
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
1435
|
+
>(({ className, ...props }, ref) => (
|
|
1436
|
+
<AvatarPrimitive.Root
|
|
1437
|
+
ref={ref}
|
|
1438
|
+
className={cn(
|
|
1439
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
1440
|
+
className,
|
|
1441
|
+
)}
|
|
1442
|
+
{...props}
|
|
1443
|
+
/>
|
|
1444
|
+
));
|
|
1445
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1446
|
+
|
|
1447
|
+
const AvatarImage = React.forwardRef<
|
|
1448
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
1449
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
1450
|
+
>(({ className, ...props }, ref) => (
|
|
1451
|
+
<AvatarPrimitive.Image
|
|
1452
|
+
ref={ref}
|
|
1453
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
1454
|
+
{...props}
|
|
1455
|
+
/>
|
|
1456
|
+
));
|
|
1457
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
1458
|
+
|
|
1459
|
+
const AvatarFallback = React.forwardRef<
|
|
1460
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
1461
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
1462
|
+
>(({ className, ...props }, ref) => (
|
|
1463
|
+
<AvatarPrimitive.Fallback
|
|
1464
|
+
ref={ref}
|
|
1465
|
+
className={cn(
|
|
1466
|
+
"bg-muted flex h-full w-full items-center justify-center rounded-full",
|
|
1467
|
+
className,
|
|
1468
|
+
)}
|
|
1469
|
+
{...props}
|
|
1470
|
+
/>
|
|
1471
|
+
));
|
|
1472
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
1473
|
+
|
|
1474
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
1475
|
+
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1073
1478
|
## components/ui/button.tsx
|
|
1074
1479
|
|
|
1075
1480
|
```tsx
|
|
@@ -1135,6 +1540,147 @@ export { Button, buttonVariants };
|
|
|
1135
1540
|
|
|
1136
1541
|
```
|
|
1137
1542
|
|
|
1543
|
+
## components/ui/dialog.tsx
|
|
1544
|
+
|
|
1545
|
+
```tsx
|
|
1546
|
+
"use client";
|
|
1547
|
+
|
|
1548
|
+
import * as React from "react";
|
|
1549
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1550
|
+
import { XIcon } from "lucide-react";
|
|
1551
|
+
|
|
1552
|
+
import { cn } from "@/lib/utils";
|
|
1553
|
+
|
|
1554
|
+
function Dialog({
|
|
1555
|
+
...props
|
|
1556
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
1557
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
function DialogTrigger({
|
|
1561
|
+
...props
|
|
1562
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
1563
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
function DialogPortal({
|
|
1567
|
+
...props
|
|
1568
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
1569
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
function DialogClose({
|
|
1573
|
+
...props
|
|
1574
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
1575
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
function DialogOverlay({
|
|
1579
|
+
className,
|
|
1580
|
+
...props
|
|
1581
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
1582
|
+
return (
|
|
1583
|
+
<DialogPrimitive.Overlay
|
|
1584
|
+
data-slot="dialog-overlay"
|
|
1585
|
+
className={cn(
|
|
1586
|
+
"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",
|
|
1587
|
+
className,
|
|
1588
|
+
)}
|
|
1589
|
+
{...props}
|
|
1590
|
+
/>
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
function DialogContent({
|
|
1595
|
+
className,
|
|
1596
|
+
children,
|
|
1597
|
+
...props
|
|
1598
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
|
|
1599
|
+
return (
|
|
1600
|
+
<DialogPortal data-slot="dialog-portal">
|
|
1601
|
+
<DialogOverlay />
|
|
1602
|
+
<DialogPrimitive.Content
|
|
1603
|
+
data-slot="dialog-content"
|
|
1604
|
+
className={cn(
|
|
1605
|
+
"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",
|
|
1606
|
+
className,
|
|
1607
|
+
)}
|
|
1608
|
+
{...props}
|
|
1609
|
+
>
|
|
1610
|
+
{children}
|
|
1611
|
+
<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">
|
|
1612
|
+
<XIcon />
|
|
1613
|
+
<span className="sr-only">Close</span>
|
|
1614
|
+
</DialogPrimitive.Close>
|
|
1615
|
+
</DialogPrimitive.Content>
|
|
1616
|
+
</DialogPortal>
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
1621
|
+
return (
|
|
1622
|
+
<div
|
|
1623
|
+
data-slot="dialog-header"
|
|
1624
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
1625
|
+
{...props}
|
|
1626
|
+
/>
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
1631
|
+
return (
|
|
1632
|
+
<div
|
|
1633
|
+
data-slot="dialog-footer"
|
|
1634
|
+
className={cn(
|
|
1635
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1636
|
+
className,
|
|
1637
|
+
)}
|
|
1638
|
+
{...props}
|
|
1639
|
+
/>
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
function DialogTitle({
|
|
1644
|
+
className,
|
|
1645
|
+
...props
|
|
1646
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
1647
|
+
return (
|
|
1648
|
+
<DialogPrimitive.Title
|
|
1649
|
+
data-slot="dialog-title"
|
|
1650
|
+
className={cn("text-lg leading-none font-semibold", className)}
|
|
1651
|
+
{...props}
|
|
1652
|
+
/>
|
|
1653
|
+
);
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
function DialogDescription({
|
|
1657
|
+
className,
|
|
1658
|
+
...props
|
|
1659
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
1660
|
+
return (
|
|
1661
|
+
<DialogPrimitive.Description
|
|
1662
|
+
data-slot="dialog-description"
|
|
1663
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
1664
|
+
{...props}
|
|
1665
|
+
/>
|
|
1666
|
+
);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
export {
|
|
1670
|
+
Dialog,
|
|
1671
|
+
DialogClose,
|
|
1672
|
+
DialogContent,
|
|
1673
|
+
DialogDescription,
|
|
1674
|
+
DialogFooter,
|
|
1675
|
+
DialogHeader,
|
|
1676
|
+
DialogOverlay,
|
|
1677
|
+
DialogPortal,
|
|
1678
|
+
DialogTitle,
|
|
1679
|
+
DialogTrigger,
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
```
|
|
1683
|
+
|
|
1138
1684
|
## components/ui/tooltip.tsx
|
|
1139
1685
|
|
|
1140
1686
|
```tsx
|
|
@@ -1241,20 +1787,24 @@ export default nextConfig;
|
|
|
1241
1787
|
"lint": "eslint ."
|
|
1242
1788
|
},
|
|
1243
1789
|
"dependencies": {
|
|
1244
|
-
"@ai-sdk/openai": "^2.0.
|
|
1790
|
+
"@ai-sdk/openai": "^2.0.73",
|
|
1245
1791
|
"@assistant-ui/react": "workspace:*",
|
|
1246
1792
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1793
|
+
"@radix-ui/react-avatar": "^1.1.4",
|
|
1794
|
+
"@radix-ui/react-dialog": "^1.1.7",
|
|
1247
1795
|
"@radix-ui/react-slot": "^1.2.4",
|
|
1248
1796
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1249
1797
|
"class-variance-authority": "^0.7.1",
|
|
1250
1798
|
"clsx": "^2.1.1",
|
|
1251
|
-
"lucide-react": "^0.
|
|
1252
|
-
"
|
|
1799
|
+
"lucide-react": "^0.555.0",
|
|
1800
|
+
"motion": "^11.18.2",
|
|
1801
|
+
"next": "16.0.4",
|
|
1253
1802
|
"react": "19.2.0",
|
|
1254
1803
|
"react-dom": "19.2.0",
|
|
1255
1804
|
"remark-gfm": "^4.0.1",
|
|
1256
1805
|
"tailwind-merge": "^3.4.0",
|
|
1257
|
-
"tw-animate-css": "^1.4.0"
|
|
1806
|
+
"tw-animate-css": "^1.4.0",
|
|
1807
|
+
"zustand": "^5.0.8"
|
|
1258
1808
|
},
|
|
1259
1809
|
"devDependencies": {
|
|
1260
1810
|
"@assistant-ui/x-buildutils": "workspace:*",
|