Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 49 additions & 47 deletions components/assistant-ui/thread.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
import {
ActionBarPrimitive,
BranchPickerPrimitive,
ComposerPrimitive,
ErrorPrimitive,
MessagePrimitive,
ThreadPrimitive,
} from "@assistant-ui/react";
import {
ArrowDownIcon,
ArrowUpIcon,
Expand All @@ -17,20 +9,31 @@ import {
RefreshCwIcon,
Square,
} from "lucide-react";

import {
ActionBarPrimitive,
BranchPickerPrimitive,
ComposerPrimitive,
ErrorPrimitive,
MessagePrimitive,
ThreadPrimitive,
} from "@assistant-ui/react";

import type { FC } from "react";
import { LazyMotion, MotionConfig, domAnimation } from "motion/react";
import * as m from "motion/react-m";

import { Button } from "@/components/ui/button";
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
import {
ComposerAddAttachment,
ComposerAttachments,
UserMessageAttachments,
} from "@/components/assistant-ui/attachment";
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
import { Button } from "@/components/ui/button";

import { cn } from "@/lib/utils";
import { LazyMotion, MotionConfig, domAnimation } from "motion/react";
import * as m from "motion/react-m";

export const Thread: FC = () => {
return (
Expand All @@ -43,7 +46,9 @@ export const Thread: FC = () => {
}}
>
<ThreadPrimitive.Viewport className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4">
<ThreadWelcome />
<ThreadPrimitive.If empty>
<ThreadWelcome />
</ThreadPrimitive.If>

<ThreadPrimitive.Messages
components={{
Expand All @@ -52,9 +57,11 @@ export const Thread: FC = () => {
AssistantMessage,
}}
/>

<ThreadPrimitive.If empty={false}>
<div className="aui-thread-viewport-spacer min-h-8 grow" />
</ThreadPrimitive.If>

<Composer />
</ThreadPrimitive.Viewport>
</ThreadPrimitive.Root>
Expand All @@ -79,37 +86,36 @@ const ThreadScrollToBottom: FC = () => {

const ThreadWelcome: FC = () => {
return (
<ThreadPrimitive.Empty>
<div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
<div className="aui-thread-welcome-center flex w-full flex-grow flex-col items-center justify-center">
<div className="aui-thread-welcome-message flex size-full flex-col justify-center px-8">
<m.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
className="aui-thread-welcome-message-motion-1 text-2xl font-semibold"
>
Hello there!
</m.div>
<m.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ delay: 0.1 }}
className="aui-thread-welcome-message-motion-2 text-2xl text-muted-foreground/65"
>
How can I help you today?
</m.div>
</div>
<div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
<div className="aui-thread-welcome-center flex w-full flex-grow flex-col items-center justify-center">
<div className="aui-thread-welcome-message flex size-full flex-col justify-center px-8">
<m.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
className="aui-thread-welcome-message-motion-1 text-2xl font-semibold"
>
Hello there!
</m.div>
<m.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ delay: 0.1 }}
className="aui-thread-welcome-message-motion-2 text-2xl text-muted-foreground/65"
>
How can I help you today?
</m.div>
</div>
</div>
</ThreadPrimitive.Empty>
<ThreadSuggestions />
</div>
);
};

const ThreadWelcomeSuggestions: FC = () => {
const ThreadSuggestions: FC = () => {
return (
<div className="aui-thread-welcome-suggestions grid w-full gap-2 @md:grid-cols-2">
<div className="aui-thread-welcome-suggestions grid w-full gap-2 pb-4 @md:grid-cols-2">
{[
{
title: "What's the weather",
Expand Down Expand Up @@ -142,8 +148,7 @@ const ThreadWelcomeSuggestions: FC = () => {
>
<ThreadPrimitive.Suggestion
prompt={suggestedAction.action}
method="replace"
autoSend
send
asChild
>
<Button
Expand All @@ -169,9 +174,6 @@ const Composer: FC = () => {
return (
<div className="aui-composer-wrapper sticky bottom-0 mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6">
<ThreadScrollToBottom />
<ThreadPrimitive.Empty>
<ThreadWelcomeSuggestions />
</ThreadPrimitive.Empty>
<ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col rounded-3xl border border-border bg-muted px-1 pt-2 shadow-[0_9px_9px_0px_rgba(0,0,0,0.01),0_2px_5px_0px_rgba(0,0,0,0.06)] dark:border-muted-foreground/15">
<ComposerAttachments />
<ComposerPrimitive.Input
Expand Down Expand Up @@ -239,7 +241,7 @@ const AssistantMessage: FC = () => {
return (
<MessagePrimitive.Root asChild>
<div
className="aui-assistant-message-root relative mx-auto w-full max-w-[var(--thread-max-width)] animate-in py-4 duration-200 fade-in slide-in-from-bottom-1 last:mb-24"
className="aui-assistant-message-root relative mx-auto w-full max-w-[var(--thread-max-width)] animate-in py-4 duration-150 ease-out fade-in slide-in-from-bottom-1 last:mb-24"
data-role="assistant"
>
<div className="aui-assistant-message-content mx-2 leading-7 break-words text-foreground">
Expand Down Expand Up @@ -292,7 +294,7 @@ const UserMessage: FC = () => {
return (
<MessagePrimitive.Root asChild>
<div
className="aui-user-message-root mx-auto grid w-full max-w-[var(--thread-max-width)] animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 px-2 py-4 duration-200 fade-in slide-in-from-bottom-1 first:mt-3 last:mb-5 [&:where(>*)]:col-start-2"
className="aui-user-message-root mx-auto grid w-full max-w-[var(--thread-max-width)] animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 px-2 py-4 duration-150 ease-out fade-in slide-in-from-bottom-1 first:mt-3 last:mb-5 [&:where(>*)]:col-start-2"
data-role="user"
>
<UserMessageAttachments />
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"tailwindStylesheet": "app/globals.css"
},
"dependencies": {
"@assistant-ui/react": "^0.11.15",
"@assistant-ui/react-langgraph": "^0.6.9",
"@assistant-ui/react": "^0.11.24",
"@assistant-ui/react-langgraph": "^0.7.0",
"@assistant-ui/react-markdown": "^0.11.0",
"@langchain/langgraph-sdk": "^0.1.6",
"@langchain/langgraph-sdk": "^0.1.9",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-separator": "^1.1.7",
Expand All @@ -29,13 +29,13 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.544.0",
"motion": "^12.23.19",
"motion": "^12.23.22",
"next": "15.5.4",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"remark-gfm": "^4.0.1",
"tailwind-merge": "^3.3.1",
"tw-animate-css": "^1.3.8",
"tw-animate-css": "^1.4.0",
"zustand": "^5.0.8"
},
"devDependencies": {
Expand Down
Loading