diff --git a/components/artifact-messages.tsx b/components/artifact-messages.tsx index b7cddaa..e4097d4 100644 --- a/components/artifact-messages.tsx +++ b/components/artifact-messages.tsx @@ -1,29 +1,26 @@ import { PreviewMessage } from './message'; import { useScrollToBottom } from './use-scroll-to-bottom'; import { Vote } from '@/lib/db/schema'; -import { ChatRequestOptions, Message } from 'ai'; +import { Message } from 'ai'; import { memo } from 'react'; import equal from 'fast-deep-equal'; import { UIArtifact } from './artifact'; +import { UseChatHelpers } from '@ai-sdk/react'; interface ArtifactMessagesProps { chatId: string; - isLoading: boolean; + status: UseChatHelpers['status']; votes: Array | undefined; messages: Array; - setMessages: ( - messages: Message[] | ((messages: Message[]) => Message[]), - ) => void; - reload: ( - chatRequestOptions?: ChatRequestOptions, - ) => Promise; + setMessages: UseChatHelpers['setMessages']; + reload: UseChatHelpers['reload']; isReadonly: boolean; artifactStatus: UIArtifact['status']; } function PureArtifactMessages({ chatId, - isLoading, + status, votes, messages, setMessages, @@ -43,8 +40,7 @@ function PureArtifactMessages({ chatId={chatId} key={message.id} message={message} - isLoading={isLoading && index === messages.length - 1} - index={index} + isLoading={status === 'streaming' && index === messages.length - 1} vote={ votes ? votes.find((vote) => vote.messageId === message.id) @@ -74,8 +70,8 @@ function areEqual( ) return true; - if (prevProps.isLoading !== nextProps.isLoading) return false; - if (prevProps.isLoading && nextProps.isLoading) return false; + if (prevProps.status !== nextProps.status) return false; + if (prevProps.status && nextProps.status) return false; if (prevProps.messages.length !== nextProps.messages.length) return false; if (!equal(prevProps.votes, nextProps.votes)) return false; diff --git a/components/artifact.tsx b/components/artifact.tsx index 5be9f1a..ec7a7b5 100644 --- a/components/artifact.tsx +++ b/components/artifact.tsx @@ -1,9 +1,4 @@ -import type { - Attachment, - ChatRequestOptions, - CreateMessage, - Message, -} from 'ai'; +import type { Attachment, Message } from 'ai'; import { formatDistance } from 'date-fns'; import { AnimatePresence, motion } from 'framer-motion'; import { @@ -31,6 +26,7 @@ import { codeArtifact } from '@/artifacts/code/client'; import { sheetArtifact } from '@/artifacts/sheet/client'; import { textArtifact } from '@/artifacts/text/client'; import equal from 'fast-deep-equal'; +import { UseChatHelpers } from '@ai-sdk/react'; export const artifactDefinitions = [ textArtifact, @@ -60,7 +56,7 @@ function PureArtifact({ input, setInput, handleSubmit, - isLoading, + status, stop, attachments, setAttachments, @@ -73,27 +69,17 @@ function PureArtifact({ }: { chatId: string; input: string; - setInput: (input: string) => void; - isLoading: boolean; - stop: () => void; + setInput: UseChatHelpers['setInput']; + status: UseChatHelpers['status']; + stop: UseChatHelpers['stop']; attachments: Array; setAttachments: Dispatch>>; messages: Array; setMessages: Dispatch>>; votes: Array | undefined; - append: ( - message: Message | CreateMessage, - chatRequestOptions?: ChatRequestOptions, - ) => Promise; - handleSubmit: ( - event?: { - preventDefault?: () => void; - }, - chatRequestOptions?: ChatRequestOptions, - ) => void; - reload: ( - chatRequestOptions?: ChatRequestOptions, - ) => Promise; + append: UseChatHelpers['append']; + handleSubmit: UseChatHelpers['handleSubmit']; + reload: UseChatHelpers['reload']; isReadonly: boolean; }) { const { artifact, setArtifact, metadata, setMetadata } = useArtifact(); @@ -326,7 +312,7 @@ function PureArtifact({
{ - if (prevProps.isLoading !== nextProps.isLoading) return false; + if (prevProps.status !== nextProps.status) return false; if (!equal(prevProps.votes, nextProps.votes)) return false; if (prevProps.input !== nextProps.input) return false; if (!equal(prevProps.messages, nextProps.messages.length)) return false; diff --git a/components/chat.tsx b/components/chat.tsx index 4a5f236..2f40593 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -36,7 +36,7 @@ export function Chat({ input, setInput, append, - isLoading, + status, stop, reload, } = useChat({ @@ -74,7 +74,7 @@ export function Chat({ Promise; isReadonly: boolean; - index: number; }) => { const [mode, setMode] = useState<'view' | 'edit'>('view'); diff --git a/components/messages.tsx b/components/messages.tsx index 5e801d0..18c7785 100644 --- a/components/messages.tsx +++ b/components/messages.tsx @@ -1,29 +1,26 @@ -import { ChatRequestOptions, Message } from 'ai'; +import { Message } from 'ai'; import { PreviewMessage, ThinkingMessage } from './message'; import { useScrollToBottom } from './use-scroll-to-bottom'; import { Overview } from './overview'; import { memo } from 'react'; import { Vote } from '@/lib/db/schema'; import equal from 'fast-deep-equal'; +import { UseChatHelpers } from '@ai-sdk/react'; interface MessagesProps { chatId: string; - isLoading: boolean; + status: UseChatHelpers['status']; votes: Array | undefined; messages: Array; - setMessages: ( - messages: Message[] | ((messages: Message[]) => Message[]), - ) => void; - reload: ( - chatRequestOptions?: ChatRequestOptions, - ) => Promise; + setMessages: UseChatHelpers['setMessages']; + reload: UseChatHelpers['reload']; isReadonly: boolean; isArtifactVisible: boolean; } function PureMessages({ chatId, - isLoading, + status, votes, messages, setMessages, @@ -43,10 +40,9 @@ function PureMessages({ {messages.map((message, index) => ( vote.messageId === message.id) @@ -58,7 +54,7 @@ function PureMessages({ /> ))} - {isLoading && + {status === 'submitted' && messages.length > 0 && messages[messages.length - 1].role === 'user' && } @@ -73,8 +69,8 @@ function PureMessages({ export const Messages = memo(PureMessages, (prevProps, nextProps) => { if (prevProps.isArtifactVisible && nextProps.isArtifactVisible) return true; - if (prevProps.isLoading !== nextProps.isLoading) return false; - if (prevProps.isLoading && nextProps.isLoading) return false; + if (prevProps.status !== nextProps.status) return false; + if (prevProps.status && nextProps.status) return false; if (prevProps.messages.length !== nextProps.messages.length) return false; if (!equal(prevProps.messages, nextProps.messages)) return false; if (!equal(prevProps.votes, nextProps.votes)) return false; diff --git a/components/multimodal-input.tsx b/components/multimodal-input.tsx index 2eeb93c..74c2a80 100644 --- a/components/multimodal-input.tsx +++ b/components/multimodal-input.tsx @@ -29,12 +29,13 @@ import { Button } from './ui/button'; import { Textarea } from './ui/textarea'; import { SuggestedActions } from './suggested-actions'; import equal from 'fast-deep-equal'; +import { UseChatHelpers, UseChatOptions } from '@ai-sdk/react'; function PureMultimodalInput({ chatId, input, setInput, - isLoading, + status, stop, attachments, setAttachments, @@ -45,24 +46,16 @@ function PureMultimodalInput({ className, }: { chatId: string; - input: string; - setInput: (value: string) => void; - isLoading: boolean; + input: UseChatHelpers['input']; + setInput: UseChatHelpers['setInput']; + status: UseChatHelpers['status']; stop: () => void; attachments: Array; setAttachments: Dispatch>>; messages: Array; setMessages: Dispatch>>; - append: ( - message: Message | CreateMessage, - chatRequestOptions?: ChatRequestOptions, - ) => Promise; - handleSubmit: ( - event?: { - preventDefault?: () => void; - }, - chatRequestOptions?: ChatRequestOptions, - ) => void; + append: UseChatHelpers['append']; + handleSubmit: UseChatHelpers['handleSubmit']; className?: string; }) { const textareaRef = useRef(null); @@ -253,7 +246,7 @@ function PureMultimodalInput({ ) { event.preventDefault(); - if (isLoading) { + if (status !== 'ready') { toast.error('Please wait for the model to finish its response!'); } else { submitForm(); @@ -263,11 +256,11 @@ function PureMultimodalInput({ />
- +
- {isLoading ? ( + {status === 'submitted' ? ( ) : ( { if (prevProps.input !== nextProps.input) return false; - if (prevProps.isLoading !== nextProps.isLoading) return false; + if (prevProps.status !== nextProps.status) return false; if (!equal(prevProps.attachments, nextProps.attachments)) return false; return true; @@ -294,10 +287,10 @@ export const MultimodalInput = memo( function PureAttachmentsButton({ fileInputRef, - isLoading, + status, }: { fileInputRef: React.MutableRefObject; - isLoading: boolean; + status: UseChatHelpers['status']; }) { return (