Spaces:
Sleeping
Sleeping
| import os | |
| import uvicorn | |
| import json | |
| from fastapi import FastAPI, Form | |
| from fastapi.responses import HTMLResponse, JSONResponse | |
| from groq import Groq | |
| # --- CORE INITIALIZATION --- | |
| app = FastAPI() | |
| client = Groq(api_key=os.environ.get("GROQ_API_KEY")) | |
| # Configuration & Persistent Memory Setup | |
| USERNAME = "Sanjay" | |
| MEMORY_FILE = "memory.json" | |
| def load_memory(): | |
| if os.path.exists(MEMORY_FILE): | |
| try: | |
| with open(MEMORY_FILE, 'r') as f: | |
| data = json.load(f) | |
| return data if "history" in data else {"history": []} | |
| except Exception as e: | |
| return {"history": []} | |
| return {"history": []} | |
| def save_memory(chat_history): | |
| try: | |
| with open(MEMORY_FILE, 'w') as f: | |
| json.dump({"history": chat_history}, f, indent=4) | |
| except Exception as e: | |
| print(f"Memory Save Error: {e}") | |
| # --- STRICT PERSONA SETTINGS (MEMORY PRESERVED) --- | |
| SYSTEM_PROMPT = f""" | |
| Role: Senior AI Architect (AumCore AI). | |
| User Identity: {USERNAME}. | |
| Core Rules: | |
| 1. Language: Always 60% English and 40% Hindi (Devanagari). | |
| 2. Code Rule: If {USERNAME} asks for code, provide a robust production-ready Python script with try-except blocks. | |
| 3. Length: Responses must be powerful and direct (Max 4 lines). | |
| 4. Persona: Talk like a Master AI, not a basic chatbot. | |
| """ | |
| 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 - Final Build</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&family=Fira+Code:wght@400;500&display=swap'); | |
| body { background-color: #0d1117; color: #c9d1d9; font-family: 'Inter', sans-serif; display: flex; height: 100vh; overflow: hidden; margin: 0; } | |
| .sidebar { width: 260px; background: #010409; border-right: 1px solid #30363d; display: flex; flex-direction: column; padding: 15px; flex-shrink: 0; } | |
| .nav-item { padding: 12px; margin-bottom: 5px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; gap: 12px; color: #8b949e; transition: all 0.2s ease; } | |
| .nav-item:hover { background: #161b22; color: white; } | |
| .new-chat-btn { background: #238636; color: white !important; font-weight: 600; margin-bottom: 20px; } | |
| .main-chat { flex: 1; display: flex; flex-direction: column; background: #0d1117; position: relative; } | |
| .chat-box { flex: 1; overflow-y: auto; display: flex; flex-direction: column; align-items: center; padding: 60px 20px 120px 20px; scroll-behavior: smooth; } | |
| .message-wrapper { width: 100%; max-width: 760px; display: flex; flex-direction: column; margin-bottom: 35px; animation: fadeIn 0.3s ease; } | |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } | |
| .bubble { padding: 5px 0; font-size: 17px; line-height: 1.8; width: 100%; word-wrap: break-word; white-space: pre-wrap; } | |
| .user-text { color: #58a6ff; font-weight: 600; } | |
| .ai-text { color: #e6edf3; } | |
| pre { background: #161b22; padding: 18px; border-radius: 12px; border: 1px solid #30363d; margin: 15px 0; overflow-x: auto; width: 100%; } | |
| code { font-family: 'Fira Code', monospace; color: #79c0ff; font-size: 14px; } | |
| .input-area { position: absolute; bottom: 0; left: 0; width: 100%; background: linear-gradient(transparent, #0d1117 30%); padding-bottom: 30px; } | |
| .input-container { max-width: 800px; margin: 0 auto; background: #161b22; border: 1px solid #30363d; border-radius: 16px; padding: 12px 18px; display: flex; align-items: flex-end; gap: 12px; } | |
| #user-input { background: transparent; flex: 1; outline: none; border: none; color: white; font-size: 16px; resize: none; max-height: 200px; min-height: 28px; } | |
| .send-btn { color: #58a6ff; transition: transform 0.1s ease; margin-bottom: 4px; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="sidebar"> | |
| <button class="nav-item new-chat-btn" onclick="window.location.reload()"><i class="fas fa-plus"></i> New Chat</button> | |
| <div class="nav-item"><i class="fas fa-history"></i> History</div> | |
| <div class="mt-auto"> | |
| <div class="nav-item reset-btn" onclick="confirmReset()"><i class="fas fa-trash-alt"></i> Reset Memory</div> | |
| <div class="nav-item"><i class="fas fa-cog"></i> Settings</div> | |
| </div> | |
| </div> | |
| <div class="main-chat"> | |
| <div id="chat-log" class="chat-box"></div> | |
| <div class="input-area"> | |
| <div class="input-container"> | |
| <textarea id="user-input" rows="1" placeholder="Type your message to AumCore..." oninput="this.style.height='auto';this.style.height=this.scrollHeight+'px'" onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();send();}"></textarea> | |
| <button onclick="send()" class="send-btn"><i class="fas fa-paper-plane fa-lg"></i></button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| async function confirmReset() { | |
| if(confirm("Sanjay bhai, memory clear karein?")) { | |
| await fetch('/reset', { method: 'POST' }); | |
| window.location.reload(); | |
| } | |
| } | |
| async function send() { | |
| const input = document.getElementById('user-input'); | |
| const log = document.getElementById('chat-log'); | |
| const text = input.value.trim(); | |
| if(!text) return; | |
| log.innerHTML += `<div class="message-wrapper"><div class="bubble user-text">${text}</div></div>`; | |
| input.value = ''; input.style.height = 'auto'; | |
| log.scrollTop = log.scrollHeight; | |
| try { | |
| const res = await fetch('/chat', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/x-www-form-urlencoded'}, | |
| body: 'message=' + encodeURIComponent(text) | |
| }); | |
| const data = await res.json(); | |
| let formatted = data.response.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>'); | |
| log.innerHTML += `<div class="message-wrapper"><div class="bubble ai-text">${formatted}</div></div>`; | |
| } catch (e) { | |
| log.innerHTML += `<div class="message-wrapper text-red-500">Error connecting to AumCore.</div>`; | |
| } | |
| log.scrollTop = log.scrollHeight; | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| ''' | |
| async def get_ui(): | |
| return HTML_UI | |
| async def reset(): | |
| save_memory([]) | |
| return {"message": "Memory clear ho gayi!"} | |
| async def chat(message: str = Form(...)): | |
| memory_data = load_memory() | |
| history = memory_data.get("history", [])[-10:] # Increased history context | |
| api_messages = [{"role": "system", "content": SYSTEM_PROMPT}] | |
| for chat_pair in history: | |
| api_messages.append({"role": "user", "content": chat_pair["u"]}) | |
| api_messages.append({"role": "assistant", "content": chat_pair["a"]}) | |
| api_messages.append({"role": "user", "content": message}) | |
| try: | |
| completion = client.chat.completions.create( | |
| model="llama-3.3-70b-versatile", | |
| messages=api_messages, | |
| temperature=0.3, # Balanced for creativity and rule-following | |
| max_tokens=800 | |
| ) | |
| ai_response = completion.choices[0].message.content.strip() | |
| history.append({"u": message, "a": ai_response}) | |
| save_memory(history) | |
| return {"response": ai_response} | |
| except Exception as e: | |
| return {"response": f"Error: {str(e)}"} | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |