Download app.py from nRTAGROUP/JARVIS-UI: direct link, hf CLI and curl.
- Browser
- Download file 12.7 kB
-
https://huggingface.co/spaces/nRTAGROUP/JARVIS-UI/resolve/main/app.py
- Command line
-
hf download hf://spaces/nRTAGROUP/JARVIS-UI/app.py
-
curl -L -o app.py https://huggingface.co/spaces/nRTAGROUP/JARVIS-UI/resolve/main/app.py
12.7 kB
| import gradio as gr | |
| import requests | |
| import os | |
| JARVIS_API = os.getenv("JARVIS_API_URL", "https://jarvis-9vys.onrender.com") | |
| def chat_with_jarvis(message, history): | |
| if not message.strip(): | |
| return history, "" | |
| try: | |
| res = requests.post(f"{JARVIS_API}/chat", json={ | |
| "message": message, | |
| "force_offline": False, | |
| "text_only": False | |
| }, timeout=60) | |
| data = res.json() | |
| response = data.get("response", "কোনো সাড়া পাওয়া যায়নি") | |
| brain = data.get("brain_used", "Unknown") | |
| mode = data.get("mode", "normal") | |
| online = "🌐 Online" if data.get("online") else "📴 Offline" | |
| reply = f"{response}\n\n---\n🧠 `{brain}` | {online} | Mode: `{mode}`" | |
| except Exception as e: | |
| reply = f"⚠️ JARVIS Server connect করা যাচ্ছে না।\n\n`Error: {str(e)}`" | |
| history = history or [] | |
| # 🔴 ফিক্স: Gradio-এর নতুন 'messages' ফরম্যাট অনুযায়ী ডেটা সেভ করা হচ্ছে | |
| history.append({"role": "user", "content": message}) | |
| history.append({"role": "assistant", "content": reply}) | |
| return history, "" | |
| def get_status(): | |
| try: | |
| res = requests.get(f"{JARVIS_API}/status", timeout=60) | |
| data = res.json() | |
| cpu = data["resource"]["cpu_percent"] | |
| ram = data["resource"]["ram_percent"] | |
| # 🔴 ফিক্স: 'total_memories' এর বদলে সঠিক key ব্যবহার করা হলো | |
| mem = data["memory"].get("supabase_total_memories", data["memory"].get("json_memory", 0)) | |
| idle = data["resource"]["idle_minutes"] | |
| sleeping = data["resource"]["sleeping"] | |
| status = "😴 SLEEP MODE" if sleeping else "⚡ ACTIVE" | |
| return f"◈ SYSTEM STATUS: **{status}** | 🖥️ CPU: **{cpu}%** | 💾 RAM: **{ram}%** | 🧠 MEMORIES: **{mem}** | ⏱️ IDLE: **{idle} min**" | |
| except Exception as e: | |
| # 🔴 ফিক্স: এখন থেকে সার্ভার অফলাইন হলে আসল কারণটাও (Error) লেখা উঠবে | |
| return f"◈ SYSTEM STATUS: **⚠️ SERVER OFFLINE** — Error: {str(e)}" | |
| custom_css = """ | |
| @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Share+Tech+Mono&family=Exo+2:wght@300;400&display=swap'); | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| background: #000510 !important; | |
| font-family: 'Share Tech Mono', monospace !important; | |
| overflow-x: hidden; | |
| } | |
| /* Animated grid background */ | |
| body::before { | |
| content: ''; | |
| position: fixed; | |
| top: 0; left: 0; right: 0; bottom: 0; | |
| background-image: | |
| linear-gradient(rgba(0, 212, 255, 0.03) 1px, transparent 1px), | |
| linear-gradient(90deg, rgba(0, 212, 255, 0.03) 1px, transparent 1px); | |
| background-size: 50px 50px; | |
| animation: gridMove 20s linear infinite; | |
| pointer-events: none; | |
| z-index: 0; | |
| } | |
| /* Scanlines */ | |
| body::after { | |
| content: ''; | |
| position: fixed; | |
| top: 0; left: 0; right: 0; bottom: 0; | |
| background: repeating-linear-gradient( | |
| 0deg, | |
| transparent, | |
| transparent 2px, | |
| rgba(0, 212, 255, 0.012) 2px, | |
| rgba(0, 212, 255, 0.012) 4px | |
| ); | |
| pointer-events: none; | |
| z-index: 1; | |
| } | |
| @keyframes gridMove { | |
| 0% { transform: translateY(0); } | |
| 100% { transform: translateY(50px); } | |
| } | |
| .gradio-container { | |
| background: transparent !important; | |
| max-width: 960px !important; | |
| margin: 0 auto !important; | |
| position: relative; | |
| z-index: 2; | |
| padding: 20px !important; | |
| } | |
| /* ══ HEADER ══ */ | |
| #jarvis-header { | |
| text-align: center; | |
| padding: 40px 0 10px; | |
| position: relative; | |
| } | |
| #jarvis-header::before { | |
| content: ''; | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| transform: translate(-50%, -50%); | |
| width: 400px; height: 400px; | |
| background: radial-gradient(circle, rgba(0,100,255,0.08) 0%, transparent 70%); | |
| pointer-events: none; | |
| } | |
| #jarvis-logo { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 4rem; | |
| font-weight: 900; | |
| background: linear-gradient(90deg, #00d4ff, #0066ff, #00ffcc, #00d4ff); | |
| background-size: 300%; | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| animation: shimmer 4s linear infinite; | |
| letter-spacing: 0.5em; | |
| text-indent: 0.5em; | |
| filter: drop-shadow(0 0 20px rgba(0, 212, 255, 0.4)); | |
| } | |
| #jarvis-tagline { | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 0.65rem; | |
| color: rgba(0, 212, 255, 0.4); | |
| letter-spacing: 0.6em; | |
| text-transform: uppercase; | |
| margin-top: 4px; | |
| text-indent: 0.6em; | |
| } | |
| #jarvis-divider { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| margin: 20px 0; | |
| opacity: 0.4; | |
| } | |
| #jarvis-divider::before, #jarvis-divider::after { | |
| content: ''; | |
| flex: 1; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, #00d4ff, transparent); | |
| } | |
| #jarvis-divider span { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 0.5rem; | |
| color: #00d4ff; | |
| letter-spacing: 0.3em; | |
| } | |
| @keyframes shimmer { | |
| 0% { background-position: 0% } | |
| 100% { background-position: 300% } | |
| } | |
| /* ══ STATUS BAR ══ */ | |
| #status-bar { | |
| background: rgba(0, 20, 50, 0.6) !important; | |
| border: 1px solid rgba(0, 212, 255, 0.2) !important; | |
| border-radius: 6px !important; | |
| padding: 10px 20px !important; | |
| margin-bottom: 16px !important; | |
| font-family: 'Share Tech Mono', monospace !important; | |
| font-size: 0.72rem !important; | |
| color: rgba(0, 212, 255, 0.6) !important; | |
| text-align: center; | |
| letter-spacing: 0.05em; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| #status-bar::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; left: -100%; | |
| width: 60%; height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(0,212,255,0.05), transparent); | |
| animation: scan 4s linear infinite; | |
| } | |
| @keyframes scan { | |
| 0% { left: -60%; } | |
| 100% { left: 160%; } | |
| } | |
| /* ══ CHAT WINDOW ══ */ | |
| .chat-wrap { | |
| background: rgba(0, 10, 30, 0.85) !important; | |
| border: 1px solid rgba(0, 212, 255, 0.2) !important; | |
| border-radius: 12px !important; | |
| overflow: hidden !important; | |
| box-shadow: | |
| 0 0 40px rgba(0, 212, 255, 0.08), | |
| 0 0 80px rgba(0, 50, 200, 0.06), | |
| inset 0 0 40px rgba(0, 0, 20, 0.5) !important; | |
| position: relative; | |
| } | |
| .chat-wrap::before { | |
| content: 'NEURAL INTERFACE'; | |
| position: absolute; | |
| top: 10px; right: 16px; | |
| font-family: 'Orbitron', monospace; | |
| font-size: 0.45rem; | |
| color: rgba(0,212,255,0.2); | |
| letter-spacing: 0.3em; | |
| z-index: 10; | |
| } | |
| /* Messages */ | |
| .message { | |
| font-family: 'Share Tech Mono', monospace !important; | |
| font-size: 0.88rem !important; | |
| line-height: 1.6 !important; | |
| border-radius: 8px !important; | |
| padding: 12px 16px !important; | |
| } | |
| .message.user { | |
| background: rgba(0, 80, 200, 0.12) !important; | |
| border: 1px solid rgba(0, 100, 255, 0.25) !important; | |
| color: rgba(160, 210, 255, 0.9) !important; | |
| } | |
| .message.bot, .message.assistant { | |
| background: rgba(0, 212, 255, 0.06) !important; | |
| border: 1px solid rgba(0, 212, 255, 0.2) !important; | |
| color: rgba(220, 245, 255, 0.9) !important; | |
| } | |
| /* ══ INPUT AREA ══ */ | |
| textarea, input[type="text"] { | |
| background: rgba(0, 8, 24, 0.95) !important; | |
| border: 1px solid rgba(0, 212, 255, 0.3) !important; | |
| border-radius: 8px !important; | |
| color: #00d4ff !important; | |
| font-family: 'Share Tech Mono', monospace !important; | |
| font-size: 0.9rem !important; | |
| caret-color: #00d4ff !important; | |
| transition: all 0.3s !important; | |
| padding: 12px 16px !important; | |
| } | |
| textarea:focus, input[type="text"]:focus { | |
| border-color: rgba(0, 212, 255, 0.8) !important; | |
| box-shadow: 0 0 20px rgba(0, 212, 255, 0.2), inset 0 0 10px rgba(0,212,255,0.03) !important; | |
| outline: none !important; | |
| } | |
| textarea::placeholder { color: rgba(0, 212, 255, 0.25) !important; } | |
| /* ══ BUTTONS ══ */ | |
| button { | |
| font-family: 'Orbitron', monospace !important; | |
| letter-spacing: 0.15em !important; | |
| font-size: 0.65rem !important; | |
| border-radius: 6px !important; | |
| transition: all 0.3s ease !important; | |
| text-transform: uppercase !important; | |
| } | |
| button.primary { | |
| background: transparent !important; | |
| border: 1px solid rgba(0, 212, 255, 0.8) !important; | |
| color: #00d4ff !important; | |
| padding: 10px 20px !important; | |
| } | |
| button.primary:hover { | |
| background: rgba(0, 212, 255, 0.1) !important; | |
| box-shadow: 0 0 25px rgba(0, 212, 255, 0.3), inset 0 0 15px rgba(0,212,255,0.05) !important; | |
| border-color: #00d4ff !important; | |
| } | |
| button.secondary { | |
| background: transparent !important; | |
| border: 1px solid rgba(0, 100, 255, 0.4) !important; | |
| color: rgba(80, 150, 255, 0.8) !important; | |
| } | |
| button.secondary:hover { | |
| background: rgba(0, 80, 200, 0.1) !important; | |
| border-color: rgba(0, 150, 255, 0.7) !important; | |
| box-shadow: 0 0 15px rgba(0, 100, 255, 0.2) !important; | |
| } | |
| /* ══ LABELS ══ */ | |
| label, .label-wrap span { | |
| font-family: 'Share Tech Mono', monospace !important; | |
| font-size: 0.65rem !important; | |
| color: rgba(0, 212, 255, 0.35) !important; | |
| letter-spacing: 0.25em !important; | |
| text-transform: uppercase !important; | |
| } | |
| /* ══ SCROLLBAR ══ */ | |
| ::-webkit-scrollbar { width: 3px; height: 3px; } | |
| ::-webkit-scrollbar-track { background: rgba(0,5,16,0.5); } | |
| ::-webkit-scrollbar-thumb { | |
| background: linear-gradient(180deg, #00d4ff44, #0066ff44); | |
| border-radius: 2px; | |
| } | |
| /* ══ CORNER DECORATIONS ══ */ | |
| #corner-tl, #corner-tr, #corner-bl, #corner-br { | |
| position: absolute; | |
| width: 20px; height: 20px; | |
| pointer-events: none; | |
| opacity: 0.5; | |
| } | |
| #corner-tl { top: 0; left: 0; border-top: 1px solid #00d4ff; border-left: 1px solid #00d4ff; } | |
| #corner-tr { top: 0; right: 0; border-top: 1px solid #00d4ff; border-right: 1px solid #00d4ff; } | |
| #corner-bl { bottom: 0; left: 0; border-bottom: 1px solid #00d4ff; border-left: 1px solid #00d4ff; } | |
| #corner-br { bottom: 0; right: 0; border-bottom: 1px solid #00d4ff; border-right: 1px solid #00d4ff; } | |
| """ | |
| # 🟢 ফিক্স: Gradio 6.0 অনুযায়ী Blocks এ css পাঠানো যাবে না | |
| with gr.Blocks(title="J.A.R.V.I.S — AI System") as demo: | |
| gr.HTML(""" | |
| <div id="jarvis-header"> | |
| <div id="jarvis-logo">JARVIS</div> | |
| <div id="jarvis-tagline">Just A Rather Very Intelligent System</div> | |
| </div> | |
| <div id="jarvis-divider"><span>◈ NEURAL LINK ESTABLISHED ◈</span></div> | |
| """) | |
| status_bar = gr.Markdown("◈ Connecting to JARVIS core...", elem_id="status-bar") | |
| with gr.Column(elem_classes="chat-wrap"): | |
| gr.HTML('<div id="corner-tl"></div><div id="corner-tr"></div><div id="corner-bl"></div><div id="corner-br"></div>') | |
| # 🟢 ফিক্স: Chatbot এ 'type="messages"' এর দরকার নেই (এখন এটাই ডিফল্ট) | |
| chatbot = gr.Chatbot( | |
| label="NEURAL INTERFACE", | |
| height=480, | |
| show_label=False | |
| ) | |
| with gr.Row(): | |
| msg_input = gr.Textbox( | |
| placeholder="▸ Command input — JARVIS-কে যা বলতে চাও লেখো...", | |
| show_label=False, | |
| scale=6, | |
| container=False, | |
| lines=1 | |
| ) | |
| send_btn = gr.Button("⚡ EXECUTE", variant="primary", scale=1) | |
| clear_btn = gr.Button("⊘ CLEAR", variant="secondary", scale=1) | |
| gr.HTML(""" | |
| <div style="text-align:center; margin-top:16px; font-family:'Share Tech Mono',monospace; | |
| font-size:0.6rem; color:rgba(0,212,255,0.2); letter-spacing:0.3em;"> | |
| ◈ JARVIS AI SYSTEM v1.0 | MULTI-BRAIN ENGINE | ENCRYPTED CHANNEL ◈ | |
| </div> | |
| """) | |
| send_btn.click(chat_with_jarvis, inputs=[msg_input, chatbot], outputs=[chatbot, msg_input]) | |
| msg_input.submit(chat_with_jarvis, inputs=[msg_input, chatbot], outputs=[chatbot, msg_input]) | |
| clear_btn.click(lambda: ([], ""), outputs=[chatbot, msg_input]) | |
| demo.load(get_status, outputs=status_bar) | |
| timer = gr.Timer(30) | |
| timer.tick(get_status, outputs=status_bar) | |
| # 🟢 ফিক্স: Gradio 6.0 অনুযায়ী css এখানে পাঠাতে হবে | |
| if __name__ == "__main__": | |
| demo.launch(css=custom_css) | |