// 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 remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math'; import { cn } from '@/lib/utils'; import { CodeBlock } from '@/components/ui/CodeBlock'; import { MemoizedReactMarkdown } from '@/components/chat/MemoizedReactMarkdown'; import { IconOpenAI, IconUser } from '@/components/ui/Icons'; import { ChatMessageActions } from '@/components/chat/ChatMessageActions'; import { MessageBase } from '../../lib/types'; export interface ChatMessageProps { message: MessageBase; } const PAIRS: Record = { '┍': '┑', '┝': '┥', '├': '┤', '┕': '┙', }; const MIDDLE_STARTER = '┝'; const MIDDLE_SEPARATOR = '┿'; export function ChatMessage({ message, ...props }: ChatMessageProps) { const cleanupMessage = ({ content, role }: MessageBase) => { if (role === 'user') { return { content, }; } const [logs = '', answer = ''] = content.split(''); const cleanedLogs = []; let left = 0; let right = 0; while (right < logs.length) { if (Object.keys(PAIRS).includes(content[right])) { cleanedLogs.push(content.substring(left, right)); left = right++; while ( right < content.length && PAIRS[content[left]] !== content[right] ) { right++; } if (content[left] === MIDDLE_STARTER) { // add the text alignment so it can be shown as a table const separators = logs .substring(left, right) .split(MIDDLE_SEPARATOR).length; if (separators > 0) { cleanedLogs.push( Array(separators + 1) .fill('|') .join(' :- '), ); } } left = ++right; } else { right++; } } cleanedLogs.push(content.substring(left, right)); return { logs: cleanedLogs .join('') .replace(/│/g, '|') .split('|\n\n|') .join('|\n|'), content: answer.replace('', '').replace('', ''), }; }; const { logs, content } = cleanupMessage(message); return (
{message.role === 'user' ? : }
{logs && message.role !== 'user' && (
Thinking Process
{children}

); }, code({ children, ...props }) { return ( {children} ); }, }} > {logs}
)} {children}

); }, code({ node, inline, className, children, ...props }) { if (children.length) { if (children[0] == '▍') { return ( ); } children[0] = (children[0] as string).replace('`▍`', '▍'); } const match = /language-(\w+)/.exec(className || ''); if (inline) { return ( {children} ); } return ( ); }, }} > {content}
); }