'use client'; import type { Attachment, UIMessage } from 'ai'; import { useChat } from '@ai-sdk/react'; import { useEffect, useState } from 'react'; import useSWR, { useSWRConfig } from 'swr'; import { ChatHeader } from '@/components/chat-header'; import type { Vote } from '@/lib/db/schema'; import { fetcher, generateUUID } from '@/lib/utils'; import { Artifact } from './artifact'; import { MultimodalInput } from './multimodal-input'; import { Messages } from './messages'; import type { VisibilityType } from './visibility-selector'; import { useArtifactSelector } from '@/hooks/use-artifact'; import { unstable_serialize } from 'swr/infinite'; import { getChatHistoryPaginationKey } from './sidebar-history'; import { toast } from './toast'; import type { Session } from 'next-auth'; import { useSearchParams } from 'next/navigation'; import { useChatVisibility } from '@/hooks/use-chat-visibility'; export function Chat({ id, initialMessages, initialChatModel, initialVisibilityType, isReadonly, session, autoResume, }: { id: string; initialMessages: Array; initialChatModel: string; initialVisibilityType: VisibilityType; isReadonly: boolean; session: Session; autoResume: boolean; }) { const { mutate } = useSWRConfig(); const { visibilityType } = useChatVisibility({ chatId: id, initialVisibilityType, }); const { messages, setMessages, handleSubmit, input, setInput, append, status, stop, reload, experimental_resume, } = useChat({ id, initialMessages, experimental_throttle: 100, sendExtraMessageFields: true, generateId: generateUUID, experimental_prepareRequestBody: (body) => ({ id, message: body.messages.at(-1), selectedChatModel: initialChatModel, selectedVisibilityType: visibilityType, }), onFinish: () => { mutate(unstable_serialize(getChatHistoryPaginationKey)); }, onError: (error) => { toast({ type: 'error', description: error.message, }); }, }); useEffect(() => { if (autoResume) { experimental_resume(); } // note: this hook has no dependencies since it only needs to run once // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const searchParams = useSearchParams(); const query = searchParams.get('query'); const [hasAppendedQuery, setHasAppendedQuery] = useState(false); useEffect(() => { if (query && !hasAppendedQuery) { append({ role: 'user', content: query, }); setHasAppendedQuery(true); window.history.replaceState({}, '', `/chat/${id}`); } }, [query, append, hasAppendedQuery, id]); const { data: votes } = useSWR>( messages.length >= 2 ? `/api/vote?chatId=${id}` : null, fetcher, ); const [attachments, setAttachments] = useState>([]); const isArtifactVisible = useArtifactSelector((state) => state.isVisible); return ( <>
{!isReadonly && ( )}
); }