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

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 +249 -147
  2. package/.docs/organized/code-examples/with-ag-ui.md +250 -186
  3. package/.docs/organized/code-examples/with-ai-sdk-v5.md +250 -199
  4. package/.docs/organized/code-examples/with-assistant-transport.md +195 -243
  5. package/.docs/organized/code-examples/with-cloud.md +277 -226
  6. package/.docs/organized/code-examples/with-custom-thread-list.md +1855 -0
  7. package/.docs/organized/code-examples/with-external-store.md +246 -180
  8. package/.docs/organized/code-examples/with-ffmpeg.md +255 -189
  9. package/.docs/organized/code-examples/with-langgraph.md +293 -242
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +243 -263
  11. package/.docs/organized/code-examples/with-react-hook-form.md +262 -196
  12. package/.docs/organized/code-examples/with-tanstack.md +1578 -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 +6 -7
@@ -151,8 +151,8 @@ export default function RootLayout({
151
151
  <html lang="en">
152
152
  <body className="font-sans antialiased">
153
153
  <div className="flex h-screen flex-col">
154
- <header className="bg-background border-b px-4 py-2">
155
- <h1 className="text-lg font-semibold">
154
+ <header className="border-b bg-background px-4 py-2">
155
+ <h1 className="font-semibold text-lg">
156
156
  Assistant Transport Example
157
157
  </h1>
158
158
  </header>
@@ -181,7 +181,7 @@ import {
181
181
  convertLangChainMessages,
182
182
  LangChainMessage,
183
183
  } from "@assistant-ui/react-langgraph";
184
- import React, { ReactNode } from "react";
184
+ import { ReactNode } from "react";
185
185
  import { z } from "zod";
186
186
 
187
187
  // Frontend tool with execute function
@@ -455,16 +455,16 @@ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
455
455
  return (
456
456
  <Dialog>
457
457
  <DialogTrigger
458
- className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
458
+ className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
459
459
  asChild
460
460
  >
461
461
  {children}
462
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">
463
+ <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">
464
464
  <DialogTitle className="aui-sr-only sr-only">
465
465
  Image Attachment Preview
466
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">
467
+ <div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
468
468
  <AttachmentPreview src={src} />
469
469
  </div>
470
470
  </DialogContent>
@@ -486,7 +486,7 @@ const AttachmentThumb: FC = () => {
486
486
  className="aui-attachment-tile-image object-cover"
487
487
  />
488
488
  <AvatarFallback delayMs={isImage ? 200 : 0}>
489
- <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
489
+ <FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
490
490
  </AvatarFallback>
491
491
  </Avatar>
492
492
  );
@@ -527,7 +527,7 @@ const AttachmentUI: FC = () => {
527
527
  <TooltipTrigger asChild>
528
528
  <div
529
529
  className={cn(
530
- "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
530
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
531
531
  isComposer &&
532
532
  "aui-attachment-tile-composer border-foreground/20",
533
533
  )}
@@ -553,7 +553,7 @@ const AttachmentRemove: FC = () => {
553
553
  <AttachmentPrimitive.Remove asChild>
554
554
  <TooltipIconButton
555
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"
556
+ 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"
557
557
  side="top"
558
558
  >
559
559
  <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
@@ -588,7 +588,7 @@ export const ComposerAddAttachment: FC = () => {
588
588
  side="bottom"
589
589
  variant="ghost"
590
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"
591
+ 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"
592
592
  aria-label="Add Attachment"
593
593
  >
594
594
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -639,7 +639,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
639
639
  };
640
640
 
641
641
  return (
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">
642
+ <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">
643
643
  <span className="aui-code-header-language lowercase [&>span]:text-xs">
644
644
  {language}
645
645
  </span>
@@ -674,7 +674,7 @@ const defaultComponents = memoizeMarkdownComponents({
674
674
  h1: ({ className, ...props }) => (
675
675
  <h1
676
676
  className={cn(
677
- "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
677
+ "aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
678
678
  className,
679
679
  )}
680
680
  {...props}
@@ -683,7 +683,7 @@ const defaultComponents = memoizeMarkdownComponents({
683
683
  h2: ({ className, ...props }) => (
684
684
  <h2
685
685
  className={cn(
686
- "aui-md-h2 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 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
687
687
  className,
688
688
  )}
689
689
  {...props}
@@ -692,7 +692,7 @@ const defaultComponents = memoizeMarkdownComponents({
692
692
  h3: ({ className, ...props }) => (
693
693
  <h3
694
694
  className={cn(
695
- "aui-md-h3 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 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
696
696
  className,
697
697
  )}
698
698
  {...props}
@@ -701,7 +701,7 @@ const defaultComponents = memoizeMarkdownComponents({
701
701
  h4: ({ className, ...props }) => (
702
702
  <h4
703
703
  className={cn(
704
- "aui-md-h4 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 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
705
705
  className,
706
706
  )}
707
707
  {...props}
@@ -710,7 +710,7 @@ const defaultComponents = memoizeMarkdownComponents({
710
710
  h5: ({ className, ...props }) => (
711
711
  <h5
712
712
  className={cn(
713
- "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
713
+ "aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
714
714
  className,
715
715
  )}
716
716
  {...props}
@@ -737,7 +737,7 @@ const defaultComponents = memoizeMarkdownComponents({
737
737
  a: ({ className, ...props }) => (
738
738
  <a
739
739
  className={cn(
740
- "aui-md-a text-primary font-medium underline underline-offset-4",
740
+ "aui-md-a font-medium text-primary underline underline-offset-4",
741
741
  className,
742
742
  )}
743
743
  {...props}
@@ -776,7 +776,7 @@ const defaultComponents = memoizeMarkdownComponents({
776
776
  th: ({ className, ...props }) => (
777
777
  <th
778
778
  className={cn(
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",
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",
780
780
  className,
781
781
  )}
782
782
  {...props}
@@ -785,7 +785,7 @@ const defaultComponents = memoizeMarkdownComponents({
785
785
  td: ({ className, ...props }) => (
786
786
  <td
787
787
  className={cn(
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",
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",
789
789
  className,
790
790
  )}
791
791
  {...props}
@@ -809,7 +809,7 @@ const defaultComponents = memoizeMarkdownComponents({
809
809
  pre: ({ className, ...props }) => (
810
810
  <pre
811
811
  className={cn(
812
- "aui-md-pre 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",
813
813
  className,
814
814
  )}
815
815
  {...props}
@@ -821,7 +821,7 @@ const defaultComponents = memoizeMarkdownComponents({
821
821
  <code
822
822
  className={cn(
823
823
  !isCodeBlock &&
824
- "aui-md-inline-code bg-muted rounded border font-semibold",
824
+ "aui-md-inline-code rounded border bg-muted font-semibold",
825
825
  className,
826
826
  )}
827
827
  {...props}
@@ -837,45 +837,53 @@ const defaultComponents = memoizeMarkdownComponents({
837
837
 
838
838
  ```tsx
839
839
  import {
840
- ThreadPrimitive,
841
- ComposerPrimitive,
842
- MessagePrimitive,
840
+ ComposerAddAttachment,
841
+ ComposerAttachments,
842
+ UserMessageAttachments,
843
+ } from "@/components/assistant-ui/attachment";
844
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
845
+ import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
846
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
847
+ import { Button } from "@/components/ui/button";
848
+ import { cn } from "@/lib/utils";
849
+ import {
843
850
  ActionBarPrimitive,
851
+ AssistantIf,
844
852
  BranchPickerPrimitive,
853
+ ComposerPrimitive,
845
854
  ErrorPrimitive,
855
+ MessagePrimitive,
856
+ ThreadPrimitive,
846
857
  } from "@assistant-ui/react";
847
- import type { FC } from "react";
848
858
  import {
849
859
  ArrowDownIcon,
850
860
  ArrowUpIcon,
851
- PlusIcon,
852
- CopyIcon,
853
861
  CheckIcon,
854
- PencilIcon,
855
- RefreshCwIcon,
856
862
  ChevronLeftIcon,
857
863
  ChevronRightIcon,
858
- Square,
864
+ CopyIcon,
865
+ DownloadIcon,
866
+ PencilIcon,
867
+ RefreshCwIcon,
868
+ SquareIcon,
859
869
  } from "lucide-react";
860
-
861
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
862
- import { motion } from "framer-motion";
863
- import { Button } from "@/components/ui/button";
864
- import { cn } from "@/lib/utils";
865
- import { MarkdownText } from "./markdown-text";
866
- import { ToolFallback } from "./tool-fallback";
870
+ import type { FC } from "react";
867
871
 
868
872
  export const Thread: FC = () => {
869
873
  return (
870
874
  <ThreadPrimitive.Root
871
- className="bg-background flex h-full flex-col"
875
+ className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
872
876
  style={{
873
- ["--thread-max-width" as string]: "48rem",
874
- ["--thread-padding-x" as string]: "1rem",
877
+ ["--thread-max-width" as string]: "44rem",
875
878
  }}
876
879
  >
877
- <ThreadPrimitive.Viewport className="relative flex min-w-0 flex-1 flex-col gap-6 overflow-y-scroll">
878
- <ThreadWelcome />
880
+ <ThreadPrimitive.Viewport
881
+ turnAnchor="top"
882
+ className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
883
+ >
884
+ <AssistantIf condition={({ thread }) => thread.isEmpty}>
885
+ <ThreadWelcome />
886
+ </AssistantIf>
879
887
 
880
888
  <ThreadPrimitive.Messages
881
889
  components={{
@@ -885,12 +893,11 @@ export const Thread: FC = () => {
885
893
  }}
886
894
  />
887
895
 
888
- <ThreadPrimitive.If empty={false}>
889
- <motion.div className="min-h-6 min-w-6 shrink-0" />
890
- </ThreadPrimitive.If>
896
+ <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">
897
+ <ThreadScrollToBottom />
898
+ <Composer />
899
+ </ThreadPrimitive.ViewportFooter>
891
900
  </ThreadPrimitive.Viewport>
892
-
893
- <Composer />
894
901
  </ThreadPrimitive.Root>
895
902
  );
896
903
  };
@@ -901,7 +908,7 @@ const ThreadScrollToBottom: FC = () => {
901
908
  <TooltipIconButton
902
909
  tooltip="Scroll to bottom"
903
910
  variant="outline"
904
- className="dark:bg-background dark:hover:bg-accent absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible"
911
+ 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"
905
912
  >
906
913
  <ArrowDownIcon />
907
914
  </TooltipIconButton>
@@ -911,84 +918,59 @@ const ThreadScrollToBottom: FC = () => {
911
918
 
912
919
  const ThreadWelcome: FC = () => {
913
920
  return (
914
- <ThreadPrimitive.Empty>
915
- <div className="mx-auto flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col px-[var(--thread-padding-x)]">
916
- <div className="flex w-full flex-grow flex-col items-center justify-center">
917
- <div className="flex size-full flex-col justify-center px-8 md:mt-20">
918
- <motion.div
919
- initial={{ opacity: 0, y: 10 }}
920
- animate={{ opacity: 1, y: 0 }}
921
- exit={{ opacity: 0, y: 10 }}
922
- transition={{ delay: 0.5 }}
923
- className="text-2xl font-semibold"
924
- >
925
- Hello there!
926
- </motion.div>
927
- <motion.div
928
- initial={{ opacity: 0, y: 10 }}
929
- animate={{ opacity: 1, y: 0 }}
930
- exit={{ opacity: 0, y: 10 }}
931
- transition={{ delay: 0.6 }}
932
- className="text-muted-foreground/65 text-2xl"
933
- >
934
- How can I help you today?
935
- </motion.div>
936
- </div>
921
+ <div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
922
+ <div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
923
+ <div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
924
+ <h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
925
+ Hello there!
926
+ </h1>
927
+ <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">
928
+ How can I help you today?
929
+ </p>
937
930
  </div>
938
931
  </div>
939
- </ThreadPrimitive.Empty>
932
+ <ThreadSuggestions />
933
+ </div>
940
934
  );
941
935
  };
942
936
 
943
- const ThreadWelcomeSuggestions: FC = () => {
937
+ const SUGGESTIONS = [
938
+ {
939
+ title: "What's the weather",
940
+ label: "in San Francisco?",
941
+ prompt: "What's the weather in San Francisco?",
942
+ },
943
+ {
944
+ title: "Explain React hooks",
945
+ label: "like useState and useEffect",
946
+ prompt: "Explain React hooks like useState and useEffect",
947
+ },
948
+ ] as const;
949
+
950
+ const ThreadSuggestions: FC = () => {
944
951
  return (
945
- <div className="grid w-full gap-2 sm:grid-cols-2">
946
- {[
947
- {
948
- title: "What are the advantages",
949
- label: "of using Assistant Cloud?",
950
- action: "What are the advantages of using Assistant Cloud?",
951
- },
952
- {
953
- title: "Write code to",
954
- label: `demonstrate topological sorting`,
955
- action: `Write code to demonstrate topological sorting`,
956
- },
957
- {
958
- title: "Help me write an essay",
959
- label: `about AI chat applications`,
960
- action: `Help me write an essay about AI chat applications`,
961
- },
962
- {
963
- title: "What is the weather",
964
- label: "in San Francisco?",
965
- action: "What is the weather in San Francisco?",
966
- },
967
- ].map((suggestedAction, index) => (
968
- <motion.div
969
- initial={{ opacity: 0, y: 20 }}
970
- animate={{ opacity: 1, y: 0 }}
971
- exit={{ opacity: 0, y: 20 }}
972
- transition={{ delay: 0.05 * index }}
973
- key={`suggested-action-${suggestedAction.title}-${index}`}
974
- className="[&:nth-child(n+3)]:hidden sm:[&:nth-child(n+3)]:block"
952
+ <div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
953
+ {SUGGESTIONS.map((suggestion, index) => (
954
+ <div
955
+ key={suggestion.prompt}
956
+ 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"
957
+ style={{ animationDelay: `${100 + index * 50}ms` }}
975
958
  >
976
- <ThreadPrimitive.Suggestion
977
- prompt={suggestedAction.action}
978
- method="replace"
979
- autoSend
980
- asChild
981
- >
959
+ <ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
982
960
  <Button
983
961
  variant="ghost"
984
- className="dark:hover:bg-accent/60 h-auto w-full flex-1 flex-wrap items-start justify-start gap-1 rounded-xl border px-4 py-3.5 text-left text-sm sm:flex-col"
985
- aria-label={suggestedAction.action}
962
+ 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"
963
+ aria-label={suggestion.prompt}
986
964
  >
987
- <span className="font-medium">{suggestedAction.title}</span>
988
- <p className="text-muted-foreground">{suggestedAction.label}</p>
965
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">
966
+ {suggestion.title}
967
+ </span>
968
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
969
+ {suggestion.label}
970
+ </span>
989
971
  </Button>
990
972
  </ThreadPrimitive.Suggestion>
991
- </motion.div>
973
+ </div>
992
974
  ))}
993
975
  </div>
994
976
  );
@@ -996,64 +978,56 @@ const ThreadWelcomeSuggestions: FC = () => {
996
978
 
997
979
  const Composer: FC = () => {
998
980
  return (
999
- <div className="bg-background relative mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 px-[var(--thread-padding-x)] pb-4 md:pb-6">
1000
- <ThreadScrollToBottom />
1001
- <ThreadPrimitive.Empty>
1002
- <ThreadWelcomeSuggestions />
1003
- </ThreadPrimitive.Empty>
1004
- <ComposerPrimitive.Root className="relative flex w-full flex-col rounded-2xl focus-within:ring-2 focus-within:ring-black focus-within:ring-offset-2 dark:focus-within:ring-white">
981
+ <ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
982
+ <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">
983
+ <ComposerAttachments />
1005
984
  <ComposerPrimitive.Input
1006
985
  placeholder="Send a message..."
1007
- className="bg-muted border-border dark:border-muted-foreground/15 focus:outline-primary placeholder:text-muted-foreground max-h-[calc(50dvh)] min-h-16 w-full resize-none rounded-t-2xl border-x border-t px-4 pt-2 pb-3 text-base outline-none"
986
+ 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"
1008
987
  rows={1}
1009
988
  autoFocus
1010
989
  aria-label="Message input"
1011
990
  />
1012
991
  <ComposerAction />
1013
- </ComposerPrimitive.Root>
1014
- </div>
992
+ </ComposerPrimitive.AttachmentDropzone>
993
+ </ComposerPrimitive.Root>
1015
994
  );
1016
995
  };
1017
996
 
1018
997
  const ComposerAction: FC = () => {
1019
998
  return (
1020
- <div className="bg-muted border-border dark:border-muted-foreground/15 relative flex items-center justify-between rounded-b-2xl border-x border-b p-2">
1021
- <TooltipIconButton
1022
- tooltip="Attach file"
1023
- variant="ghost"
1024
- className="hover:bg-foreground/15 dark:hover:bg-background/50 scale-115 p-3.5"
1025
- onClick={() => {
1026
- console.log("Attachment clicked - not implemented");
1027
- }}
1028
- >
1029
- <PlusIcon />
1030
- </TooltipIconButton>
999
+ <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
1000
+ <ComposerAddAttachment />
1031
1001
 
1032
- <ThreadPrimitive.If running={false}>
1002
+ <AssistantIf condition={({ thread }) => !thread.isRunning}>
1033
1003
  <ComposerPrimitive.Send asChild>
1034
- <Button
1004
+ <TooltipIconButton
1005
+ tooltip="Send message"
1006
+ side="bottom"
1035
1007
  type="submit"
1036
1008
  variant="default"
1037
- className="dark:border-muted-foreground/90 border-muted-foreground/60 hover:bg-primary/75 size-8 rounded-full border"
1009
+ size="icon"
1010
+ className="aui-composer-send size-8 rounded-full"
1038
1011
  aria-label="Send message"
1039
1012
  >
1040
- <ArrowUpIcon className="size-5" />
1041
- </Button>
1013
+ <ArrowUpIcon className="aui-composer-send-icon size-4" />
1014
+ </TooltipIconButton>
1042
1015
  </ComposerPrimitive.Send>
1043
- </ThreadPrimitive.If>
1016
+ </AssistantIf>
1044
1017
 
1045
- <ThreadPrimitive.If running>
1018
+ <AssistantIf condition={({ thread }) => thread.isRunning}>
1046
1019
  <ComposerPrimitive.Cancel asChild>
1047
1020
  <Button
1048
1021
  type="button"
1049
1022
  variant="default"
1050
- className="dark:border-muted-foreground/90 border-muted-foreground/60 hover:bg-primary/75 size-8 rounded-full border"
1023
+ size="icon"
1024
+ className="aui-composer-cancel size-8 rounded-full"
1051
1025
  aria-label="Stop generating"
1052
1026
  >
1053
- <Square className="size-3.5 fill-white dark:size-4 dark:fill-black" />
1027
+ <SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
1054
1028
  </Button>
1055
1029
  </ComposerPrimitive.Cancel>
1056
- </ThreadPrimitive.If>
1030
+ </AssistantIf>
1057
1031
  </div>
1058
1032
  );
1059
1033
  };
@@ -1061,8 +1035,8 @@ const ComposerAction: FC = () => {
1061
1035
  const MessageError: FC = () => {
1062
1036
  return (
1063
1037
  <MessagePrimitive.Error>
1064
- <ErrorPrimitive.Root className="border-destructive bg-destructive/10 dark:bg-destructive/5 text-destructive mt-2 rounded-md border p-3 text-sm dark:text-red-200">
1065
- <ErrorPrimitive.Message className="line-clamp-2" />
1038
+ <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">
1039
+ <ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
1066
1040
  </ErrorPrimitive.Root>
1067
1041
  </MessagePrimitive.Error>
1068
1042
  );
@@ -1070,31 +1044,24 @@ const MessageError: FC = () => {
1070
1044
 
1071
1045
  const AssistantMessage: FC = () => {
1072
1046
  return (
1073
- <MessagePrimitive.Root asChild>
1074
- <motion.div
1075
- className="relative mx-auto grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] px-[var(--thread-padding-x)] py-4"
1076
- initial={{ y: 5, opacity: 0 }}
1077
- animate={{ y: 0, opacity: 1 }}
1078
- data-role="assistant"
1079
- >
1080
- <div className="ring-border bg-background col-start-1 row-start-1 flex size-8 shrink-0 items-center justify-center rounded-full ring-1">
1081
- <StarIcon size={14} />
1082
- </div>
1083
-
1084
- <div className="text-foreground col-span-2 col-start-2 row-start-1 ml-4 leading-7 break-words">
1085
- <MessagePrimitive.Content
1086
- components={{
1087
- Text: MarkdownText,
1088
- tools: { Fallback: ToolFallback },
1089
- }}
1090
- />
1091
- <MessageError />
1092
- </div>
1047
+ <MessagePrimitive.Root
1048
+ 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"
1049
+ data-role="assistant"
1050
+ >
1051
+ <div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
1052
+ <MessagePrimitive.Parts
1053
+ components={{
1054
+ Text: MarkdownText,
1055
+ tools: { Fallback: ToolFallback },
1056
+ }}
1057
+ />
1058
+ <MessageError />
1059
+ </div>
1093
1060
 
1061
+ <div className="aui-assistant-message-footer mt-1 ml-2 flex">
1062
+ <BranchPicker />
1094
1063
  <AssistantActionBar />
1095
-
1096
- <BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
1097
- </motion.div>
1064
+ </div>
1098
1065
  </MessagePrimitive.Root>
1099
1066
  );
1100
1067
  };
@@ -1105,18 +1072,23 @@ const AssistantActionBar: FC = () => {
1105
1072
  hideWhenRunning
1106
1073
  autohide="not-last"
1107
1074
  autohideFloat="single-branch"
1108
- className="text-muted-foreground data-floating:bg-background col-start-3 row-start-2 mt-3 ml-3 flex gap-1 data-floating:absolute data-floating:mt-2 data-floating:rounded-md data-floating:border data-floating:p-1 data-floating:shadow-sm"
1075
+ 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"
1109
1076
  >
1110
1077
  <ActionBarPrimitive.Copy asChild>
1111
1078
  <TooltipIconButton tooltip="Copy">
1112
- <MessagePrimitive.If copied>
1079
+ <AssistantIf condition={({ message }) => message.isCopied}>
1113
1080
  <CheckIcon />
1114
- </MessagePrimitive.If>
1115
- <MessagePrimitive.If copied={false}>
1081
+ </AssistantIf>
1082
+ <AssistantIf condition={({ message }) => !message.isCopied}>
1116
1083
  <CopyIcon />
1117
- </MessagePrimitive.If>
1084
+ </AssistantIf>
1118
1085
  </TooltipIconButton>
1119
1086
  </ActionBarPrimitive.Copy>
1087
+ <ActionBarPrimitive.ExportMarkdown asChild>
1088
+ <TooltipIconButton tooltip="Export as Markdown">
1089
+ <DownloadIcon />
1090
+ </TooltipIconButton>
1091
+ </ActionBarPrimitive.ExportMarkdown>
1120
1092
  <ActionBarPrimitive.Reload asChild>
1121
1093
  <TooltipIconButton tooltip="Refresh">
1122
1094
  <RefreshCwIcon />
@@ -1128,21 +1100,22 @@ const AssistantActionBar: FC = () => {
1128
1100
 
1129
1101
  const UserMessage: FC = () => {
1130
1102
  return (
1131
- <MessagePrimitive.Root asChild>
1132
- <motion.div
1133
- className="mx-auto grid w-full max-w-[var(--thread-max-width)] auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-1 px-[var(--thread-padding-x)] py-4 [&:where(>*)]:col-start-2"
1134
- initial={{ y: 5, opacity: 0 }}
1135
- animate={{ y: 0, opacity: 1 }}
1136
- data-role="user"
1137
- >
1138
- <UserActionBar />
1103
+ <MessagePrimitive.Root
1104
+ 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"
1105
+ data-role="user"
1106
+ >
1107
+ <UserMessageAttachments />
1139
1108
 
1140
- <div className="bg-muted text-foreground col-start-2 rounded-3xl px-5 py-2.5 break-words">
1141
- <MessagePrimitive.Content components={{ Text: MarkdownText }} />
1109
+ <div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
1110
+ <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1111
+ <MessagePrimitive.Parts />
1112
+ </div>
1113
+ <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1114
+ <UserActionBar />
1142
1115
  </div>
1116
+ </div>
1143
1117
 
1144
- <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1145
- </motion.div>
1118
+ <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1146
1119
  </MessagePrimitive.Root>
1147
1120
  );
1148
1121
  };
@@ -1152,10 +1125,10 @@ const UserActionBar: FC = () => {
1152
1125
  <ActionBarPrimitive.Root
1153
1126
  hideWhenRunning
1154
1127
  autohide="not-last"
1155
- className="col-start-1 mt-2.5 mr-3 flex flex-col items-end"
1128
+ className="aui-user-action-bar-root flex flex-col items-end"
1156
1129
  >
1157
1130
  <ActionBarPrimitive.Edit asChild>
1158
- <TooltipIconButton tooltip="Edit">
1131
+ <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
1159
1132
  <PencilIcon />
1160
1133
  </TooltipIconButton>
1161
1134
  </ActionBarPrimitive.Edit>
@@ -1165,27 +1138,24 @@ const UserActionBar: FC = () => {
1165
1138
 
1166
1139
  const EditComposer: FC = () => {
1167
1140
  return (
1168
- <div className="mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 px-[var(--thread-padding-x)]">
1169
- <ComposerPrimitive.Root className="bg-muted ml-auto flex w-full max-w-7/8 flex-col rounded-xl">
1141
+ <MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
1142
+ <ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
1170
1143
  <ComposerPrimitive.Input
1171
- className="text-foreground flex min-h-[60px] w-full resize-none bg-transparent p-4 outline-none"
1144
+ className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
1172
1145
  autoFocus
1173
1146
  />
1174
-
1175
- <div className="mx-3 mb-3 flex items-center justify-center gap-2 self-end">
1147
+ <div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
1176
1148
  <ComposerPrimitive.Cancel asChild>
1177
- <Button variant="ghost" size="sm" aria-label="Cancel edit">
1149
+ <Button variant="ghost" size="sm">
1178
1150
  Cancel
1179
1151
  </Button>
1180
1152
  </ComposerPrimitive.Cancel>
1181
1153
  <ComposerPrimitive.Send asChild>
1182
- <Button size="sm" aria-label="Update message">
1183
- Update
1184
- </Button>
1154
+ <Button size="sm">Update</Button>
1185
1155
  </ComposerPrimitive.Send>
1186
1156
  </div>
1187
1157
  </ComposerPrimitive.Root>
1188
- </div>
1158
+ </MessagePrimitive.Root>
1189
1159
  );
1190
1160
  };
1191
1161
 
@@ -1197,7 +1167,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1197
1167
  <BranchPickerPrimitive.Root
1198
1168
  hideWhenSingleBranch
1199
1169
  className={cn(
1200
- "text-muted-foreground inline-flex items-center text-xs",
1170
+ "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1201
1171
  className,
1202
1172
  )}
1203
1173
  {...rest}
@@ -1207,7 +1177,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1207
1177
  <ChevronLeftIcon />
1208
1178
  </TooltipIconButton>
1209
1179
  </BranchPickerPrimitive.Previous>
1210
- <span className="font-medium">
1180
+ <span className="aui-branch-picker-state font-medium">
1211
1181
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
1212
1182
  </span>
1213
1183
  <BranchPickerPrimitive.Next asChild>
@@ -1219,21 +1189,6 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1219
1189
  );
1220
1190
  };
1221
1191
 
1222
- const StarIcon = ({ size = 14 }: { size?: number }) => (
1223
- <svg
1224
- width={size}
1225
- height={size}
1226
- viewBox="0 0 16 16"
1227
- fill="none"
1228
- xmlns="http://www.w3.org/2000/svg"
1229
- >
1230
- <path
1231
- d="M8 0L9.79611 6.20389L16 8L9.79611 9.79611L8 16L6.20389 9.79611L0 8L6.20389 6.20389L8 0Z"
1232
- fill="currentColor"
1233
- />
1234
- </svg>
1235
- );
1236
-
1237
1192
  ```
1238
1193
 
1239
1194
  ## components/assistant-ui/tool-fallback.tsx
@@ -1276,7 +1231,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1276
1231
  >
1277
1232
  <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1278
1233
  {isCancelled ? (
1279
- <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1234
+ <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1280
1235
  ) : (
1281
1236
  <CheckIcon className="aui-tool-fallback-icon size-4" />
1282
1237
  )}
@@ -1297,7 +1252,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1297
1252
  <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1298
1253
  {cancelledReason && (
1299
1254
  <div className="aui-tool-fallback-cancelled-root px-4">
1300
- <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1255
+ <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1301
1256
  Cancelled reason:
1302
1257
  </p>
1303
1258
  <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
@@ -1427,7 +1382,7 @@ const AvatarFallback = React.forwardRef<
1427
1382
  <AvatarPrimitive.Fallback
1428
1383
  ref={ref}
1429
1384
  className={cn(
1430
- "bg-muted flex h-full w-full items-center justify-center rounded-full",
1385
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1431
1386
  className,
1432
1387
  )}
1433
1388
  {...props}
@@ -1449,16 +1404,16 @@ import { cva, type VariantProps } from "class-variance-authority";
1449
1404
  import { cn } from "@/lib/utils";
1450
1405
 
1451
1406
  const buttonVariants = cva(
1452
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
1407
+ "inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
1453
1408
  {
1454
1409
  variants: {
1455
1410
  variant: {
1456
1411
  default:
1457
1412
  "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1458
1413
  destructive:
1459
- "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
1414
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1460
1415
  outline:
1461
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
1416
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1462
1417
  secondary:
1463
1418
  "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1464
1419
  ghost:
@@ -1467,7 +1422,7 @@ const buttonVariants = cva(
1467
1422
  },
1468
1423
  size: {
1469
1424
  default: "h-9 px-4 py-2 has-[>svg]:px-3",
1470
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
1425
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1471
1426
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1472
1427
  icon: "size-9",
1473
1428
  },
@@ -1547,7 +1502,7 @@ function DialogOverlay({
1547
1502
  <DialogPrimitive.Overlay
1548
1503
  data-slot="dialog-overlay"
1549
1504
  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",
1505
+ "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",
1551
1506
  className,
1552
1507
  )}
1553
1508
  {...props}
@@ -1566,13 +1521,13 @@ function DialogContent({
1566
1521
  <DialogPrimitive.Content
1567
1522
  data-slot="dialog-content"
1568
1523
  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",
1524
+ "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",
1570
1525
  className,
1571
1526
  )}
1572
1527
  {...props}
1573
1528
  >
1574
1529
  {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">
1530
+ <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">
1576
1531
  <XIcon />
1577
1532
  <span className="sr-only">Close</span>
1578
1533
  </DialogPrimitive.Close>
@@ -1611,7 +1566,7 @@ function DialogTitle({
1611
1566
  return (
1612
1567
  <DialogPrimitive.Title
1613
1568
  data-slot="dialog-title"
1614
- className={cn("text-lg leading-none font-semibold", className)}
1569
+ className={cn("font-semibold text-lg leading-none", className)}
1615
1570
  {...props}
1616
1571
  />
1617
1572
  );
@@ -1696,13 +1651,13 @@ function TooltipContent({
1696
1651
  data-slot="tooltip-content"
1697
1652
  sideOffset={sideOffset}
1698
1653
  className={cn(
1699
- "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",
1654
+ "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",
1700
1655
  className,
1701
1656
  )}
1702
1657
  {...props}
1703
1658
  >
1704
1659
  {children}
1705
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
1660
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1706
1661
  </TooltipPrimitive.Content>
1707
1662
  </TooltipPrimitive.Portal>
1708
1663
  );
@@ -1758,31 +1713,29 @@ export default nextConfig;
1758
1713
  "@assistant-ui/react": "workspace:^",
1759
1714
  "@assistant-ui/react-langgraph": "workspace:^",
1760
1715
  "@assistant-ui/react-markdown": "workspace:^",
1761
- "@radix-ui/react-avatar": "^1.1.4",
1762
- "@radix-ui/react-dialog": "^1.1.7",
1716
+ "@radix-ui/react-avatar": "^1.1.11",
1717
+ "@radix-ui/react-dialog": "^1.1.15",
1763
1718
  "@radix-ui/react-slot": "^1.2.4",
1764
1719
  "@radix-ui/react-tooltip": "^1.2.8",
1765
- "@tailwindcss/postcss": "^4.1.17",
1766
- "assistant-stream": "^0.2.42",
1720
+ "@tailwindcss/postcss": "^4.1.18",
1721
+ "assistant-stream": "^0.2.45",
1767
1722
  "class-variance-authority": "^0.7.1",
1768
1723
  "clsx": "^2.1.1",
1769
- "framer-motion": "^12.23.24",
1770
- "lucide-react": "^0.555.0",
1771
- "motion": "^11.18.2",
1772
- "next": "16.0.4",
1724
+ "lucide-react": "^0.560.0",
1725
+ "next": "16.0.10",
1773
1726
  "postcss": "^8.5.6",
1774
- "react": "19.2.0",
1775
- "react-dom": "19.2.0",
1727
+ "react": "19.2.3",
1728
+ "react-dom": "19.2.3",
1776
1729
  "remark-gfm": "^4.0.1",
1777
1730
  "tailwind-merge": "^3.4.0",
1778
- "tailwindcss": "^4.1.17",
1731
+ "tailwindcss": "^4.1.18",
1779
1732
  "tailwindcss-animate": "^1.0.7",
1780
1733
  "zod": "^4.1.13",
1781
- "zustand": "^5.0.8"
1734
+ "zustand": "^5.0.9"
1782
1735
  },
1783
1736
  "devDependencies": {
1784
1737
  "@assistant-ui/x-buildutils": "workspace:*",
1785
- "@types/node": "^24.10.1",
1738
+ "@types/node": "^25.0.0",
1786
1739
  "@types/react": "^19.2.7",
1787
1740
  "@types/react-dom": "^19.2.3",
1788
1741
  "tw-animate-css": "^1.4.0",
@@ -1791,8 +1744,7 @@ export default nextConfig;
1791
1744
  "scripts": {
1792
1745
  "dev": "next dev",
1793
1746
  "build": "next build",
1794
- "start": "next start",
1795
- "lint": "eslint ."
1747
+ "start": "next start"
1796
1748
  }
1797
1749
  }
1798
1750