@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
@@ -219,7 +219,7 @@ import Link from "next/link";
219
219
 
220
220
  const SetFormFieldTool = () => {
221
221
  return (
222
- <p className="text-center font-mono text-sm font-bold text-blue-500">
222
+ <p className="text-center font-bold font-mono text-blue-500 text-sm">
223
223
  set_form_field(...)
224
224
  </p>
225
225
  );
@@ -227,7 +227,7 @@ const SetFormFieldTool = () => {
227
227
 
228
228
  const SubmitFormTool = () => {
229
229
  return (
230
- <p className="text-center font-mono text-sm font-bold text-blue-500">
230
+ <p className="text-center font-bold font-mono text-blue-500 text-sm">
231
231
  submit_form(...)
232
232
  </p>
233
233
  );
@@ -260,7 +260,7 @@ export default function Home() {
260
260
  <AssistantSidebar>
261
261
  <div className="h-full overflow-y-scroll">
262
262
  <main className="container py-8">
263
- <h1 className="mb-2 text-2xl font-semibold">
263
+ <h1 className="mb-2 font-semibold text-2xl">
264
264
  Simon&apos;s Hackathon
265
265
  </h1>
266
266
  <p>
@@ -436,16 +436,16 @@ const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
436
436
  return (
437
437
  <Dialog>
438
438
  <DialogTrigger
439
- className="aui-attachment-preview-trigger hover:bg-accent/50 cursor-pointer transition-colors"
439
+ className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50"
440
440
  asChild
441
441
  >
442
442
  {children}
443
443
  </DialogTrigger>
444
- <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">
444
+ <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">
445
445
  <DialogTitle className="aui-sr-only sr-only">
446
446
  Image Attachment Preview
447
447
  </DialogTitle>
448
- <div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden">
448
+ <div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
449
449
  <AttachmentPreview src={src} />
450
450
  </div>
451
451
  </DialogContent>
@@ -467,7 +467,7 @@ const AttachmentThumb: FC = () => {
467
467
  className="aui-attachment-tile-image object-cover"
468
468
  />
469
469
  <AvatarFallback delayMs={isImage ? 200 : 0}>
470
- <FileText className="aui-attachment-tile-fallback-icon text-muted-foreground size-8" />
470
+ <FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
471
471
  </AvatarFallback>
472
472
  </Avatar>
473
473
  );
@@ -508,7 +508,7 @@ const AttachmentUI: FC = () => {
508
508
  <TooltipTrigger asChild>
509
509
  <div
510
510
  className={cn(
511
- "aui-attachment-tile bg-muted size-14 cursor-pointer overflow-hidden rounded-[14px] border transition-opacity hover:opacity-75",
511
+ "aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
512
512
  isComposer &&
513
513
  "aui-attachment-tile-composer border-foreground/20",
514
514
  )}
@@ -534,7 +534,7 @@ const AttachmentRemove: FC = () => {
534
534
  <AttachmentPrimitive.Remove asChild>
535
535
  <TooltipIconButton
536
536
  tooltip="Remove file"
537
- 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"
537
+ 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"
538
538
  side="top"
539
539
  >
540
540
  <XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
@@ -569,7 +569,7 @@ export const ComposerAddAttachment: FC = () => {
569
569
  side="bottom"
570
570
  variant="ghost"
571
571
  size="icon"
572
- 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"
572
+ 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"
573
573
  aria-label="Add Attachment"
574
574
  >
575
575
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -620,7 +620,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
620
620
  };
621
621
 
622
622
  return (
623
- <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">
623
+ <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">
624
624
  <span className="aui-code-header-language lowercase [&>span]:text-xs">
625
625
  {language}
626
626
  </span>
@@ -655,7 +655,7 @@ const defaultComponents = memoizeMarkdownComponents({
655
655
  h1: ({ className, ...props }) => (
656
656
  <h1
657
657
  className={cn(
658
- "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
658
+ "aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
659
659
  className,
660
660
  )}
661
661
  {...props}
@@ -664,7 +664,7 @@ const defaultComponents = memoizeMarkdownComponents({
664
664
  h2: ({ className, ...props }) => (
665
665
  <h2
666
666
  className={cn(
667
- "aui-md-h2 mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
667
+ "aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
668
668
  className,
669
669
  )}
670
670
  {...props}
@@ -673,7 +673,7 @@ const defaultComponents = memoizeMarkdownComponents({
673
673
  h3: ({ className, ...props }) => (
674
674
  <h3
675
675
  className={cn(
676
- "aui-md-h3 mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
676
+ "aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
677
677
  className,
678
678
  )}
679
679
  {...props}
@@ -682,7 +682,7 @@ const defaultComponents = memoizeMarkdownComponents({
682
682
  h4: ({ className, ...props }) => (
683
683
  <h4
684
684
  className={cn(
685
- "aui-md-h4 mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
685
+ "aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
686
686
  className,
687
687
  )}
688
688
  {...props}
@@ -691,7 +691,7 @@ const defaultComponents = memoizeMarkdownComponents({
691
691
  h5: ({ className, ...props }) => (
692
692
  <h5
693
693
  className={cn(
694
- "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
694
+ "aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
695
695
  className,
696
696
  )}
697
697
  {...props}
@@ -718,7 +718,7 @@ const defaultComponents = memoizeMarkdownComponents({
718
718
  a: ({ className, ...props }) => (
719
719
  <a
720
720
  className={cn(
721
- "aui-md-a text-primary font-medium underline underline-offset-4",
721
+ "aui-md-a font-medium text-primary underline underline-offset-4",
722
722
  className,
723
723
  )}
724
724
  {...props}
@@ -757,7 +757,7 @@ const defaultComponents = memoizeMarkdownComponents({
757
757
  th: ({ className, ...props }) => (
758
758
  <th
759
759
  className={cn(
760
- "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",
760
+ "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",
761
761
  className,
762
762
  )}
763
763
  {...props}
@@ -766,7 +766,7 @@ const defaultComponents = memoizeMarkdownComponents({
766
766
  td: ({ className, ...props }) => (
767
767
  <td
768
768
  className={cn(
769
- "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
769
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right",
770
770
  className,
771
771
  )}
772
772
  {...props}
@@ -790,7 +790,7 @@ const defaultComponents = memoizeMarkdownComponents({
790
790
  pre: ({ className, ...props }) => (
791
791
  <pre
792
792
  className={cn(
793
- "aui-md-pre overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
793
+ "aui-md-pre overflow-x-auto rounded-t-none! rounded-b-lg bg-black p-4 text-white",
794
794
  className,
795
795
  )}
796
796
  {...props}
@@ -802,7 +802,7 @@ const defaultComponents = memoizeMarkdownComponents({
802
802
  <code
803
803
  className={cn(
804
804
  !isCodeBlock &&
805
- "aui-md-inline-code bg-muted rounded border font-semibold",
805
+ "aui-md-inline-code rounded border bg-muted font-semibold",
806
806
  className,
807
807
  )}
808
808
  {...props}
@@ -817,57 +817,67 @@ const defaultComponents = memoizeMarkdownComponents({
817
817
  ## components/assistant-ui/thread.tsx
818
818
 
819
819
  ```tsx
820
+ import {
821
+ ComposerAddAttachment,
822
+ ComposerAttachments,
823
+ UserMessageAttachments,
824
+ } from "@/components/assistant-ui/attachment";
825
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
826
+ import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
827
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
828
+ import { Button } from "@/components/ui/button";
829
+ import { cn } from "@/lib/utils";
820
830
  import {
821
831
  ActionBarPrimitive,
832
+ AssistantIf,
822
833
  BranchPickerPrimitive,
823
834
  ComposerPrimitive,
835
+ ErrorPrimitive,
824
836
  MessagePrimitive,
825
837
  ThreadPrimitive,
826
838
  } from "@assistant-ui/react";
827
- import type { FC } from "react";
828
839
  import {
829
840
  ArrowDownIcon,
841
+ ArrowUpIcon,
830
842
  CheckIcon,
831
843
  ChevronLeftIcon,
832
844
  ChevronRightIcon,
833
845
  CopyIcon,
846
+ DownloadIcon,
834
847
  PencilIcon,
835
848
  RefreshCwIcon,
836
- SendHorizontalIcon,
849
+ SquareIcon,
837
850
  } from "lucide-react";
838
- import { cn } from "@/lib/utils";
839
-
840
- import { Button } from "@/components/ui/button";
841
- import { MarkdownText } from "@/components/assistant-ui/markdown-text";
842
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
851
+ import type { FC } from "react";
843
852
 
844
853
  export const Thread: FC = () => {
845
854
  return (
846
855
  <ThreadPrimitive.Root
847
- className="bg-background box-border flex h-full flex-col overflow-hidden"
856
+ className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
848
857
  style={{
849
- ["--thread-max-width" as string]: "42rem",
858
+ ["--thread-max-width" as string]: "44rem",
850
859
  }}
851
860
  >
852
- <ThreadPrimitive.Viewport className="flex h-full flex-col items-center overflow-y-scroll scroll-smooth bg-inherit px-4 pt-8">
853
- <ThreadWelcome />
861
+ <ThreadPrimitive.Viewport
862
+ turnAnchor="top"
863
+ className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
864
+ >
865
+ <AssistantIf condition={({ thread }) => thread.isEmpty}>
866
+ <ThreadWelcome />
867
+ </AssistantIf>
854
868
 
855
869
  <ThreadPrimitive.Messages
856
870
  components={{
857
- UserMessage: UserMessage,
858
- EditComposer: EditComposer,
859
- AssistantMessage: AssistantMessage,
871
+ UserMessage,
872
+ EditComposer,
873
+ AssistantMessage,
860
874
  }}
861
875
  />
862
876
 
863
- <ThreadPrimitive.If empty={false}>
864
- <div className="min-h-8 flex-grow" />
865
- </ThreadPrimitive.If>
866
-
867
- <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">
877
+ <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">
868
878
  <ThreadScrollToBottom />
869
879
  <Composer />
870
- </div>
880
+ </ThreadPrimitive.ViewportFooter>
871
881
  </ThreadPrimitive.Viewport>
872
882
  </ThreadPrimitive.Root>
873
883
  );
@@ -879,7 +889,7 @@ const ThreadScrollToBottom: FC = () => {
879
889
  <TooltipIconButton
880
890
  tooltip="Scroll to bottom"
881
891
  variant="outline"
882
- className="absolute -top-8 rounded-full disabled:invisible"
892
+ 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"
883
893
  >
884
894
  <ArrowDownIcon />
885
895
  </TooltipIconButton>
@@ -889,175 +899,247 @@ const ThreadScrollToBottom: FC = () => {
889
899
 
890
900
  const ThreadWelcome: FC = () => {
891
901
  return (
892
- <ThreadPrimitive.Empty>
893
- <div className="flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
894
- <div className="flex w-full flex-grow flex-col items-center justify-center">
895
- <p className="mt-4 font-medium">How can I help you today?</p>
902
+ <div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
903
+ <div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
904
+ <div className="aui-thread-welcome-message flex size-full flex-col justify-center px-4">
905
+ <h1 className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in font-semibold text-2xl duration-200">
906
+ Hello there!
907
+ </h1>
908
+ <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">
909
+ How can I help you today?
910
+ </p>
896
911
  </div>
897
- <ThreadWelcomeSuggestions />
898
912
  </div>
899
- </ThreadPrimitive.Empty>
913
+ <ThreadSuggestions />
914
+ </div>
900
915
  );
901
916
  };
902
917
 
903
- const ThreadWelcomeSuggestions: FC = () => {
918
+ const SUGGESTIONS = [
919
+ {
920
+ title: "What's the weather",
921
+ label: "in San Francisco?",
922
+ prompt: "What's the weather in San Francisco?",
923
+ },
924
+ {
925
+ title: "Explain React hooks",
926
+ label: "like useState and useEffect",
927
+ prompt: "Explain React hooks like useState and useEffect",
928
+ },
929
+ ] as const;
930
+
931
+ const ThreadSuggestions: FC = () => {
904
932
  return (
905
- <div className="mt-3 flex w-full items-stretch justify-center gap-4">
906
- <ThreadPrimitive.Suggestion
907
- 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"
908
- prompt="What is the weather in Tokyo?"
909
- method="replace"
910
- autoSend
911
- >
912
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
913
- What is the weather in Tokyo?
914
- </span>
915
- </ThreadPrimitive.Suggestion>
916
- <ThreadPrimitive.Suggestion
917
- 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"
918
- prompt="What is assistant-ui?"
919
- method="replace"
920
- autoSend
921
- >
922
- <span className="line-clamp-2 text-sm font-semibold text-ellipsis">
923
- What is assistant-ui?
924
- </span>
925
- </ThreadPrimitive.Suggestion>
933
+ <div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
934
+ {SUGGESTIONS.map((suggestion, index) => (
935
+ <div
936
+ key={suggestion.prompt}
937
+ 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"
938
+ style={{ animationDelay: `${100 + index * 50}ms` }}
939
+ >
940
+ <ThreadPrimitive.Suggestion prompt={suggestion.prompt} send asChild>
941
+ <Button
942
+ variant="ghost"
943
+ 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"
944
+ aria-label={suggestion.prompt}
945
+ >
946
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">
947
+ {suggestion.title}
948
+ </span>
949
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
950
+ {suggestion.label}
951
+ </span>
952
+ </Button>
953
+ </ThreadPrimitive.Suggestion>
954
+ </div>
955
+ ))}
926
956
  </div>
927
957
  );
928
958
  };
929
959
 
930
960
  const Composer: FC = () => {
931
961
  return (
932
- <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">
933
- <ComposerPrimitive.Input
934
- rows={1}
935
- autoFocus
936
- placeholder="Write a message..."
937
- 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"
938
- />
939
- <ComposerAction />
962
+ <ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
963
+ <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">
964
+ <ComposerAttachments />
965
+ <ComposerPrimitive.Input
966
+ placeholder="Send a message..."
967
+ 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"
968
+ rows={1}
969
+ autoFocus
970
+ aria-label="Message input"
971
+ />
972
+ <ComposerAction />
973
+ </ComposerPrimitive.AttachmentDropzone>
940
974
  </ComposerPrimitive.Root>
941
975
  );
942
976
  };
943
977
 
944
978
  const ComposerAction: FC = () => {
945
979
  return (
946
- <>
947
- <ThreadPrimitive.If running={false}>
980
+ <div className="aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between">
981
+ <ComposerAddAttachment />
982
+
983
+ <AssistantIf condition={({ thread }) => !thread.isRunning}>
948
984
  <ComposerPrimitive.Send asChild>
949
985
  <TooltipIconButton
950
- tooltip="Send"
986
+ tooltip="Send message"
987
+ side="bottom"
988
+ type="submit"
951
989
  variant="default"
952
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
990
+ size="icon"
991
+ className="aui-composer-send size-8 rounded-full"
992
+ aria-label="Send message"
953
993
  >
954
- <SendHorizontalIcon />
994
+ <ArrowUpIcon className="aui-composer-send-icon size-4" />
955
995
  </TooltipIconButton>
956
996
  </ComposerPrimitive.Send>
957
- </ThreadPrimitive.If>
958
- <ThreadPrimitive.If running>
997
+ </AssistantIf>
998
+
999
+ <AssistantIf condition={({ thread }) => thread.isRunning}>
959
1000
  <ComposerPrimitive.Cancel asChild>
960
- <TooltipIconButton
961
- tooltip="Cancel"
1001
+ <Button
1002
+ type="button"
962
1003
  variant="default"
963
- className="my-2.5 size-8 p-2 transition-opacity ease-in"
1004
+ size="icon"
1005
+ className="aui-composer-cancel size-8 rounded-full"
1006
+ aria-label="Stop generating"
964
1007
  >
965
- <CircleStopIcon />
966
- </TooltipIconButton>
1008
+ <SquareIcon className="aui-composer-cancel-icon size-3 fill-current" />
1009
+ </Button>
967
1010
  </ComposerPrimitive.Cancel>
968
- </ThreadPrimitive.If>
969
- </>
1011
+ </AssistantIf>
1012
+ </div>
970
1013
  );
971
1014
  };
972
1015
 
973
- const UserMessage: FC = () => {
1016
+ const MessageError: FC = () => {
974
1017
  return (
975
- <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">
976
- <UserActionBar />
1018
+ <MessagePrimitive.Error>
1019
+ <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">
1020
+ <ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
1021
+ </ErrorPrimitive.Root>
1022
+ </MessagePrimitive.Error>
1023
+ );
1024
+ };
977
1025
 
978
- <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">
979
- <MessagePrimitive.Parts />
1026
+ const AssistantMessage: FC = () => {
1027
+ return (
1028
+ <MessagePrimitive.Root
1029
+ 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"
1030
+ data-role="assistant"
1031
+ >
1032
+ <div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
1033
+ <MessagePrimitive.Parts
1034
+ components={{
1035
+ Text: MarkdownText,
1036
+ tools: { Fallback: ToolFallback },
1037
+ }}
1038
+ />
1039
+ <MessageError />
980
1040
  </div>
981
1041
 
982
- <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1042
+ <div className="aui-assistant-message-footer mt-1 ml-2 flex">
1043
+ <BranchPicker />
1044
+ <AssistantActionBar />
1045
+ </div>
983
1046
  </MessagePrimitive.Root>
984
1047
  );
985
1048
  };
986
1049
 
987
- const UserActionBar: FC = () => {
1050
+ const AssistantActionBar: FC = () => {
988
1051
  return (
989
1052
  <ActionBarPrimitive.Root
990
1053
  hideWhenRunning
991
1054
  autohide="not-last"
992
- className="col-start-1 row-start-2 mt-2.5 mr-3 flex flex-col items-end"
1055
+ autohideFloat="single-branch"
1056
+ 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"
993
1057
  >
994
- <ActionBarPrimitive.Edit asChild>
995
- <TooltipIconButton tooltip="Edit">
996
- <PencilIcon />
1058
+ <ActionBarPrimitive.Copy asChild>
1059
+ <TooltipIconButton tooltip="Copy">
1060
+ <AssistantIf condition={({ message }) => message.isCopied}>
1061
+ <CheckIcon />
1062
+ </AssistantIf>
1063
+ <AssistantIf condition={({ message }) => !message.isCopied}>
1064
+ <CopyIcon />
1065
+ </AssistantIf>
997
1066
  </TooltipIconButton>
998
- </ActionBarPrimitive.Edit>
1067
+ </ActionBarPrimitive.Copy>
1068
+ <ActionBarPrimitive.ExportMarkdown asChild>
1069
+ <TooltipIconButton tooltip="Export as Markdown">
1070
+ <DownloadIcon />
1071
+ </TooltipIconButton>
1072
+ </ActionBarPrimitive.ExportMarkdown>
1073
+ <ActionBarPrimitive.Reload asChild>
1074
+ <TooltipIconButton tooltip="Refresh">
1075
+ <RefreshCwIcon />
1076
+ </TooltipIconButton>
1077
+ </ActionBarPrimitive.Reload>
999
1078
  </ActionBarPrimitive.Root>
1000
1079
  );
1001
1080
  };
1002
1081
 
1003
- const EditComposer: FC = () => {
1082
+ const UserMessage: FC = () => {
1004
1083
  return (
1005
- <ComposerPrimitive.Root className="bg-muted my-4 flex w-full max-w-[var(--thread-max-width)] flex-col gap-2 rounded-xl">
1006
- <ComposerPrimitive.Input className="text-foreground flex h-8 w-full resize-none bg-transparent p-4 pb-0 outline-none" />
1007
-
1008
- <div className="mx-3 mb-3 flex items-center justify-center gap-2 self-end">
1009
- <ComposerPrimitive.Cancel asChild>
1010
- <Button variant="ghost">Cancel</Button>
1011
- </ComposerPrimitive.Cancel>
1012
- <ComposerPrimitive.Send asChild>
1013
- <Button>Send</Button>
1014
- </ComposerPrimitive.Send>
1015
- </div>
1016
- </ComposerPrimitive.Root>
1017
- );
1018
- };
1084
+ <MessagePrimitive.Root
1085
+ 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"
1086
+ data-role="user"
1087
+ >
1088
+ <UserMessageAttachments />
1019
1089
 
1020
- const AssistantMessage: FC = () => {
1021
- return (
1022
- <MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
1023
- <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">
1024
- <MessagePrimitive.Parts components={{ Text: MarkdownText }} />
1090
+ <div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
1091
+ <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1092
+ <MessagePrimitive.Parts />
1093
+ </div>
1094
+ <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1095
+ <UserActionBar />
1096
+ </div>
1025
1097
  </div>
1026
1098
 
1027
- <AssistantActionBar />
1028
-
1029
- <BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
1099
+ <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1030
1100
  </MessagePrimitive.Root>
1031
1101
  );
1032
1102
  };
1033
1103
 
1034
- const AssistantActionBar: FC = () => {
1104
+ const UserActionBar: FC = () => {
1035
1105
  return (
1036
1106
  <ActionBarPrimitive.Root
1037
1107
  hideWhenRunning
1038
1108
  autohide="not-last"
1039
- autohideFloat="single-branch"
1040
- 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"
1109
+ className="aui-user-action-bar-root flex flex-col items-end"
1041
1110
  >
1042
- <ActionBarPrimitive.Copy asChild>
1043
- <TooltipIconButton tooltip="Copy">
1044
- <MessagePrimitive.If copied>
1045
- <CheckIcon />
1046
- </MessagePrimitive.If>
1047
- <MessagePrimitive.If copied={false}>
1048
- <CopyIcon />
1049
- </MessagePrimitive.If>
1050
- </TooltipIconButton>
1051
- </ActionBarPrimitive.Copy>
1052
- <ActionBarPrimitive.Reload asChild>
1053
- <TooltipIconButton tooltip="Refresh">
1054
- <RefreshCwIcon />
1111
+ <ActionBarPrimitive.Edit asChild>
1112
+ <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
1113
+ <PencilIcon />
1055
1114
  </TooltipIconButton>
1056
- </ActionBarPrimitive.Reload>
1115
+ </ActionBarPrimitive.Edit>
1057
1116
  </ActionBarPrimitive.Root>
1058
1117
  );
1059
1118
  };
1060
1119
 
1120
+ const EditComposer: FC = () => {
1121
+ return (
1122
+ <MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3">
1123
+ <ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted">
1124
+ <ComposerPrimitive.Input
1125
+ className="aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none"
1126
+ autoFocus
1127
+ />
1128
+ <div className="aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end">
1129
+ <ComposerPrimitive.Cancel asChild>
1130
+ <Button variant="ghost" size="sm">
1131
+ Cancel
1132
+ </Button>
1133
+ </ComposerPrimitive.Cancel>
1134
+ <ComposerPrimitive.Send asChild>
1135
+ <Button size="sm">Update</Button>
1136
+ </ComposerPrimitive.Send>
1137
+ </div>
1138
+ </ComposerPrimitive.Root>
1139
+ </MessagePrimitive.Root>
1140
+ );
1141
+ };
1142
+
1061
1143
  const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1062
1144
  className,
1063
1145
  ...rest
@@ -1066,7 +1148,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1066
1148
  <BranchPickerPrimitive.Root
1067
1149
  hideWhenSingleBranch
1068
1150
  className={cn(
1069
- "text-muted-foreground inline-flex items-center text-xs",
1151
+ "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1070
1152
  className,
1071
1153
  )}
1072
1154
  {...rest}
@@ -1076,7 +1158,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1076
1158
  <ChevronLeftIcon />
1077
1159
  </TooltipIconButton>
1078
1160
  </BranchPickerPrimitive.Previous>
1079
- <span className="font-medium">
1161
+ <span className="aui-branch-picker-state font-medium">
1080
1162
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
1081
1163
  </span>
1082
1164
  <BranchPickerPrimitive.Next asChild>
@@ -1088,20 +1170,6 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1088
1170
  );
1089
1171
  };
1090
1172
 
1091
- const CircleStopIcon = () => {
1092
- return (
1093
- <svg
1094
- xmlns="http://www.w3.org/2000/svg"
1095
- viewBox="0 0 16 16"
1096
- fill="currentColor"
1097
- width="16"
1098
- height="16"
1099
- >
1100
- <rect width="10" height="10" x="3" y="3" rx="2" />
1101
- </svg>
1102
- );
1103
- };
1104
-
1105
1173
  ```
1106
1174
 
1107
1175
  ## components/assistant-ui/tool-fallback.tsx
@@ -1144,7 +1212,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1144
1212
  >
1145
1213
  <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1146
1214
  {isCancelled ? (
1147
- <XCircleIcon className="aui-tool-fallback-icon text-muted-foreground size-4" />
1215
+ <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1148
1216
  ) : (
1149
1217
  <CheckIcon className="aui-tool-fallback-icon size-4" />
1150
1218
  )}
@@ -1165,7 +1233,7 @@ export const ToolFallback: ToolCallMessagePartComponent = ({
1165
1233
  <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1166
1234
  {cancelledReason && (
1167
1235
  <div className="aui-tool-fallback-cancelled-root px-4">
1168
- <p className="aui-tool-fallback-cancelled-header text-muted-foreground font-semibold">
1236
+ <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1169
1237
  Cancelled reason:
1170
1238
  </p>
1171
1239
  <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
@@ -1444,7 +1512,7 @@ const AvatarFallback = React.forwardRef<
1444
1512
  <AvatarPrimitive.Fallback
1445
1513
  ref={ref}
1446
1514
  className={cn(
1447
- "bg-muted flex h-full w-full items-center justify-center rounded-full",
1515
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
1448
1516
  className,
1449
1517
  )}
1450
1518
  {...props}
@@ -1466,16 +1534,16 @@ import { cva, type VariantProps } from "class-variance-authority";
1466
1534
  import { cn } from "@/lib/utils";
1467
1535
 
1468
1536
  const buttonVariants = cva(
1469
- "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",
1537
+ "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",
1470
1538
  {
1471
1539
  variants: {
1472
1540
  variant: {
1473
1541
  default:
1474
1542
  "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1475
1543
  destructive:
1476
- "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",
1544
+ "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",
1477
1545
  outline:
1478
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
1546
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1479
1547
  secondary:
1480
1548
  "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1481
1549
  ghost:
@@ -1484,7 +1552,7 @@ const buttonVariants = cva(
1484
1552
  },
1485
1553
  size: {
1486
1554
  default: "h-9 px-4 py-2 has-[>svg]:px-3",
1487
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
1555
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1488
1556
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1489
1557
  icon: "size-9",
1490
1558
  },
@@ -1564,7 +1632,7 @@ function DialogOverlay({
1564
1632
  <DialogPrimitive.Overlay
1565
1633
  data-slot="dialog-overlay"
1566
1634
  className={cn(
1567
- "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",
1635
+ "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",
1568
1636
  className,
1569
1637
  )}
1570
1638
  {...props}
@@ -1583,13 +1651,13 @@ function DialogContent({
1583
1651
  <DialogPrimitive.Content
1584
1652
  data-slot="dialog-content"
1585
1653
  className={cn(
1586
- "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",
1654
+ "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",
1587
1655
  className,
1588
1656
  )}
1589
1657
  {...props}
1590
1658
  >
1591
1659
  {children}
1592
- <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">
1660
+ <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">
1593
1661
  <XIcon />
1594
1662
  <span className="sr-only">Close</span>
1595
1663
  </DialogPrimitive.Close>
@@ -1628,7 +1696,7 @@ function DialogTitle({
1628
1696
  return (
1629
1697
  <DialogPrimitive.Title
1630
1698
  data-slot="dialog-title"
1631
- className={cn("text-lg leading-none font-semibold", className)}
1699
+ className={cn("font-semibold text-lg leading-none", className)}
1632
1700
  {...props}
1633
1701
  />
1634
1702
  );
@@ -1849,9 +1917,9 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
1849
1917
  type={type}
1850
1918
  data-slot="input"
1851
1919
  className={cn(
1852
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1853
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
1854
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
1920
+ "flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
1921
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
1922
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
1855
1923
  className,
1856
1924
  )}
1857
1925
  {...props}
@@ -1881,7 +1949,7 @@ function Label({
1881
1949
  <LabelPrimitive.Root
1882
1950
  data-slot="label"
1883
1951
  className={cn(
1884
- "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
1952
+ "flex select-none items-center gap-2 font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50",
1885
1953
  className,
1886
1954
  )}
1887
1955
  {...props}
@@ -1937,13 +2005,13 @@ function ResizableHandle({
1937
2005
  <ResizablePrimitive.PanelResizeHandle
1938
2006
  data-slot="resizable-handle"
1939
2007
  className={cn(
1940
- "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
2008
+ "after:-translate-x-1/2 data-[panel-group-direction=vertical]:after:-translate-y-1/2 relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
1941
2009
  className,
1942
2010
  )}
1943
2011
  {...props}
1944
2012
  >
1945
2013
  {withHandle && (
1946
- <div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
2014
+ <div className="z-10 flex h-4 w-3 items-center justify-center rounded-xs border bg-border">
1947
2015
  <GripVerticalIcon className="size-2.5" />
1948
2016
  </div>
1949
2017
  )}
@@ -1986,7 +2054,7 @@ function TabsList({
1986
2054
  <TabsPrimitive.List
1987
2055
  data-slot="tabs-list"
1988
2056
  className={cn(
1989
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
2057
+ "inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-[3px] text-muted-foreground",
1990
2058
  className,
1991
2059
  )}
1992
2060
  {...props}
@@ -2002,7 +2070,7 @@ function TabsTrigger({
2002
2070
  <TabsPrimitive.Trigger
2003
2071
  data-slot="tabs-trigger"
2004
2072
  className={cn(
2005
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2073
+ "inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 font-medium text-foreground text-sm transition-[color,box-shadow] focus-visible:border-ring focus-visible:outline-1 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:shadow-sm dark:text-muted-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
2006
2074
  className,
2007
2075
  )}
2008
2076
  {...props}
@@ -2078,13 +2146,13 @@ function TooltipContent({
2078
2146
  data-slot="tooltip-content"
2079
2147
  sideOffset={sideOffset}
2080
2148
  className={cn(
2081
- "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",
2149
+ "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",
2082
2150
  className,
2083
2151
  )}
2084
2152
  {...props}
2085
2153
  >
2086
2154
  {children}
2087
- <TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
2155
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
2088
2156
  </TooltipPrimitive.Content>
2089
2157
  </TooltipPrimitive.Portal>
2090
2158
  );
@@ -2147,47 +2215,45 @@ export default nextConfig;
2147
2215
  "scripts": {
2148
2216
  "dev": "next dev --turbo",
2149
2217
  "build": "next build",
2150
- "start": "next start",
2151
- "lint": "eslint ."
2218
+ "start": "next start"
2152
2219
  },
2153
2220
  "dependencies": {
2154
- "@ai-sdk/openai": "^2.0.73",
2221
+ "@ai-sdk/openai": "^2.0.84",
2155
2222
  "@assistant-ui/react": "workspace:*",
2156
2223
  "@assistant-ui/react-ai-sdk": "workspace:*",
2157
2224
  "@assistant-ui/react-hook-form": "workspace:*",
2158
2225
  "@assistant-ui/react-markdown": "workspace:*",
2159
2226
  "@hookform/resolvers": "^5.2.2",
2160
- "@radix-ui/react-avatar": "^1.1.4",
2161
- "@radix-ui/react-dialog": "^1.1.7",
2227
+ "@radix-ui/react-avatar": "^1.1.11",
2228
+ "@radix-ui/react-dialog": "^1.1.15",
2162
2229
  "@radix-ui/react-icons": "^1.3.2",
2163
2230
  "@radix-ui/react-label": "^2.1.8",
2164
2231
  "@radix-ui/react-slot": "^1.2.4",
2165
2232
  "@radix-ui/react-tabs": "^1.1.13",
2166
2233
  "@radix-ui/react-tooltip": "^1.2.8",
2167
2234
  "@react-hook/media-query": "^1.1.1",
2168
- "ai": "^5.0.102",
2235
+ "ai": "^5.0.112",
2169
2236
  "class-variance-authority": "^0.7.1",
2170
2237
  "clsx": "^2.1.1",
2171
- "lucide-react": "^0.555.0",
2172
- "motion": "^11.18.2",
2173
- "next": "16.0.4",
2174
- "react": "19.2.0",
2175
- "react-dom": "19.2.0",
2176
- "react-hook-form": "^7.66.1",
2238
+ "lucide-react": "^0.560.0",
2239
+ "next": "16.0.10",
2240
+ "react": "19.2.3",
2241
+ "react-dom": "19.2.3",
2242
+ "react-hook-form": "^7.68.0",
2177
2243
  "react-resizable-panels": "^3.0.6",
2178
2244
  "remark-gfm": "^4.0.1",
2179
2245
  "tailwind-merge": "^3.4.0",
2180
2246
  "tw-animate-css": "^1.4.0",
2181
2247
  "zod": "^4.1.13",
2182
- "zustand": "^5.0.8"
2248
+ "zustand": "^5.0.9"
2183
2249
  },
2184
2250
  "devDependencies": {
2185
2251
  "@assistant-ui/x-buildutils": "workspace:*",
2186
- "@types/node": "^24",
2252
+ "@types/node": "^25",
2187
2253
  "@types/react": "^19",
2188
2254
  "@types/react-dom": "^19",
2189
2255
  "postcss": "^8",
2190
- "tailwindcss": "^4.1.17",
2256
+ "tailwindcss": "^4.1.18",
2191
2257
  "typescript": "^5.9.3"
2192
2258
  }
2193
2259
  }