'use client'; import type { UIMessage } from 'ai'; import cx from 'classnames'; import { AnimatePresence, motion } from 'framer-motion'; import { memo, useState } from 'react'; import type { Vote } from '@/lib/db/schema'; import { DocumentToolCall, DocumentToolResult } from './document'; import { PencilEditIcon, SparklesIcon } from './icons'; import { Markdown } from './markdown'; import { MessageActions } from './message-actions'; import { PreviewAttachment } from './preview-attachment'; import { Weather } from './weather'; import equal from 'fast-deep-equal'; import { cn, sanitizeText } from '@/lib/utils'; import { Button } from './ui/button'; import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; import { MessageEditor } from './message-editor'; import { DocumentPreview } from './document-preview'; import { MessageReasoning } from './message-reasoning'; import type { UseChatHelpers } from '@ai-sdk/react'; const PurePreviewMessage = ({ chatId, message, vote, isLoading, setMessages, reload, isReadonly, requiresScrollPadding, }: { chatId: string; message: UIMessage; vote: Vote | undefined; isLoading: boolean; setMessages: UseChatHelpers['setMessages']; reload: UseChatHelpers['reload']; isReadonly: boolean; requiresScrollPadding: boolean; }) => { const [mode, setMode] = useState<'view' | 'edit'>('view'); return (
{message.role === 'assistant' && (
)}
{message.experimental_attachments && message.experimental_attachments.length > 0 && (
{message.experimental_attachments.map((attachment) => ( ))}
)} {message.parts?.map((part, index) => { const { type } = part; const key = `message-${message.id}-part-${index}`; if (type === 'reasoning') { return ( ); } if (type === 'text') { if (mode === 'view') { return (
{message.role === 'user' && !isReadonly && ( Edit message )}
{sanitizeText(part.text)}
); } if (mode === 'edit') { return (
); } } if (type === 'tool-invocation') { const { toolInvocation } = part; const { toolName, toolCallId, state } = toolInvocation; if (state === 'call') { const { args } = toolInvocation; return (
{toolName === 'getWeather' ? ( ) : toolName === 'createDocument' ? ( ) : toolName === 'updateDocument' ? ( ) : toolName === 'requestSuggestions' ? ( ) : null}
); } if (state === 'result') { const { result } = toolInvocation; return (
{toolName === 'getWeather' ? ( ) : toolName === 'createDocument' ? ( ) : toolName === 'updateDocument' ? ( ) : toolName === 'requestSuggestions' ? ( ) : (
{JSON.stringify(result, null, 2)}
)}
); } } })} {!isReadonly && ( )}
); }; export const PreviewMessage = memo( PurePreviewMessage, (prevProps, nextProps) => { if (prevProps.isLoading !== nextProps.isLoading) return false; if (prevProps.message.id !== nextProps.message.id) return false; if (prevProps.requiresScrollPadding !== nextProps.requiresScrollPadding) return false; if (!equal(prevProps.message.parts, nextProps.message.parts)) return false; if (!equal(prevProps.vote, nextProps.vote)) return false; return true; }, ); export const ThinkingMessage = () => { const role = 'assistant'; return (
Hmm...
); };