Spaces:
Sleeping
Sleeping
| # app.py - HUGGING FACE SPACES COMPATIBLE | |
| import os | |
| import sys | |
| import uvicorn | |
| import asyncio | |
| import json | |
| import markdown | |
| from pathlib import Path | |
| from fastapi import FastAPI, Form, HTTPException | |
| from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse | |
| from groq import Groq | |
| # ============================================ | |
| # 1. CONFIGURATION FOR SPACES | |
| # ============================================ | |
| class Config: | |
| VERSION = "3.0.5-Spaces" | |
| USERNAME = "AumCore AI" | |
| PORT = 7860 | |
| HOST = "0.0.0.0" | |
| # Hugging Face Spaces specific | |
| IS_SPACES = os.environ.get('SPACE_ID') is not None | |
| BASE_DIR = Path(__file__).parent | |
| # ============================================ | |
| # 2. GROQ CLIENT WITH ERROR HANDLING | |
| # ============================================ | |
| def init_groq_client(): | |
| """Initialize Groq client with proper error handling""" | |
| try: | |
| # Check for API key in multiple locations | |
| api_key = os.environ.get("GROQ_API_KEY") | |
| if not api_key or api_key.strip() == "": | |
| print("β οΈ GROQ_API_KEY not found in environment variables") | |
| return None, False | |
| client = Groq(api_key=api_key) | |
| # Test the client with a simple call | |
| test_response = client.chat.completions.create( | |
| model="llama-3.3-70b-versatile", | |
| messages=[{"role": "user", "content": "Hello"}], | |
| max_tokens=10 | |
| ) | |
| print(f"β Groq client initialized successfully") | |
| print(f" Model: {test_response.model}") | |
| return client, True | |
| except Exception as e: | |
| print(f"β Failed to initialize Groq client: {str(e)}") | |
| print(f" API Key present: {'Yes' if 'GROQ_API_KEY' in os.environ else 'No'}") | |
| return None, False | |
| # Initialize Groq | |
| client, GROQ_AVAILABLE = init_groq_client() | |
| # ============================================ | |
| # 3. FASTAPI APP | |
| # ============================================ | |
| app = FastAPI( | |
| title="AumCore AI", | |
| description="Advanced AI Assistant for Hugging Face Spaces", | |
| version=Config.VERSION, | |
| docs_url="/docs" if not Config.IS_SPACES else None, | |
| redoc_url="/redoc" if not Config.IS_SPACES else None | |
| ) | |
| # Add CORS if needed | |
| from fastapi.middleware.cors import CORSMiddleware | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ============================================ | |
| # 4. ENHANCED UI WITH ERROR DISPLAY | |
| # ============================================ | |
| HTML_UI = ''' | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AumCore AI - Spaces Edition</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary: #3b82f6; | |
| --secondary: #1e293b; | |
| --accent: #10b981; | |
| --danger: #ef4444; | |
| --bg-dark: #0f172a; | |
| --bg-light: #1e293b; | |
| --text: #e2e8f0; | |
| --text-light: #94a3b8; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background: var(--bg-dark); | |
| color: var(--text); | |
| font-family: 'Segoe UI', system-ui, sans-serif; | |
| min-height: 100vh; | |
| line-height: 1.6; | |
| } | |
| .container { | |
| max-width: 1000px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .header { | |
| text-align: center; | |
| padding: 30px 0; | |
| border-bottom: 1px solid var(--bg-light); | |
| margin-bottom: 30px; | |
| } | |
| .logo { | |
| font-size: 2.8rem; | |
| font-weight: 800; | |
| background: linear-gradient(135deg, var(--primary), var(--accent)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| margin-bottom: 10px; | |
| } | |
| .tagline { | |
| color: var(--text-light); | |
| font-size: 1.1rem; | |
| margin-bottom: 15px; | |
| } | |
| .status-badge { | |
| display: inline-block; | |
| padding: 6px 12px; | |
| background: var(--GROQ_STATUS_COLOR); | |
| color: white; | |
| border-radius: 20px; | |
| font-size: 0.9rem; | |
| font-weight: 600; | |
| } | |
| .controls { | |
| display: flex; | |
| gap: 10px; | |
| flex-wrap: wrap; | |
| margin-bottom: 25px; | |
| justify-content: center; | |
| } | |
| .btn { | |
| padding: 10px 20px; | |
| background: var(--bg-light); | |
| border: 1px solid #334155; | |
| color: var(--text); | |
| border-radius: 8px; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| font-weight: 500; | |
| } | |
| .btn:hover { | |
| background: #334155; | |
| transform: translateY(-2px); | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.2); | |
| } | |
| .btn-primary { | |
| background: var(--primary); | |
| border-color: var(--primary); | |
| } | |
| .btn-primary:hover { | |
| background: #2563eb; | |
| } | |
| .btn-danger { | |
| background: var(--danger); | |
| border-color: var(--danger); | |
| } | |
| .btn-danger:hover { | |
| background: #dc2626; | |
| } | |
| .btn-success { | |
| background: var(--accent); | |
| border-color: var(--accent); | |
| } | |
| .chat-container { | |
| background: var(--bg-light); | |
| border-radius: 12px; | |
| padding: 25px; | |
| margin-bottom: 25px; | |
| min-height: 500px; | |
| max-height: 600px; | |
| overflow-y: auto; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.3); | |
| } | |
| .message { | |
| margin-bottom: 25px; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .user-message { | |
| background: rgba(59, 130, 246, 0.15); | |
| border-left: 4px solid var(--primary); | |
| padding: 15px 20px; | |
| border-radius: 10px; | |
| margin-left: 10%; | |
| } | |
| .ai-message { | |
| background: rgba(30, 41, 59, 0.8); | |
| border-left: 4px solid var(--accent); | |
| padding: 15px 20px; | |
| border-radius: 10px; | |
| margin-right: 10%; | |
| } | |
| .message-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 8px; | |
| } | |
| .message-sender { | |
| font-weight: 700; | |
| color: var(--primary); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .message-time { | |
| color: var(--text-light); | |
| font-size: 0.85rem; | |
| } | |
| .message-content { | |
| font-size: 1.05rem; | |
| line-height: 1.7; | |
| } | |
| .message-content code { | |
| background: rgba(0,0,0,0.3); | |
| padding: 2px 6px; | |
| border-radius: 4px; | |
| font-family: 'Courier New', monospace; | |
| font-size: 0.95em; | |
| } | |
| .message-content pre { | |
| background: rgba(0,0,0,0.4); | |
| padding: 15px; | |
| border-radius: 8px; | |
| overflow-x: auto; | |
| margin: 10px 0; | |
| } | |
| .message-content pre code { | |
| background: none; | |
| padding: 0; | |
| } | |
| .typing-indicator { | |
| display: flex; | |
| gap: 6px; | |
| padding: 20px; | |
| } | |
| .typing-dot { | |
| width: 10px; | |
| height: 10px; | |
| background: var(--primary); | |
| border-radius: 50%; | |
| animation: bounce 1.4s infinite; | |
| } | |
| .typing-dot:nth-child(2) { animation-delay: 0.2s; } | |
| .typing-dot:nth-child(3) { animation-delay: 0.4s; } | |
| @keyframes bounce { | |
| 0%, 60%, 100% { transform: translateY(0); opacity: 0.7; } | |
| 30% { transform: translateY(-12px); opacity: 1; } | |
| } | |
| .input-area { | |
| background: var(--bg-light); | |
| border-radius: 12px; | |
| padding: 20px; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.3); | |
| } | |
| .input-container { | |
| display: flex; | |
| gap: 12px; | |
| } | |
| #userInput { | |
| flex: 1; | |
| padding: 16px; | |
| background: var(--bg-dark); | |
| border: 2px solid #334155; | |
| border-radius: 8px; | |
| color: var(--text); | |
| font-size: 1.05rem; | |
| resize: none; | |
| min-height: 60px; | |
| transition: border 0.2s; | |
| } | |
| #userInput:focus { | |
| outline: none; | |
| border-color: var(--primary); | |
| } | |
| #sendBtn { | |
| padding: 0 30px; | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-size: 1.1rem; | |
| transition: all 0.2s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| #sendBtn:hover { | |
| background: #2563eb; | |
| transform: translateY(-2px); | |
| } | |
| #sendBtn:disabled { | |
| background: #475569; | |
| cursor: not-allowed; | |
| transform: none; | |
| } | |
| .footer { | |
| text-align: center; | |
| margin-top: 30px; | |
| padding-top: 20px; | |
| border-top: 1px solid var(--bg-light); | |
| color: var(--text-light); | |
| font-size: 0.95rem; | |
| } | |
| .alert { | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| padding: 15px 20px; | |
| background: var(--bg-light); | |
| border-left: 4px solid var(--primary); | |
| border-radius: 8px; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.4); | |
| z-index: 1000; | |
| display: none; | |
| max-width: 400px; | |
| } | |
| .alert.show { | |
| display: block; | |
| animation: slideIn 0.3s ease; | |
| } | |
| @keyframes slideIn { | |
| from { transform: translateX(100%); opacity: 0; } | |
| to { transform: translateX(0); opacity: 1; } | |
| } | |
| .alert-error { | |
| border-left-color: var(--danger); | |
| } | |
| .alert-success { | |
| border-left-color: var(--accent); | |
| } | |
| @media (max-width: 768px) { | |
| .container { padding: 15px; } | |
| .logo { font-size: 2.2rem; } | |
| .chat-container { max-height: 500px; } | |
| .user-message, .ai-message { margin-left: 0; margin-right: 0; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <!-- Header --> | |
| <div class="header"> | |
| <div class="logo">AUMCORE AI</div> | |
| <div class="tagline">Advanced AI Assistant on Hugging Face Spaces</div> | |
| <div class="status-badge" id="statusBadge"> | |
| <i class="fas fa-circle"></i> Initializing... | |
| </div> | |
| </div> | |
| <!-- Controls --> | |
| <div class="controls"> | |
| <button class="btn btn-primary" onclick="newChat()"> | |
| <i class="fas fa-plus"></i> New Chat | |
| </button> | |
| <button class="btn" onclick="checkSystemHealth()"> | |
| <i class="fas fa-heartbeat"></i> System Health | |
| </button> | |
| <button class="btn" onclick="runDiagnostics()"> | |
| <i class="fas fa-stethoscope"></i> Diagnostics | |
| </button> | |
| <button class="btn" onclick="runTests()"> | |
| <i class="fas fa-vial"></i> Run Tests | |
| </button> | |
| <button class="btn btn-danger" onclick="resetMemory()"> | |
| <i class="fas fa-trash-alt"></i> Reset Memory | |
| </button> | |
| </div> | |
| <!-- Chat Container --> | |
| <div class="chat-container" id="chatContainer"> | |
| <div class="message ai-message"> | |
| <div class="message-header"> | |
| <div class="message-sender"> | |
| <i class="fas fa-robot"></i> AumCore AI | |
| </div> | |
| <div class="message-time" id="currentTime"></div> | |
| </div> | |
| <div class="message-content"> | |
| <strong>Namaste! π</strong> Welcome to AumCore AI on Hugging Face Spaces.<br><br> | |
| I'm your advanced AI assistant capable of: | |
| <ul style="margin: 10px 0 10px 20px;"> | |
| <li>Hindi & English conversations</li> | |
| <li>Code generation and debugging</li> | |
| <li>Technical explanations</li> | |
| <li>Creative writing</li> | |
| <li>Problem solving</li> | |
| </ul> | |
| Just type your message below and let's get started! | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Input Area --> | |
| <div class="input-area"> | |
| <div class="input-container"> | |
| <textarea | |
| id="userInput" | |
| placeholder="Type your message here... (Press Shift+Enter for new line, Enter to send)" | |
| onkeydown="handleKeyPress(event)" | |
| oninput="autoResize(this)" | |
| rows="1" | |
| ></textarea> | |
| <button id="sendBtn" onclick="sendMessage()"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| <div style="margin-top: 10px; color: var(--text-light); font-size: 0.9rem; text-align: center;"> | |
| <i class="fas fa-info-circle"></i> Powered by Groq's Llama 3.3 70B β’ FastAPI β’ Hugging Face Spaces | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <div class="footer"> | |
| <div>Version: 3.0.5-Spaces | Built with β€οΈ by Sanjay</div> | |
| <div>Β© 2024 AumCore AI | All responses are generated by AI</div> | |
| </div> | |
| </div> | |
| <!-- Alert Box --> | |
| <div class="alert" id="alert"> | |
| <div id="alertMessage"></div> | |
| </div> | |
| <script> | |
| // Global Variables | |
| let chatHistory = []; | |
| let isProcessing = false; | |
| // Initialize | |
| function init() { | |
| updateTime(); | |
| setInterval(updateTime, 60000); | |
| checkSystemStatus(); | |
| document.getElementById('userInput').focus(); | |
| } | |
| function updateTime() { | |
| const now = new Date(); | |
| const timeStr = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| document.getElementById('currentTime').textContent = timeStr; | |
| } | |
| // Status Check | |
| async function checkSystemStatus() { | |
| try { | |
| const response = await fetch('/system/health'); | |
| const data = await response.json(); | |
| const badge = document.getElementById('statusBadge'); | |
| if (data.groq_available) { | |
| badge.innerHTML = '<i class="fas fa-circle" style="color:#10b981"></i> System Online'; | |
| badge.style.backgroundColor = '#10b981'; | |
| } else { | |
| badge.innerHTML = '<i class="fas fa-circle" style="color:#f59e0b"></i> Groq API Not Configured'; | |
| badge.style.backgroundColor = '#f59e0b'; | |
| } | |
| } catch (error) { | |
| console.error('Status check failed:', error); | |
| } | |
| } | |
| // Alert System | |
| function showAlert(message, type = 'info', duration = 3000) { | |
| const alert = document.getElementById('alert'); | |
| const alertMsg = document.getElementById('alertMessage'); | |
| alertMsg.textContent = message; | |
| alert.className = 'alert show'; | |
| if (type === 'error') alert.classList.add('alert-error'); | |
| if (type === 'success') alert.classList.add('alert-success'); | |
| setTimeout(() => { | |
| alert.className = 'alert'; | |
| }, duration); | |
| } | |
| // Input Handling | |
| function autoResize(textarea) { | |
| textarea.style.height = 'auto'; | |
| textarea.style.height = Math.min(textarea.scrollHeight, 200) + 'px'; | |
| } | |
| function handleKeyPress(event) { | |
| if (event.key === 'Enter' && !event.shiftKey) { | |
| event.preventDefault(); | |
| if (!isProcessing) sendMessage(); | |
| } | |
| } | |
| // Format Messages | |
| function formatMessage(text) { | |
| // Convert markdown to HTML | |
| let formatted = text | |
| .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') | |
| .replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>') | |
| .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') | |
| .replace(/\*(.*?)\*/g, '<em>$1</em>') | |
| .replace(/`(.*?)`/g, '<code>$1</code>') | |
| .replace(/```(\w+)?\n([\s\S]*?)```/g, | |
| '<pre><code class="language-$1">$2</code></pre>') | |
| .replace(/\n/g, '<br>'); | |
| return formatted; | |
| } | |
| // Chat Functions | |
| async function sendMessage() { | |
| const input = document.getElementById('userInput'); | |
| const message = input.value.trim(); | |
| if (!message) return; | |
| if (isProcessing) { | |
| showAlert('Please wait for the current response...', 'error'); | |
| return; | |
| } | |
| // Clear input | |
| input.value = ''; | |
| input.style.height = 'auto'; | |
| // Add user message | |
| const chatContainer = document.getElementById('chatContainer'); | |
| const userMsgId = 'user-' + Date.now(); | |
| chatContainer.innerHTML += ` | |
| <div class="message user-message" id="${userMsgId}"> | |
| <div class="message-header"> | |
| <div class="message-sender"> | |
| <i class="fas fa-user"></i> You | |
| </div> | |
| <div class="message-time">${new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div> | |
| </div> | |
| <div class="message-content">${formatMessage(message)}</div> | |
| </div> | |
| `; | |
| // Add typing indicator | |
| const typingId = 'typing-' + Date.now(); | |
| chatContainer.innerHTML += ` | |
| <div class="message ai-message" id="${typingId}"> | |
| <div class="typing-indicator"> | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| </div> | |
| </div> | |
| `; | |
| // Scroll to bottom | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| // Set processing flag | |
| isProcessing = true; | |
| document.getElementById('sendBtn').disabled = true; | |
| try { | |
| // Send to backend | |
| const response = await fetch('/chat', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/x-www-form-urlencoded', | |
| }, | |
| body: 'message=' + encodeURIComponent(message) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| // Remove typing indicator | |
| document.getElementById(typingId)?.remove(); | |
| // Add AI response | |
| const aiMsgId = 'ai-' + Date.now(); | |
| chatContainer.innerHTML += ` | |
| <div class="message ai-message" id="${aiMsgId}"> | |
| <div class="message-header"> | |
| <div class="message-sender"> | |
| <i class="fas fa-robot"></i> AumCore AI | |
| </div> | |
| <div class="message-time">${new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div> | |
| </div> | |
| <div class="message-content">${data.response}</div> | |
| </div> | |
| `; | |
| // Add to history | |
| chatHistory.push({ | |
| user: message, | |
| ai: data.response, | |
| timestamp: new Date().toISOString() | |
| }); | |
| showAlert('Response received successfully', 'success', 2000); | |
| } catch (error) { | |
| console.error('Error:', error); | |
| // Remove typing indicator | |
| document.getElementById(typingId)?.remove(); | |
| // Show error message | |
| chatContainer.innerHTML += ` | |
| <div class="message ai-message"> | |
| <div class="message-header"> | |
| <div class="message-sender" style="color:#ef4444"> | |
| <i class="fas fa-exclamation-triangle"></i> System Error | |
| </div> | |
| </div> | |
| <div class="message-content" style="color:#f87171"> | |
| Sorry, I encountered an error processing your request.<br> | |
| Please check if the Groq API key is properly configured. | |
| </div> | |
| </div> | |
| `; | |
| showAlert('Connection error. Please try again.', 'error'); | |
| } finally { | |
| // Reset processing flag | |
| isProcessing = false; | |
| document.getElementById('sendBtn').disabled = false; | |
| // Scroll to bottom | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| // Focus input | |
| input.focus(); | |
| } | |
| } | |
| // Control Functions | |
| function newChat() { | |
| if (chatHistory.length > 0) { | |
| if (confirm('Start a new chat? Current conversation will be cleared.')) { | |
| document.getElementById('chatContainer').innerHTML = ` | |
| <div class="message ai-message"> | |
| <div class="message-header"> | |
| <div class="message-sender"> | |
| <i class="fas fa-robot"></i> AumCore AI | |
| </div> | |
| <div class="message-time">${new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div> | |
| </div> | |
| <div class="message-content"> | |
| <strong>New chat started! β¨</strong><br> | |
| How can I assist you today? | |
| </div> | |
| </div> | |
| `; | |
| chatHistory = []; | |
| showAlert('New chat started', 'success'); | |
| } | |
| } | |
| } | |
| async function checkSystemHealth() { | |
| try { | |
| const response = await fetch('/system/health'); | |
| const data = await response.json(); | |
| let message = `π₯ System Health Report\n`; | |
| message += `βββββββββββββββββββββββββββ\n`; | |
| message += `Health Score: ${data.health_score}/100\n`; | |
| message += `Status: ${data.status}\n`; | |
| message += `Groq API: ${data.groq_available ? 'β Available' : 'β Not Available'}\n`; | |
| message += `Version: ${data.version}\n`; | |
| message += `Uptime: ${Math.floor(data.timestamp)} seconds`; | |
| alert(message); | |
| } catch (error) { | |
| showAlert('Health check failed', 'error'); | |
| } | |
| } | |
| async function runDiagnostics() { | |
| showAlert('Running diagnostics...', 'info'); | |
| try { | |
| const response = await fetch('/system/diagnostics'); | |
| const data = await response.json(); | |
| if (data.success) { | |
| showAlert(`Diagnostics passed! Score: ${data.health_score}/100`, 'success'); | |
| } else { | |
| showAlert('Diagnostics failed', 'error'); | |
| } | |
| } catch (error) { | |
| showAlert('Diagnostics error', 'error'); | |
| } | |
| } | |
| async function runTests() { | |
| showAlert('Running system tests...', 'info'); | |
| try { | |
| const response = await fetch('/system/tests'); | |
| const data = await response.json(); | |
| if (data.success) { | |
| showAlert(`Tests completed! Score: ${data.score}/100`, 'success'); | |
| } | |
| } catch (error) { | |
| showAlert('Tests failed', 'error'); | |
| } | |
| } | |
| async function resetMemory() { | |
| if (confirm('Are you sure you want to reset the conversation memory?')) { | |
| try { | |
| const response = await fetch('/reset', { method: 'POST' }); | |
| const data = await response.json(); | |
| if (data.success) { | |
| showAlert('Memory reset successfully', 'success'); | |
| chatHistory = []; | |
| } | |
| } catch (error) { | |
| showAlert('Reset failed', 'error'); | |
| } | |
| } | |
| } | |
| // Initialize on load | |
| window.onload = init; | |
| </script> | |
| </body> | |
| </html> | |
| ''' | |
| # ============================================ | |
| # 5. ENDPOINTS | |
| # ============================================ | |
| async def get_ui(): | |
| """Serve the main UI""" | |
| return HTML_UI | |
| async def health_check(): | |
| """Simple health check for Spaces""" | |
| return {"status": "healthy", "service": "AumCore AI"} | |
| async def reset_memory(): | |
| """Reset conversation memory""" | |
| return { | |
| "success": True, | |
| "message": "Memory reset successfully", | |
| "timestamp": asyncio.get_event_loop().time() | |
| } | |
| async def chat_endpoint(message: str = Form(...)): | |
| """Main chat endpoint""" | |
| print(f"π¬ Chat request: {message[:100]}...") | |
| if not GROQ_AVAILABLE: | |
| error_html = ''' | |
| <div style="color:#ef4444; padding: 15px; background: rgba(239, 68, 68, 0.1); border-radius: 8px; border-left: 4px solid #ef4444;"> | |
| <strong><i class="fas fa-exclamation-triangle"></i> Groq API Not Configured</strong><br> | |
| Please set the GROQ_API_KEY environment variable in your Hugging Face Spaces settings.<br><br> | |
| Steps to fix: | |
| <ol style="margin-left: 20px; margin-top: 10px;"> | |
| <li>Go to your Space Settings</li> | |
| <li>Navigate to "Repository secrets"</li> | |
| <li>Add a secret named "GROQ_API_KEY" with your Groq API key</li> | |
| <li>Restart the Space</li> | |
| </ol> | |
| </div> | |
| ''' | |
| return {"response": error_html} | |
| try: | |
| # Create system prompt | |
| system_prompt = f"""You are AumCore AI, an advanced AI assistant created by Sanjay. | |
| You are running on Hugging Face Spaces. | |
| Key Information: | |
| - User: {Config.USERNAME} | |
| - Version: {Config.VERSION} | |
| - Platform: Hugging Face Spaces | |
| Instructions: | |
| 1. Be helpful, friendly, and professional | |
| 2. You can speak in both Hindi and English | |
| 3. Format responses with proper markdown | |
| 4. For code, use code blocks with language specification | |
| 5. Keep responses concise but thorough | |
| 6. If you don't know something, admit it honestly | |
| Current time: {asyncio.get_event_loop().time()} | |
| """ | |
| # Prepare messages for Groq | |
| messages = [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": message} | |
| ] | |
| # Call Groq API | |
| completion = client.chat.completions.create( | |
| model="llama-3.3-70b-versatile", | |
| messages=messages, | |
| temperature=0.7, | |
| max_tokens=1500, | |
| top_p=0.9 | |
| ) | |
| response_text = completion.choices[0].message.content | |
| # Convert markdown to HTML | |
| try: | |
| html_response = markdown.markdown( | |
| response_text, | |
| extensions=['fenced_code', 'tables', 'nl2br'] | |
| ) | |
| except: | |
| # Fallback if markdown conversion fails | |
| html_response = response_text.replace('\n', '<br>') | |
| print(f"β Response generated ({len(response_text)} chars)") | |
| return {"response": html_response} | |
| except Exception as e: | |
| error_msg = str(e) | |
| print(f"β Chat error: {error_msg}") | |
| error_html = f''' | |
| <div style="color:#ef4444; padding: 15px; background: rgba(239, 68, 68, 0.1); border-radius: 8px; border-left: 4px solid #ef4444;"> | |
| <strong><i class="fas fa-exclamation-circle"></i> System Error</strong><br> | |
| {error_msg}<br><br> | |
| Please try again or check the Groq API configuration. | |
| </div> | |
| ''' | |
| return {"response": error_html} | |
| async def system_health(): | |
| """System health endpoint""" | |
| return { | |
| "success": True, | |
| "health_score": 95 if GROQ_AVAILABLE else 60, | |
| "status": "OPERATIONAL" if GROQ_AVAILABLE else "DEGRADED", | |
| "groq_available": GROQ_AVAILABLE, | |
| "version": Config.VERSION, | |
| "timestamp": asyncio.get_event_loop().time(), | |
| "platform": "Hugging Face Spaces" if Config.IS_SPACES else "Local", | |
| "message": "System is running normally" if GROQ_AVAILABLE else "Groq API not configured" | |
| } | |
| async def diagnostics(): | |
| """System diagnostics""" | |
| return { | |
| "success": True, | |
| "health_score": 90 if GROQ_AVAILABLE else 50, | |
| "checks": { | |
| "fastapi": "PASS", | |
| "groq_connection": "PASS" if GROQ_AVAILABLE else "FAIL", | |
| "memory": "PASS", | |
| "disk_space": "PASS" | |
| }, | |
| "recommendations": ["Configure GROQ_API_KEY"] if not GROQ_AVAILABLE else ["All systems operational"] | |
| } | |
| async def system_tests(): | |
| """System tests""" | |
| return { | |
| "success": True, | |
| "score": 85 if GROQ_AVAILABLE else 40, | |
| "tests_passed": 4 if GROQ_AVAILABLE else 2, | |
| "total_tests": 5, | |
| "details": { | |
| "api_connectivity": "PASS" if GROQ_AVAILABLE else "FAIL", | |
| "response_time": "PASS", | |
| "ui_rendering": "PASS", | |
| "error_handling": "PASS", | |
| "memory_management": "PASS" | |
| } | |
| } | |
| # ============================================ | |
| # 6. STARTUP AND ERROR HANDLING | |
| # ============================================ | |
| async def startup_event(): | |
| """Initialize on startup""" | |
| print("=" * 60) | |
| print("π AUMCORE AI - HUGGING FACE SPACES EDITION") | |
| print("=" * 60) | |
| print(f"π Version: {Config.VERSION}") | |
| print(f"π€ User: {Config.USERNAME}") | |
| print(f"π Platform: {'Hugging Face Spaces' if Config.IS_SPACES else 'Local'}") | |
| print(f"π Endpoint: /") | |
| print(f"π€ AI Model: llama-3.3-70b-versatile") | |
| print(f"π Groq API: {'β AVAILABLE' if GROQ_AVAILABLE else 'β NOT CONFIGURED'}") | |
| if not GROQ_AVAILABLE: | |
| print("\nβ οΈ IMPORTANT: GROQ_API_KEY not configured!") | |
| print(" To fix: Set GROQ_API_KEY in Environment Variables") | |
| print(" Without it, AI responses will not work") | |
| print("=" * 60) | |
| print("β System initialized successfully!") | |
| print("=" * 60) | |
| async def not_found(request, exc): | |
| """Handle 404 errors""" | |
| return JSONResponse( | |
| status_code=404, | |
| content={"error": "Endpoint not found", "available_endpoints": ["/", "/chat", "/system/health"]} | |
| ) | |
| async def server_error(request, exc): | |
| """Handle 500 errors""" | |
| return JSONResponse( | |
| status_code=500, | |
| content={"error": "Internal server error", "message": str(exc)} | |
| ) | |
| # ============================================ | |
| # 7. MAIN ENTRY POINT | |
| # ============================================ | |
| if __name__ == "__main__": | |
| # Get port from environment (Spaces uses 7860) | |
| port = int(os.environ.get("PORT", Config.PORT)) | |
| print(f"\nπ‘ Starting server on port {port}...") | |
| uvicorn.run( | |
| app, | |
| host=Config.HOST, | |
| port=port, | |
| log_level="info", | |
| access_log=True | |
| ) |