@assistant-ui/mcp-docs-server 0.1.13 → 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.
Files changed (26) hide show
  1. package/.docs/organized/code-examples/store-example.md +554 -0
  2. package/.docs/organized/code-examples/with-ag-ui.md +1639 -0
  3. package/.docs/organized/code-examples/with-ai-sdk-v5.md +555 -53
  4. package/.docs/organized/code-examples/with-assistant-transport.md +553 -52
  5. package/.docs/organized/code-examples/with-cloud.md +637 -42
  6. package/.docs/organized/code-examples/with-external-store.md +584 -34
  7. package/.docs/organized/code-examples/with-ffmpeg.md +586 -52
  8. package/.docs/organized/code-examples/with-langgraph.md +636 -53
  9. package/.docs/organized/code-examples/with-parent-id-grouping.md +584 -34
  10. package/.docs/organized/code-examples/with-react-hook-form.md +587 -75
  11. package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -1
  12. package/.docs/raw/docs/cli.mdx +396 -0
  13. package/.docs/raw/docs/cloud/authorization.mdx +2 -2
  14. package/.docs/raw/docs/getting-started.mdx +31 -37
  15. package/.docs/raw/docs/guides/context-api.mdx +5 -5
  16. package/.docs/raw/docs/migrations/v0-12.mdx +2 -2
  17. package/.docs/raw/docs/runtimes/assistant-transport.mdx +891 -0
  18. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +9 -0
  19. package/.docs/raw/docs/runtimes/custom/local.mdx +77 -4
  20. package/.docs/raw/docs/runtimes/langgraph/index.mdx +8 -5
  21. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +12 -10
  22. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +50 -31
  23. package/.docs/raw/docs/ui/Reasoning.mdx +174 -0
  24. package/dist/chunk-M2RKUM66.js +3 -3
  25. package/dist/chunk-NVNFQ5ZO.js +2 -2
  26. package/package.json +15 -7
@@ -265,7 +265,6 @@ const converter = (
265
265
  );
266
266
 
267
267
  const messages = [...state.messages, ...optimisticStateMessages.flat()];
268
- console.log({ state, messages });
269
268
  return {
270
269
  messages: LangChainMessageConverter.toThreadMessages(messages),
271
270
  isRunning: connectionMetadata.isSending || false,
@@ -359,6 +358,247 @@ export default function Home() {
359
358
 
360
359
  ```
361
360
 
361
+ ## components/assistant-ui/attachment.tsx
362
+
363
+ ```tsx
364
+ "use client";
365
+
366
+ import { PropsWithChildren, useEffect, useState, type FC } from "react";
367
+ import Image from "next/image";
368
+ import { XIcon, PlusIcon, FileText } from "lucide-react";
369
+ import {
370
+ AttachmentPrimitive,
371
+ ComposerPrimitive,
372
+ MessagePrimitive,
373
+ useAssistantState,
374
+ useAssistantApi,
375
+ } from "@assistant-ui/react";
376
+ import { useShallow } from "zustand/shallow";
377
+ import {
378
+ Tooltip,
379
+ TooltipContent,
380
+ TooltipTrigger,
381
+ } from "@/components/ui/tooltip";
382
+ import {
383
+ Dialog,
384
+ DialogTitle,
385
+ DialogContent,
386
+ DialogTrigger,
387
+ } from "@/components/ui/dialog";
388
+ import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
389
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
390
+ import { cn } from "@/lib/utils";
391
+
392
+ const useFileSrc = (file: File | undefined) => {
393
+ const [src, setSrc] = useState<string | undefined>(undefined);
394
+
395
+ useEffect(() => {
396
+ if (!file) {
397
+ setSrc(undefined);
398
+ return;
399
+ }
400
+
401
+ const objectUrl = URL.createObjectURL(file);
402
+ setSrc(objectUrl);
403
+
404
+ return () => {
405
+ URL.revokeObjectURL(objectUrl);
406
+ };
407
+ }, [file]);
408
+
409
+ return src;
410
+ };
411
+
412
+ const useAttachmentSrc = () => {
413
+ const { file, src } = useAssistantState(
414
+ useShallow(({ attachment }): { file?: File; src?: string } => {
415
+ if (attachment.type !== "image") return {};
416
+ if (attachment.file) return { file: attachment.file };
417
+ const src = attachment.content?.filter((c) => c.type === "image")[0]
418
+ ?.image;
419
+ if (!src) return {};
420
+ return { src };
421
+ }),
422
+ );
423
+
424
+ return useFileSrc(file) ?? src;
425
+ };
426
+
427
+ type AttachmentPreviewProps = {
428
+ src: string;
429
+ };
430
+
431
+ const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
432
+ const [isLoaded, setIsLoaded] = useState(false);
433
+ return (
434
+ <Image
435
+ src={src}
436
+ alt="Image Preview"
437
+ width={1}
438
+ height={1}
439
+ className={
440
+ isLoaded
441
+ ? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
442
+ : "aui-attachment-preview-image-loading hidden"
443
+ }
444
+ onLoadingComplete={() => setIsLoaded(true)}
445
+ priority={false}
446
+ />
447
+ );
448
+ };
449
+
450
+ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
451
+ const src = useAttachmentSrc();
452
+
453
+ if (!src) return children;
454
+
455
+ return (
456
+ <Dialog>
457
+ <DialogTrigger
458
+ className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
459
+ asChild
460
+ >
461
+ {children}
462
+ </DialogTrigger>
463
+ <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">
464
+ <DialogTitle className="aui-sr-only sr-only">
465
+ Image Attachment Preview
466
+ </DialogTitle>
467
+ <div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
468
+ <AttachmentPreview src={src} />
469
+ </div>
470
+ </DialogContent>
471
+ </Dialog>
472
+ );
473
+ };
474
+
475
+ const AttachmentThumb: FC = () => {
476
+ const isImage = useAssistantState(
477
+ ({ attachment }) => attachment.type === "image",
478
+ );
479
+ const src = useAttachmentSrc();
480
+
481
+ return (
482
+ <Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
483
+ <AvatarImage
484
+ src={src}
485
+ alt="Attachment preview"
486
+ className="aui-attachment-tile-image object-cover"
487
+ />
488
+ <AvatarFallback delayMs={isImage ? 200 : 0}>
489
+ <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
490
+ </AvatarFallback>
491
+ </Avatar>
492
+ );
493
+ };
494
+
495
+ const AttachmentUI: FC = () => {
496
+ const api = useAssistantApi();
497
+ const isComposer = api.attachment.source === "composer";
498
+
499
+ const isImage = useAssistantState(
500
+ ({ attachment }) => attachment.type === "image",
501
+ );
502
+ const typeLabel = useAssistantState(({ attachment }) => {
503
+ const type = attachment.type;
504
+ switch (type) {
505
+ case "image":
506
+ return "Image";
507
+ case "document":
508
+ return "Document";
509
+ case "file":
510
+ return "File";
511
+ default:
512
+ const _exhaustiveCheck: never = type;
513
+ throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
514
+ }
515
+ });
516
+
517
+ return (
518
+ <Tooltip>
519
+ <AttachmentPrimitive.Root
520
+ className={cn(
521
+ "aui-attachment-root relative",
522
+ isImage &&
523
+ "aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
524
+ )}
525
+ >
526
+ <AttachmentPreviewDialog>
527
+ <TooltipTrigger asChild>
528
+ <div
529
+ className={cn(
530
+ "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
531
+ isComposer &&
532
+ "aui-attachment-tile-composer border-foreground/20",
533
+ )}
534
+ role="button"
535
+ id="attachment-tile"
536
+ aria-label={`${typeLabel} attachment`}
537
+ >
538
+ <AttachmentThumb />
539
+ </div>
540
+ </TooltipTrigger>
541
+ </AttachmentPreviewDialog>
542
+ {isComposer && <AttachmentRemove />}
543
+ </AttachmentPrimitive.Root>
544
+ <TooltipContent side="top">
545
+ <AttachmentPrimitive.Name />
546
+ </TooltipContent>
547
+ </Tooltip>
548
+ );
549
+ };
550
+
551
+ const AttachmentRemove: FC = () => {
552
+ return (
553
+ <AttachmentPrimitive.Remove asChild>
554
+ <TooltipIconButton
555
+ tooltip="Remove file"
556
+ 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"
557
+ side="top"
558
+ >
559
+ <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
560
+ </TooltipIconButton>
561
+ </AttachmentPrimitive.Remove>
562
+ );
563
+ };
564
+
565
+ export const UserMessageAttachments: FC = () => {
566
+ return (
567
+ <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">
568
+ <MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
569
+ </div>
570
+ );
571
+ };
572
+
573
+ export const ComposerAttachments: FC = () => {
574
+ return (
575
+ <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">
576
+ <ComposerPrimitive.Attachments
577
+ components={{ Attachment: AttachmentUI }}
578
+ />
579
+ </div>
580
+ );
581
+ };
582
+
583
+ export const ComposerAddAttachment: FC = () => {
584
+ return (
585
+ <ComposerPrimitive.AddAttachment asChild>
586
+ <TooltipIconButton
587
+ tooltip="Add Attachment"
588
+ side="bottom"
589
+ variant="ghost"
590
+ size="icon"
591
+ 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"
592
+ aria-label="Add Attachment"
593
+ >
594
+ <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
595
+ </TooltipIconButton>
596
+ </ComposerPrimitive.AddAttachment>
597
+ );
598
+ };
599
+
600
+ ```
601
+
362
602
  ## components/assistant-ui/markdown-text.tsx
363
603
 
364
604
  ```tsx
@@ -399,8 +639,10 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
399
639
  };
400
640
 
401
641
  return (
402
- <div className="mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white">
403
- <span className="lowercase [&>span]:text-xs">{language}</span>
642
+ <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">
643
+ <span className="aui-code-header-language lowercase [&>span]:text-xs">
644
+ {language}
645
+ </span>
404
646
  <TooltipIconButton tooltip="Copy" onClick={onCopy}>
405
647
  {!isCopied && <CopyIcon />}
406
648
  {isCopied && <CheckIcon />}
@@ -432,7 +674,7 @@ const defaultComponents = memoizeMarkdownComponents({
432
674
  h1: ({ className, ...props }) => (
433
675
  <h1
434
676
  className={cn(
435
- "mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
677
+ "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
436
678
  className,
437
679
  )}
438
680
  {...props}
@@ -441,7 +683,7 @@ const defaultComponents = memoizeMarkdownComponents({
441
683
  h2: ({ className, ...props }) => (
442
684
  <h2
443
685
  className={cn(
444
- "mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
686
+ "aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
445
687
  className,
446
688
  )}
447
689
  {...props}
@@ -450,7 +692,7 @@ const defaultComponents = memoizeMarkdownComponents({
450
692
  h3: ({ className, ...props }) => (
451
693
  <h3
452
694
  className={cn(
453
- "mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
695
+ "aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
454
696
  className,
455
697
  )}
456
698
  {...props}
@@ -459,7 +701,7 @@ const defaultComponents = memoizeMarkdownComponents({
459
701
  h4: ({ className, ...props }) => (
460
702
  <h4
461
703
  className={cn(
462
- "mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
704
+ "aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
463
705
  className,
464
706
  )}
465
707
  {...props}
@@ -468,7 +710,7 @@ const defaultComponents = memoizeMarkdownComponents({
468
710
  h5: ({ className, ...props }) => (
469
711
  <h5
470
712
  className={cn(
471
- "my-4 text-lg font-semibold first:mt-0 last:mb-0",
713
+ "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
472
714
  className,
473
715
  )}
474
716
  {...props}
@@ -476,20 +718,26 @@ const defaultComponents = memoizeMarkdownComponents({
476
718
  ),
477
719
  h6: ({ className, ...props }) => (
478
720
  <h6
479
- className={cn("my-4 font-semibold first:mt-0 last:mb-0", className)}
721
+ className={cn(
722
+ "aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
723
+ className,
724
+ )}
480
725
  {...props}
481
726
  />
482
727
  ),
483
728
  p: ({ className, ...props }) => (
484
729
  <p
485
- className={cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className)}
730
+ className={cn(
731
+ "aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
732
+ className,
733
+ )}
486
734
  {...props}
487
735
  />
488
736
  ),
489
737
  a: ({ className, ...props }) => (
490
738
  <a
491
739
  className={cn(
492
- "text-primary font-medium underline underline-offset-4",
740
+ "aui-md-a text-primary font-medium underline underline-offset-4",
493
741
  className,
494
742
  )}
495
743
  {...props}
@@ -497,29 +745,29 @@ const defaultComponents = memoizeMarkdownComponents({
497
745
  ),
498
746
  blockquote: ({ className, ...props }) => (
499
747
  <blockquote
500
- className={cn("border-l-2 pl-6 italic", className)}
748
+ className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
501
749
  {...props}
502
750
  />
503
751
  ),
504
752
  ul: ({ className, ...props }) => (
505
753
  <ul
506
- className={cn("my-5 ml-6 list-disc [&>li]:mt-2", className)}
754
+ className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
507
755
  {...props}
508
756
  />
509
757
  ),
510
758
  ol: ({ className, ...props }) => (
511
759
  <ol
512
- className={cn("my-5 ml-6 list-decimal [&>li]:mt-2", className)}
760
+ className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
513
761
  {...props}
514
762
  />
515
763
  ),
516
764
  hr: ({ className, ...props }) => (
517
- <hr className={cn("my-5 border-b", className)} {...props} />
765
+ <hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
518
766
  ),
519
767
  table: ({ className, ...props }) => (
520
768
  <table
521
769
  className={cn(
522
- "my-5 w-full border-separate border-spacing-0 overflow-y-auto",
770
+ "aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
523
771
  className,
524
772
  )}
525
773
  {...props}
@@ -528,7 +776,7 @@ const defaultComponents = memoizeMarkdownComponents({
528
776
  th: ({ className, ...props }) => (
529
777
  <th
530
778
  className={cn(
531
- "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",
779
+ "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",
532
780
  className,
533
781
  )}
534
782
  {...props}
@@ -537,7 +785,7 @@ const defaultComponents = memoizeMarkdownComponents({
537
785
  td: ({ className, ...props }) => (
538
786
  <td
539
787
  className={cn(
540
- "border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
788
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
541
789
  className,
542
790
  )}
543
791
  {...props}
@@ -546,7 +794,7 @@ const defaultComponents = memoizeMarkdownComponents({
546
794
  tr: ({ className, ...props }) => (
547
795
  <tr
548
796
  className={cn(
549
- "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",
797
+ "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",
550
798
  className,
551
799
  )}
552
800
  {...props}
@@ -554,14 +802,14 @@ const defaultComponents = memoizeMarkdownComponents({
554
802
  ),
555
803
  sup: ({ className, ...props }) => (
556
804
  <sup
557
- className={cn("[&>a]:text-xs [&>a]:no-underline", className)}
805
+ className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
558
806
  {...props}
559
807
  />
560
808
  ),
561
809
  pre: ({ className, ...props }) => (
562
810
  <pre
563
811
  className={cn(
564
- "overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
812
+ "aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
565
813
  className,
566
814
  )}
567
815
  {...props}
@@ -572,7 +820,8 @@ const defaultComponents = memoizeMarkdownComponents({
572
820
  return (
573
821
  <code
574
822
  className={cn(
575
- !isCodeBlock && "bg-muted rounded border font-semibold",
823
+ !isCodeBlock &&
824
+ "aui-md-inline-code bg-muted rounded border font-semibold",
576
825
  className,
577
826
  )}
578
827
  {...props}
@@ -990,37 +1239,88 @@ const StarIcon = ({ size = 14 }: { size?: number }) => (
990
1239
  ## components/assistant-ui/tool-fallback.tsx
991
1240
 
992
1241
  ```tsx
993
- import { ToolCallMessagePartComponent } from "@assistant-ui/react";
994
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
1242
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1243
+ import {
1244
+ CheckIcon,
1245
+ ChevronDownIcon,
1246
+ ChevronUpIcon,
1247
+ XCircleIcon,
1248
+ } from "lucide-react";
995
1249
  import { useState } from "react";
996
- import { Button } from "../ui/button";
1250
+ import { Button } from "@/components/ui/button";
1251
+ import { cn } from "@/lib/utils";
997
1252
 
998
1253
  export const ToolFallback: ToolCallMessagePartComponent = ({
999
1254
  toolName,
1000
1255
  argsText,
1001
1256
  result,
1257
+ status,
1002
1258
  }) => {
1003
1259
  const [isCollapsed, setIsCollapsed] = useState(true);
1260
+
1261
+ const isCancelled =
1262
+ status?.type === "incomplete" && status.reason === "cancelled";
1263
+ const cancelledReason =
1264
+ isCancelled && status.error
1265
+ ? typeof status.error === "string"
1266
+ ? status.error
1267
+ : JSON.stringify(status.error)
1268
+ : null;
1269
+
1004
1270
  return (
1005
- <div className="mb-4 flex w-full flex-col gap-3 rounded-lg border py-3">
1006
- <div className="flex items-center gap-2 px-4">
1007
- <CheckIcon className="size-4" />
1008
- <p className="flex-grow">
1009
- Used tool: <b>{toolName}</b>
1271
+ <div
1272
+ className={cn(
1273
+ "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1274
+ isCancelled && "border-muted-foreground/30 bg-muted/30",
1275
+ )}
1276
+ >
1277
+ <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1278
+ {isCancelled ? (
1279
+ <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1280
+ ) : (
1281
+ <CheckIcon className="aui-tool-fallback-icon size-4" />
1282
+ )}
1283
+ <p
1284
+ className={cn(
1285
+ "aui-tool-fallback-title grow",
1286
+ isCancelled && "text-muted-foreground line-through",
1287
+ )}
1288
+ >
1289
+ {isCancelled ? "Cancelled tool: " : "Used tool: "}
1290
+ <b>{toolName}</b>
1010
1291
  </p>
1011
1292
  <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1012
1293
  {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1013
1294
  </Button>
1014
1295
  </div>
1015
1296
  {!isCollapsed && (
1016
- <div className="flex flex-col gap-2 border-t pt-2">
1017
- <div className="px-4">
1018
- <pre className="whitespace-pre-wrap">{argsText}</pre>
1297
+ <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1298
+ {cancelledReason && (
1299
+ <div className="aui-tool-fallback-cancelled-root px-4">
1300
+ <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1301
+ Cancelled reason:
1302
+ </p>
1303
+ <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1304
+ {cancelledReason}
1305
+ </p>
1306
+ </div>
1307
+ )}
1308
+ <div
1309
+ className={cn(
1310
+ "aui-tool-fallback-args-root px-4",
1311
+ isCancelled && "opacity-60",
1312
+ )}
1313
+ >
1314
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1315
+ {argsText}
1316
+ </pre>
1019
1317
  </div>
1020
- {result !== undefined && (
1021
- <div className="border-t border-dashed px-4 pt-2">
1022
- <p className="font-semibold">Result:</p>
1023
- <pre className="whitespace-pre-wrap">
1318
+ {!isCancelled && result !== undefined && (
1319
+ <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1320
+ <p className="aui-tool-fallback-result-header font-semibold">
1321
+ Result:
1322
+ </p>
1323
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1024
1324
  {typeof result === "string"
1025
1325
  ? result
1026
1326
  : JSON.stringify(result, null, 2)}
@@ -1040,7 +1340,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1040
1340
  ```tsx
1041
1341
  "use client";
1042
1342
 
1043
- import { ComponentPropsWithoutRef, forwardRef } from "react";
1343
+ import { ComponentPropsWithRef, forwardRef } from "react";
1044
1344
  import { Slottable } from "@radix-ui/react-slot";
1045
1345
 
1046
1346
  import {
@@ -1051,7 +1351,7 @@ import {
1051
1351
  import { Button } from "@/components/ui/button";
1052
1352
  import { cn } from "@/lib/utils";
1053
1353
 
1054
- export type TooltipIconButtonProps = ComponentPropsWithoutRef<typeof Button> & {
1354
+ export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
1055
1355
  tooltip: string;
1056
1356
  side?: "top" | "bottom" | "left" | "right";
1057
1357
  };
@@ -1067,11 +1367,11 @@ export const TooltipIconButton = forwardRef<
1067
1367
  variant="ghost"
1068
1368
  size="icon"
1069
1369
  {...rest}
1070
- className={cn("size-6 p-1", className)}
1370
+ className={cn("aui-button-icon size-6 p-1", className)}
1071
1371
  ref={ref}
1072
1372
  >
1073
1373
  <Slottable>{children}</Slottable>
1074
- <span className="sr-only">{tooltip}</span>
1374
+ <span className="aui-sr-only sr-only">{tooltip}</span>
1075
1375
  </Button>
1076
1376
  </TooltipTrigger>
1077
1377
  <TooltipContent side={side}>{tooltip}</TooltipContent>
@@ -1083,6 +1383,62 @@ TooltipIconButton.displayName = "TooltipIconButton";
1083
1383
 
1084
1384
  ```
1085
1385
 
1386
+ ## components/ui/avatar.tsx
1387
+
1388
+ ```tsx
1389
+ "use client";
1390
+
1391
+ import * as React from "react";
1392
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1393
+
1394
+ import { cn } from "@/lib/utils";
1395
+
1396
+ const Avatar = React.forwardRef<
1397
+ React.ElementRef<typeof AvatarPrimitive.Root>,
1398
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1399
+ >(({ className, ...props }, ref) => (
1400
+ <AvatarPrimitive.Root
1401
+ ref={ref}
1402
+ className={cn(
1403
+ "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1404
+ className,
1405
+ )}
1406
+ {...props}
1407
+ />
1408
+ ));
1409
+ Avatar.displayName = AvatarPrimitive.Root.displayName;
1410
+
1411
+ const AvatarImage = React.forwardRef<
1412
+ React.ElementRef<typeof AvatarPrimitive.Image>,
1413
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1414
+ >(({ className, ...props }, ref) => (
1415
+ <AvatarPrimitive.Image
1416
+ ref={ref}
1417
+ className={cn("aspect-square h-full w-full", className)}
1418
+ {...props}
1419
+ />
1420
+ ));
1421
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1422
+
1423
+ const AvatarFallback = React.forwardRef<
1424
+ React.ElementRef<typeof AvatarPrimitive.Fallback>,
1425
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1426
+ >(({ className, ...props }, ref) => (
1427
+ <AvatarPrimitive.Fallback
1428
+ ref={ref}
1429
+ className={cn(
1430
+ "bg-muted flex h-full w-full items-center justify-center rounded-full",
1431
+ className,
1432
+ )}
1433
+ {...props}
1434
+ />
1435
+ ));
1436
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1437
+
1438
+ export { Avatar, AvatarImage, AvatarFallback };
1439
+
1440
+ ```
1441
+
1086
1442
  ## components/ui/button.tsx
1087
1443
 
1088
1444
  ```tsx
@@ -1148,6 +1504,147 @@ export { Button, buttonVariants };
1148
1504
 
1149
1505
  ```
1150
1506
 
1507
+ ## components/ui/dialog.tsx
1508
+
1509
+ ```tsx
1510
+ "use client";
1511
+
1512
+ import * as React from "react";
1513
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
1514
+ import { XIcon } from "lucide-react";
1515
+
1516
+ import { cn } from "@/lib/utils";
1517
+
1518
+ function Dialog({
1519
+ ...props
1520
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
1521
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />;
1522
+ }
1523
+
1524
+ function DialogTrigger({
1525
+ ...props
1526
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
1527
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
1528
+ }
1529
+
1530
+ function DialogPortal({
1531
+ ...props
1532
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
1533
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
1534
+ }
1535
+
1536
+ function DialogClose({
1537
+ ...props
1538
+ }: React.ComponentProps<typeof DialogPrimitive.Close>) {
1539
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
1540
+ }
1541
+
1542
+ function DialogOverlay({
1543
+ className,
1544
+ ...props
1545
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
1546
+ return (
1547
+ <DialogPrimitive.Overlay
1548
+ data-slot="dialog-overlay"
1549
+ className={cn(
1550
+ "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",
1551
+ className,
1552
+ )}
1553
+ {...props}
1554
+ />
1555
+ );
1556
+ }
1557
+
1558
+ function DialogContent({
1559
+ className,
1560
+ children,
1561
+ ...props
1562
+ }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1563
+ return (
1564
+ <DialogPortal data-slot="dialog-portal">
1565
+ <DialogOverlay />
1566
+ <DialogPrimitive.Content
1567
+ data-slot="dialog-content"
1568
+ className={cn(
1569
+ "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",
1570
+ className,
1571
+ )}
1572
+ {...props}
1573
+ >
1574
+ {children}
1575
+ <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">
1576
+ <XIcon />
1577
+ <span className="sr-only">Close</span>
1578
+ </DialogPrimitive.Close>
1579
+ </DialogPrimitive.Content>
1580
+ </DialogPortal>
1581
+ );
1582
+ }
1583
+
1584
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
1585
+ return (
1586
+ <div
1587
+ data-slot="dialog-header"
1588
+ className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
1589
+ {...props}
1590
+ />
1591
+ );
1592
+ }
1593
+
1594
+ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
1595
+ return (
1596
+ <div
1597
+ data-slot="dialog-footer"
1598
+ className={cn(
1599
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
1600
+ className,
1601
+ )}
1602
+ {...props}
1603
+ />
1604
+ );
1605
+ }
1606
+
1607
+ function DialogTitle({
1608
+ className,
1609
+ ...props
1610
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
1611
+ return (
1612
+ <DialogPrimitive.Title
1613
+ data-slot="dialog-title"
1614
+ className={cn("text-lg leading-none font-semibold", className)}
1615
+ {...props}
1616
+ />
1617
+ );
1618
+ }
1619
+
1620
+ function DialogDescription({
1621
+ className,
1622
+ ...props
1623
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
1624
+ return (
1625
+ <DialogPrimitive.Description
1626
+ data-slot="dialog-description"
1627
+ className={cn("text-muted-foreground text-sm", className)}
1628
+ {...props}
1629
+ />
1630
+ );
1631
+ }
1632
+
1633
+ export {
1634
+ Dialog,
1635
+ DialogClose,
1636
+ DialogContent,
1637
+ DialogDescription,
1638
+ DialogFooter,
1639
+ DialogHeader,
1640
+ DialogOverlay,
1641
+ DialogPortal,
1642
+ DialogTitle,
1643
+ DialogTrigger,
1644
+ };
1645
+
1646
+ ```
1647
+
1151
1648
  ## components/ui/tooltip.tsx
1152
1649
 
1153
1650
  ```tsx
@@ -1261,29 +1758,33 @@ export default nextConfig;
1261
1758
  "@assistant-ui/react": "workspace:^",
1262
1759
  "@assistant-ui/react-langgraph": "workspace:^",
1263
1760
  "@assistant-ui/react-markdown": "workspace:^",
1264
- "@radix-ui/react-slot": "^1.2.3",
1761
+ "@radix-ui/react-avatar": "^1.1.4",
1762
+ "@radix-ui/react-dialog": "^1.1.7",
1763
+ "@radix-ui/react-slot": "^1.2.4",
1265
1764
  "@radix-ui/react-tooltip": "^1.2.8",
1266
- "@tailwindcss/postcss": "^4.1.16",
1267
- "assistant-stream": "^0.2.39",
1765
+ "@tailwindcss/postcss": "^4.1.17",
1766
+ "assistant-stream": "^0.2.42",
1268
1767
  "class-variance-authority": "^0.7.1",
1269
1768
  "clsx": "^2.1.1",
1270
1769
  "framer-motion": "^12.23.24",
1271
- "lucide-react": "^0.552.0",
1272
- "next": "16.0.1",
1770
+ "lucide-react": "^0.555.0",
1771
+ "motion": "^11.18.2",
1772
+ "next": "16.0.4",
1273
1773
  "postcss": "^8.5.6",
1274
1774
  "react": "19.2.0",
1275
1775
  "react-dom": "19.2.0",
1276
1776
  "remark-gfm": "^4.0.1",
1277
- "tailwind-merge": "^3.3.1",
1278
- "tailwindcss": "^4.1.16",
1777
+ "tailwind-merge": "^3.4.0",
1778
+ "tailwindcss": "^4.1.17",
1279
1779
  "tailwindcss-animate": "^1.0.7",
1280
- "zod": "^4.1.12"
1780
+ "zod": "^4.1.13",
1781
+ "zustand": "^5.0.8"
1281
1782
  },
1282
1783
  "devDependencies": {
1283
1784
  "@assistant-ui/x-buildutils": "workspace:*",
1284
- "@types/node": "^24.10.0",
1285
- "@types/react": "^19.2.2",
1286
- "@types/react-dom": "^19.2.2",
1785
+ "@types/node": "^24.10.1",
1786
+ "@types/react": "^19.2.7",
1787
+ "@types/react-dom": "^19.2.3",
1287
1788
  "tw-animate-css": "^1.4.0",
1288
1789
  "typescript": "^5.9.3"
1289
1790
  },