import React, { useRef, useState, useCallback, useEffect } from 'react'; import { CircleDashed, CheckCircle, AlertTriangle } from 'lucide-react'; import { UnifiedMessage, ParsedContent, ParsedMetadata } from '@/components/thread/types'; import { FileAttachmentGrid } from '@/components/thread/file-attachment'; import { useFilePreloader } from '@/hooks/react-query/files'; import { useAuth } from '@/components/AuthProvider'; import { Project } from '@/lib/api'; import { extractPrimaryParam, getToolIcon, getUserFriendlyToolName, safeJsonParse, } from '@/components/thread/utils'; import { KortixLogo } from '@/components/sidebar/kortix-logo'; import { AgentLoader } from './loader'; import { AgentAvatar, AgentName } from './agent-avatar'; import { parseXmlToolCalls, isNewXmlFormat } from '@/components/thread/tool-views/xml-parser'; import { ShowToolStream } from './ShowToolStream'; import { ComposioUrlDetector } from './composio-url-detector'; import { HIDE_STREAMING_XML_TAGS } from '@/components/thread/utils'; // Helper function to render all attachments as standalone messages export function renderStandaloneAttachments(attachments: string[], fileViewerHandler?: (filePath?: string, filePathList?: string[]) => void, sandboxId?: string, project?: Project, alignRight: boolean = false) { if (!attachments || attachments.length === 0) return null; // Filter out empty strings and check if we have any valid attachments const validAttachments = attachments.filter(attachment => attachment && attachment.trim() !== ''); if (validAttachments.length === 0) return null; return (
{content}
);
}
if (isNewXmlFormat(content)) {
const contentParts: React.ReactNode[] = [];
let lastIndex = 0;
// Find all function_calls blocks
const functionCallsRegex = /
{message.content}
{groupAgentId ? (
{JSON.stringify(message.content, null, 2)}
{message.metadata && message.metadata !== '{}' && (
{JSON.stringify(message.metadata, null, 2)}
{streamingTextContent}
);
}
let detectedTag: string | null = null;
let tagStartIndex = -1;
if (streamingTextContent) {
// First check for new format
const functionCallsIndex = streamingTextContent.indexOf('
{streamingText}
) : (
<>
{textBeforeTag && (
{getAgentInfo().name}
{getAgentInfo().name}
{getAgentInfo().name}