import React, { useMemo, useState } from 'react'; import { useRecoilValue } from 'recoil'; import type { TAttachment } from 'librechat-data-provider'; import ProgressText from '~/components/Chat/Messages/Content/ProgressText'; import FinishedIcon from '~/components/Chat/Messages/Content/FinishedIcon'; import MarkdownLite from '~/components/Chat/Messages/Content/MarkdownLite'; import { CodeInProgress } from './CodeProgress'; import Attachment from './Attachment'; import LogContent from './LogContent'; import { useProgress } from '~/hooks'; import store from '~/store'; interface ParsedArgs { lang: string; code: string; } export function useParseArgs(args: string): ParsedArgs { return useMemo(() => { const langMatch = args.match(/"lang"\s*:\s*"(\w+)"/); const codeMatch = args.match(/"code"\s*:\s*"(.+?)(?="\s*,\s*"args"|$)/s); let code = ''; if (codeMatch) { code = codeMatch[1]; if (code.endsWith('"}')) { code = code.slice(0, -2); } code = code.replace(/\\n/g, '\n').replace(/\\/g, ''); } return { lang: langMatch ? langMatch[1] : '', code, }; }, [args]); } export default function ExecuteCode({ initialProgress = 0.1, args, output = '', isSubmitting, attachments, }: { initialProgress: number; args: string; output?: string; isSubmitting: boolean; attachments?: TAttachment[]; }) { const showAnalysisCode = useRecoilValue(store.showCode); const [showCode, setShowCode] = useState(showAnalysisCode); const { lang, code } = useParseArgs(args); const progress = useProgress(initialProgress); const radius = 56.08695652173913; const circumference = 2 * Math.PI * radius; const offset = circumference - progress * circumference; return ( <>