@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
@@ -312,7 +312,7 @@ const FfmpegTool: FC<{ file: File }> = ({ file }) => {
312
312
  load();
313
313
  }, []);
314
314
 
315
- useAssistantInstructions("The user has attached a file: " + file.name);
315
+ useAssistantInstructions(`The user has attached a file: ${file.name}`);
316
316
 
317
317
  useAssistantTool({
318
318
  toolName: "run_ffmpeg",
@@ -357,7 +357,7 @@ const FfmpegTool: FC<{ file: File }> = ({ file }) => {
357
357
  hint:
358
358
  code === 0
359
359
  ? "note: a download button is appearing in the chat for the user"
360
- : "some error happened, logs: " + logs.join("\n"),
360
+ : `some error happened, logs: ${logs.join("\n")}`,
361
361
  };
362
362
  },
363
363
  render: function RenderFfmpeg({
@@ -391,7 +391,7 @@ const FfmpegTool: FC<{ file: File }> = ({ file }) => {
391
391
  )}
392
392
  <p>Running ffmpeg</p>
393
393
  </div>
394
- <pre className="font-sm overflow-y-scroll">
394
+ <pre className="overflow-y-scroll font-sm">
395
395
  ffmpeg {command?.join(" ")}
396
396
  </pre>
397
397
  </div>
@@ -429,7 +429,7 @@ export default function Home() {
429
429
  return (
430
430
  <div className="flex h-full flex-col">
431
431
  <div className="border-b">
432
- <p className="my-4 ml-8 text-xl font-bold">
432
+ <p className="my-4 ml-8 font-bold text-xl">
433
433
  ConvertGPT (built with{" "}
434
434
  <a
435
435
  href="https://github.com/assistant-ui/assistant-ui"
@@ -568,16 +568,16 @@ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
568
568
  return (
569
569
  <Dialog>
570
570
  <DialogTrigger
571
- className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
571
+ className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
572
572
  asChild
573
573
  >
574
574
  {children}
575
575
  </DialogTrigger>
576
- <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">
576
+ <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">
577
577
  <DialogTitle className="aui-sr-only sr-only">
578
578
  Image Attachment Preview
579
579
  </DialogTitle>
580
- <div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
580
+ <div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
581
581
  <AttachmentPreview src={src} />
582
582
  </div>
583
583
  </DialogContent>
@@ -599,7 +599,7 @@ const AttachmentThumb: FC = () => {
599
599
  className="aui-attachment-tile-image object-cover"
600
600
  />
601
601
  <AvatarFallback delayMs={isImage ? 200 : 0}>
602
- <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
602
+ <FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
603
603
  </AvatarFallback>
604
604
  </Avatar>
605
605
  );
@@ -640,7 +640,7 @@ const AttachmentUI: FC = () => {
640
640
  <TooltipTrigger asChild>
641
641
  <div
642
642
  className={cn(
643
- "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
643
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
644
644
  isComposer &&
645
645
  "aui-attachment-tile-composer border-foreground/20",
646
646
  )}
@@ -666,7 +666,7 @@ const AttachmentRemove: FC = () => {
666
666
  <AttachmentPrimitive.Remove asChild>
667
667
  <TooltipIconButton
668
668
  tooltip="Remove file"
669
- 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"
669
+ 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"
670
670
  side="top"
671
671
  >
672
672
  <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
@@ -701,7 +701,7 @@ export const ComposerAddAttachment: FC = () => {
701
701
  side="bottom"
702
702
  variant="ghost"
703
703
  size="icon"
704
- 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"
704
+ 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"
705
705
  aria-label="Add Attachment"
706
706
  >
707
707
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -752,7 +752,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
752
752
  };
753
753
 
754
754
  return (
755
- <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">
755
+ <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">
756
756
  <span className="aui-code-header-language lowercase [&>span]:text-xs">
757
757
  {language}
758
758
  </span>
@@ -787,7 +787,7 @@ const defaultComponents = memoizeMarkdownComponents({
787
787
  h1: ({ className, ...props }) => (
788
788
  <h1
789
789
  className={cn(
790
- "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
790
+ "aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
791
791
  className,
792
792
  )}
793
793
  {...props}
@@ -796,7 +796,7 @@ const defaultComponents = memoizeMarkdownComponents({
796
796
  h2: ({ className, ...props }) => (
797
797
  <h2
798
798
  className={cn(
799
- "aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
799
+ "aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
800
800
  className,
801
801
  )}
802
802
  {...props}
@@ -805,7 +805,7 @@ const defaultComponents = memoizeMarkdownComponents({
805
805
  h3: ({ className, ...props }) => (
806
806
  <h3
807
807
  className={cn(
808
- "aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
808
+ "aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
809
809
  className,
810
810
  )}
811
811
  {...props}
@@ -814,7 +814,7 @@ const defaultComponents = memoizeMarkdownComponents({
814
814
  h4: ({ className, ...props }) => (
815
815
  <h4
816
816
  className={cn(
817
- "aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
817
+ "aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
818
818
  className,
819
819
  )}
820
820
  {...props}
@@ -823,7 +823,7 @@ const defaultComponents = memoizeMarkdownComponents({
823
823
  h5: ({ className, ...props }) => (
824
824
  <h5
825
825
  className={cn(
826
- "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
826
+ "aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
827
827
  className,
828
828
  )}
829
829
  {...props}
@@ -850,7 +850,7 @@ const defaultComponents = memoizeMarkdownComponents({
850
850
  a: ({ className, ...props }) => (
851
851
  <a
852
852
  className={cn(
853
- "aui-md-a text-primary font-medium underline underline-offset-4",
853
+ "aui-md-a font-medium text-primary underline underline-offset-4",
854
854
  className,
855
855
  )}
856
856
  {...props}
@@ -889,7 +889,7 @@ const defaultComponents = memoizeMarkdownComponents({
889
889
  th: ({ className, ...props }) => (
890
890
  <th
891
891
  className={cn(
892
- "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",
892
+ "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",
893
893
  className,
894
894
  )}
895
895
  {...props}
@@ -898,7 +898,7 @@ const defaultComponents = memoizeMarkdownComponents({
898
898
  td: ({ className, ...props }) => (
899
899
  <td
900
900
  className={cn(
901
- "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
901
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right",
902
902
  className,
903
903
  )}
904
904
  {...props}
@@ -922,7 +922,7 @@ const defaultComponents = memoizeMarkdownComponents({
922
922
  pre: ({ className, ...props }) => (
923
923
  <pre
924
924
  className={cn(
925
- "aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
925
+ "aui-md-pre overflow-x-auto rounded-t-none! rounded-b-lg bg-black p-4 text-white",
926
926
  className,
927
927
  )}
928
928
  {...props}
@@ -934,7 +934,7 @@ const defaultComponents = memoizeMarkdownComponents({
934
934
  <code
935
935
  className={cn(
936
936
  !isCodeBlock &&
937
- "aui-md-inline-code bg-muted rounded border font-semibold",
937
+ "aui-md-inline-code rounded border bg-muted font-semibold",
938
938
  className,
939
939
  )}
940
940
  {...props}
@@ -949,57 +949,67 @@ const defaultComponents = memoizeMarkdownComponents({
949
949
  ## components/assistant-ui/thread.tsx
950
950
 
951
951
  ```tsx
952
+ import {
953
+ ComposerAddAttachment,
954
+ ComposerAttachments,
955
+ UserMessageAttachments,
956
+ } from "@/components/assistant-ui/attachment";
957
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
958
+ import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
959
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
960
+ import { Button } from "@/components/ui/button";
961
+ import { cn } from "@/lib/utils";
952
962
  import {
953
963
  ActionBarPrimitive,
964
+ AssistantIf,
954
965
  BranchPickerPrimitive,
955
966
  ComposerPrimitive,
967
+ ErrorPrimitive,
956
968
  MessagePrimitive,
957
969
  ThreadPrimitive,
958
970
  } from "@assistant-ui/react";
959
- import type { FC } from "react";
960
971
  import {
961
972
  ArrowDownIcon,
973
+ ArrowUpIcon,
962
974
  CheckIcon,
963
975
  ChevronLeftIcon,
964
976
  ChevronRightIcon,
965
977
  CopyIcon,
978
+ DownloadIcon,
966
979
  PencilIcon,
967
980
  RefreshCwIcon,
968
- SendHorizontalIcon,
981
+ SquareIcon,
969
982
  } from "lucide-react";
970
- import { cn } from "@/lib/utils";
971
-
972
- import { Button } from "@/components/ui/button";
973
- import { MarkdownText } from "@/components/assistant-ui/markdown-text";
974
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
983
+ import type { FC } from "react";
975
984
 
976
985
  export const Thread: FC = () => {
977
986
  return (
978
987
  <ThreadPrimitive.Root
979
- className="bg-background box-border flex h-full flex-col overflow-hidden"
988
+ className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
980
989
  style={{
981
- ["--thread-max-width" as string]: "42rem",
990
+ ["--thread-max-width" as string]: "44rem",
982
991
  }}
983
992
  >
984
- <ThreadPrimitive.Viewport className="flex h-full flex-col items-center overflow-y-scroll scroll-smooth bg-inherit px-4 pt-8">
985
- <ThreadWelcome />
993
+ <ThreadPrimitive.Viewport
994
+ turnAnchor="top"
995
+ className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
996
+ >
997
+ <AssistantIf condition={({ thread }) => thread.isEmpty}>
998
+ <ThreadWelcome />
999
+ </AssistantIf>
986
1000
 
987
1001
  <ThreadPrimitive.Messages
988
1002
  components={{
989
- UserMessage: UserMessage,
990
- EditComposer: EditComposer,
991
- AssistantMessage: AssistantMessage,
1003
+ UserMessage,
1004
+ EditComposer,
1005
+ AssistantMessage,
992
1006
  }}
993
1007
  />
994
1008
 
995
- <ThreadPrimitive.If empty={false}>
996
- <div className="min-h-8 flex-grow" />
997
- </ThreadPrimitive.If>
998
-
999
- <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">
1009
+ <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">
1000
1010
  <ThreadScrollToBottom />
1001
1011
  <Composer />
1002
- </div>
1012
+ </ThreadPrimitive.ViewportFooter>
1003
1013
  </ThreadPrimitive.Viewport>
1004
1014
  </ThreadPrimitive.Root>
1005
1015
  );
@@ -1011,7 +1021,7 @@ const ThreadScrollToBottom: FC = () => {
1011
1021
  <TooltipIconButton
1012
1022
  tooltip="Scroll to bottom"
1013
1023
  variant="outline"
1014
- className="absolute -top-8 rounded-full disabled:invisible"
1024
+ 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"
1015
1025
  >
1016
1026
  <ArrowDownIcon />
1017
1027
  </TooltipIconButton>
@@ -1021,175 +1031,247 @@ const ThreadScrollToBottom: FC = () => {
1021
1031
 
1022
1032
  const ThreadWelcome: FC = () => {
1023
1033
  return (
1024
- <ThreadPrimitive.Empty>
1025
- <div className="flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
1026
- <div className="flex w-full flex-grow flex-col items-center justify-center">
1027
- <p className="mt-4 font-medium">How can I help you today?</p>
1034
+ <div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
1035
+ <div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
1036
+ <div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
1037
+ <h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
1038
+ Hello there!
1039
+ </h1>
1040
+ <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">
1041
+ How can I help you today?
1042
+ </p>
1028
1043
  </div>
1029
- <ThreadWelcomeSuggestions />
1030
1044
  </div>
1031
- </ThreadPrimitive.Empty>
1045
+ <ThreadSuggestions />
1046
+ </div>
1032
1047
  );
1033
1048
  };
1034
1049
 
1035
- const ThreadWelcomeSuggestions: FC = () => {
1050
+ const SUGGESTIONS = [
1051
+ {
1052
+ title: "What's the weather",
1053
+ label: "in San Francisco?",
1054
+ prompt: "What's the weather in San Francisco?",
1055
+ },
1056
+ {
1057
+ title: "Explain React hooks",
1058
+ label: "like useState and useEffect",
1059
+ prompt: "Explain React hooks like useState and useEffect",
1060
+ },
1061
+ ] as const;
1062
+
1063
+ const ThreadSuggestions: FC = () => {
1036
1064
  return (
1037
- <div className="mt-3 flex w-full items-stretch justify-center gap-4">
1038
- <ThreadPrimitive.Suggestion
1039
- 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"
1040
- prompt="What is the weather in Tokyo?"
1041
- method="replace"
1042
- autoSend
1043
- >
1044
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
1045
- What is the weather in Tokyo?
1046
- </span>
1047
- </ThreadPrimitive.Suggestion>
1048
- <ThreadPrimitive.Suggestion
1049
- 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"
1050
- prompt="What is assistant-ui?"
1051
- method="replace"
1052
- autoSend
1053
- >
1054
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
1055
- What is assistant-ui?
1056
- </span>
1057
- </ThreadPrimitive.Suggestion>
1065
+ <div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
1066
+ {SUGGESTIONS.map((suggestion, index) => (
1067
+ <div
1068
+ key={suggestion.prompt}
1069
+ 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"
1070
+ style={{ animationDelay: `${100 + index * 50}ms` }}
1071
+ >
1072
+ <ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
1073
+ <Button
1074
+ variant="ghost"
1075
+ 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"
1076
+ aria-label={suggestion.prompt}
1077
+ >
1078
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">
1079
+ {suggestion.title}
1080
+ </span>
1081
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
1082
+ {suggestion.label}
1083
+ </span>
1084
+ </Button>
1085
+ </ThreadPrimitive.Suggestion>
1086
+ </div>
1087
+ ))}
1058
1088
  </div>
1059
1089
  );
1060
1090
  };
1061
1091
 
1062
1092
  const Composer: FC = () => {
1063
1093
  return (
1064
- <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">
1065
- <ComposerPrimitive.Input
1066
- rows={1}
1067
- autoFocus
1068
- placeholder="Write a message..."
1069
- 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"
1070
- />
1071
- <ComposerAction />
1094
+ <ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
1095
+ <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">
1096
+ <ComposerAttachments />
1097
+ <ComposerPrimitive.Input
1098
+ placeholder="Send a message..."
1099
+ 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"
1100
+ rows={1}
1101
+ autoFocus
1102
+ aria-label="Message input"
1103
+ />
1104
+ <ComposerAction />
1105
+ </ComposerPrimitive.AttachmentDropzone>
1072
1106
  </ComposerPrimitive.Root>
1073
1107
  );
1074
1108
  };
1075
1109
 
1076
1110
  const ComposerAction: FC = () => {
1077
1111
  return (
1078
- <>
1079
- <ThreadPrimitive.If running={false}>
1112
+ <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
1113
+ <ComposerAddAttachment />
1114
+
1115
+ <AssistantIf condition={({ thread }) => !thread.isRunning}>
1080
1116
  <ComposerPrimitive.Send asChild>
1081
1117
  <TooltipIconButton
1082
- tooltip="Send"
1118
+ tooltip="Send message"
1119
+ side="bottom"
1120
+ type="submit"
1083
1121
  variant="default"
1084
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
1122
+ size="icon"
1123
+ className="aui-composer-send size-8 rounded-full"
1124
+ aria-label="Send message"
1085
1125
  >
1086
- <SendHorizontalIcon />
1126
+ <ArrowUpIcon className="aui-composer-send-icon size-4" />
1087
1127
  </TooltipIconButton>
1088
1128
  </ComposerPrimitive.Send>
1089
- </ThreadPrimitive.If>
1090
- <ThreadPrimitive.If running>
1129
+ </AssistantIf>
1130
+
1131
+ <AssistantIf condition={({ thread }) => thread.isRunning}>
1091
1132
  <ComposerPrimitive.Cancel asChild>
1092
- <TooltipIconButton
1093
- tooltip="Cancel"
1133
+ <Button
1134
+ type="button"
1094
1135
  variant="default"
1095
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
1136
+ size="icon"
1137
+ className="aui-composer-cancel size-8 rounded-full"
1138
+ aria-label="Stop generating"
1096
1139
  >
1097
- <CircleStopIcon />
1098
- </TooltipIconButton>
1140
+ <SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
1141
+ </Button>
1099
1142
  </ComposerPrimitive.Cancel>
1100
- </ThreadPrimitive.If>
1101
- </>
1143
+ </AssistantIf>
1144
+ </div>
1102
1145
  );
1103
1146
  };
1104
1147
 
1105
- const UserMessage: FC = () => {
1148
+ const MessageError: FC = () => {
1106
1149
  return (
1107
- <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">
1108
- <UserActionBar />
1150
+ <MessagePrimitive.Error>
1151
+ <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">
1152
+ <ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
1153
+ </ErrorPrimitive.Root>
1154
+ </MessagePrimitive.Error>
1155
+ );
1156
+ };
1109
1157
 
1110
- <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">
1111
- <MessagePrimitive.Parts />
1158
+ const AssistantMessage: FC = () => {
1159
+ return (
1160
+ <MessagePrimitive.Root
1161
+ 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"
1162
+ data-role="assistant"
1163
+ >
1164
+ <div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
1165
+ <MessagePrimitive.Parts
1166
+ components={{
1167
+ Text: MarkdownText,
1168
+ tools: { Fallback: ToolFallback },
1169
+ }}
1170
+ />
1171
+ <MessageError />
1112
1172
  </div>
1113
1173
 
1114
- <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1174
+ <div className="aui-assistant-message-footer mt-1 ml-2 flex">
1175
+ <BranchPicker />
1176
+ <AssistantActionBar />
1177
+ </div>
1115
1178
  </MessagePrimitive.Root>
1116
1179
  );
1117
1180
  };
1118
1181
 
1119
- const UserActionBar: FC = () => {
1182
+ const AssistantActionBar: FC = () => {
1120
1183
  return (
1121
1184
  <ActionBarPrimitive.Root
1122
1185
  hideWhenRunning
1123
1186
  autohide="not-last"
1124
- className="col-start-1 row-start-2 mt-2.5 mr-3 flex flex-col items-end"
1187
+ autohideFloat="single-branch"
1188
+ 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"
1125
1189
  >
1126
- <ActionBarPrimitive.Edit asChild>
1127
- <TooltipIconButton tooltip="Edit">
1128
- <PencilIcon />
1190
+ <ActionBarPrimitive.Copy asChild>
1191
+ <TooltipIconButton tooltip="Copy">
1192
+ <AssistantIf condition={({ message }) => message.isCopied}>
1193
+ <CheckIcon />
1194
+ </AssistantIf>
1195
+ <AssistantIf condition={({ message }) => !message.isCopied}>
1196
+ <CopyIcon />
1197
+ </AssistantIf>
1129
1198
  </TooltipIconButton>
1130
- </ActionBarPrimitive.Edit>
1199
+ </ActionBarPrimitive.Copy>
1200
+ <ActionBarPrimitive.ExportMarkdown asChild>
1201
+ <TooltipIconButton tooltip="Export as Markdown">
1202
+ <DownloadIcon />
1203
+ </TooltipIconButton>
1204
+ </ActionBarPrimitive.ExportMarkdown>
1205
+ <ActionBarPrimitive.Reload asChild>
1206
+ <TooltipIconButton tooltip="Refresh">
1207
+ <RefreshCwIcon />
1208
+ </TooltipIconButton>
1209
+ </ActionBarPrimitive.Reload>
1131
1210
  </ActionBarPrimitive.Root>
1132
1211
  );
1133
1212
  };
1134
1213
 
1135
- const EditComposer: FC = () => {
1214
+ const UserMessage: FC = () => {
1136
1215
  return (
1137
- <ComposerPrimitive.Root className="bg-muted my-4 flex w-full max-w-[var(--thread-max-width)] flex-col gap-2 rounded-xl">
1138
- <ComposerPrimitive.Input className="text-foreground flex h-8 w-full resize-none bg-transparent p-4 pb-0 outline-none" />
1139
-
1140
- <div className="mx-3 mb-3 flex items-center justify-center gap-2 self-end">
1141
- <ComposerPrimitive.Cancel asChild>
1142
- <Button variant="ghost">Cancel</Button>
1143
- </ComposerPrimitive.Cancel>
1144
- <ComposerPrimitive.Send asChild>
1145
- <Button>Send</Button>
1146
- </ComposerPrimitive.Send>
1147
- </div>
1148
- </ComposerPrimitive.Root>
1149
- );
1150
- };
1216
+ <MessagePrimitive.Root
1217
+ 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"
1218
+ data-role="user"
1219
+ >
1220
+ <UserMessageAttachments />
1151
1221
 
1152
- const AssistantMessage: FC = () => {
1153
- return (
1154
- <MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
1155
- <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">
1156
- <MessagePrimitive.Parts components={{ Text: MarkdownText }} />
1222
+ <div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
1223
+ <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1224
+ <MessagePrimitive.Parts />
1225
+ </div>
1226
+ <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1227
+ <UserActionBar />
1228
+ </div>
1157
1229
  </div>
1158
1230
 
1159
- <AssistantActionBar />
1160
-
1161
- <BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
1231
+ <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1162
1232
  </MessagePrimitive.Root>
1163
1233
  );
1164
1234
  };
1165
1235
 
1166
- const AssistantActionBar: FC = () => {
1236
+ const UserActionBar: FC = () => {
1167
1237
  return (
1168
1238
  <ActionBarPrimitive.Root
1169
1239
  hideWhenRunning
1170
1240
  autohide="not-last"
1171
- autohideFloat="single-branch"
1172
- 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"
1241
+ className="aui-user-action-bar-root flex flex-col items-end"
1173
1242
  >
1174
- <ActionBarPrimitive.Copy asChild>
1175
- <TooltipIconButton tooltip="Copy">
1176
- <MessagePrimitive.If copied>
1177
- <CheckIcon />
1178
- </MessagePrimitive.If>
1179
- <MessagePrimitive.If copied={false}>
1180
- <CopyIcon />
1181
- </MessagePrimitive.If>
1182
- </TooltipIconButton>
1183
- </ActionBarPrimitive.Copy>
1184
- <ActionBarPrimitive.Reload asChild>
1185
- <TooltipIconButton tooltip="Refresh">
1186
- <RefreshCwIcon />
1243
+ <ActionBarPrimitive.Edit asChild>
1244
+ <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
1245
+ <PencilIcon />
1187
1246
  </TooltipIconButton>
1188
- </ActionBarPrimitive.Reload>
1247
+ </ActionBarPrimitive.Edit>
1189
1248
  </ActionBarPrimitive.Root>
1190
1249
  );
1191
1250
  };
1192
1251
 
1252
+ const EditComposer: FC = () => {
1253
+ return (
1254
+ <MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
1255
+ <ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
1256
+ <ComposerPrimitive.Input
1257
+ className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
1258
+ autoFocus
1259
+ />
1260
+ <div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
1261
+ <ComposerPrimitive.Cancel asChild>
1262
+ <Button variant="ghost" size="sm">
1263
+ Cancel
1264
+ </Button>
1265
+ </ComposerPrimitive.Cancel>
1266
+ <ComposerPrimitive.Send asChild>
1267
+ <Button size="sm">Update</Button>
1268
+ </ComposerPrimitive.Send>
1269
+ </div>
1270
+ </ComposerPrimitive.Root>
1271
+ </MessagePrimitive.Root>
1272
+ );
1273
+ };
1274
+
1193
1275
  const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1194
1276
  className,
1195
1277
  ...rest
@@ -1198,7 +1280,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1198
1280
  <BranchPickerPrimitive.Root
1199
1281
  hideWhenSingleBranch
1200
1282
  className={cn(
1201
- "text-muted-foreground inline-flex items-center text-xs",
1283
+ "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1202
1284
  className,
1203
1285
  )}
1204
1286
  {...rest}
@@ -1208,7 +1290,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1208
1290
  <ChevronLeftIcon />
1209
1291
  </TooltipIconButton>
1210
1292
  </BranchPickerPrimitive.Previous>
1211
- <span className="font-medium">
1293
+ <span className="aui-branch-picker-state font-medium">
1212
1294
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
1213
1295
  </span>
1214
1296
  <BranchPickerPrimitive.Next asChild>
@@ -1220,20 +1302,6 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1220
1302
  );
1221
1303
  };
1222
1304
 
1223
- const CircleStopIcon = () => {
1224
- return (
1225
- <svg
1226
- xmlns="http://www.w3.org/2000/svg"
1227
- viewBox="0 0 16 16"
1228
- fill="currentColor"
1229
- width="16"
1230
- height="16"
1231
- >
1232
- <rect width="10" height="10" x="3" y="3" rx="2" />
1233
- </svg>
1234
- );
1235
- };
1236
-
1237
1305
  ```
1238
1306
 
1239
1307
  ## components/assistant-ui/tool-fallback.tsx
@@ -1276,7 +1344,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1276
1344
  >
1277
1345
  <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1278
1346
  {isCancelled ? (
1279
- <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1347
+ <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1280
1348
  ) : (
1281
1349
  <CheckIcon className="aui-tool-fallback-icon size-4" />
1282
1350
  )}
@@ -1297,7 +1365,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1297
1365
  <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1298
1366
  {cancelledReason && (
1299
1367
  <div className="aui-tool-fallback-cancelled-root px-4">
1300
- <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1368
+ <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1301
1369
  Cancelled reason:
1302
1370
  </p>
1303
1371
  <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
@@ -1427,7 +1495,7 @@ const AvatarFallback = React.forwardRef<
1427
1495
  <AvatarPrimitive.Fallback
1428
1496
  ref={ref}
1429
1497
  className={cn(
1430
- "bg-muted flex h-full w-full items-center justify-center rounded-full",
1498
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1431
1499
  className,
1432
1500
  )}
1433
1501
  {...props}
@@ -1451,16 +1519,16 @@ import { cva, type VariantProps } from "class-variance-authority";
1451
1519
  import { cn } from "@/lib/utils";
1452
1520
 
1453
1521
  const buttonVariants = cva(
1454
- "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",
1522
+ "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",
1455
1523
  {
1456
1524
  variants: {
1457
1525
  variant: {
1458
1526
  default:
1459
1527
  "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1460
1528
  destructive:
1461
- "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",
1529
+ "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",
1462
1530
  outline:
1463
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
1531
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1464
1532
  secondary:
1465
1533
  "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1466
1534
  ghost:
@@ -1469,7 +1537,7 @@ const buttonVariants = cva(
1469
1537
  },
1470
1538
  size: {
1471
1539
  default: "h-9 px-4 py-2 has-[>svg]:px-3",
1472
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
1540
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1473
1541
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1474
1542
  icon: "size-9",
1475
1543
  },
@@ -1549,7 +1617,7 @@ function DialogOverlay({
1549
1617
  <DialogPrimitive.Overlay
1550
1618
  data-slot="dialog-overlay"
1551
1619
  className={cn(
1552
- "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",
1620
+ "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",
1553
1621
  className,
1554
1622
  )}
1555
1623
  {...props}
@@ -1568,13 +1636,13 @@ function DialogContent({
1568
1636
  <DialogPrimitive.Content
1569
1637
  data-slot="dialog-content"
1570
1638
  className={cn(
1571
- "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",
1639
+ "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",
1572
1640
  className,
1573
1641
  )}
1574
1642
  {...props}
1575
1643
  >
1576
1644
  {children}
1577
- <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">
1645
+ <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">
1578
1646
  <XIcon />
1579
1647
  <span className="sr-only">Close</span>
1580
1648
  </DialogPrimitive.Close>
@@ -1613,7 +1681,7 @@ function DialogTitle({
1613
1681
  return (
1614
1682
  <DialogPrimitive.Title
1615
1683
  data-slot="dialog-title"
1616
- className={cn("text-lg leading-none font-semibold", className)}
1684
+ className={cn("font-semibold text-lg leading-none", className)}
1617
1685
  {...props}
1618
1686
  />
1619
1687
  );
@@ -1698,13 +1766,13 @@ function TooltipContent({
1698
1766
  data-slot="tooltip-content"
1699
1767
  sideOffset={sideOffset}
1700
1768
  className={cn(
1701
- "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",
1769
+ "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",
1702
1770
  className,
1703
1771
  )}
1704
1772
  {...props}
1705
1773
  >
1706
1774
  {children}
1707
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
1775
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1708
1776
  </TooltipPrimitive.Content>
1709
1777
  </TooltipPrimitive.Portal>
1710
1778
  );
@@ -1749,11 +1817,10 @@ export default nextConfig;
1749
1817
  "scripts": {
1750
1818
  "dev": "next dev --turbo",
1751
1819
  "build": "next build",
1752
- "start": "next start",
1753
- "lint": "eslint ."
1820
+ "start": "next start"
1754
1821
  },
1755
1822
  "dependencies": {
1756
- "@ai-sdk/openai": "^2.0.73",
1823
+ "@ai-sdk/openai": "^2.0.84",
1757
1824
  "@assistant-ui/react": "workspace:*",
1758
1825
  "@assistant-ui/react-ai-sdk": "workspace:*",
1759
1826
  "@assistant-ui/react-hook-form": "workspace:*",
@@ -1761,37 +1828,36 @@ export default nextConfig;
1761
1828
  "@ffmpeg/ffmpeg": "^0.12.15",
1762
1829
  "@ffmpeg/util": "^0.12.2",
1763
1830
  "@hookform/resolvers": "^5.2.2",
1764
- "@radix-ui/react-avatar": "^1.1.4",
1765
- "@radix-ui/react-dialog": "^1.1.7",
1831
+ "@radix-ui/react-avatar": "^1.1.11",
1832
+ "@radix-ui/react-dialog": "^1.1.15",
1766
1833
  "@radix-ui/react-icons": "^1.3.2",
1767
1834
  "@radix-ui/react-label": "^2.1.8",
1768
1835
  "@radix-ui/react-slot": "^1.2.4",
1769
1836
  "@radix-ui/react-tabs": "^1.1.13",
1770
1837
  "@radix-ui/react-tooltip": "^1.2.8",
1771
1838
  "@react-hook/media-query": "^1.1.1",
1772
- "ai": "^5.0.102",
1839
+ "ai": "^5.0.112",
1773
1840
  "class-variance-authority": "^0.7.1",
1774
1841
  "clsx": "^2.1.1",
1775
- "lucide-react": "^0.555.0",
1776
- "motion": "^11.18.2",
1777
- "next": "16.0.4",
1778
- "react": "19.2.0",
1779
- "react-dom": "19.2.0",
1780
- "react-hook-form": "^7.66.1",
1842
+ "lucide-react": "^0.560.0",
1843
+ "next": "16.0.10",
1844
+ "react": "19.2.3",
1845
+ "react-dom": "19.2.3",
1846
+ "react-hook-form": "^7.68.0",
1781
1847
  "react-resizable-panels": "^3.0.6",
1782
1848
  "remark-gfm": "^4.0.1",
1783
1849
  "tailwind-merge": "^3.4.0",
1784
1850
  "tw-animate-css": "^1.4.0",
1785
1851
  "zod": "^4.1.13",
1786
- "zustand": "^5.0.8"
1852
+ "zustand": "^5.0.9"
1787
1853
  },
1788
1854
  "devDependencies": {
1789
1855
  "@assistant-ui/x-buildutils": "workspace:*",
1790
- "@types/node": "^24",
1856
+ "@types/node": "^25",
1791
1857
  "@types/react": "^19",
1792
1858
  "@types/react-dom": "^19",
1793
1859
  "postcss": "^8",
1794
- "tailwindcss": "^4.1.17",
1860
+ "tailwindcss": "^4.1.18",
1795
1861
  "typescript": "^5.9.3"
1796
1862
  }
1797
1863
  }