@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
@@ -518,16 +518,16 @@ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
518
518
  return (
519
519
  <Dialog>
520
520
  <DialogTrigger
521
- className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
521
+ className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
522
522
  asChild
523
523
  >
524
524
  {children}
525
525
  </DialogTrigger>
526
- <DialogContent className="aui-attachment-preview-dialog-content [&_svg]:text-background [&>button]:bg-foreground/60 [&>button]:hover:[&_svg]:text-destructive p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:p-1 [&>button]:opacity-100 [&>button]:!ring-0">
526
+ <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">
527
527
  <DialogTitle className="aui-sr-only sr-only">
528
528
  Image Attachment Preview
529
529
  </DialogTitle>
530
- <div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
530
+ <div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
531
531
  <AttachmentPreview src={src} />
532
532
  </div>
533
533
  </DialogContent>
@@ -549,7 +549,7 @@ const AttachmentThumb: FC = () => {
549
549
  className="aui-attachment-tile-image object-cover"
550
550
  />
551
551
  <AvatarFallback delayMs={isImage ? 200 : 0}>
552
- <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
552
+ <FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
553
553
  </AvatarFallback>
554
554
  </Avatar>
555
555
  );
@@ -590,7 +590,7 @@ const AttachmentUI: FC = () => {
590
590
  <TooltipTrigger asChild>
591
591
  <div
592
592
  className={cn(
593
- "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
593
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
594
594
  isComposer &&
595
595
  "aui-attachment-tile-composer border-foreground/20",
596
596
  )}
@@ -616,7 +616,7 @@ const AttachmentRemove: FC = () => {
616
616
  <AttachmentPrimitive.Remove asChild>
617
617
  <TooltipIconButton
618
618
  tooltip="Remove file"
619
- className="aui-attachment-tile-remove text-muted-foreground hover:[&_svg]:text-destructive absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white opacity-100 shadow-sm hover:!bg-white [&_svg]:text-black"
619
+ 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"
620
620
  side="top"
621
621
  >
622
622
  <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
@@ -651,7 +651,7 @@ export const ComposerAddAttachment: FC = () => {
651
651
  side="bottom"
652
652
  variant="ghost"
653
653
  size="icon"
654
- className="aui-composer-add-attachment hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30 size-[34px] rounded-full p-1 text-xs font-semibold"
654
+ 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"
655
655
  aria-label="Add Attachment"
656
656
  >
657
657
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -702,7 +702,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
702
702
  };
703
703
 
704
704
  return (
705
- <div className="aui-code-header-root bg-muted-foreground/15 text-foreground dark:bg-muted-foreground/20 mt-4 flex items-center justify-between gap-4 rounded-t-lg px-4 py-2 text-sm font-semibold">
705
+ <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">
706
706
  <span className="aui-code-header-language lowercase [&>span]:text-xs">
707
707
  {language}
708
708
  </span>
@@ -737,7 +737,7 @@ const defaultComponents = memoizeMarkdownComponents({
737
737
  h1: ({ className, ...props }) => (
738
738
  <h1
739
739
  className={cn(
740
- "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
740
+ "aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
741
741
  className,
742
742
  )}
743
743
  {...props}
@@ -746,7 +746,7 @@ const defaultComponents = memoizeMarkdownComponents({
746
746
  h2: ({ className, ...props }) => (
747
747
  <h2
748
748
  className={cn(
749
- "aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
749
+ "aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
750
750
  className,
751
751
  )}
752
752
  {...props}
@@ -755,7 +755,7 @@ const defaultComponents = memoizeMarkdownComponents({
755
755
  h3: ({ className, ...props }) => (
756
756
  <h3
757
757
  className={cn(
758
- "aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
758
+ "aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
759
759
  className,
760
760
  )}
761
761
  {...props}
@@ -764,7 +764,7 @@ const defaultComponents = memoizeMarkdownComponents({
764
764
  h4: ({ className, ...props }) => (
765
765
  <h4
766
766
  className={cn(
767
- "aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
767
+ "aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
768
768
  className,
769
769
  )}
770
770
  {...props}
@@ -773,7 +773,7 @@ const defaultComponents = memoizeMarkdownComponents({
773
773
  h5: ({ className, ...props }) => (
774
774
  <h5
775
775
  className={cn(
776
- "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
776
+ "aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
777
777
  className,
778
778
  )}
779
779
  {...props}
@@ -800,7 +800,7 @@ const defaultComponents = memoizeMarkdownComponents({
800
800
  a: ({ className, ...props }) => (
801
801
  <a
802
802
  className={cn(
803
- "aui-md-a text-primary font-medium underline underline-offset-4",
803
+ "aui-md-a font-medium text-primary underline underline-offset-4",
804
804
  className,
805
805
  )}
806
806
  {...props}
@@ -839,7 +839,7 @@ const defaultComponents = memoizeMarkdownComponents({
839
839
  th: ({ className, ...props }) => (
840
840
  <th
841
841
  className={cn(
842
- "aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
842
+ "aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [[align=center]]:text-center [[align=right]]:text-right",
843
843
  className,
844
844
  )}
845
845
  {...props}
@@ -848,7 +848,7 @@ const defaultComponents = memoizeMarkdownComponents({
848
848
  td: ({ className, ...props }) => (
849
849
  <td
850
850
  className={cn(
851
- "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
851
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right",
852
852
  className,
853
853
  )}
854
854
  {...props}
@@ -872,7 +872,7 @@ const defaultComponents = memoizeMarkdownComponents({
872
872
  pre: ({ className, ...props }) => (
873
873
  <pre
874
874
  className={cn(
875
- "aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
875
+ "aui-md-pre overflow-x-auto rounded-t-none! rounded-b-lg bg-black p-4 text-white",
876
876
  className,
877
877
  )}
878
878
  {...props}
@@ -884,7 +884,7 @@ const defaultComponents = memoizeMarkdownComponents({
884
884
  <code
885
885
  className={cn(
886
886
  !isCodeBlock &&
887
- "aui-md-inline-code bg-muted rounded border font-semibold",
887
+ "aui-md-inline-code rounded border bg-muted font-semibold",
888
888
  className,
889
889
  )}
890
890
  {...props}
@@ -899,60 +899,67 @@ const defaultComponents = memoizeMarkdownComponents({
899
899
  ## components/assistant-ui/thread.tsx
900
900
 
901
901
  ```tsx
902
+ import {
903
+ ComposerAddAttachment,
904
+ ComposerAttachments,
905
+ UserMessageAttachments,
906
+ } from "@/components/assistant-ui/attachment";
907
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
908
+ import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
909
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
910
+ import { Button } from "@/components/ui/button";
911
+ import { cn } from "@/lib/utils";
902
912
  import {
903
913
  ActionBarPrimitive,
914
+ AssistantIf,
904
915
  BranchPickerPrimitive,
905
916
  ComposerPrimitive,
917
+ ErrorPrimitive,
906
918
  MessagePrimitive,
907
919
  ThreadPrimitive,
908
920
  } from "@assistant-ui/react";
909
- import type { FC, PropsWithChildren } from "react";
910
921
  import {
911
922
  ArrowDownIcon,
923
+ ArrowUpIcon,
912
924
  CheckIcon,
913
925
  ChevronLeftIcon,
914
926
  ChevronRightIcon,
915
927
  CopyIcon,
928
+ DownloadIcon,
916
929
  PencilIcon,
917
930
  RefreshCwIcon,
918
- SendHorizontalIcon,
919
- ChevronDownIcon,
920
- ChevronUpIcon,
931
+ SquareIcon,
921
932
  } from "lucide-react";
922
- import { cn } from "@/lib/utils";
923
-
924
- import { Button } from "@/components/ui/button";
925
- import { MarkdownText } from "@/components/assistant-ui/markdown-text";
926
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
927
- import { useState } from "react";
933
+ import type { FC } from "react";
928
934
 
929
935
  export const Thread: FC = () => {
930
936
  return (
931
937
  <ThreadPrimitive.Root
932
- className="bg-background box-border flex h-full flex-col overflow-hidden"
938
+ className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
933
939
  style={{
934
- ["--thread-max-width" as string]: "42rem",
940
+ ["--thread-max-width" as string]: "44rem",
935
941
  }}
936
942
  >
937
- <ThreadPrimitive.Viewport className="flex h-full flex-col items-center overflow-y-scroll scroll-smooth bg-inherit px-4 pt-8">
938
- <ThreadWelcome />
943
+ <ThreadPrimitive.Viewport
944
+ turnAnchor="top"
945
+ className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
946
+ >
947
+ <AssistantIf condition={({ thread }) => thread.isEmpty}>
948
+ <ThreadWelcome />
949
+ </AssistantIf>
939
950
 
940
951
  <ThreadPrimitive.Messages
941
952
  components={{
942
- UserMessage: UserMessage,
943
- EditComposer: EditComposer,
944
- AssistantMessage: AssistantMessage,
953
+ UserMessage,
954
+ EditComposer,
955
+ AssistantMessage,
945
956
  }}
946
957
  />
947
958
 
948
- <ThreadPrimitive.If empty={false}>
949
- <div className="min-h-8 flex-grow" />
950
- </ThreadPrimitive.If>
951
-
952
- <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">
959
+ <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">
953
960
  <ThreadScrollToBottom />
954
961
  <Composer />
955
- </div>
962
+ </ThreadPrimitive.ViewportFooter>
956
963
  </ThreadPrimitive.Viewport>
957
964
  </ThreadPrimitive.Root>
958
965
  );
@@ -964,7 +971,7 @@ const ThreadScrollToBottom: FC = () => {
964
971
  <TooltipIconButton
965
972
  tooltip="Scroll to bottom"
966
973
  variant="outline"
967
- className="absolute -top-8 rounded-full disabled:invisible"
974
+ 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"
968
975
  >
969
976
  <ArrowDownIcon />
970
977
  </TooltipIconButton>
@@ -974,227 +981,150 @@ const ThreadScrollToBottom: FC = () => {
974
981
 
975
982
  const ThreadWelcome: FC = () => {
976
983
  return (
977
- <ThreadPrimitive.Empty>
978
- <div className="flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
979
- <div className="flex w-full flex-grow flex-col items-center justify-center">
980
- <p className="mt-4 font-medium">Parent ID Grouping Demo</p>
981
- <p className="text-muted-foreground mt-2 text-sm">
982
- This example demonstrates how message parts can be grouped by parent
983
- ID
984
+ <div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
985
+ <div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
986
+ <div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
987
+ <h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
988
+ Hello there!
989
+ </h1>
990
+ <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">
991
+ How can I help you today?
984
992
  </p>
985
993
  </div>
986
- <ThreadWelcomeSuggestions />
987
994
  </div>
988
- </ThreadPrimitive.Empty>
995
+ <ThreadSuggestions />
996
+ </div>
989
997
  );
990
998
  };
991
999
 
992
- const ThreadWelcomeSuggestions: FC = () => {
1000
+ const SUGGESTIONS = [
1001
+ {
1002
+ title: "What's the weather",
1003
+ label: "in San Francisco?",
1004
+ prompt: "What's the weather in San Francisco?",
1005
+ },
1006
+ {
1007
+ title: "Explain React hooks",
1008
+ label: "like useState and useEffect",
1009
+ prompt: "Explain React hooks like useState and useEffect",
1010
+ },
1011
+ ] as const;
1012
+
1013
+ const ThreadSuggestions: FC = () => {
993
1014
  return (
994
- <div className="mt-3 flex w-full items-stretch justify-center gap-4">
995
- <ThreadPrimitive.Suggestion
996
- 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"
997
- prompt="Tell me more about this"
998
- method="replace"
999
- autoSend
1000
- >
1001
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
1002
- Tell me more about this
1003
- </span>
1004
- </ThreadPrimitive.Suggestion>
1005
- <ThreadPrimitive.Suggestion
1006
- 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"
1007
- prompt="What are the latest updates?"
1008
- method="replace"
1009
- autoSend
1010
- >
1011
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
1012
- What are the latest updates?
1013
- </span>
1014
- </ThreadPrimitive.Suggestion>
1015
+ <div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
1016
+ {SUGGESTIONS.map((suggestion, index) => (
1017
+ <div
1018
+ key={suggestion.prompt}
1019
+ 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"
1020
+ style={{ animationDelay: `${100 + index * 50}ms` }}
1021
+ >
1022
+ <ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
1023
+ <Button
1024
+ variant="ghost"
1025
+ 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"
1026
+ aria-label={suggestion.prompt}
1027
+ >
1028
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">
1029
+ {suggestion.title}
1030
+ </span>
1031
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
1032
+ {suggestion.label}
1033
+ </span>
1034
+ </Button>
1035
+ </ThreadPrimitive.Suggestion>
1036
+ </div>
1037
+ ))}
1015
1038
  </div>
1016
1039
  );
1017
1040
  };
1018
1041
 
1019
1042
  const Composer: FC = () => {
1020
1043
  return (
1021
- <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">
1022
- <ComposerPrimitive.Input
1023
- rows={1}
1024
- autoFocus
1025
- placeholder="Write a message..."
1026
- 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"
1027
- />
1028
- <ComposerAction />
1044
+ <ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
1045
+ <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">
1046
+ <ComposerAttachments />
1047
+ <ComposerPrimitive.Input
1048
+ placeholder="Send a message..."
1049
+ 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"
1050
+ rows={1}
1051
+ autoFocus
1052
+ aria-label="Message input"
1053
+ />
1054
+ <ComposerAction />
1055
+ </ComposerPrimitive.AttachmentDropzone>
1029
1056
  </ComposerPrimitive.Root>
1030
1057
  );
1031
1058
  };
1032
1059
 
1033
1060
  const ComposerAction: FC = () => {
1034
1061
  return (
1035
- <>
1036
- <ThreadPrimitive.If running={false}>
1062
+ <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
1063
+ <ComposerAddAttachment />
1064
+
1065
+ <AssistantIf condition={({ thread }) => !thread.isRunning}>
1037
1066
  <ComposerPrimitive.Send asChild>
1038
1067
  <TooltipIconButton
1039
- tooltip="Send"
1068
+ tooltip="Send message"
1069
+ side="bottom"
1070
+ type="submit"
1040
1071
  variant="default"
1041
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
1072
+ size="icon"
1073
+ className="aui-composer-send size-8 rounded-full"
1074
+ aria-label="Send message"
1042
1075
  >
1043
- <SendHorizontalIcon />
1076
+ <ArrowUpIcon className="aui-composer-send-icon size-4" />
1044
1077
  </TooltipIconButton>
1045
1078
  </ComposerPrimitive.Send>
1046
- </ThreadPrimitive.If>
1047
- <ThreadPrimitive.If running>
1079
+ </AssistantIf>
1080
+
1081
+ <AssistantIf condition={({ thread }) => thread.isRunning}>
1048
1082
  <ComposerPrimitive.Cancel asChild>
1049
- <TooltipIconButton
1050
- tooltip="Cancel"
1083
+ <Button
1084
+ type="button"
1051
1085
  variant="default"
1052
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
1086
+ size="icon"
1087
+ className="aui-composer-cancel size-8 rounded-full"
1088
+ aria-label="Stop generating"
1053
1089
  >
1054
- <CircleStopIcon />
1055
- </TooltipIconButton>
1090
+ <SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
1091
+ </Button>
1056
1092
  </ComposerPrimitive.Cancel>
1057
- </ThreadPrimitive.If>
1058
- </>
1059
- );
1060
- };
1061
-
1062
- const UserMessage: FC = () => {
1063
- return (
1064
- <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">
1065
- <UserActionBar />
1066
-
1067
- <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">
1068
- <MessagePrimitive.Parts />
1069
- </div>
1070
-
1071
- <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1072
- </MessagePrimitive.Root>
1073
- );
1074
- };
1075
-
1076
- const UserActionBar: FC = () => {
1077
- return (
1078
- <ActionBarPrimitive.Root
1079
- hideWhenRunning
1080
- autohide="not-last"
1081
- className="col-start-1 row-start-2 mt-2.5 mr-3 flex flex-col items-end"
1082
- >
1083
- <ActionBarPrimitive.Edit asChild>
1084
- <TooltipIconButton tooltip="Edit">
1085
- <PencilIcon />
1086
- </TooltipIconButton>
1087
- </ActionBarPrimitive.Edit>
1088
- </ActionBarPrimitive.Root>
1089
- );
1090
- };
1091
-
1092
- const EditComposer: FC = () => {
1093
- return (
1094
- <ComposerPrimitive.Root className="bg-muted my-4 flex w-full max-w-[var(--thread-max-width)] flex-col gap-2 rounded-xl">
1095
- <ComposerPrimitive.Input className="text-foreground flex h-8 w-full resize-none bg-transparent p-4 pb-0 outline-none" />
1096
-
1097
- <div className="mx-3 mb-3 flex items-center justify-center gap-2 self-end">
1098
- <ComposerPrimitive.Cancel asChild>
1099
- <Button variant="ghost">Cancel</Button>
1100
- </ComposerPrimitive.Cancel>
1101
- <ComposerPrimitive.Send asChild>
1102
- <Button>Send</Button>
1103
- </ComposerPrimitive.Send>
1104
- </div>
1105
- </ComposerPrimitive.Root>
1093
+ </AssistantIf>
1094
+ </div>
1106
1095
  );
1107
1096
  };
1108
1097
 
1109
- // Custom Group component for parent ID grouping
1110
- const ParentIdGroup: FC<
1111
- PropsWithChildren<{ groupKey: string | undefined; indices: number[] }>
1112
- > = ({ groupKey, indices, children }) => {
1113
- const [isCollapsed, setIsCollapsed] = useState(false);
1114
-
1115
- if (!groupKey) {
1116
- // Ungrouped parts - just render them directly
1117
- return <>{children}</>;
1118
- }
1119
-
1098
+ const MessageError: FC = () => {
1120
1099
  return (
1121
- <div className="border-border/50 bg-muted/20 my-2 overflow-hidden rounded-lg border">
1122
- <button
1123
- onClick={() => setIsCollapsed(!isCollapsed)}
1124
- className="hover:bg-muted/40 flex w-full items-center justify-between px-4 py-2 text-sm font-medium transition-colors"
1125
- >
1126
- <span className="flex items-center gap-2">
1127
- <span className="text-muted-foreground">Research Group:</span>
1128
- <span className="text-foreground">
1129
- {groupKey === "research-climate-causes" && "Climate Change Causes"}
1130
- {groupKey === "research-climate-effects" &&
1131
- "Climate Change Effects"}
1132
- {groupKey === "new-research" && "Recent Research"}
1133
- {![
1134
- "research-climate-causes",
1135
- "research-climate-effects",
1136
- "new-research",
1137
- ].includes(groupKey) && groupKey}
1138
- </span>
1139
- <span className="text-muted-foreground text-xs">
1140
- ({indices.length} parts)
1141
- </span>
1142
- </span>
1143
- {isCollapsed ? (
1144
- <ChevronDownIcon className="h-4 w-4" />
1145
- ) : (
1146
- <ChevronUpIcon className="h-4 w-4" />
1147
- )}
1148
- </button>
1149
- {!isCollapsed && <div className="space-y-2 px-4 py-2">{children}</div>}
1150
- </div>
1100
+ <MessagePrimitive.Error>
1101
+ <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">
1102
+ <ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
1103
+ </ErrorPrimitive.Root>
1104
+ </MessagePrimitive.Error>
1151
1105
  );
1152
1106
  };
1153
1107
 
1154
1108
  const AssistantMessage: FC = () => {
1155
1109
  return (
1156
- <MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
1157
- <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">
1158
- <MessagePrimitive.Unstable_PartsGroupedByParentId
1110
+ <MessagePrimitive.Root
1111
+ 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"
1112
+ data-role="assistant"
1113
+ >
1114
+ <div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
1115
+ <MessagePrimitive.Parts
1159
1116
  components={{
1160
1117
  Text: MarkdownText,
1161
- Group: ParentIdGroup,
1162
- Source: ({ url, title }) => (
1163
- <div className="text-muted-foreground text-sm">
1164
- <a
1165
- href={url}
1166
- target="_blank"
1167
- rel="noopener noreferrer"
1168
- className="hover:underline"
1169
- >
1170
- 📄 {title || url}
1171
- </a>
1172
- </div>
1173
- ),
1174
- tools: {
1175
- Fallback: ({ toolName, args, result }) => (
1176
- <div className="bg-muted/40 my-1 rounded-md p-2 text-sm">
1177
- <div className="text-muted-foreground font-medium">
1178
- 🔧 {toolName}
1179
- </div>
1180
- <div className="text-muted-foreground mt-1 text-xs">
1181
- <details>
1182
- <summary className="cursor-pointer">View details</summary>
1183
- <pre className="mt-2 overflow-x-auto">
1184
- {JSON.stringify({ args, result }, null, 2)}
1185
- </pre>
1186
- </details>
1187
- </div>
1188
- </div>
1189
- ),
1190
- },
1118
+ tools: { Fallback: ToolFallback },
1191
1119
  }}
1192
1120
  />
1121
+ <MessageError />
1193
1122
  </div>
1194
1123
 
1195
- <AssistantActionBar />
1196
-
1197
- <BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
1124
+ <div className="aui-assistant-message-footer mt-1 ml-2 flex">
1125
+ <BranchPicker />
1126
+ <AssistantActionBar />
1127
+ </div>
1198
1128
  </MessagePrimitive.Root>
1199
1129
  );
1200
1130
  };
@@ -1205,18 +1135,23 @@ const AssistantActionBar: FC = () => {
1205
1135
  hideWhenRunning
1206
1136
  autohide="not-last"
1207
1137
  autohideFloat="single-branch"
1208
- 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"
1138
+ 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"
1209
1139
  >
1210
1140
  <ActionBarPrimitive.Copy asChild>
1211
1141
  <TooltipIconButton tooltip="Copy">
1212
- <MessagePrimitive.If copied>
1142
+ <AssistantIf condition={({ message }) => message.isCopied}>
1213
1143
  <CheckIcon />
1214
- </MessagePrimitive.If>
1215
- <MessagePrimitive.If copied={false}>
1144
+ </AssistantIf>
1145
+ <AssistantIf condition={({ message }) => !message.isCopied}>
1216
1146
  <CopyIcon />
1217
- </MessagePrimitive.If>
1147
+ </AssistantIf>
1218
1148
  </TooltipIconButton>
1219
1149
  </ActionBarPrimitive.Copy>
1150
+ <ActionBarPrimitive.ExportMarkdown asChild>
1151
+ <TooltipIconButton tooltip="Export as Markdown">
1152
+ <DownloadIcon />
1153
+ </TooltipIconButton>
1154
+ </ActionBarPrimitive.ExportMarkdown>
1220
1155
  <ActionBarPrimitive.Reload asChild>
1221
1156
  <TooltipIconButton tooltip="Refresh">
1222
1157
  <RefreshCwIcon />
@@ -1226,6 +1161,67 @@ const AssistantActionBar: FC = () => {
1226
1161
  );
1227
1162
  };
1228
1163
 
1164
+ const UserMessage: FC = () => {
1165
+ return (
1166
+ <MessagePrimitive.Root
1167
+ 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"
1168
+ data-role="user"
1169
+ >
1170
+ <UserMessageAttachments />
1171
+
1172
+ <div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
1173
+ <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1174
+ <MessagePrimitive.Parts />
1175
+ </div>
1176
+ <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1177
+ <UserActionBar />
1178
+ </div>
1179
+ </div>
1180
+
1181
+ <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1182
+ </MessagePrimitive.Root>
1183
+ );
1184
+ };
1185
+
1186
+ const UserActionBar: FC = () => {
1187
+ return (
1188
+ <ActionBarPrimitive.Root
1189
+ hideWhenRunning
1190
+ autohide="not-last"
1191
+ className="aui-user-action-bar-root flex flex-col items-end"
1192
+ >
1193
+ <ActionBarPrimitive.Edit asChild>
1194
+ <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
1195
+ <PencilIcon />
1196
+ </TooltipIconButton>
1197
+ </ActionBarPrimitive.Edit>
1198
+ </ActionBarPrimitive.Root>
1199
+ );
1200
+ };
1201
+
1202
+ const EditComposer: FC = () => {
1203
+ return (
1204
+ <MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
1205
+ <ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
1206
+ <ComposerPrimitive.Input
1207
+ className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
1208
+ autoFocus
1209
+ />
1210
+ <div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
1211
+ <ComposerPrimitive.Cancel asChild>
1212
+ <Button variant="ghost" size="sm">
1213
+ Cancel
1214
+ </Button>
1215
+ </ComposerPrimitive.Cancel>
1216
+ <ComposerPrimitive.Send asChild>
1217
+ <Button size="sm">Update</Button>
1218
+ </ComposerPrimitive.Send>
1219
+ </div>
1220
+ </ComposerPrimitive.Root>
1221
+ </MessagePrimitive.Root>
1222
+ );
1223
+ };
1224
+
1229
1225
  const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1230
1226
  className,
1231
1227
  ...rest
@@ -1234,7 +1230,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1234
1230
  <BranchPickerPrimitive.Root
1235
1231
  hideWhenSingleBranch
1236
1232
  className={cn(
1237
- "text-muted-foreground inline-flex items-center text-xs",
1233
+ "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1238
1234
  className,
1239
1235
  )}
1240
1236
  {...rest}
@@ -1244,7 +1240,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1244
1240
  <ChevronLeftIcon />
1245
1241
  </TooltipIconButton>
1246
1242
  </BranchPickerPrimitive.Previous>
1247
- <span className="font-medium">
1243
+ <span className="aui-branch-picker-state font-medium">
1248
1244
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
1249
1245
  </span>
1250
1246
  <BranchPickerPrimitive.Next asChild>
@@ -1256,20 +1252,6 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1256
1252
  );
1257
1253
  };
1258
1254
 
1259
- const CircleStopIcon = () => {
1260
- return (
1261
- <svg
1262
- xmlns="http://www.w3.org/2000/svg"
1263
- viewBox="0 0 16 16"
1264
- fill="currentColor"
1265
- width="16"
1266
- height="16"
1267
- >
1268
- <rect width="10" height="10" x="3" y="3" rx="2" />
1269
- </svg>
1270
- );
1271
- };
1272
-
1273
1255
  ```
1274
1256
 
1275
1257
  ## components/assistant-ui/tool-fallback.tsx
@@ -1312,7 +1294,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1312
1294
  >
1313
1295
  <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1314
1296
  {isCancelled ? (
1315
- <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1297
+ <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1316
1298
  ) : (
1317
1299
  <CheckIcon className="aui-tool-fallback-icon size-4" />
1318
1300
  )}
@@ -1333,7 +1315,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1333
1315
  <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1334
1316
  {cancelledReason && (
1335
1317
  <div className="aui-tool-fallback-cancelled-root px-4">
1336
- <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1318
+ <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1337
1319
  Cancelled reason:
1338
1320
  </p>
1339
1321
  <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
@@ -1463,7 +1445,7 @@ const AvatarFallback = React.forwardRef<
1463
1445
  <AvatarPrimitive.Fallback
1464
1446
  ref={ref}
1465
1447
  className={cn(
1466
- "bg-muted flex h-full w-full items-center justify-center rounded-full",
1448
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1467
1449
  className,
1468
1450
  )}
1469
1451
  {...props}
@@ -1487,7 +1469,7 @@ import { cva, type VariantProps } from "class-variance-authority";
1487
1469
  import { cn } from "@/lib/utils";
1488
1470
 
1489
1471
  const buttonVariants = cva(
1490
- "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",
1472
+ "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",
1491
1473
  {
1492
1474
  variants: {
1493
1475
  variant: {
@@ -1583,7 +1565,7 @@ function DialogOverlay({
1583
1565
  <DialogPrimitive.Overlay
1584
1566
  data-slot="dialog-overlay"
1585
1567
  className={cn(
1586
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
1568
+ "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",
1587
1569
  className,
1588
1570
  )}
1589
1571
  {...props}
@@ -1602,13 +1584,13 @@ function DialogContent({
1602
1584
  <DialogPrimitive.Content
1603
1585
  data-slot="dialog-content"
1604
1586
  className={cn(
1605
- "bg-background data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
1587
+ "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",
1606
1588
  className,
1607
1589
  )}
1608
1590
  {...props}
1609
1591
  >
1610
1592
  {children}
1611
- <DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
1593
+ <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">
1612
1594
  <XIcon />
1613
1595
  <span className="sr-only">Close</span>
1614
1596
  </DialogPrimitive.Close>
@@ -1647,7 +1629,7 @@ function DialogTitle({
1647
1629
  return (
1648
1630
  <DialogPrimitive.Title
1649
1631
  data-slot="dialog-title"
1650
- className={cn("text-lg leading-none font-semibold", className)}
1632
+ className={cn("font-semibold text-lg leading-none", className)}
1651
1633
  {...props}
1652
1634
  />
1653
1635
  );
@@ -1732,13 +1714,13 @@ function TooltipContent({
1732
1714
  data-slot="tooltip-content"
1733
1715
  sideOffset={sideOffset}
1734
1716
  className={cn(
1735
- "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",
1717
+ "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",
1736
1718
  className,
1737
1719
  )}
1738
1720
  {...props}
1739
1721
  >
1740
1722
  {children}
1741
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
1723
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1742
1724
  </TooltipPrimitive.Content>
1743
1725
  </TooltipPrimitive.Portal>
1744
1726
  );
@@ -1783,28 +1765,26 @@ export default nextConfig;
1783
1765
  "scripts": {
1784
1766
  "dev": "next dev --turbo",
1785
1767
  "build": "next build",
1786
- "start": "next start",
1787
- "lint": "eslint ."
1768
+ "start": "next start"
1788
1769
  },
1789
1770
  "dependencies": {
1790
- "@ai-sdk/openai": "^2.0.73",
1771
+ "@ai-sdk/openai": "^2.0.77",
1791
1772
  "@assistant-ui/react": "workspace:*",
1792
1773
  "@assistant-ui/react-markdown": "workspace:*",
1793
- "@radix-ui/react-avatar": "^1.1.4",
1794
- "@radix-ui/react-dialog": "^1.1.7",
1774
+ "@radix-ui/react-avatar": "^1.1.11",
1775
+ "@radix-ui/react-dialog": "^1.1.15",
1795
1776
  "@radix-ui/react-slot": "^1.2.4",
1796
1777
  "@radix-ui/react-tooltip": "^1.2.8",
1797
1778
  "class-variance-authority": "^0.7.1",
1798
1779
  "clsx": "^2.1.1",
1799
- "lucide-react": "^0.555.0",
1800
- "motion": "^11.18.2",
1801
- "next": "16.0.4",
1802
- "react": "19.2.0",
1803
- "react-dom": "19.2.0",
1780
+ "lucide-react": "^0.556.0",
1781
+ "next": "16.0.7",
1782
+ "react": "19.2.1",
1783
+ "react-dom": "19.2.1",
1804
1784
  "remark-gfm": "^4.0.1",
1805
1785
  "tailwind-merge": "^3.4.0",
1806
1786
  "tw-animate-css": "^1.4.0",
1807
- "zustand": "^5.0.8"
1787
+ "zustand": "^5.0.9"
1808
1788
  },
1809
1789
  "devDependencies": {
1810
1790
  "@assistant-ui/x-buildutils": "workspace:*",