import { useMemo } from 'react' import { Dialog, DialogTitle, DialogContent, IconButton, Box, } from '@mui/material' import { Close } from '@mui/icons-material' import { CopyButton } from '../../components/copy-button/copy-button' import type { ChatToolFullViewDialogProps } from '../types' import { styles } from './styles' interface Token { type: 'key' | 'string' | 'number' | 'boolean' | 'null' | 'punctuation' value: string } const NUMBER_START_REGEX = /^-?\d/ function tokenizeLine(line: string): (Token | string)[] { const tokens: (Token | string)[] = [] let lastIndex = 0 let match: RegExpExecArray | null // First, find all key positions by looking for "...": patterns const keyPositions = new Set() const keyRegex = /("(?:[^"\\]|\\.)*")\s*:/g let keyMatch: RegExpExecArray | null while ((keyMatch = keyRegex.exec(line)) !== null) { keyPositions.add(keyMatch.index) } const tokenRegex = // eslint-disable-next-line no-useless-escape /"(?:[^"\\]|\\.)*"|\b(?:true|false)\b|\bnull\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[{}\[\]:,]/g while ((match = tokenRegex.exec(line)) !== null) { if (match.index > lastIndex) { tokens.push(line.slice(lastIndex, match.index)) } const value = match[0] if (value.startsWith('"')) { if (keyPositions.has(match.index)) { tokens.push({ type: 'key', value }) } else { tokens.push({ type: 'string', value }) } } else if (NUMBER_START_REGEX.test(value)) { tokens.push({ type: 'number', value }) } else if (value === 'true' || value === 'false') { tokens.push({ type: 'boolean', value }) } else if (value === 'null') { tokens.push({ type: 'null', value }) } else { tokens.push({ type: 'punctuation', value }) } lastIndex = match.index + value.length } if (lastIndex < line.length) { tokens.push(line.slice(lastIndex)) } return tokens } export function ChatToolFullViewDialog({ open, onClose, title, content, }: ChatToolFullViewDialogProps) { const tokenizedLines = useMemo( () => content.split('\n').map((line) => tokenizeLine(line)), [content], ) return ( {title} {tokenizedLines.map((tokens, i) => ( {tokens.map((token, j) => typeof token === 'string' ? ( token ) : ( {token.value} ), )} {'\n'} ))} ) }