import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'; import { motion } from 'framer-motion'; import { getStoredGatewayUrl } from '../lib/gateway-client'; import { useConnectionStore } from '../store/connectionStore'; import { useAgentStore, type PluginStatus } from '../store/agentStore'; import { useConfigStore } from '../store/configStore'; import { toChatAgent, useChatStore, type CodeBlock } from '../store/chatStore'; import { useConversationStore } from '../store/chat/conversationStore'; import { intelligenceClient, type IdentitySnapshot } from '../lib/intelligence-client'; import { Wifi, WifiOff, Bot, BarChart3, Plug, RefreshCw, MessageSquare, Cpu, FileText, User, Activity, Brain, Shield, Sparkles, List, Network, Dna, History, ChevronDown, ChevronUp, RotateCcw, AlertCircle, Loader2, ConciergeBell, } from 'lucide-react'; import { ButlerPanel } from './ButlerPanel'; // === Helper to extract code blocks from markdown content === function extractCodeBlocksFromContent(content: string): CodeBlock[] { const blocks: CodeBlock[] = []; const regex = /```(\w*)\n([\s\S]*?)```/g; let match; while ((match = regex.exec(content)) !== null) { const language = match[1] || 'text'; const codeContent = match[2].trim(); // Try to extract filename from first line comment let filename: string | undefined; let actualContent = codeContent; // Check for filename patterns like "# filename.py" or "// filename.js" const firstLine = codeContent.split('\n')[0]; const filenameMatch = firstLine.match(/^(?:#|\/\/|\/\*|