@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
|
@@ -288,6 +288,247 @@ export default function Home() {
|
|
|
288
288
|
|
|
289
289
|
```
|
|
290
290
|
|
|
291
|
+
## components/assistant-ui/attachment.tsx
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
"use client";
|
|
295
|
+
|
|
296
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
297
|
+
import Image from "next/image";
|
|
298
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
299
|
+
import {
|
|
300
|
+
AttachmentPrimitive,
|
|
301
|
+
ComposerPrimitive,
|
|
302
|
+
MessagePrimitive,
|
|
303
|
+
useAssistantState,
|
|
304
|
+
useAssistantApi,
|
|
305
|
+
} from "@assistant-ui/react";
|
|
306
|
+
import { useShallow } from "zustand/shallow";
|
|
307
|
+
import {
|
|
308
|
+
Tooltip,
|
|
309
|
+
TooltipContent,
|
|
310
|
+
TooltipTrigger,
|
|
311
|
+
} from "@/components/ui/tooltip";
|
|
312
|
+
import {
|
|
313
|
+
Dialog,
|
|
314
|
+
DialogTitle,
|
|
315
|
+
DialogContent,
|
|
316
|
+
DialogTrigger,
|
|
317
|
+
} from "@/components/ui/dialog";
|
|
318
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
319
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
320
|
+
import { cn } from "@/lib/utils";
|
|
321
|
+
|
|
322
|
+
const useFileSrc = (file: File | undefined) => {
|
|
323
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
324
|
+
|
|
325
|
+
useEffect(() => {
|
|
326
|
+
if (!file) {
|
|
327
|
+
setSrc(undefined);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const objectUrl = URL.createObjectURL(file);
|
|
332
|
+
setSrc(objectUrl);
|
|
333
|
+
|
|
334
|
+
return () => {
|
|
335
|
+
URL.revokeObjectURL(objectUrl);
|
|
336
|
+
};
|
|
337
|
+
}, [file]);
|
|
338
|
+
|
|
339
|
+
return src;
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const useAttachmentSrc = () => {
|
|
343
|
+
const { file, src } = useAssistantState(
|
|
344
|
+
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
345
|
+
if (attachment.type !== "image") return {};
|
|
346
|
+
if (attachment.file) return { file: attachment.file };
|
|
347
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
348
|
+
?.image;
|
|
349
|
+
if (!src) return {};
|
|
350
|
+
return { src };
|
|
351
|
+
}),
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
return useFileSrc(file) ?? src;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
type AttachmentPreviewProps = {
|
|
358
|
+
src: string;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
362
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
363
|
+
return (
|
|
364
|
+
<Image
|
|
365
|
+
src={src}
|
|
366
|
+
alt="Image Preview"
|
|
367
|
+
width={1}
|
|
368
|
+
height={1}
|
|
369
|
+
className={
|
|
370
|
+
isLoaded
|
|
371
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
372
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
373
|
+
}
|
|
374
|
+
onLoadingComplete={() => setIsLoaded(true)}
|
|
375
|
+
priority={false}
|
|
376
|
+
/>
|
|
377
|
+
);
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
381
|
+
const src = useAttachmentSrc();
|
|
382
|
+
|
|
383
|
+
if (!src) return children;
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<Dialog>
|
|
387
|
+
<DialogTrigger
|
|
388
|
+
className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
|
|
389
|
+
asChild
|
|
390
|
+
>
|
|
391
|
+
{children}
|
|
392
|
+
</DialogTrigger>
|
|
393
|
+
<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">
|
|
394
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
395
|
+
Image Attachment Preview
|
|
396
|
+
</DialogTitle>
|
|
397
|
+
<div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
|
|
398
|
+
<AttachmentPreview src={src} />
|
|
399
|
+
</div>
|
|
400
|
+
</DialogContent>
|
|
401
|
+
</Dialog>
|
|
402
|
+
);
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const AttachmentThumb: FC = () => {
|
|
406
|
+
const isImage = useAssistantState(
|
|
407
|
+
({ attachment }) => attachment.type === "image",
|
|
408
|
+
);
|
|
409
|
+
const src = useAttachmentSrc();
|
|
410
|
+
|
|
411
|
+
return (
|
|
412
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
413
|
+
<AvatarImage
|
|
414
|
+
src={src}
|
|
415
|
+
alt="Attachment preview"
|
|
416
|
+
className="aui-attachment-tile-image object-cover"
|
|
417
|
+
/>
|
|
418
|
+
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
419
|
+
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
|
|
420
|
+
</AvatarFallback>
|
|
421
|
+
</Avatar>
|
|
422
|
+
);
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
const AttachmentUI: FC = () => {
|
|
426
|
+
const api = useAssistantApi();
|
|
427
|
+
const isComposer = api.attachment.source === "composer";
|
|
428
|
+
|
|
429
|
+
const isImage = useAssistantState(
|
|
430
|
+
({ attachment }) => attachment.type === "image",
|
|
431
|
+
);
|
|
432
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
433
|
+
const type = attachment.type;
|
|
434
|
+
switch (type) {
|
|
435
|
+
case "image":
|
|
436
|
+
return "Image";
|
|
437
|
+
case "document":
|
|
438
|
+
return "Document";
|
|
439
|
+
case "file":
|
|
440
|
+
return "File";
|
|
441
|
+
default:
|
|
442
|
+
const _exhaustiveCheck: never = type;
|
|
443
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
return (
|
|
448
|
+
<Tooltip>
|
|
449
|
+
<AttachmentPrimitive.Root
|
|
450
|
+
className={cn(
|
|
451
|
+
"aui-attachment-root relative",
|
|
452
|
+
isImage &&
|
|
453
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
454
|
+
)}
|
|
455
|
+
>
|
|
456
|
+
<AttachmentPreviewDialog>
|
|
457
|
+
<TooltipTrigger asChild>
|
|
458
|
+
<div
|
|
459
|
+
className={cn(
|
|
460
|
+
"aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
|
|
461
|
+
isComposer &&
|
|
462
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
463
|
+
)}
|
|
464
|
+
role="button"
|
|
465
|
+
id="attachment-tile"
|
|
466
|
+
aria-label={`${typeLabel} attachment`}
|
|
467
|
+
>
|
|
468
|
+
<AttachmentThumb />
|
|
469
|
+
</div>
|
|
470
|
+
</TooltipTrigger>
|
|
471
|
+
</AttachmentPreviewDialog>
|
|
472
|
+
{isComposer && <AttachmentRemove />}
|
|
473
|
+
</AttachmentPrimitive.Root>
|
|
474
|
+
<TooltipContent side="top">
|
|
475
|
+
<AttachmentPrimitive.Name />
|
|
476
|
+
</TooltipContent>
|
|
477
|
+
</Tooltip>
|
|
478
|
+
);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
const AttachmentRemove: FC = () => {
|
|
482
|
+
return (
|
|
483
|
+
<AttachmentPrimitive.Remove asChild>
|
|
484
|
+
<TooltipIconButton
|
|
485
|
+
tooltip="Remove file"
|
|
486
|
+
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"
|
|
487
|
+
side="top"
|
|
488
|
+
>
|
|
489
|
+
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
490
|
+
</TooltipIconButton>
|
|
491
|
+
</AttachmentPrimitive.Remove>
|
|
492
|
+
);
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
export const UserMessageAttachments: FC = () => {
|
|
496
|
+
return (
|
|
497
|
+
<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">
|
|
498
|
+
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
499
|
+
</div>
|
|
500
|
+
);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
export const ComposerAttachments: FC = () => {
|
|
504
|
+
return (
|
|
505
|
+
<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">
|
|
506
|
+
<ComposerPrimitive.Attachments
|
|
507
|
+
components={{ Attachment: AttachmentUI }}
|
|
508
|
+
/>
|
|
509
|
+
</div>
|
|
510
|
+
);
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
export const ComposerAddAttachment: FC = () => {
|
|
514
|
+
return (
|
|
515
|
+
<ComposerPrimitive.AddAttachment asChild>
|
|
516
|
+
<TooltipIconButton
|
|
517
|
+
tooltip="Add Attachment"
|
|
518
|
+
side="bottom"
|
|
519
|
+
variant="ghost"
|
|
520
|
+
size="icon"
|
|
521
|
+
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"
|
|
522
|
+
aria-label="Add Attachment"
|
|
523
|
+
>
|
|
524
|
+
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
525
|
+
</TooltipIconButton>
|
|
526
|
+
</ComposerPrimitive.AddAttachment>
|
|
527
|
+
);
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
|
|
291
532
|
## components/assistant-ui/markdown-text.tsx
|
|
292
533
|
|
|
293
534
|
```tsx
|
|
@@ -296,13 +537,13 @@ export default function Home() {
|
|
|
296
537
|
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
297
538
|
|
|
298
539
|
import {
|
|
299
|
-
CodeHeaderProps,
|
|
540
|
+
type CodeHeaderProps,
|
|
300
541
|
MarkdownTextPrimitive,
|
|
301
542
|
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
302
543
|
useIsMarkdownCodeBlock,
|
|
303
544
|
} from "@assistant-ui/react-markdown";
|
|
304
545
|
import remarkGfm from "remark-gfm";
|
|
305
|
-
import { FC, memo, useState } from "react";
|
|
546
|
+
import { type FC, memo, useState } from "react";
|
|
306
547
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
307
548
|
|
|
308
549
|
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
@@ -328,8 +569,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
|
|
|
328
569
|
};
|
|
329
570
|
|
|
330
571
|
return (
|
|
331
|
-
<div className="flex items-center justify-between gap-4 rounded-t-lg
|
|
332
|
-
<span className="lowercase [&>span]:text-xs">
|
|
572
|
+
<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">
|
|
573
|
+
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
574
|
+
{language}
|
|
575
|
+
</span>
|
|
333
576
|
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
334
577
|
{!isCopied && <CopyIcon />}
|
|
335
578
|
{isCopied && <CheckIcon />}
|
|
@@ -361,7 +604,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
361
604
|
h1: ({ className, ...props }) => (
|
|
362
605
|
<h1
|
|
363
606
|
className={cn(
|
|
364
|
-
"mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
607
|
+
"aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
|
|
365
608
|
className,
|
|
366
609
|
)}
|
|
367
610
|
{...props}
|
|
@@ -370,7 +613,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
370
613
|
h2: ({ className, ...props }) => (
|
|
371
614
|
<h2
|
|
372
615
|
className={cn(
|
|
373
|
-
"mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
616
|
+
"aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
374
617
|
className,
|
|
375
618
|
)}
|
|
376
619
|
{...props}
|
|
@@ -379,7 +622,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
379
622
|
h3: ({ className, ...props }) => (
|
|
380
623
|
<h3
|
|
381
624
|
className={cn(
|
|
382
|
-
"mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
625
|
+
"aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
383
626
|
className,
|
|
384
627
|
)}
|
|
385
628
|
{...props}
|
|
@@ -388,7 +631,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
388
631
|
h4: ({ className, ...props }) => (
|
|
389
632
|
<h4
|
|
390
633
|
className={cn(
|
|
391
|
-
"mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
634
|
+
"aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
392
635
|
className,
|
|
393
636
|
)}
|
|
394
637
|
{...props}
|
|
@@ -397,7 +640,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
397
640
|
h5: ({ className, ...props }) => (
|
|
398
641
|
<h5
|
|
399
642
|
className={cn(
|
|
400
|
-
"my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
643
|
+
"aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
|
|
401
644
|
className,
|
|
402
645
|
)}
|
|
403
646
|
{...props}
|
|
@@ -405,20 +648,26 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
405
648
|
),
|
|
406
649
|
h6: ({ className, ...props }) => (
|
|
407
650
|
<h6
|
|
408
|
-
className={cn(
|
|
651
|
+
className={cn(
|
|
652
|
+
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
653
|
+
className,
|
|
654
|
+
)}
|
|
409
655
|
{...props}
|
|
410
656
|
/>
|
|
411
657
|
),
|
|
412
658
|
p: ({ className, ...props }) => (
|
|
413
659
|
<p
|
|
414
|
-
className={cn(
|
|
660
|
+
className={cn(
|
|
661
|
+
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
662
|
+
className,
|
|
663
|
+
)}
|
|
415
664
|
{...props}
|
|
416
665
|
/>
|
|
417
666
|
),
|
|
418
667
|
a: ({ className, ...props }) => (
|
|
419
668
|
<a
|
|
420
669
|
className={cn(
|
|
421
|
-
"text-primary font-medium underline underline-offset-4",
|
|
670
|
+
"aui-md-a text-primary font-medium underline underline-offset-4",
|
|
422
671
|
className,
|
|
423
672
|
)}
|
|
424
673
|
{...props}
|
|
@@ -426,29 +675,29 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
426
675
|
),
|
|
427
676
|
blockquote: ({ className, ...props }) => (
|
|
428
677
|
<blockquote
|
|
429
|
-
className={cn("border-l-2 pl-6 italic", className)}
|
|
678
|
+
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
430
679
|
{...props}
|
|
431
680
|
/>
|
|
432
681
|
),
|
|
433
682
|
ul: ({ className, ...props }) => (
|
|
434
683
|
<ul
|
|
435
|
-
className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
684
|
+
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
436
685
|
{...props}
|
|
437
686
|
/>
|
|
438
687
|
),
|
|
439
688
|
ol: ({ className, ...props }) => (
|
|
440
689
|
<ol
|
|
441
|
-
className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
690
|
+
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
442
691
|
{...props}
|
|
443
692
|
/>
|
|
444
693
|
),
|
|
445
694
|
hr: ({ className, ...props }) => (
|
|
446
|
-
<hr className={cn("my-5 border-b", className)} {...props} />
|
|
695
|
+
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
447
696
|
),
|
|
448
697
|
table: ({ className, ...props }) => (
|
|
449
698
|
<table
|
|
450
699
|
className={cn(
|
|
451
|
-
"my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
700
|
+
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
452
701
|
className,
|
|
453
702
|
)}
|
|
454
703
|
{...props}
|
|
@@ -457,7 +706,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
457
706
|
th: ({ className, ...props }) => (
|
|
458
707
|
<th
|
|
459
708
|
className={cn(
|
|
460
|
-
"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",
|
|
709
|
+
"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",
|
|
461
710
|
className,
|
|
462
711
|
)}
|
|
463
712
|
{...props}
|
|
@@ -466,7 +715,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
466
715
|
td: ({ className, ...props }) => (
|
|
467
716
|
<td
|
|
468
717
|
className={cn(
|
|
469
|
-
"border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
718
|
+
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
470
719
|
className,
|
|
471
720
|
)}
|
|
472
721
|
{...props}
|
|
@@ -475,7 +724,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
475
724
|
tr: ({ className, ...props }) => (
|
|
476
725
|
<tr
|
|
477
726
|
className={cn(
|
|
478
|
-
"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",
|
|
727
|
+
"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",
|
|
479
728
|
className,
|
|
480
729
|
)}
|
|
481
730
|
{...props}
|
|
@@ -483,14 +732,14 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
483
732
|
),
|
|
484
733
|
sup: ({ className, ...props }) => (
|
|
485
734
|
<sup
|
|
486
|
-
className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
|
|
735
|
+
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
487
736
|
{...props}
|
|
488
737
|
/>
|
|
489
738
|
),
|
|
490
739
|
pre: ({ className, ...props }) => (
|
|
491
740
|
<pre
|
|
492
741
|
className={cn(
|
|
493
|
-
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
|
|
742
|
+
"aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
|
|
494
743
|
className,
|
|
495
744
|
)}
|
|
496
745
|
{...props}
|
|
@@ -501,7 +750,8 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
501
750
|
return (
|
|
502
751
|
<code
|
|
503
752
|
className={cn(
|
|
504
|
-
!isCodeBlock &&
|
|
753
|
+
!isCodeBlock &&
|
|
754
|
+
"aui-md-inline-code bg-muted rounded border font-semibold",
|
|
505
755
|
className,
|
|
506
756
|
)}
|
|
507
757
|
{...props}
|
|
@@ -803,12 +1053,111 @@ const CircleStopIcon = () => {
|
|
|
803
1053
|
|
|
804
1054
|
```
|
|
805
1055
|
|
|
1056
|
+
## components/assistant-ui/tool-fallback.tsx
|
|
1057
|
+
|
|
1058
|
+
```tsx
|
|
1059
|
+
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
1060
|
+
import {
|
|
1061
|
+
CheckIcon,
|
|
1062
|
+
ChevronDownIcon,
|
|
1063
|
+
ChevronUpIcon,
|
|
1064
|
+
XCircleIcon,
|
|
1065
|
+
} from "lucide-react";
|
|
1066
|
+
import { useState } from "react";
|
|
1067
|
+
import { Button } from "@/components/ui/button";
|
|
1068
|
+
import { cn } from "@/lib/utils";
|
|
1069
|
+
|
|
1070
|
+
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
1071
|
+
toolName,
|
|
1072
|
+
argsText,
|
|
1073
|
+
result,
|
|
1074
|
+
status,
|
|
1075
|
+
}) => {
|
|
1076
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
1077
|
+
|
|
1078
|
+
const isCancelled =
|
|
1079
|
+
status?.type === "incomplete" && status.reason === "cancelled";
|
|
1080
|
+
const cancelledReason =
|
|
1081
|
+
isCancelled && status.error
|
|
1082
|
+
? typeof status.error === "string"
|
|
1083
|
+
? status.error
|
|
1084
|
+
: JSON.stringify(status.error)
|
|
1085
|
+
: null;
|
|
1086
|
+
|
|
1087
|
+
return (
|
|
1088
|
+
<div
|
|
1089
|
+
className={cn(
|
|
1090
|
+
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
1091
|
+
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
1092
|
+
)}
|
|
1093
|
+
>
|
|
1094
|
+
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
1095
|
+
{isCancelled ? (
|
|
1096
|
+
<XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
|
|
1097
|
+
) : (
|
|
1098
|
+
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
1099
|
+
)}
|
|
1100
|
+
<p
|
|
1101
|
+
className={cn(
|
|
1102
|
+
"aui-tool-fallback-title grow",
|
|
1103
|
+
isCancelled && "text-muted-foreground line-through",
|
|
1104
|
+
)}
|
|
1105
|
+
>
|
|
1106
|
+
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
1107
|
+
<b>{toolName}</b>
|
|
1108
|
+
</p>
|
|
1109
|
+
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
1110
|
+
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
1111
|
+
</Button>
|
|
1112
|
+
</div>
|
|
1113
|
+
{!isCollapsed && (
|
|
1114
|
+
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
1115
|
+
{cancelledReason && (
|
|
1116
|
+
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
1117
|
+
<p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
|
|
1118
|
+
Cancelled reason:
|
|
1119
|
+
</p>
|
|
1120
|
+
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
1121
|
+
{cancelledReason}
|
|
1122
|
+
</p>
|
|
1123
|
+
</div>
|
|
1124
|
+
)}
|
|
1125
|
+
<div
|
|
1126
|
+
className={cn(
|
|
1127
|
+
"aui-tool-fallback-args-root px-4",
|
|
1128
|
+
isCancelled && "opacity-60",
|
|
1129
|
+
)}
|
|
1130
|
+
>
|
|
1131
|
+
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
1132
|
+
{argsText}
|
|
1133
|
+
</pre>
|
|
1134
|
+
</div>
|
|
1135
|
+
{!isCancelled && result !== undefined && (
|
|
1136
|
+
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
1137
|
+
<p className="aui-tool-fallback-result-header font-semibold">
|
|
1138
|
+
Result:
|
|
1139
|
+
</p>
|
|
1140
|
+
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
1141
|
+
{typeof result === "string"
|
|
1142
|
+
? result
|
|
1143
|
+
: JSON.stringify(result, null, 2)}
|
|
1144
|
+
</pre>
|
|
1145
|
+
</div>
|
|
1146
|
+
)}
|
|
1147
|
+
</div>
|
|
1148
|
+
)}
|
|
1149
|
+
</div>
|
|
1150
|
+
);
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1153
|
+
```
|
|
1154
|
+
|
|
806
1155
|
## components/assistant-ui/tooltip-icon-button.tsx
|
|
807
1156
|
|
|
808
1157
|
```tsx
|
|
809
1158
|
"use client";
|
|
810
1159
|
|
|
811
|
-
import {
|
|
1160
|
+
import { ComponentPropsWithRef, forwardRef } from "react";
|
|
812
1161
|
import { Slottable } from "@radix-ui/react-slot";
|
|
813
1162
|
|
|
814
1163
|
import {
|
|
@@ -819,7 +1168,7 @@ import {
|
|
|
819
1168
|
import { Button } from "@/components/ui/button";
|
|
820
1169
|
import { cn } from "@/lib/utils";
|
|
821
1170
|
|
|
822
|
-
export type TooltipIconButtonProps =
|
|
1171
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
823
1172
|
tooltip: string;
|
|
824
1173
|
side?: "top" | "bottom" | "left" | "right";
|
|
825
1174
|
};
|
|
@@ -835,11 +1184,11 @@ export const TooltipIconButton = forwardRef<
|
|
|
835
1184
|
variant="ghost"
|
|
836
1185
|
size="icon"
|
|
837
1186
|
{...rest}
|
|
838
|
-
className={cn("size-6 p-1", className)}
|
|
1187
|
+
className={cn("aui-button-icon size-6 p-1", className)}
|
|
839
1188
|
ref={ref}
|
|
840
1189
|
>
|
|
841
1190
|
<Slottable>{children}</Slottable>
|
|
842
|
-
<span className="sr-only">{tooltip}</span>
|
|
1191
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
843
1192
|
</Button>
|
|
844
1193
|
</TooltipTrigger>
|
|
845
1194
|
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
@@ -851,6 +1200,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
|
|
|
851
1200
|
|
|
852
1201
|
```
|
|
853
1202
|
|
|
1203
|
+
## components/ui/avatar.tsx
|
|
1204
|
+
|
|
1205
|
+
```tsx
|
|
1206
|
+
"use client";
|
|
1207
|
+
|
|
1208
|
+
import * as React from "react";
|
|
1209
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
1210
|
+
|
|
1211
|
+
import { cn } from "@/lib/utils";
|
|
1212
|
+
|
|
1213
|
+
const Avatar = React.forwardRef<
|
|
1214
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
1215
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
1216
|
+
>(({ className, ...props }, ref) => (
|
|
1217
|
+
<AvatarPrimitive.Root
|
|
1218
|
+
ref={ref}
|
|
1219
|
+
className={cn(
|
|
1220
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
1221
|
+
className,
|
|
1222
|
+
)}
|
|
1223
|
+
{...props}
|
|
1224
|
+
/>
|
|
1225
|
+
));
|
|
1226
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1227
|
+
|
|
1228
|
+
const AvatarImage = React.forwardRef<
|
|
1229
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
1230
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
1231
|
+
>(({ className, ...props }, ref) => (
|
|
1232
|
+
<AvatarPrimitive.Image
|
|
1233
|
+
ref={ref}
|
|
1234
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
1235
|
+
{...props}
|
|
1236
|
+
/>
|
|
1237
|
+
));
|
|
1238
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
1239
|
+
|
|
1240
|
+
const AvatarFallback = React.forwardRef<
|
|
1241
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
1242
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
1243
|
+
>(({ className, ...props }, ref) => (
|
|
1244
|
+
<AvatarPrimitive.Fallback
|
|
1245
|
+
ref={ref}
|
|
1246
|
+
className={cn(
|
|
1247
|
+
"bg-muted flex h-full w-full items-center justify-center rounded-full",
|
|
1248
|
+
className,
|
|
1249
|
+
)}
|
|
1250
|
+
{...props}
|
|
1251
|
+
/>
|
|
1252
|
+
));
|
|
1253
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
1254
|
+
|
|
1255
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
1256
|
+
|
|
1257
|
+
```
|
|
1258
|
+
|
|
854
1259
|
## components/ui/button.tsx
|
|
855
1260
|
|
|
856
1261
|
```tsx
|
|
@@ -916,6 +1321,147 @@ export { Button, buttonVariants };
|
|
|
916
1321
|
|
|
917
1322
|
```
|
|
918
1323
|
|
|
1324
|
+
## components/ui/dialog.tsx
|
|
1325
|
+
|
|
1326
|
+
```tsx
|
|
1327
|
+
"use client";
|
|
1328
|
+
|
|
1329
|
+
import * as React from "react";
|
|
1330
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1331
|
+
import { XIcon } from "lucide-react";
|
|
1332
|
+
|
|
1333
|
+
import { cn } from "@/lib/utils";
|
|
1334
|
+
|
|
1335
|
+
function Dialog({
|
|
1336
|
+
...props
|
|
1337
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
1338
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
function DialogTrigger({
|
|
1342
|
+
...props
|
|
1343
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
1344
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
function DialogPortal({
|
|
1348
|
+
...props
|
|
1349
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
1350
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
function DialogClose({
|
|
1354
|
+
...props
|
|
1355
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
1356
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
function DialogOverlay({
|
|
1360
|
+
className,
|
|
1361
|
+
...props
|
|
1362
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
1363
|
+
return (
|
|
1364
|
+
<DialogPrimitive.Overlay
|
|
1365
|
+
data-slot="dialog-overlay"
|
|
1366
|
+
className={cn(
|
|
1367
|
+
"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",
|
|
1368
|
+
className,
|
|
1369
|
+
)}
|
|
1370
|
+
{...props}
|
|
1371
|
+
/>
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
function DialogContent({
|
|
1376
|
+
className,
|
|
1377
|
+
children,
|
|
1378
|
+
...props
|
|
1379
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
|
|
1380
|
+
return (
|
|
1381
|
+
<DialogPortal data-slot="dialog-portal">
|
|
1382
|
+
<DialogOverlay />
|
|
1383
|
+
<DialogPrimitive.Content
|
|
1384
|
+
data-slot="dialog-content"
|
|
1385
|
+
className={cn(
|
|
1386
|
+
"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",
|
|
1387
|
+
className,
|
|
1388
|
+
)}
|
|
1389
|
+
{...props}
|
|
1390
|
+
>
|
|
1391
|
+
{children}
|
|
1392
|
+
<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">
|
|
1393
|
+
<XIcon />
|
|
1394
|
+
<span className="sr-only">Close</span>
|
|
1395
|
+
</DialogPrimitive.Close>
|
|
1396
|
+
</DialogPrimitive.Content>
|
|
1397
|
+
</DialogPortal>
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
1402
|
+
return (
|
|
1403
|
+
<div
|
|
1404
|
+
data-slot="dialog-header"
|
|
1405
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
1406
|
+
{...props}
|
|
1407
|
+
/>
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
1412
|
+
return (
|
|
1413
|
+
<div
|
|
1414
|
+
data-slot="dialog-footer"
|
|
1415
|
+
className={cn(
|
|
1416
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1417
|
+
className,
|
|
1418
|
+
)}
|
|
1419
|
+
{...props}
|
|
1420
|
+
/>
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
function DialogTitle({
|
|
1425
|
+
className,
|
|
1426
|
+
...props
|
|
1427
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
1428
|
+
return (
|
|
1429
|
+
<DialogPrimitive.Title
|
|
1430
|
+
data-slot="dialog-title"
|
|
1431
|
+
className={cn("text-lg leading-none font-semibold", className)}
|
|
1432
|
+
{...props}
|
|
1433
|
+
/>
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
function DialogDescription({
|
|
1438
|
+
className,
|
|
1439
|
+
...props
|
|
1440
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
1441
|
+
return (
|
|
1442
|
+
<DialogPrimitive.Description
|
|
1443
|
+
data-slot="dialog-description"
|
|
1444
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
1445
|
+
{...props}
|
|
1446
|
+
/>
|
|
1447
|
+
);
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
export {
|
|
1451
|
+
Dialog,
|
|
1452
|
+
DialogClose,
|
|
1453
|
+
DialogContent,
|
|
1454
|
+
DialogDescription,
|
|
1455
|
+
DialogFooter,
|
|
1456
|
+
DialogHeader,
|
|
1457
|
+
DialogOverlay,
|
|
1458
|
+
DialogPortal,
|
|
1459
|
+
DialogTitle,
|
|
1460
|
+
DialogTrigger,
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
```
|
|
1464
|
+
|
|
919
1465
|
## components/ui/tooltip.tsx
|
|
920
1466
|
|
|
921
1467
|
```tsx
|
|
@@ -1022,22 +1568,26 @@ export default nextConfig;
|
|
|
1022
1568
|
"lint": "eslint ."
|
|
1023
1569
|
},
|
|
1024
1570
|
"dependencies": {
|
|
1025
|
-
"@ai-sdk/openai": "^2.0.
|
|
1571
|
+
"@ai-sdk/openai": "^2.0.73",
|
|
1026
1572
|
"@assistant-ui/react": "workspace:*",
|
|
1027
1573
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1028
1574
|
"@assistant-ui/react-ag-ui": "workspace:*",
|
|
1029
1575
|
"@ag-ui/client": "^0.0.41",
|
|
1576
|
+
"@radix-ui/react-avatar": "^1.1.4",
|
|
1577
|
+
"@radix-ui/react-dialog": "^1.1.7",
|
|
1030
1578
|
"@radix-ui/react-slot": "^1.2.4",
|
|
1031
1579
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1032
1580
|
"class-variance-authority": "^0.7.1",
|
|
1033
1581
|
"clsx": "^2.1.1",
|
|
1034
|
-
"lucide-react": "^0.
|
|
1035
|
-
"
|
|
1582
|
+
"lucide-react": "^0.555.0",
|
|
1583
|
+
"motion": "^11.18.2",
|
|
1584
|
+
"next": "16.0.4",
|
|
1036
1585
|
"react": "19.2.0",
|
|
1037
1586
|
"react-dom": "19.2.0",
|
|
1038
1587
|
"remark-gfm": "^4.0.1",
|
|
1039
1588
|
"tailwind-merge": "^3.4.0",
|
|
1040
|
-
"tw-animate-css": "^1.4.0"
|
|
1589
|
+
"tw-animate-css": "^1.4.0",
|
|
1590
|
+
"zustand": "^5.0.8"
|
|
1041
1591
|
},
|
|
1042
1592
|
"devDependencies": {
|
|
1043
1593
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
@@ -1045,7 +1595,7 @@ export default nextConfig;
|
|
|
1045
1595
|
"@types/react": "^19",
|
|
1046
1596
|
"@types/react-dom": "^19",
|
|
1047
1597
|
"eslint": "^9",
|
|
1048
|
-
"eslint-config-next": "16.0.
|
|
1598
|
+
"eslint-config-next": "16.0.4",
|
|
1049
1599
|
"postcss": "^8",
|
|
1050
1600
|
"tailwindcss": "^4.1.17",
|
|
1051
1601
|
"typescript": "^5"
|