<html><head><base href="blob:https://party.websim.ai/f044f1aa-28e1-467f-989e-abf9ac58ea88"> <title>Echo AI - Advanced Enterprise Intelligence Platform</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap'); :root { --primary-color: #6366f1; --secondary-color: #4f46e5; --background-color: #0f172a; --surface-color: #1e293b; --text-color: #f8fafc; --text-color-muted: #94a3b8; --message-bg-user: #334155; --message-bg-bot: #1e293b; --error-color: #ef4444; --success-color: #22c55e; } * { box-sizing: border-box; } body, html { margin: 0; padding: 0; font-family: 'Inter', sans-serif; height: 100%; background-color: var(--background-color); color: var(--text-color); line-height: 1.6; } .chat-container { display: flex; flex-direction: column; height: 100vh; width: 100%; max-width: 100%; margin: 0 auto; background-color: var(--surface-color); box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .chat-header { display: flex; align-items: center; padding: 1rem; background-color: rgba(255, 255, 255, 0.05); border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .chat-header h1 { margin: 0; font-size: 1.25rem; font-weight: 600; color: var(--text-color); } .chat-header .model-info { margin-left: auto; font-size: 0.75rem; color: var(--text-color-muted); } .chat-messages { flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 1rem; } .message { max-width: 85%; padding: 0.75rem; border-radius: 0.5rem; animation: fadeIn 0.3s ease-out; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); font-size: 0.9rem; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .user-message { background-color: var(--message-bg-user); align-self: flex-end; border-bottom-right-radius: 0; } .bot-message { background-color: var(--message-bg-bot); align-self: flex-start; border-bottom-left-radius: 0; border-left: 4px solid var(--primary-color); } .input-area { display: flex; padding: 0.75rem; background-color: rgba(255, 255, 255, 0.05); border-top: 1px solid rgba(255, 255, 255, 0.1); position: sticky; bottom: 0; } .input-wrapper { position: relative; flex-grow: 1; display: flex; align-items: center; } #user-input, #chat-user-input { width: 100%; padding: 0.5rem 3rem 0.5rem 0.75rem; border: 2px solid rgba(255, 255, 255, 0.2); border-radius: 0.5rem; background-color: rgba(255, 255, 255, 0.05); color: var(--text-color); resize: none; font-size: 0.9rem; line-height: 1.5; transition: all 0.3s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); min-height: 2.5rem; max-height: 10rem; overflow-y: auto; } #user-input:focus, #chat-user-input:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2); } #send-button, #chat-send-button { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); padding: 0.4rem 0.75rem; background-color: var(--primary-color); color: white; border: none; border-radius: 0.5rem; cursor: pointer; font-size: 0.85rem; font-weight: 500; transition: all 0.3s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } #send-button:hover, #chat-send-button:hover { background-color: var(--secondary-color); transform: translateY(-50%) scale(1.05); } #send-button:active, #chat-send-button:active { transform: translateY(-50%) scale(0.95); } .code-block { background-color: rgba(0, 0, 0, 0.3); color: #e0e0e0; padding: 0.75rem; border-radius: 0.375rem; font-family: 'Fira Code', monospace; font-size: 0.85rem; line-height: 1.6; white-space: pre-wrap; overflow-x: auto; margin: 0.75rem 0; border-left: 3px solid var(--primary-color); } .central-prompt { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; padding: 1rem; } .central-prompt h2 { font-size: 1.25rem; margin-bottom: 1rem; color: var(--text-color); font-weight: 500; } .central-prompt .input-area { width: 100%; max-width: 600px; background: none; border: none; padding: 0; } .logo { width: 60px; height: 60px; margin-bottom: 1rem; } ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: var(--surface-color); } ::-webkit-scrollbar-thumb { background: var(--primary-color); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--secondary-color); } .typing-indicator { display: flex; padding: 0.5rem; background: var(--message-bg-bot); border-radius: 0.375rem; margin-bottom: 0.5rem; align-items: center; align-self: flex-start; } .typing-indicator span { height: 6px; width: 6px; background: var(--text-color-muted); border-radius: 50%; display: inline-block; margin-right: 4px; animation: pulse 1.5s infinite ease-in-out; } .typing-indicator span:nth-child(2) { animation-delay: 0.2s; } .typing-indicator span:nth-child(3) { animation-delay: 0.4s; } @keyframes pulse { 0% { transform: scale(0.8); opacity: 0.5; } 50% { transform: scale(1.2); opacity: 1; } 100% { transform: scale(0.8); opacity: 0.5; } } .menu-icon { cursor: pointer; margin-left: 0.75rem; font-size: 1.25rem; color: var(--text-color-muted); transition: color 0.3s ease; } .menu-icon:hover { color: var(--text-color); } .dropdown-menu { position: absolute; top: 3.5rem; right: 0.75rem; background-color: var(--surface-color); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 0.375rem; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); display: none; z-index: 10; } .dropdown-menu.show { display: block; } .dropdown-menu button { display: block; width: 100%; padding: 0.6rem 0.75rem; text-align: left; background: none; border: none; color: var(--text-color); cursor: pointer; transition: background-color 0.3s ease; font-size: 0.9rem; } .dropdown-menu button:hover { background-color: rgba(255, 255, 255, 0.05); } @media (max-width: 768px) { .chat-header h1 { font-size: 1.1rem; } .message { max-width: 90%; font-size: 0.85rem; } .central-prompt h2 { font-size: 1.1rem; } .code-block { font-size: 0.8rem; } #send-button, #chat-send-button { padding: 0.35rem 0.6rem; font-size: 0.8rem; } } @media (max-width: 480px) { .chat-header h1 { font-size: 1rem; } .chat-header .model-info { font-size: 0.7rem; } .message { max-width: 95%; font-size: 0.8rem; padding: 0.6rem; } .central-prompt h2 { font-size: 1rem; } .logo { width: 50px; height: 50px; } #user-input, #chat-user-input { font-size: 0.85rem; padding: 0.4rem 2.5rem 0.4rem 0.6rem; } #send-button, #chat-send-button { padding: 0.3rem 0.5rem; font-size: 0.75rem; } .code-block { font-size: 0.75rem; padding: 0.6rem; } } </style> </head> <body> <div class="chat-container"> <div class="chat-header"> <h1>Echo AI</h1> <span class="model-info">Powered by Echo-1.5</span> <div class="menu-icon" id="menu-icon">⋮</div> <div class="dropdown-menu" id="dropdown-menu"> <button id="clear-chat">Clear Chat</button> <button id="export-chat">Export Chat</button> <button id="settings">Settings</button> </div> </div> <div id="central-prompt" class="central-prompt"> <svg class="logo" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%"> <stop offset="0%" style="stop-color:#6366f1;stop-opacity:1" /> <stop offset="100%" style="stop-color:#4f46e5;stop-opacity:1" /> </linearGradient> </defs> <circle cx="50" cy="50" r="45" fill="url(#grad)" /> <path d="M50 20C33.43 20 20 33.43 20 50s13.43 30 30 30 30-13.43 30-30S66.57 20 50 20zm0 55c-13.79 0-25-11.21-25-25s11.21-25 25-25 25 11.21 25 25-11.21 25-25 25z" fill="#ffffff"/> <circle cx="40" cy="40" r="5" fill="#ffffff" /> <circle cx="60" cy="40" r="5" fill="#ffffff" /> <path d="M65 60c0 8.28-6.72 15-15 15s-15-6.72-15-15" stroke="#ffffff" stroke-width="3" fill="none"/> </svg> <h2>Welcome to Echo AI. How may we assist you today?</h2> <div class="input-area"> <div class="input-wrapper"> <textarea id="user-input" placeholder="Type your message here..." rows="1"></textarea> <button id="send-button">Send</button> </div> </div> </div> <div class="chat-messages" id="chat-messages" style="display: none;"></div> <div class="input-area" id="chat-input-area" style="display: none;"> <div class="input-wrapper"> <textarea id="chat-user-input" placeholder="Type your message here..." rows="1"></textarea> <button id="chat-send-button">Send</button> </div> </div> </div> <script> const chatMessages = document.getElementById('chat-messages'); const userInput = document.getElementById('user-input'); const sendButton = document.getElementById('send-button'); const centralPrompt = document.getElementById('central-prompt'); const clearChatButton = document.getElementById('clear-chat'); const exportChatButton = document.getElementById('export-chat'); const settingsButton = document.getElementById('settings'); const menuIcon = document.getElementById('menu-icon'); const dropdownMenu = document.getElementById('dropdown-menu'); const chatInputArea = document.getElementById('chat-input-area'); const chatUserInput = document.getElementById('chat-user-input'); const chatSendButton = document.getElementById('chat-send-button'); let conversationHistory = []; function addMessage(content, isUser = false) { const messageDiv = document.createElement('div'); messageDiv.classList.add('message'); messageDiv.classList.add(isUser ? 'user-message' : 'bot-message'); // Process content for code blocks and HTML rendering const processedContent = processContent(content); messageDiv.innerHTML = processedContent; chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; return messageDiv; } function processContent(content) { // Process code blocks content = content.replace(/```(\w+)?\n?([\s\S]*?)```/g, function(match, language, code) { return `<pre class="code-block"><code class="${language || ''}">${escapeHtml(code.trim())}</code></pre>`; }); // Process inline code content = content.replace(/`([^`]+)`/g, '<code>$1</code>'); // Replace newlines with <br> tags content = content.replace(/\n/g, '<br>'); return content; } function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function addTypingIndicator() { const indicator = document.createElement('div'); indicator.classList.add('typing-indicator'); indicator.innerHTML = '<span></span><span></span><span></span>'; chatMessages.appendChild(indicator); chatMessages.scrollTop = chatMessages.scrollHeight; return indicator; } function removeTypingIndicator(indicator) { chatMessages.removeChild(indicator); } async function sendMessage(input) { const message = input.value.trim(); if (message) { addMessage(message, true); conversationHistory.push({ role: "user", content: message }); input.value = ''; adjustTextareaHeight(input); switchToChatMode(); getAIResponse(message); } } async function getAIResponse(message) { const typingIndicator = addTypingIndicator(); const messageDiv = addMessage('', false); try { const response = await fetch('https://gefiwek187-ecfrgrgeggegergui.hf.space/chat', { // Use the relative path to your Flask route method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ user_input: message }) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`); } const data = await response.json(); if (data.error) { throw new Error(data.error); } messageDiv.innerHTML = processContent(data.response); conversationHistory.push({ role: "assistant", content: data.response }); chatMessages.scrollTop = chatMessages.scrollHeight; } catch (error) { console.error('Error fetching AI response:', error); messageDiv.textContent = `Sorry, an error occurred while fetching the response: ${error.message}`; } finally { removeTypingIndicator(typingIndicator); } } function switchToChatMode() { centralPrompt.style.display = 'none'; chatMessages.style.display = 'flex'; chatInputArea.style.display = 'flex'; } sendButton.addEventListener('click', () => { sendMessage(userInput); }); chatSendButton.addEventListener('click', () => { sendMessage(chatUserInput); }); userInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(userInput); } }); chatUserInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(chatUserInput); } }); function adjustTextareaHeight(textarea) { textarea.style.height = 'auto'; textarea.style.height = (textarea.scrollHeight) + 'px'; } userInput.addEventListener('input', function() { adjustTextareaHeight(this); }); chatUserInput.addEventListener('input', function() { adjustTextareaHeight(this); }); menuIcon.addEventListener('click', () => { dropdownMenu.classList.toggle('show'); }); clearChatButton.addEventListener('click', () => { chatMessages.innerHTML = ''; centralPrompt.style.display = 'flex'; chatMessages.style.display = 'none'; chatInputArea.style.display = 'none'; dropdownMenu.classList.remove('show'); conversationHistory = []; // Clear the conversation history }); exportChatButton.addEventListener('click', () => { const chatContent = Array.from(chatMessages.children) .map(msg => `${msg.classList.contains('user-message') ? 'User' : 'Echo AI'}: ${msg.textContent}`) .join('\n\n'); const blob = new Blob([chatContent], { type: 'text/plain' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'echo-ai-chat-export.txt'; document.body.appendChild(a); a.click(); document.body.removeChild(a); dropdownMenu.classList.remove('show'); }); settingsButton.addEventListener('click', () => { alert('Settings functionality to be implemented in future updates.'); dropdownMenu.classList.remove('show'); }); document.addEventListener('click', (event) => { if (!menuIcon.contains(event.target) && !dropdownMenu.contains(event.target)) { dropdownMenu.classList.remove('show'); } }); // Function to handle window resize function handleResize() { const vh = window.innerHeight * 0.01; document.documentElement.style.setProperty('--vh', `${vh}px`); } // Initial call and event listener for resize handleResize(); window.addEventListener('resize', handleResize); </script> </body></html>