Spaces:
Sleeping
Sleeping
File size: 6,198 Bytes
5f02ff5 1c41e23 7a43222 7246ac3 b8f89e6 7a43222 b8f89e6 5f02ff5 1c41e23 5f02ff5 1c41e23 b8f89e6 2cd9f16 5f02ff5 1c41e23 449048d b8f89e6 449048d 5f02ff5 1c41e23 5f02ff5 1c41e23 5f02ff5 1c41e23 449048d 1c41e23 5f02ff5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import os
import gc
from flask import Flask, request, jsonify, render_template_string
from flask_cors import CORS
from brain import MairaBrain
app = Flask(__name__)
CORS(app)
# --- Configuration for the 5 Neural Cores ---
MODELS = {
"small": {"repo": "CyberCoder225/maira-model", "file": "SmolLM2-360M-Instruct.Q4_K_M.gguf"},
"medium": {"repo": "bartowski/Llama-3.2-1B-Instruct-GGUF", "file": "Llama-3.2-1B-Instruct-Q4_K_M.gguf"},
"qwen": {"repo": "Qwen/Qwen2.5-1.5B-Instruct-GGUF", "file": "qwen2.5-1.5b-instruct-q4_k_m.gguf"},
"danube": {"repo": "h2oai/h2o-danube3-500m-chat-GGUF", "file": "h2o-danube3-500m-chat-Q4_K_M.gguf"},
"granite": {"repo": "bartowski/granite-3.0-2b-instruct-GGUF", "file": "granite-3.0-2b-instruct-Q4_K_M.gguf"}
}
# --- Initialize Neural Core Registry ---
print("🌌 Loading Neural Core Registry...")
cores = {name: MairaBrain(cfg["repo"], cfg["file"]) for name, cfg in MODELS.items()}
# --- EMBEDDED HTML (No more templates folder needed!) ---
HTML_UI = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maira Quintessence</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.glass { background: rgba(15, 23, 42, 0.9); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); }
.chat-scroll::-webkit-scrollbar { width: 4px; }
.chat-scroll::-webkit-scrollbar-thumb { background: #6366f1; border-radius: 10px; }
</style>
</head>
<body class="bg-[#020617] text-slate-300 min-h-screen flex items-center justify-center p-4 font-sans">
<div class="w-full max-w-2xl h-[90vh] glass rounded-3xl flex flex-col overflow-hidden shadow-2xl">
<div class="p-5 border-b border-white/10 flex justify-between items-center">
<div>
<h1 class="text-xl font-bold text-indigo-400">Maira Quintessence</h1>
<p class="text-[10px] uppercase tracking-widest text-slate-500">Owner: CyberCoder225</p>
</div>
<select id="model-select" class="bg-slate-800 border border-white/10 rounded-lg px-3 py-2 text-xs text-white outline-none focus:ring-1 focus:ring-indigo-500">
<option value="small">Maira Lite (Fast)</option>
<option value="medium">Maira Prime (Llama)</option>
<option value="qwen">Maira Logic (Qwen)</option>
<option value="danube">Maira Chat (H2O)</option>
<option value="granite">Maira Art (Granite)</option>
</select>
</div>
<div id="chat-window" class="flex-grow p-6 overflow-y-auto chat-scroll space-y-4">
<div class="bg-indigo-500/10 border border-indigo-500/20 p-4 rounded-2xl rounded-tl-none max-w-[85%] text-sm">
Awaiting your command, Boss. All cores are on standby.
</div>
</div>
<form id="chat-form" class="p-4 bg-black/20 border-t border-white/10 flex gap-2">
<input type="text" id="user-input" placeholder="Enter message..." required
class="flex-grow bg-slate-800/50 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500">
<button type="submit" id="send-btn" class="bg-indigo-600 hover:bg-indigo-500 px-5 py-3 rounded-xl text-sm font-bold transition-all disabled:opacity-50">
SEND
</button>
</form>
</div>
<script>
const chatWindow = document.getElementById('chat-window');
const chatForm = document.getElementById('chat-form');
const userInput = document.getElementById('user-input');
const modelSelect = document.getElementById('model-select');
const sendBtn = document.getElementById('send-btn');
function addMessage(role, text) {
const div = document.createElement('div');
div.className = role === 'user'
? 'bg-slate-800 ml-auto p-4 rounded-2xl rounded-tr-none max-w-[85%] text-sm text-white'
: 'bg-indigo-500/10 border border-indigo-500/20 p-4 rounded-2xl rounded-tl-none max-w-[85%] text-sm';
div.innerText = text;
chatWindow.appendChild(div);
chatWindow.scrollTop = chatWindow.scrollHeight;
}
chatForm.onsubmit = async (e) => {
e.preventDefault();
const message = userInput.value.trim();
const model = modelSelect.value;
if (!message) return;
addMessage('user', message);
userInput.value = '';
sendBtn.disabled = true;
sendBtn.innerText = 'CORE BUSY...';
try {
const response = await fetch('/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message, model_type: model })
});
const data = await response.json();
addMessage('maira', data.maira || "ERROR: " + data.error);
} catch (err) {
addMessage('maira', "CONNECTION LOST: Check if Space is still building.");
} finally {
sendBtn.disabled = false;
sendBtn.innerText = 'SEND';
}
};
</script>
</body>
</html>
"""
@app.route('/')
def home():
return render_template_string(HTML_UI)
@app.route('/chat', methods=['POST'])
def chat():
try:
data = request.json
user_input = data.get("message", "")
model_type = data.get("model_type", "small")
# Memory Cleanup: Unload all EXCEPT active model
for name, core in cores.items():
if name != model_type:
core.unload()
active_core = cores.get(model_type, cores["small"])
answer = active_core.get_response("CyberCoder225", user_input)
return jsonify({"maira": answer})
except Exception as e:
print(f"❌ ERROR: {e}")
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False) |