@assistant-ui/mcp-docs-server 0.1.15 → 0.1.16

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 (55) hide show
  1. package/.docs/organized/code-examples/store-example.md +112 -38
  2. package/.docs/organized/code-examples/with-ag-ui.md +248 -184
  3. package/.docs/organized/code-examples/with-ai-sdk-v5.md +247 -196
  4. package/.docs/organized/code-examples/with-assistant-transport.md +192 -240
  5. package/.docs/organized/code-examples/with-cloud.md +275 -224
  6. package/.docs/organized/code-examples/with-custom-thread-list.md +1855 -0
  7. package/.docs/organized/code-examples/with-external-store.md +244 -178
  8. package/.docs/organized/code-examples/with-ffmpeg.md +253 -187
  9. package/.docs/organized/code-examples/with-langgraph.md +291 -240
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +241 -261
  11. package/.docs/organized/code-examples/with-react-hook-form.md +260 -194
  12. package/.docs/organized/code-examples/with-tanstack.md +1574 -0
  13. package/.docs/raw/blog/2024-07-29-hello/index.mdx +2 -2
  14. package/.docs/raw/docs/api-reference/overview.mdx +6 -6
  15. package/.docs/raw/docs/api-reference/primitives/ActionBar.mdx +85 -4
  16. package/.docs/raw/docs/api-reference/primitives/AssistantIf.mdx +200 -0
  17. package/.docs/raw/docs/api-reference/primitives/Composer.mdx +0 -20
  18. package/.docs/raw/docs/api-reference/primitives/Message.mdx +0 -45
  19. package/.docs/raw/docs/api-reference/primitives/Thread.mdx +0 -50
  20. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +2 -3
  21. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +2 -3
  22. package/.docs/raw/docs/devtools.mdx +2 -3
  23. package/.docs/raw/docs/getting-started.mdx +36 -1102
  24. package/.docs/raw/docs/guides/Attachments.mdx +3 -25
  25. package/.docs/raw/docs/guides/Branching.mdx +1 -1
  26. package/.docs/raw/docs/guides/Speech.mdx +1 -1
  27. package/.docs/raw/docs/guides/ToolUI.mdx +1 -1
  28. package/.docs/raw/docs/legacy/styled/AssistantModal.mdx +2 -3
  29. package/.docs/raw/docs/legacy/styled/Decomposition.mdx +6 -5
  30. package/.docs/raw/docs/legacy/styled/Markdown.mdx +2 -3
  31. package/.docs/raw/docs/legacy/styled/Thread.mdx +2 -3
  32. package/.docs/raw/docs/react-compatibility.mdx +2 -5
  33. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +3 -4
  34. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +3 -6
  35. package/.docs/raw/docs/runtimes/custom/external-store.mdx +2 -3
  36. package/.docs/raw/docs/runtimes/custom/local.mdx +11 -41
  37. package/.docs/raw/docs/runtimes/data-stream.mdx +15 -11
  38. package/.docs/raw/docs/runtimes/langgraph/index.mdx +3 -3
  39. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
  40. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +2 -3
  41. package/.docs/raw/docs/runtimes/langserve.mdx +2 -3
  42. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +2 -3
  43. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +2 -3
  44. package/.docs/raw/docs/ui/AssistantModal.mdx +3 -25
  45. package/.docs/raw/docs/ui/AssistantSidebar.mdx +2 -24
  46. package/.docs/raw/docs/ui/Attachment.mdx +3 -25
  47. package/.docs/raw/docs/ui/Markdown.mdx +2 -24
  48. package/.docs/raw/docs/ui/Mermaid.mdx +2 -24
  49. package/.docs/raw/docs/ui/Reasoning.mdx +2 -24
  50. package/.docs/raw/docs/ui/Scrollbar.mdx +4 -6
  51. package/.docs/raw/docs/ui/SyntaxHighlighting.mdx +3 -47
  52. package/.docs/raw/docs/ui/Thread.mdx +38 -53
  53. package/.docs/raw/docs/ui/ThreadList.mdx +4 -47
  54. package/.docs/raw/docs/ui/ToolFallback.mdx +2 -24
  55. package/package.json +5 -6
@@ -231,15 +231,15 @@ const BrowserAlertTool = () => {
231
231
  },
232
232
  render: ({ args, result }) => (
233
233
  <div className="mt-3 w-full max-w-[var(--thread-max-width)] rounded-lg border px-4 py-3 text-sm">
234
- <p className="text-muted-foreground font-semibold">browser_alert</p>
234
+ <p className="font-semibold text-muted-foreground">browser_alert</p>
235
235
  <p className="mt-1">
236
236
  Requested alert with message:
237
- <span className="text-foreground ml-1 font-mono">
237
+ <span className="ml-1 font-mono text-foreground">
238
238
  {JSON.stringify(args.message)}
239
239
  </span>
240
240
  </p>
241
241
  {result?.status === "shown" && (
242
- <p className="text-foreground/70 mt-2 text-xs">
242
+ <p className="mt-2 text-foreground/70 text-xs">
243
243
  Alert displayed in this tab.
244
244
  </p>
245
245
  )}
@@ -385,16 +385,16 @@ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
385
385
  return (
386
386
  <Dialog>
387
387
  <DialogTrigger
388
- className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
388
+ className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
389
389
  asChild
390
390
  >
391
391
  {children}
392
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">
393
+ <DialogContent className="aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0! [&_svg]:text-background [&>button]:hover:[&_svg]:text-destructive">
394
394
  <DialogTitle className="aui-sr-only sr-only">
395
395
  Image Attachment Preview
396
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">
397
+ <div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
398
398
  <AttachmentPreview src={src} />
399
399
  </div>
400
400
  </DialogContent>
@@ -416,7 +416,7 @@ const AttachmentThumb: FC = () => {
416
416
  className="aui-attachment-tile-image object-cover"
417
417
  />
418
418
  <AvatarFallback delayMs={isImage ? 200 : 0}>
419
- <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
419
+ <FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
420
420
  </AvatarFallback>
421
421
  </Avatar>
422
422
  );
@@ -457,7 +457,7 @@ const AttachmentUI: FC = () => {
457
457
  <TooltipTrigger asChild>
458
458
  <div
459
459
  className={cn(
460
- "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
460
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
461
461
  isComposer &&
462
462
  "aui-attachment-tile-composer border-foreground/20",
463
463
  )}
@@ -483,7 +483,7 @@ const AttachmentRemove: FC = () => {
483
483
  <AttachmentPrimitive.Remove asChild>
484
484
  <TooltipIconButton
485
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"
486
+ className="aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:bg-white! [&_svg]:text-black hover:[&_svg]:text-destructive"
487
487
  side="top"
488
488
  >
489
489
  <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
@@ -518,7 +518,7 @@ export const ComposerAddAttachment: FC = () => {
518
518
  side="bottom"
519
519
  variant="ghost"
520
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"
521
+ className="aui-composer-add-attachment size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
522
522
  aria-label="Add Attachment"
523
523
  >
524
524
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -569,7 +569,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
569
569
  };
570
570
 
571
571
  return (
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">
572
+ <div className="aui-code-header-root mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-muted-foreground/15 px-4 py-2 font-semibold text-foreground text-sm dark:bg-muted-foreground/20">
573
573
  <span className="aui-code-header-language lowercase [&>span]:text-xs">
574
574
  {language}
575
575
  </span>
@@ -604,7 +604,7 @@ const defaultComponents = memoizeMarkdownComponents({
604
604
  h1: ({ className, ...props }) => (
605
605
  <h1
606
606
  className={cn(
607
- "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
607
+ "aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
608
608
  className,
609
609
  )}
610
610
  {...props}
@@ -613,7 +613,7 @@ const defaultComponents = memoizeMarkdownComponents({
613
613
  h2: ({ className, ...props }) => (
614
614
  <h2
615
615
  className={cn(
616
- "aui-md-h2 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 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
617
617
  className,
618
618
  )}
619
619
  {...props}
@@ -622,7 +622,7 @@ const defaultComponents = memoizeMarkdownComponents({
622
622
  h3: ({ className, ...props }) => (
623
623
  <h3
624
624
  className={cn(
625
- "aui-md-h3 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 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
626
626
  className,
627
627
  )}
628
628
  {...props}
@@ -631,7 +631,7 @@ const defaultComponents = memoizeMarkdownComponents({
631
631
  h4: ({ className, ...props }) => (
632
632
  <h4
633
633
  className={cn(
634
- "aui-md-h4 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 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
635
635
  className,
636
636
  )}
637
637
  {...props}
@@ -640,7 +640,7 @@ const defaultComponents = memoizeMarkdownComponents({
640
640
  h5: ({ className, ...props }) => (
641
641
  <h5
642
642
  className={cn(
643
- "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
643
+ "aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
644
644
  className,
645
645
  )}
646
646
  {...props}
@@ -667,7 +667,7 @@ const defaultComponents = memoizeMarkdownComponents({
667
667
  a: ({ className, ...props }) => (
668
668
  <a
669
669
  className={cn(
670
- "aui-md-a text-primary font-medium underline underline-offset-4",
670
+ "aui-md-a font-medium text-primary underline underline-offset-4",
671
671
  className,
672
672
  )}
673
673
  {...props}
@@ -706,7 +706,7 @@ const defaultComponents = memoizeMarkdownComponents({
706
706
  th: ({ className, ...props }) => (
707
707
  <th
708
708
  className={cn(
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",
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",
710
710
  className,
711
711
  )}
712
712
  {...props}
@@ -715,7 +715,7 @@ const defaultComponents = memoizeMarkdownComponents({
715
715
  td: ({ className, ...props }) => (
716
716
  <td
717
717
  className={cn(
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",
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",
719
719
  className,
720
720
  )}
721
721
  {...props}
@@ -739,7 +739,7 @@ const defaultComponents = memoizeMarkdownComponents({
739
739
  pre: ({ className, ...props }) => (
740
740
  <pre
741
741
  className={cn(
742
- "aui-md-pre overflow-x-auto !rounded-t-none 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",
743
743
  className,
744
744
  )}
745
745
  {...props}
@@ -751,7 +751,7 @@ const defaultComponents = memoizeMarkdownComponents({
751
751
  <code
752
752
  className={cn(
753
753
  !isCodeBlock &&
754
- "aui-md-inline-code bg-muted rounded border font-semibold",
754
+ "aui-md-inline-code rounded border bg-muted font-semibold",
755
755
  className,
756
756
  )}
757
757
  {...props}
@@ -766,57 +766,67 @@ const defaultComponents = memoizeMarkdownComponents({
766
766
  ## components/assistant-ui/thread.tsx
767
767
 
768
768
  ```tsx
769
+ import {
770
+ ComposerAddAttachment,
771
+ ComposerAttachments,
772
+ UserMessageAttachments,
773
+ } from "@/components/assistant-ui/attachment";
774
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
775
+ import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
776
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
777
+ import { Button } from "@/components/ui/button";
778
+ import { cn } from "@/lib/utils";
769
779
  import {
770
780
  ActionBarPrimitive,
781
+ AssistantIf,
771
782
  BranchPickerPrimitive,
772
783
  ComposerPrimitive,
784
+ ErrorPrimitive,
773
785
  MessagePrimitive,
774
786
  ThreadPrimitive,
775
787
  } from "@assistant-ui/react";
776
- import type { FC } from "react";
777
788
  import {
778
789
  ArrowDownIcon,
790
+ ArrowUpIcon,
779
791
  CheckIcon,
780
792
  ChevronLeftIcon,
781
793
  ChevronRightIcon,
782
794
  CopyIcon,
795
+ DownloadIcon,
783
796
  PencilIcon,
784
797
  RefreshCwIcon,
785
- SendHorizontalIcon,
798
+ SquareIcon,
786
799
  } from "lucide-react";
787
- import { cn } from "@/lib/utils";
788
-
789
- import { Button } from "@/components/ui/button";
790
- import { MarkdownText } from "@/components/assistant-ui/markdown-text";
791
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
800
+ import type { FC } from "react";
792
801
 
793
802
  export const Thread: FC = () => {
794
803
  return (
795
804
  <ThreadPrimitive.Root
796
- className="bg-background box-border flex h-full flex-col overflow-hidden"
805
+ className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
797
806
  style={{
798
- ["--thread-max-width" as string]: "42rem",
807
+ ["--thread-max-width" as string]: "44rem",
799
808
  }}
800
809
  >
801
- <ThreadPrimitive.Viewport className="flex h-full flex-col items-center overflow-y-scroll scroll-smooth bg-inherit px-4 pt-8">
802
- <ThreadWelcome />
810
+ <ThreadPrimitive.Viewport
811
+ turnAnchor="top"
812
+ className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
813
+ >
814
+ <AssistantIf condition={({ thread }) => thread.isEmpty}>
815
+ <ThreadWelcome />
816
+ </AssistantIf>
803
817
 
804
818
  <ThreadPrimitive.Messages
805
819
  components={{
806
- UserMessage: UserMessage,
807
- EditComposer: EditComposer,
808
- AssistantMessage: AssistantMessage,
820
+ UserMessage,
821
+ EditComposer,
822
+ AssistantMessage,
809
823
  }}
810
824
  />
811
825
 
812
- <ThreadPrimitive.If empty={false}>
813
- <div className="min-h-8 flex-grow" />
814
- </ThreadPrimitive.If>
815
-
816
- <div className="sticky bottom-0 mt-3 flex w-full max-w-[var(--thread-max-width)] flex-col items-center justify-end rounded-t-lg bg-inherit pb-4">
826
+ <ThreadPrimitive.ViewportFooter className="aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6">
817
827
  <ThreadScrollToBottom />
818
828
  <Composer />
819
- </div>
829
+ </ThreadPrimitive.ViewportFooter>
820
830
  </ThreadPrimitive.Viewport>
821
831
  </ThreadPrimitive.Root>
822
832
  );
@@ -828,7 +838,7 @@ const ThreadScrollToBottom: FC = () => {
828
838
  <TooltipIconButton
829
839
  tooltip="Scroll to bottom"
830
840
  variant="outline"
831
- className="absolute -top-8 rounded-full disabled:invisible"
841
+ className="aui-thread-scroll-to-bottom -top-12 absolute z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
832
842
  >
833
843
  <ArrowDownIcon />
834
844
  </TooltipIconButton>
@@ -838,175 +848,247 @@ const ThreadScrollToBottom: FC = () => {
838
848
 
839
849
  const ThreadWelcome: FC = () => {
840
850
  return (
841
- <ThreadPrimitive.Empty>
842
- <div className="flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
843
- <div className="flex w-full flex-grow flex-col items-center justify-center">
844
- <p className="mt-4 font-medium">How can I help you today?</p>
851
+ <div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
852
+ <div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
853
+ <div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
854
+ <h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
855
+ Hello there!
856
+ </h1>
857
+ <p className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in text-muted-foreground text-xl delay-75 duration-200">
858
+ How can I help you today?
859
+ </p>
845
860
  </div>
846
- <ThreadWelcomeSuggestions />
847
861
  </div>
848
- </ThreadPrimitive.Empty>
862
+ <ThreadSuggestions />
863
+ </div>
849
864
  );
850
865
  };
851
866
 
852
- const ThreadWelcomeSuggestions: FC = () => {
867
+ const SUGGESTIONS = [
868
+ {
869
+ title: "What's the weather",
870
+ label: "in San Francisco?",
871
+ prompt: "What's the weather in San Francisco?",
872
+ },
873
+ {
874
+ title: "Explain React hooks",
875
+ label: "like useState and useEffect",
876
+ prompt: "Explain React hooks like useState and useEffect",
877
+ },
878
+ ] as const;
879
+
880
+ const ThreadSuggestions: FC = () => {
853
881
  return (
854
- <div className="mt-3 flex w-full items-stretch justify-center gap-4">
855
- <ThreadPrimitive.Suggestion
856
- className="hover:bg-muted/80 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-lg border p-3 transition-colors ease-in"
857
- prompt="What is the weather in Tokyo?"
858
- method="replace"
859
- autoSend
860
- >
861
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
862
- What is the weather in Tokyo?
863
- </span>
864
- </ThreadPrimitive.Suggestion>
865
- <ThreadPrimitive.Suggestion
866
- className="hover:bg-muted/80 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-lg border p-3 transition-colors ease-in"
867
- prompt="What is assistant-ui?"
868
- method="replace"
869
- autoSend
870
- >
871
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
872
- What is assistant-ui?
873
- </span>
874
- </ThreadPrimitive.Suggestion>
882
+ <div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
883
+ {SUGGESTIONS.map((suggestion, index) => (
884
+ <div
885
+ key={suggestion.prompt}
886
+ className="aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-2 @md:nth-[n+3]:block nth-[n+3]:hidden animate-in fill-mode-both duration-200"
887
+ style={{ animationDelay: `${100 + index * 50}ms` }}
888
+ >
889
+ <ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
890
+ <Button
891
+ variant="ghost"
892
+ className="aui-thread-welcome-suggestion h-auto w-full @md:flex-col flex-wrap items-start justify-start gap-1 rounded-2xl border px-4 py-3 text-left text-sm transition-colors hover:bg-muted"
893
+ aria-label={suggestion.prompt}
894
+ >
895
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">
896
+ {suggestion.title}
897
+ </span>
898
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
899
+ {suggestion.label}
900
+ </span>
901
+ </Button>
902
+ </ThreadPrimitive.Suggestion>
903
+ </div>
904
+ ))}
875
905
  </div>
876
906
  );
877
907
  };
878
908
 
879
909
  const Composer: FC = () => {
880
910
  return (
881
- <ComposerPrimitive.Root className="focus-within:border-ring/20 flex w-full flex-wrap items-end rounded-lg border bg-inherit px-2.5 shadow-sm transition-colors ease-in">
882
- <ComposerPrimitive.Input
883
- rows={1}
884
- autoFocus
885
- placeholder="Write a message..."
886
- className="placeholder:text-muted-foreground max-h-40 flex-grow resize-none border-none bg-transparent px-2 py-4 text-sm outline-none focus:ring-0 disabled:cursor-not-allowed"
887
- />
888
- <ComposerAction />
911
+ <ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
912
+ <ComposerPrimitive.AttachmentDropzone className="aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-2 has-[textarea:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50">
913
+ <ComposerAttachments />
914
+ <ComposerPrimitive.Input
915
+ placeholder="Send a message..."
916
+ className="aui-composer-input mb-1 max-h-32 min-h-14 w-full resize-none bg-transparent px-4 pt-2 pb-3 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-0"
917
+ rows={1}
918
+ autoFocus
919
+ aria-label="Message input"
920
+ />
921
+ <ComposerAction />
922
+ </ComposerPrimitive.AttachmentDropzone>
889
923
  </ComposerPrimitive.Root>
890
924
  );
891
925
  };
892
926
 
893
927
  const ComposerAction: FC = () => {
894
928
  return (
895
- <>
896
- <ThreadPrimitive.If running={false}>
929
+ <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
930
+ <ComposerAddAttachment />
931
+
932
+ <AssistantIf condition={({ thread }) => !thread.isRunning}>
897
933
  <ComposerPrimitive.Send asChild>
898
934
  <TooltipIconButton
899
- tooltip="Send"
935
+ tooltip="Send message"
936
+ side="bottom"
937
+ type="submit"
900
938
  variant="default"
901
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
939
+ size="icon"
940
+ className="aui-composer-send size-8 rounded-full"
941
+ aria-label="Send message"
902
942
  >
903
- <SendHorizontalIcon />
943
+ <ArrowUpIcon className="aui-composer-send-icon size-4" />
904
944
  </TooltipIconButton>
905
945
  </ComposerPrimitive.Send>
906
- </ThreadPrimitive.If>
907
- <ThreadPrimitive.If running>
946
+ </AssistantIf>
947
+
948
+ <AssistantIf condition={({ thread }) => thread.isRunning}>
908
949
  <ComposerPrimitive.Cancel asChild>
909
- <TooltipIconButton
910
- tooltip="Cancel"
950
+ <Button
951
+ type="button"
911
952
  variant="default"
912
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
953
+ size="icon"
954
+ className="aui-composer-cancel size-8 rounded-full"
955
+ aria-label="Stop generating"
913
956
  >
914
- <CircleStopIcon />
915
- </TooltipIconButton>
957
+ <SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
958
+ </Button>
916
959
  </ComposerPrimitive.Cancel>
917
- </ThreadPrimitive.If>
918
- </>
960
+ </AssistantIf>
961
+ </div>
919
962
  );
920
963
  };
921
964
 
922
- const UserMessage: FC = () => {
965
+ const MessageError: FC = () => {
923
966
  return (
924
- <MessagePrimitive.Root className="grid w-full max-w-[var(--thread-max-width)] auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 py-4 [&:where(>*)]:col-start-2">
925
- <UserActionBar />
967
+ <MessagePrimitive.Error>
968
+ <ErrorPrimitive.Root className="aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200">
969
+ <ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
970
+ </ErrorPrimitive.Root>
971
+ </MessagePrimitive.Error>
972
+ );
973
+ };
926
974
 
927
- <div className="bg-muted text-foreground col-start-2 row-start-2 max-w-[calc(var(--thread-max-width)*0.8)] rounded-3xl px-5 py-2.5 break-words">
928
- <MessagePrimitive.Parts />
975
+ const AssistantMessage: FC = () => {
976
+ return (
977
+ <MessagePrimitive.Root
978
+ className="aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150"
979
+ data-role="assistant"
980
+ >
981
+ <div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
982
+ <MessagePrimitive.Parts
983
+ components={{
984
+ Text: MarkdownText,
985
+ tools: { Fallback: ToolFallback },
986
+ }}
987
+ />
988
+ <MessageError />
929
989
  </div>
930
990
 
931
- <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
991
+ <div className="aui-assistant-message-footer mt-1 ml-2 flex">
992
+ <BranchPicker />
993
+ <AssistantActionBar />
994
+ </div>
932
995
  </MessagePrimitive.Root>
933
996
  );
934
997
  };
935
998
 
936
- const UserActionBar: FC = () => {
999
+ const AssistantActionBar: FC = () => {
937
1000
  return (
938
1001
  <ActionBarPrimitive.Root
939
1002
  hideWhenRunning
940
1003
  autohide="not-last"
941
- className="col-start-1 row-start-2 mt-2.5 mr-3 flex flex-col items-end"
1004
+ autohideFloat="single-branch"
1005
+ className="aui-assistant-action-bar-root -ml-1 col-start-3 row-start-2 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm"
942
1006
  >
943
- <ActionBarPrimitive.Edit asChild>
944
- <TooltipIconButton tooltip="Edit">
945
- <PencilIcon />
1007
+ <ActionBarPrimitive.Copy asChild>
1008
+ <TooltipIconButton tooltip="Copy">
1009
+ <AssistantIf condition={({ message }) => message.isCopied}>
1010
+ <CheckIcon />
1011
+ </AssistantIf>
1012
+ <AssistantIf condition={({ message }) => !message.isCopied}>
1013
+ <CopyIcon />
1014
+ </AssistantIf>
946
1015
  </TooltipIconButton>
947
- </ActionBarPrimitive.Edit>
1016
+ </ActionBarPrimitive.Copy>
1017
+ <ActionBarPrimitive.ExportMarkdown asChild>
1018
+ <TooltipIconButton tooltip="Export as Markdown">
1019
+ <DownloadIcon />
1020
+ </TooltipIconButton>
1021
+ </ActionBarPrimitive.ExportMarkdown>
1022
+ <ActionBarPrimitive.Reload asChild>
1023
+ <TooltipIconButton tooltip="Refresh">
1024
+ <RefreshCwIcon />
1025
+ </TooltipIconButton>
1026
+ </ActionBarPrimitive.Reload>
948
1027
  </ActionBarPrimitive.Root>
949
1028
  );
950
1029
  };
951
1030
 
952
- const EditComposer: FC = () => {
1031
+ const UserMessage: FC = () => {
953
1032
  return (
954
- <ComposerPrimitive.Root className="bg-muted my-4 flex w-full max-w-[var(--thread-max-width)] flex-col gap-2 rounded-xl">
955
- <ComposerPrimitive.Input className="text-foreground flex h-8 w-full resize-none bg-transparent p-4 pb-0 outline-none" />
956
-
957
- <div className="mx-3 mb-3 flex items-center justify-center gap-2 self-end">
958
- <ComposerPrimitive.Cancel asChild>
959
- <Button variant="ghost">Cancel</Button>
960
- </ComposerPrimitive.Cancel>
961
- <ComposerPrimitive.Send asChild>
962
- <Button>Send</Button>
963
- </ComposerPrimitive.Send>
964
- </div>
965
- </ComposerPrimitive.Root>
966
- );
967
- };
1033
+ <MessagePrimitive.Root
1034
+ className="aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto grid w-full max-w-(--thread-max-width) animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-3 duration-150 [&:where(>*)]:col-start-2"
1035
+ data-role="user"
1036
+ >
1037
+ <UserMessageAttachments />
968
1038
 
969
- const AssistantMessage: FC = () => {
970
- return (
971
- <MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
972
- <div className="text-foreground col-span-2 col-start-2 row-start-1 my-1.5 max-w-[calc(var(--thread-max-width)*0.8)] leading-7 break-words">
973
- <MessagePrimitive.Parts components={{ Text: MarkdownText }} />
1039
+ <div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
1040
+ <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1041
+ <MessagePrimitive.Parts />
1042
+ </div>
1043
+ <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1044
+ <UserActionBar />
1045
+ </div>
974
1046
  </div>
975
1047
 
976
- <AssistantActionBar />
977
-
978
- <BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
1048
+ <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
979
1049
  </MessagePrimitive.Root>
980
1050
  );
981
1051
  };
982
1052
 
983
- const AssistantActionBar: FC = () => {
1053
+ const UserActionBar: FC = () => {
984
1054
  return (
985
1055
  <ActionBarPrimitive.Root
986
1056
  hideWhenRunning
987
1057
  autohide="not-last"
988
- autohideFloat="single-branch"
989
- className="text-muted-foreground data-[floating]:bg-background col-start-3 row-start-2 -ml-1 flex gap-1 data-[floating]:absolute data-[floating]:rounded-md data-[floating]:border data-[floating]:p-1 data-[floating]:shadow-sm"
1058
+ className="aui-user-action-bar-root flex flex-col items-end"
990
1059
  >
991
- <ActionBarPrimitive.Copy asChild>
992
- <TooltipIconButton tooltip="Copy">
993
- <MessagePrimitive.If copied>
994
- <CheckIcon />
995
- </MessagePrimitive.If>
996
- <MessagePrimitive.If copied={false}>
997
- <CopyIcon />
998
- </MessagePrimitive.If>
999
- </TooltipIconButton>
1000
- </ActionBarPrimitive.Copy>
1001
- <ActionBarPrimitive.Reload asChild>
1002
- <TooltipIconButton tooltip="Refresh">
1003
- <RefreshCwIcon />
1060
+ <ActionBarPrimitive.Edit asChild>
1061
+ <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
1062
+ <PencilIcon />
1004
1063
  </TooltipIconButton>
1005
- </ActionBarPrimitive.Reload>
1064
+ </ActionBarPrimitive.Edit>
1006
1065
  </ActionBarPrimitive.Root>
1007
1066
  );
1008
1067
  };
1009
1068
 
1069
+ const EditComposer: FC = () => {
1070
+ return (
1071
+ <MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
1072
+ <ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
1073
+ <ComposerPrimitive.Input
1074
+ className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
1075
+ autoFocus
1076
+ />
1077
+ <div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
1078
+ <ComposerPrimitive.Cancel asChild>
1079
+ <Button variant="ghost" size="sm">
1080
+ Cancel
1081
+ </Button>
1082
+ </ComposerPrimitive.Cancel>
1083
+ <ComposerPrimitive.Send asChild>
1084
+ <Button size="sm">Update</Button>
1085
+ </ComposerPrimitive.Send>
1086
+ </div>
1087
+ </ComposerPrimitive.Root>
1088
+ </MessagePrimitive.Root>
1089
+ );
1090
+ };
1091
+
1010
1092
  const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1011
1093
  className,
1012
1094
  ...rest
@@ -1015,7 +1097,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1015
1097
  <BranchPickerPrimitive.Root
1016
1098
  hideWhenSingleBranch
1017
1099
  className={cn(
1018
- "text-muted-foreground inline-flex items-center text-xs",
1100
+ "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1019
1101
  className,
1020
1102
  )}
1021
1103
  {...rest}
@@ -1025,7 +1107,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1025
1107
  <ChevronLeftIcon />
1026
1108
  </TooltipIconButton>
1027
1109
  </BranchPickerPrimitive.Previous>
1028
- <span className="font-medium">
1110
+ <span className="aui-branch-picker-state font-medium">
1029
1111
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
1030
1112
  </span>
1031
1113
  <BranchPickerPrimitive.Next asChild>
@@ -1037,20 +1119,6 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1037
1119
  );
1038
1120
  };
1039
1121
 
1040
- const CircleStopIcon = () => {
1041
- return (
1042
- <svg
1043
- xmlns="http://www.w3.org/2000/svg"
1044
- viewBox="0 0 16 16"
1045
- fill="currentColor"
1046
- width="16"
1047
- height="16"
1048
- >
1049
- <rect width="10" height="10" x="3" y="3" rx="2" />
1050
- </svg>
1051
- );
1052
- };
1053
-
1054
1122
  ```
1055
1123
 
1056
1124
  ## components/assistant-ui/tool-fallback.tsx
@@ -1093,7 +1161,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1093
1161
  >
1094
1162
  <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1095
1163
  {isCancelled ? (
1096
- <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1164
+ <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1097
1165
  ) : (
1098
1166
  <CheckIcon className="aui-tool-fallback-icon size-4" />
1099
1167
  )}
@@ -1114,7 +1182,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1114
1182
  <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1115
1183
  {cancelledReason && (
1116
1184
  <div className="aui-tool-fallback-cancelled-root px-4">
1117
- <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1185
+ <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1118
1186
  Cancelled reason:
1119
1187
  </p>
1120
1188
  <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
@@ -1244,7 +1312,7 @@ const AvatarFallback = React.forwardRef<
1244
1312
  <AvatarPrimitive.Fallback
1245
1313
  ref={ref}
1246
1314
  className={cn(
1247
- "bg-muted flex h-full w-full items-center justify-center rounded-full",
1315
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1248
1316
  className,
1249
1317
  )}
1250
1318
  {...props}
@@ -1268,7 +1336,7 @@ import { cva, type VariantProps } from "class-variance-authority";
1268
1336
  import { cn } from "@/lib/utils";
1269
1337
 
1270
1338
  const buttonVariants = cva(
1271
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1339
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1272
1340
  {
1273
1341
  variants: {
1274
1342
  variant: {
@@ -1364,7 +1432,7 @@ function DialogOverlay({
1364
1432
  <DialogPrimitive.Overlay
1365
1433
  data-slot="dialog-overlay"
1366
1434
  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",
1435
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=open]:animate-in",
1368
1436
  className,
1369
1437
  )}
1370
1438
  {...props}
@@ -1383,13 +1451,13 @@ function DialogContent({
1383
1451
  <DialogPrimitive.Content
1384
1452
  data-slot="dialog-content"
1385
1453
  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",
1454
+ "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 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 bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
1387
1455
  className,
1388
1456
  )}
1389
1457
  {...props}
1390
1458
  >
1391
1459
  {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">
1460
+ <DialogPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0">
1393
1461
  <XIcon />
1394
1462
  <span className="sr-only">Close</span>
1395
1463
  </DialogPrimitive.Close>
@@ -1428,7 +1496,7 @@ function DialogTitle({
1428
1496
  return (
1429
1497
  <DialogPrimitive.Title
1430
1498
  data-slot="dialog-title"
1431
- className={cn("text-lg leading-none font-semibold", className)}
1499
+ className={cn("font-semibold text-lg leading-none", className)}
1432
1500
  {...props}
1433
1501
  />
1434
1502
  );
@@ -1513,13 +1581,13 @@ function TooltipContent({
1513
1581
  data-slot="tooltip-content"
1514
1582
  sideOffset={sideOffset}
1515
1583
  className={cn(
1516
- "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-[--radix-tooltip-content-transform-origin] rounded-md px-3 py-1.5 text-xs text-balance",
1584
+ "fade-in-0 zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-[--radix-tooltip-content-transform-origin] animate-in text-balance rounded-md bg-primary px-3 py-1.5 text-primary-foreground text-xs data-[state=closed]:animate-out",
1517
1585
  className,
1518
1586
  )}
1519
1587
  {...props}
1520
1588
  >
1521
1589
  {children}
1522
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
1590
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1523
1591
  </TooltipPrimitive.Content>
1524
1592
  </TooltipPrimitive.Portal>
1525
1593
  );
@@ -1564,38 +1632,34 @@ export default nextConfig;
1564
1632
  "scripts": {
1565
1633
  "dev": "next dev --turbo",
1566
1634
  "build": "next build",
1567
- "start": "next start",
1568
- "lint": "eslint ."
1635
+ "start": "next start"
1569
1636
  },
1570
1637
  "dependencies": {
1571
- "@ai-sdk/openai": "^2.0.73",
1638
+ "@ai-sdk/openai": "^2.0.77",
1572
1639
  "@assistant-ui/react": "workspace:*",
1573
1640
  "@assistant-ui/react-markdown": "workspace:*",
1574
1641
  "@assistant-ui/react-ag-ui": "workspace:*",
1575
- "@ag-ui/client": "^0.0.41",
1576
- "@radix-ui/react-avatar": "^1.1.4",
1577
- "@radix-ui/react-dialog": "^1.1.7",
1642
+ "@ag-ui/client": "^0.0.42",
1643
+ "@radix-ui/react-avatar": "^1.1.11",
1644
+ "@radix-ui/react-dialog": "^1.1.15",
1578
1645
  "@radix-ui/react-slot": "^1.2.4",
1579
1646
  "@radix-ui/react-tooltip": "^1.2.8",
1580
1647
  "class-variance-authority": "^0.7.1",
1581
1648
  "clsx": "^2.1.1",
1582
- "lucide-react": "^0.555.0",
1583
- "motion": "^11.18.2",
1584
- "next": "16.0.4",
1585
- "react": "19.2.0",
1586
- "react-dom": "19.2.0",
1649
+ "lucide-react": "^0.556.0",
1650
+ "next": "16.0.7",
1651
+ "react": "19.2.1",
1652
+ "react-dom": "19.2.1",
1587
1653
  "remark-gfm": "^4.0.1",
1588
1654
  "tailwind-merge": "^3.4.0",
1589
1655
  "tw-animate-css": "^1.4.0",
1590
- "zustand": "^5.0.8"
1656
+ "zustand": "^5.0.9"
1591
1657
  },
1592
1658
  "devDependencies": {
1593
1659
  "@assistant-ui/x-buildutils": "workspace:*",
1594
1660
  "@types/node": "^24",
1595
1661
  "@types/react": "^19",
1596
1662
  "@types/react-dom": "^19",
1597
- "eslint": "^9",
1598
- "eslint-config-next": "16.0.4",
1599
1663
  "postcss": "^8",
1600
1664
  "tailwindcss": "^4.1.17",
1601
1665
  "typescript": "^5"