Spaces:
Running
Running
| // Inspired by Chatbot-UI and modified to fit the needs of this project | |
| // @see https://github.com/mckaywrigley/chatbot-ui/blob/main/components/Chat/ChatMessage.tsx | |
| import { Message } from 'ai'; | |
| import remarkGfm from 'remark-gfm'; | |
| import remarkMath from 'remark-math'; | |
| import { cn } from '@/lib/utils'; | |
| import { CodeBlock } from '@/components/ui/codeblock'; | |
| import { MemoizedReactMarkdown } from '@/components/markdown'; | |
| import { IconOpenAI, IconUser } from '@/components/ui/icons'; | |
| import { ChatMessageActions } from '@/components/chat-message-actions'; | |
| export interface ChatMessageProps { | |
| message: Message; | |
| } | |
| export function ChatMessage({ message, ...props }: ChatMessageProps) { | |
| return ( | |
| <div className={cn('group relative mb-4 flex items-start')} {...props}> | |
| <div | |
| className={cn( | |
| 'flex size-8 shrink-0 select-none items-center justify-center rounded-md border shadow', | |
| message.role === 'user' | |
| ? 'bg-background' | |
| : 'bg-primary text-primary-foreground', | |
| )} | |
| > | |
| {message.role === 'user' ? <IconUser /> : <IconOpenAI />} | |
| </div> | |
| <div className="flex-1 px-1 ml-4 space-y-2 overflow-hidden"> | |
| <MemoizedReactMarkdown | |
| className="prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0" | |
| remarkPlugins={[remarkGfm, remarkMath]} | |
| components={{ | |
| p({ children }) { | |
| return <p className="mb-2 last:mb-0">{children}</p>; | |
| }, | |
| code({ node, inline, className, children, ...props }) { | |
| if (children.length) { | |
| if (children[0] == 'β') { | |
| return ( | |
| <span className="mt-1 cursor-default animate-pulse">β</span> | |
| ); | |
| } | |
| children[0] = (children[0] as string).replace('`β`', 'β'); | |
| } | |
| const match = /language-(\w+)/.exec(className || ''); | |
| if (inline) { | |
| return ( | |
| <code className={className} {...props}> | |
| {children} | |
| </code> | |
| ); | |
| } | |
| return ( | |
| <CodeBlock | |
| key={Math.random()} | |
| language={(match && match[1]) || ''} | |
| value={String(children).replace(/\n$/, '')} | |
| {...props} | |
| /> | |
| ); | |
| }, | |
| }} | |
| > | |
| {message.content} | |
| </MemoizedReactMarkdown> | |
| <ChatMessageActions message={message} /> | |
| </div> | |
| </div> | |
| ); | |
| } | |