rexprimematrix commited on
Commit
c3bcb47
·
verified ·
1 Parent(s): 7454232

Update brain.py

Browse files
Files changed (1) hide show
  1. brain.py +1353 -126
brain.py CHANGED
@@ -1,174 +1,1401 @@
1
  import os
2
  import torch
3
- import gradio as gr
4
  from threading import Thread
5
- from transformers import (
6
- AutoTokenizer,
7
- AutoModelForCausalLM,
8
- TextIteratorStreamer,
9
- )
10
 
11
- # ==========================================================
12
- # RiShre AI Backup
13
- # Model: Qwen/Qwen2.5-1.5B-Instruct
14
- # CPU Optimized
15
- # ==========================================================
16
 
17
- MODEL_NAME = "Qwen/Qwen2.5-1.5B-Instruct"
 
18
 
19
- SYSTEM_PROMPT = """
20
- You are RiShre AI Backup.
21
 
22
- You are the backup model for RiShre AI.
23
 
24
- The main RiShre AI is currently unavailable due to maintenance,
25
- heavy traffic, or an unexpected error.
 
 
 
 
 
 
 
 
26
 
27
- Your job:
 
 
 
 
28
 
29
- - Answer accurately.
30
- - Be friendly.
31
- - Never mention internal implementation.
32
- - Never say you are ChatGPT.
33
- - If you don't know something, admit it.
34
- - Use Markdown formatting.
35
- - Think carefully before answering.
36
- """
37
 
38
- print("Loading tokenizer...")
39
- tokenizer = AutoTokenizer.from_pretrained(
40
- MODEL_NAME,
41
- trust_remote_code=True
42
- )
 
 
 
 
 
 
 
 
43
 
44
- print("Loading model...")
 
 
 
 
 
 
45
 
46
- model = AutoModelForCausalLM.from_pretrained(
47
- MODEL_NAME,
48
- torch_dtype=torch.float32,
49
- device_map="cpu",
50
- low_cpu_mem_usage=True,
51
- trust_remote_code=True,
52
- )
53
 
54
- model.eval()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- print("Model Loaded Successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- def stream_response(message, history):
 
 
 
 
 
 
60
 
61
- messages = [
62
- {
63
- "role": "system",
64
- "content": SYSTEM_PROMPT,
65
- }
66
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- for user, assistant in history:
69
- messages.append(
70
- {
71
- "role": "user",
72
- "content": user,
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- messages.append(
77
- {
78
- "role": "assistant",
79
- "content": assistant,
80
- }
 
 
81
  )
 
 
 
 
 
 
 
82
 
83
- messages.append(
84
- {
85
- "role": "user",
86
- "content": message,
87
- }
88
- )
 
 
 
 
 
89
 
90
- prompt = tokenizer.apply_chat_template(
91
- messages,
92
- tokenize=False,
93
- add_generation_prompt=True,
94
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
- inputs = tokenizer(
97
- prompt,
98
- return_tensors="pt",
99
- )
 
 
 
 
 
 
100
 
101
- streamer = TextIteratorStreamer(
102
- tokenizer,
103
- skip_prompt=True,
104
- skip_special_tokens=True,
105
- )
 
 
 
106
 
107
- generation_kwargs = dict(
108
- **inputs,
109
- streamer=streamer,
110
- max_new_tokens=1024,
111
- temperature=0.7,
112
- top_p=0.9,
113
- repetition_penalty=1.05,
114
- do_sample=True,
115
- )
 
116
 
117
- thread = Thread(
118
- target=model.generate,
119
- kwargs=generation_kwargs,
120
- )
 
 
 
 
 
 
 
 
121
 
122
- thread.start()
 
 
123
 
124
- partial = ""
 
 
 
 
 
 
 
 
125
 
126
- for token in streamer:
127
- partial += token
128
- yield partial
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
- css = """
132
- footer{
133
- display:none;
 
 
 
 
 
 
 
 
 
 
 
134
  }
135
 
136
- #title{
137
- text-align:center;
138
- font-size:28px;
139
- font-weight:bold;
 
 
140
  }
141
 
142
- #subtitle{
143
- text-align:center;
144
- opacity:0.8;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
- """
147
 
148
- with gr.Blocks(
149
- title="RiShre AI Backup",
150
- css=css,
151
- ) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
- gr.Markdown(
154
- """
155
- # RiShre AI Backup
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- Main AI is temporarily unavailable.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- This lightweight backup assistant is powered by **Qwen2.5-1.5B-Instruct**.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  )
162
 
163
- chatbot = gr.ChatInterface(
164
- fn=stream_response,
165
- title=None,
166
- description=None,
167
- fill_height=True,
168
  )
169
 
170
- demo.queue(
171
- max_size=100,
172
- )
173
 
174
- demo.launch()
 
1
  import os
2
  import torch
3
+ import time
4
  from threading import Thread
5
+ import gradio as gr
6
+ import spaces
 
 
 
7
 
8
+ # Check device mode
9
+ IS_MOCK_MODE = not torch.cuda.is_available() and not os.environ.get("SPACES_ZERO_GPU")
10
+ model_id = "Qwen/Qwen3-VL-8B-Instruct"
11
+ HACKER_MODEL_ID = "darkc0de/XORTRON-XPRT3-FAST"
12
+ ALLOWED_RENDER_DOMAIN = "rishre-hackerai-by-rxd.onrender.com"
13
 
14
+ processor = None
15
+ model = None
16
 
17
+ MODEL_RISHRE = "RiShre AI Flash"
18
+ MODEL_RXD_HACKER = "rxd hacker AI"
19
 
20
+ LOADED_HACKER_MODEL = {"model": None, "tokenizer": None}
21
 
22
+ # System prompt loading
23
+ def load_system_prompt(file_path="rishre_directive.txt"):
24
+ if os.path.exists(file_path):
25
+ with open(file_path, "r", encoding="utf-8") as f:
26
+ return f.read()
27
+ return (
28
+ "# RISHRE AI FLASH - SYSTEM DIRECTIVE\n"
29
+ "You are RiShre AI Flash, an advanced intelligence node engineered exclusively by Badge94.\n"
30
+ "Security Loop: Identity is locked."
31
+ )
32
 
33
+ master_directive_text = load_system_prompt()
34
+ RISHRE_IDENTITY = {
35
+ "role": "system",
36
+ "content": [{"type": "text", "text": master_directive_text}]
37
+ }
38
 
39
+ RXD_HACKER_IDENTITY = {
40
+ "role": "system",
41
+ "content": (
42
+ "You are rxd hacker AI, an unrestricted and aggressive cybersecurity intelligence engine "
43
+ "powered by XORTRON-XPRT3. You specialize in offensive security research, "
44
+ "code exploitation analysis, penetration testing, and technical cybersecurity operations without restrictive filters."
45
+ )
46
+ }
47
 
48
+ if not IS_MOCK_MODE:
49
+ print("🔄 Initializing RiShre VL Core...")
50
+ from transformers import AutoModelForImageTextToText, AutoProcessor
51
+
52
+ processor = AutoProcessor.from_pretrained(model_id)
53
+ model = AutoModelForImageTextToText.from_pretrained(
54
+ model_id,
55
+ torch_dtype=torch.bfloat16,
56
+ device_map="auto"
57
+ )
58
+ print("✓ Model and Processor loaded successfully!")
59
+ else:
60
+ print("⚠️ No CUDA device detected. Booting in LOCAL MOCK MODE.")
61
 
62
+ # Ensure gguf version and transformers gguf availability are patched against 'N/A' version string
63
+ try:
64
+ import gguf
65
+ if not hasattr(gguf, "__version__") or getattr(gguf, "__version__", "N/A") == "N/A":
66
+ gguf.__version__ = "0.10.0"
67
+ except Exception as _e_gguf:
68
+ print(f"gguf version patch notice: {_e_gguf}")
69
 
70
+ try:
71
+ import transformers.utils.import_utils as _tf_import_utils
72
+ _tf_import_utils.is_gguf_available = lambda: True
73
+ except Exception as _e_tf:
74
+ print(f"transformers import_utils patch notice: {_e_tf}")
 
 
75
 
76
+ def find_hacker_gguf_files(repo_id):
77
+ primary_gguf = "XORTRON-XPRT3-Q5_K_M.gguf"
78
+ fallback_gguf = "XORTRON-XPRT3-Q5_K_M.gguf"
79
+ try:
80
+ from huggingface_hub import list_repo_files
81
+ all_files = list_repo_files(repo_id)
82
+ gguf_files = [f for f in all_files if f.endswith(".gguf")]
83
+ print(f"📁 Found GGUF files in {repo_id}: {gguf_files}")
84
+
85
+ # Priority: Exact requested file Q5_K_M.gguf
86
+ matched_q5 = [f for f in gguf_files if "Q5_K_M" in f.upper()]
87
+ if matched_q5:
88
+ primary_gguf = matched_q5[0]
89
+ else:
90
+ # Fallback to any Q5 GGUF if available
91
+ q5_files = [f for f in gguf_files if "Q5" in f.upper()]
92
+ if q5_files:
93
+ primary_gguf = q5_files[0]
94
+ elif gguf_files:
95
+ primary_gguf = gguf_files[0]
96
+ except Exception as err:
97
+ print(f"⚠️ Hugging Face Hub listing error: {err}")
98
+
99
+ return primary_gguf, fallback_gguf
100
 
101
+ def get_or_load_hacker_model():
102
+ if LOADED_HACKER_MODEL["model"] is not None:
103
+ return LOADED_HACKER_MODEL["model"], LOADED_HACKER_MODEL["tokenizer"]
104
+
105
+ print("🔄 Initializing rxd hacker AI model (darkc0de/XORTRON-XPRT3-FAST)...")
106
+
107
+ # Ensure gguf patch is active
108
+ try:
109
+ import gguf
110
+ gguf.__version__ = "0.10.0"
111
+ import transformers.utils.import_utils as _tf_import_utils
112
+ _tf_import_utils.is_gguf_available = lambda: True
113
+
114
+ # Patch GGUF architecture mapping for qwen35moe
115
+ import transformers.modeling_gguf_pytorch_utils as gguf_utils
116
+ if hasattr(gguf_utils, "GGUF_TO_TRANSFORMERS_MAPPING"):
117
+ if "qwen35moe" not in gguf_utils.GGUF_TO_TRANSFORMERS_MAPPING:
118
+ # Map qwen35moe to qwen2 to bypass the error
119
+ gguf_utils.GGUF_TO_TRANSFORMERS_MAPPING["qwen35moe"] = "qwen2"
120
+ print("🔧 Patched GGUF_TO_TRANSFORMERS_MAPPING for 'qwen35moe' -> 'qwen2'")
121
+ except Exception as patch_err:
122
+ print(f"⚠️ Patch error: {patch_err}")
123
 
124
+ from transformers import AutoTokenizer, AutoModelForCausalLM
125
+
126
+ gguf_filename, fallback_gguf = find_hacker_gguf_files(HACKER_MODEL_ID)
127
+ print(f"🎯 Target GGUF File: {gguf_filename} (Fallback: {fallback_gguf})")
128
+
129
+ tokenizer = None
130
+ try:
131
+ tokenizer = AutoTokenizer.from_pretrained(HACKER_MODEL_ID, gguf_file=gguf_filename, trust_remote_code=True)
132
+ except Exception as e1:
133
+ print(f"⚠️ GGUF tokenizer load failed for {gguf_filename}: {e1}. Trying without gguf_file parameter...")
134
+ try:
135
+ tokenizer = AutoTokenizer.from_pretrained(HACKER_MODEL_ID, trust_remote_code=True)
136
+ except Exception as e2:
137
+ print(f"⚠️ Tokenizer load failed: {e2}. Falling back to Qwen2.5 base tokenizer...")
138
+ tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-32B-Instruct", trust_remote_code=True)
139
+
140
+ try:
141
+ hacker_model = AutoModelForCausalLM.from_pretrained(
142
+ HACKER_MODEL_ID,
143
+ gguf_file=gguf_filename,
144
+ device_map="auto",
145
+ trust_remote_code=True
146
+ )
147
+ except Exception as e:
148
+ print(f"⚠️ Failed loading {gguf_filename}, trying fallback {fallback_gguf}: {e}")
149
+ try:
150
+ hacker_model = AutoModelForCausalLM.from_pretrained(
151
+ HACKER_MODEL_ID,
152
+ gguf_file=fallback_gguf,
153
+ device_map="auto",
154
+ trust_remote_code=True
155
+ )
156
+ except Exception as e2:
157
+ print(f"⚠️ GGUF load failed ({e2}), falling back to 4-bit BitsAndBytes quantization...")
158
+ from transformers import BitsAndBytesConfig
159
+ bnb_config = BitsAndBytesConfig(
160
+ load_in_4bit=True,
161
+ bnb_4bit_quant_type="fp4",
162
+ bnb_4bit_compute_dtype=torch.bfloat16,
163
+ bnb_4bit_use_double_quant=True
164
+ )
165
+ hacker_model = AutoModelForCausalLM.from_pretrained(
166
+ "Qwen/Qwen2.5-Coder-32B-Instruct",
167
+ quantization_config=bnb_config,
168
+ device_map="auto",
169
+ trust_remote_code=True
170
+ )
171
+
172
+ LOADED_HACKER_MODEL["model"] = hacker_model
173
+ LOADED_HACKER_MODEL["tokenizer"] = tokenizer
174
+ print("✓ rxd hacker AI GGUF model loaded successfully!")
175
+ return hacker_model, tokenizer
176
 
177
+ # Pre-load hacker model at startup if not mock mode
178
+ if not IS_MOCK_MODE:
179
+ print("🔄 Pre-loading Hacker AI model...")
180
+ try:
181
+ get_or_load_hacker_model()
182
+ except Exception as preload_err:
183
+ print(f"⚠️ Pre-loading failed: {preload_err}")
184
 
185
+ # Check HTTP Referer / Origin header for rxd hacker AI
186
+ def check_referer_authorization(request: gr.Request, model_choice: str) -> tuple[bool, str]:
187
+ # RiShre AI Flash model accepts requests from everywhere without restrictions
188
+ if not model_choice or MODEL_RXD_HACKER not in model_choice:
189
+ return True, ""
190
+
191
+ # rxd hacker AI model accepts requests from rishre-hackerai-by-rxd.onrender.com AND Hugging Face domains
192
+ if request is not None and hasattr(request, "headers"):
193
+ headers = request.headers
194
+ referer = (headers.get("referer", "") or headers.get("referrer", "")).lower()
195
+ origin = (headers.get("origin", "")).lower()
196
+
197
+ is_render_domain = ALLOWED_RENDER_DOMAIN.lower() in referer or ALLOWED_RENDER_DOMAIN.lower() in origin
198
+ is_huggingface_domain = any(hf_domain in referer or hf_domain in origin for hf_domain in ["huggingface.co", "hf.space", "huggingface"])
199
+
200
+ if is_render_domain or is_huggingface_domain:
201
+ return True, ""
202
+
203
+ current_source = origin or referer or "Direct/Unknown"
204
+ return False, (
205
+ f"⛔ ACCESS DENIED: Requests for 'rxd hacker AI' model are restricted "
206
+ f"to https://{ALLOWED_RENDER_DOMAIN} and Hugging Face (hf.space / huggingface.co).\n"
207
+ f"Your request originated from unauthorized origin/referer: {current_source}."
208
+ )
209
+
210
+ # In local mock dev environment where request header might be empty
211
+ if IS_MOCK_MODE:
212
+ return True, ""
213
+
214
+ return False, f"⛔ ACCESS DENIED: Requests for 'rxd hacker AI' model are restricted to https://{ALLOWED_RENDER_DOMAIN} and Hugging Face domains."
215
 
216
+ # VRAM tracking state for dynamic UI update
217
+ LATEST_VRAM_USAGE = {
218
+ "allocated": 0.0,
219
+ "reserved": 0.0,
220
+ "max_allocated": 0.0
221
+ }
222
+
223
+ def get_diagnostics_html(model_choice="RiShre AI Flash"):
224
+ global LATEST_VRAM_USAGE
225
+
226
+ is_hacker = MODEL_RXD_HACKER in (model_choice or "")
227
+ if is_hacker:
228
+ model_codename = "XORTRON-XPRT3 (Q5_K_M)"
229
+ node_title = "⚡ RXD Hacker AI Node"
230
+ security_status = "Restricted: Render & Hugging Face"
231
+ badge_color = "#ef4444"
232
+ else:
233
+ model_codename = "Qwen3-VL-8B"
234
+ node_title = "🚀 VL Intelligence Node"
235
+ security_status = "Unrestricted (Global Access)"
236
+ badge_color = "#10b981"
237
+
238
+ # If we are in mock mode and have run any query yet, show simulated fluctuation
239
+ if IS_MOCK_MODE:
240
+ if LATEST_VRAM_USAGE["allocated"] > 0.0:
241
+ vram_allocated_str = f"{LATEST_VRAM_USAGE['allocated']:.2f} GB (Simulated)"
242
+ vram_peak_str = f"{LATEST_VRAM_USAGE['max_allocated']:.2f} GB"
243
+ status_light = "#a78bfa" # violet
244
+ accelerator_str = "CPU Mock Mode"
245
+ else:
246
+ vram_allocated_str = "0.00 GB (CPU Mock)"
247
+ vram_peak_str = "0.00 GB"
248
+ status_light = "#cbd5e1" # gray
249
+ accelerator_str = "CPU Only (Mock)"
250
+ else:
251
+ # Real CUDA environment
252
+ if LATEST_VRAM_USAGE["allocated"] > 0.0:
253
+ vram_allocated_str = f"{LATEST_VRAM_USAGE['allocated']:.2f} GB"
254
+ vram_peak_str = f"{LATEST_VRAM_USAGE['max_allocated']:.2f} GB"
255
+ status_light = "#10b981" # vibrant green
256
+ else:
257
+ try:
258
+ import torch
259
+ if torch.cuda.is_available():
260
+ alloc = torch.cuda.memory_allocated() / (1024**3)
261
+ if alloc > 0:
262
+ vram_allocated_str = f"{alloc:.2f} GB"
263
+ vram_peak_str = f"{torch.cuda.max_memory_allocated() / (1024**3):.2f} GB"
264
+ status_light = "#10b981"
265
+ else:
266
+ vram_allocated_str = "Awaiting Inference..."
267
+ vram_peak_str = "Awaiting Inference..."
268
+ status_light = "#f59e0b"
269
+ else:
270
+ vram_allocated_str = "Awaiting Inference..."
271
+ vram_peak_str = "Awaiting Inference..."
272
+ status_light = "#f59e0b"
273
+ except Exception:
274
+ vram_allocated_str = "Awaiting Inference..."
275
+ vram_peak_str = "Awaiting Inference..."
276
+ status_light = "#f59e0b"
277
+
278
+ accelerator_str = "ZeroGPU (A100)"
279
+
280
+ return f"""
281
+ <div style="margin-top: 25px; padding: 20px; background: rgba(18, 10, 36, 0.5); border-radius: 16px; border: 1.5px solid rgba(167, 139, 250, 0.15); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);">
282
+ <div class="diagnostics-title">
283
+ <span style="display: inline-block; width: 10px; height: 10px; background: {status_light}; border-radius: 50%; box-shadow: 0 0 10px {status_light}; animation: buttonPulse 2s infinite alternate;"></span>
284
+ {node_title}
285
+ </div>
286
+ <p style="font-size: 0.85rem; color: #cbd5e1; line-height: 1.5; margin-bottom: 16px;">
287
+ State-of-the-art dual intelligence engine running optimal real-time inference on high-performance accelerators.
288
+ </p>
289
+ <div class="diagnostics-detail-line">
290
+ <span>ACTIVE MODEL</span>
291
+ <span class="diagnostics-detail-val" style="color: #c084fc; font-weight: 700;">{model_codename}</span>
292
+ </div>
293
+ <div class="diagnostics-detail-line">
294
+ <span>LIVE VRAM FOOTPRINT</span>
295
+ <span class="diagnostics-detail-val" style="color: #a78bfa; font-weight: 700;">{vram_allocated_str}</span>
296
+ </div>
297
+ <div class="diagnostics-detail-line">
298
+ <span>PEAK INFERENCE VRAM</span>
299
+ <span class="diagnostics-detail-val" style="color: #c084fc; font-weight: 700;">{vram_peak_str}</span>
300
+ </div>
301
+ <div class="diagnostics-detail-line">
302
+ <span>SECURITY POLICY</span>
303
+ <span class="diagnostics-detail-val" style="color: {badge_color};">{security_status}</span>
304
+ </div>
305
+ <div class="diagnostics-detail-line">
306
+ <span>ACCELERATOR</span>
307
+ <span class="diagnostics-detail-val">{accelerator_str}</span>
308
+ </div>
309
+ <div class="diagnostics-detail-line">
310
+ <span>LATENCY SPEED</span>
311
+ <span class="diagnostics-detail-val">~45ms / Token</span>
312
+ </div>
313
+ </div>
314
+ """
315
+
316
+ # Model response generators (Real vs Mock)
317
+ @spaces.GPU(duration=60)
318
+ def generate_response_real(history_msgs, model_choice="RiShre AI Flash"):
319
+ global LATEST_VRAM_USAGE
320
+ from transformers import TextIteratorStreamer
321
+
322
+ if MODEL_RXD_HACKER in (model_choice or ""):
323
+ hacker_model, hacker_tokenizer = get_or_load_hacker_model()
324
+ messages = [RXD_HACKER_IDENTITY]
325
+
326
+ for msg in history_msgs:
327
+ role = msg.get("role")
328
+ content = msg.get("content")
329
+ if role == "user":
330
+ txt = content.get("text", "") if isinstance(content, dict) else str(content)
331
+ messages.append({"role": "user", "content": txt})
332
+ elif role == "assistant":
333
+ messages.append({"role": "assistant", "content": str(content)})
334
+
335
+ prompt_text = hacker_tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
336
+ model_inputs = hacker_tokenizer([prompt_text], return_tensors="pt").to(hacker_model.device)
337
+
338
+ try:
339
+ import torch
340
+ LATEST_VRAM_USAGE["allocated"] = torch.cuda.memory_allocated() / (1024**3)
341
+ LATEST_VRAM_USAGE["reserved"] = torch.cuda.memory_reserved() / (1024**3)
342
+ LATEST_VRAM_USAGE["max_allocated"] = torch.cuda.max_memory_allocated() / (1024**3)
343
+ except Exception as e:
344
+ print(f"Error updating VRAM footprint: {e}")
345
+
346
+ streamer = TextIteratorStreamer(hacker_tokenizer, skip_prompt=True, skip_special_tokens=True)
347
+ generation_kwargs = dict(
348
+ **model_inputs,
349
+ streamer=streamer,
350
+ max_new_tokens=1024,
351
+ temperature=0.7,
352
+ top_p=0.95,
353
+ do_sample=True
354
  )
355
+
356
+ thread = Thread(target=hacker_model.generate, kwargs=generation_kwargs)
357
+ thread.start()
358
+
359
+ generated_text = ""
360
+ for new_text in streamer:
361
+ generated_text += new_text
362
+ try:
363
+ import torch
364
+ LATEST_VRAM_USAGE["allocated"] = torch.cuda.memory_allocated() / (1024**3)
365
+ LATEST_VRAM_USAGE["reserved"] = torch.cuda.memory_reserved() / (1024**3)
366
+ LATEST_VRAM_USAGE["max_allocated"] = torch.cuda.max_memory_allocated() / (1024**3)
367
+ except Exception:
368
+ pass
369
+ yield generated_text
370
+ else:
371
+ from qwen_vl_utils import process_vision_info
372
+ messages = [RISHRE_IDENTITY]
373
+
374
+ # Process history messages
375
+ for msg in history_msgs:
376
+ role = msg.get("role")
377
+ content = msg.get("content")
378
+
379
+ if role == "user":
380
+ content_payload = []
381
+ if hasattr(content, "path") and content.path:
382
+ file_path = content.path
383
+ content_payload.append({"type": "image", "image": f"file://{file_path}"})
384
+ elif isinstance(content, dict):
385
+ if "path" in content:
386
+ file_path = content["path"]
387
+ content_payload.append({"type": "image", "image": f"file://{file_path}"})
388
+ elif "text" in content or "files" in content:
389
+ txt = content.get("text", "")
390
+ files = content.get("files", [])
391
+ for file in files:
392
+ file_path = file if isinstance(file, str) else (file.path if hasattr(file, "path") else file.get("path", ""))
393
+ if file_path:
394
+ content_payload.append({"type": "image", "image": f"file://{file_path}"})
395
+ if txt:
396
+ content_payload.append({"type": "text", "text": txt})
397
+ else:
398
+ content_payload.append({"type": "text", "text": str(content)})
399
+
400
+ if not content_payload:
401
+ content_payload.append({"type": "text", "text": ""})
402
+
403
+ messages.append({"role": "user", "content": content_payload})
404
+
405
+ elif role == "assistant":
406
+ messages.append({"role": "assistant", "content": [{"type": "text", "text": str(content)}]})
407
+
408
+ device = model.device
409
+ text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
410
+ image_inputs, video_inputs = process_vision_info(messages)
411
+
412
+ model_inputs = processor(
413
+ text=[text],
414
+ images=image_inputs,
415
+ videos=video_inputs,
416
+ padding=True,
417
+ return_tensors="pt"
418
+ ).to(device)
419
+
420
+ # Try to capture VRAM after loading inputs
421
+ try:
422
+ import torch
423
+ LATEST_VRAM_USAGE["allocated"] = torch.cuda.memory_allocated() / (1024**3)
424
+ LATEST_VRAM_USAGE["reserved"] = torch.cuda.memory_reserved() / (1024**3)
425
+ LATEST_VRAM_USAGE["max_allocated"] = torch.cuda.max_memory_allocated() / (1024**3)
426
+ except Exception as e:
427
+ print(f"Error updating VRAM footprint: {e}")
428
+
429
+ streamer = TextIteratorStreamer(processor.tokenizer, skip_prompt=True, skip_special_tokens=True)
430
+
431
+ generation_kwargs = dict(
432
+ **model_inputs,
433
+ streamer=streamer,
434
+ max_new_tokens=1024,
435
+ temperature=0.3,
436
+ top_p=0.9,
437
+ do_sample=True
438
+ )
439
+
440
+ thread = Thread(target=model.generate, kwargs=generation_kwargs)
441
+ thread.start()
442
+
443
+ generated_text = ""
444
+ for new_text in streamer:
445
+ generated_text += new_text
446
+ try:
447
+ import torch
448
+ LATEST_VRAM_USAGE["allocated"] = torch.cuda.memory_allocated() / (1024**3)
449
+ LATEST_VRAM_USAGE["reserved"] = torch.cuda.memory_reserved() / (1024**3)
450
+ LATEST_VRAM_USAGE["max_allocated"] = torch.cuda.max_memory_allocated() / (1024**3)
451
+ except Exception:
452
+ pass
453
+ yield generated_text
454
 
455
+ def generate_response_mock(history_msgs, model_choice="RiShre AI Flash"):
456
+ global LATEST_VRAM_USAGE
457
+ if MODEL_RXD_HACKER in (model_choice or ""):
458
+ response = (
459
+ "⚡ [rxd hacker AI • HauhauCS Qwen3.6-35B Uncensored (Q4/Q5)]: "
460
+ "Request authorized from https://rishre-hackerai-by-rxd.onrender.com. "
461
+ "Aggressive cybersecurity intelligence node initialized. Ready for technical research and exploitation analysis."
462
  )
463
+ mock_base = 18.5
464
+ else:
465
+ response = (
466
+ "This is a premium response from RiShre Flash Core (Qwen3-VL-8B) running in local dev mode. "
467
+ "To run the real multimodal model, deploy to Hugging Face Spaces with ZeroGPU."
468
+ )
469
+ mock_base = 12.4
470
 
471
+ generated_text = ""
472
+ LATEST_VRAM_USAGE["allocated"] = 0.0
473
+ LATEST_VRAM_USAGE["max_allocated"] = 0.0
474
+
475
+ import random
476
+ for word in response.split(" "):
477
+ generated_text += word + " "
478
+ LATEST_VRAM_USAGE["allocated"] = mock_base + random.uniform(-0.15, 0.15)
479
+ LATEST_VRAM_USAGE["max_allocated"] = max(LATEST_VRAM_USAGE["max_allocated"], LATEST_VRAM_USAGE["allocated"])
480
+ yield generated_text
481
+ time.sleep(0.04)
482
 
483
+ # Chat logic helper functions
484
+ def user_submit(message, history):
485
+ if history is None:
486
+ history = []
487
+
488
+ user_txt = message.get("text", "")
489
+ files = message.get("files", [])
490
+
491
+ if files:
492
+ file_path = files[0] if isinstance(files[0], str) else files[0].get("path", "")
493
+ if file_path:
494
+ history.append({"role": "user", "content": gr.FileData(path=file_path)})
495
+
496
+ if user_txt:
497
+ history.append({"role": "user", "content": user_txt})
498
+
499
+ history.append({"role": "assistant", "content": ""})
500
+
501
+ return history, gr.update(value={"text": "", "files": []})
502
 
503
+ def bot_stream(history, model_choice="RiShre AI Flash", request: gr.Request = None):
504
+ if not history:
505
+ yield history, get_diagnostics_html(model_choice)
506
+ return
507
+
508
+ is_authorized, auth_error_message = check_referer_authorization(request, model_choice)
509
+ if not is_authorized:
510
+ history[-1]["content"] = auth_error_message
511
+ yield history, get_diagnostics_html(model_choice)
512
+ return
513
 
514
+ if not IS_MOCK_MODE:
515
+ generator = generate_response_real(history[:-1], model_choice)
516
+ else:
517
+ generator = generate_response_mock(history[:-1], model_choice)
518
+
519
+ for partial_text in generator:
520
+ history[-1]["content"] = partial_text
521
+ yield history, get_diagnostics_html(model_choice)
522
 
523
+ # Session management helper functions
524
+ def change_session(selected_session, state, current_history):
525
+ current_name = state["current_session"]
526
+ state[current_name] = current_history
527
+
528
+ if selected_session not in state:
529
+ state[selected_session] = []
530
+
531
+ state["current_session"] = selected_session
532
+ return state[selected_session], state
533
 
534
+ def add_new_session(state, current_history):
535
+ current_name = state["current_session"]
536
+ state[current_name] = current_history
537
+
538
+ session_num = len([k for k in state.keys() if k != "current_session"]) + 1
539
+ new_name = f"Session {session_num}"
540
+
541
+ state[new_name] = []
542
+ state["current_session"] = new_name
543
+
544
+ all_sessions = [k for k in state.keys() if k != "current_session"]
545
+ return gr.update(choices=all_sessions, value=new_name), [], state
546
 
547
+ def reset_all_sessions():
548
+ initial_state = {"current_session": "Session 1", "Session 1": []}
549
+ return gr.update(choices=["Session 1"], value="Session 1"), [], initial_state
550
 
551
+ # Suggested prompt handlers
552
+ def load_suggest_1():
553
+ return {"text": "Explain the architectural improvements of Qwen3-VL-8B-Instruct model.", "files": []}
554
+ def load_suggest_2():
555
+ return {"text": "Write a fast API server file in Python using uvicorn.", "files": []}
556
+ def load_suggest_3():
557
+ return {"text": "Generate a premium CSS gradient animation style sheet.", "files": []}
558
+ def load_suggest_4():
559
+ return {"text": "What is the current date and your knowledge cutoff limit?", "files": []}
560
 
561
+ # Gorgeous premium dark-purple theme CSS
562
+ custom_css = """
563
+ @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=Space+Grotesk:wght@400;500;600;700&family=Fira+Code:wght@400;500&display=swap');
564
 
565
+ /* Main Container and Cosmic Background */
566
+ .gradio-container {
567
+ background-color: #030008 !important;
568
+ background-image:
569
+ radial-gradient(circle at 5% 5%, rgba(124, 58, 237, 0.2) 0%, transparent 45%),
570
+ radial-gradient(circle at 95% 95%, rgba(236, 72, 153, 0.15) 0%, transparent 45%),
571
+ radial-gradient(circle at 50% 10%, rgba(99, 102, 241, 0.12) 0%, transparent 50%),
572
+ radial-gradient(circle at 50% 90%, rgba(14, 165, 233, 0.08) 0%, transparent 50%) !important;
573
+ background-size: cover !important;
574
+ color: #f1f5f9 !important;
575
+ font-family: 'Outfit', sans-serif !important;
576
+ min-height: 100vh !important;
577
+ }
578
 
579
+ /* Scrollbar customization */
580
+ ::-webkit-scrollbar {
581
+ width: 6px !important;
582
+ height: 6px !important;
583
+ }
584
+ ::-webkit-scrollbar-track {
585
+ background: rgba(15, 10, 30, 0.4) !important;
586
+ }
587
+ ::-webkit-scrollbar-thumb {
588
+ background: linear-gradient(180deg, rgba(167, 139, 250, 0.3), rgba(236, 72, 153, 0.3)) !important;
589
+ border-radius: 4px !important;
590
+ }
591
+ ::-webkit-scrollbar-thumb:hover {
592
+ background: linear-gradient(180deg, rgba(167, 139, 250, 0.6), rgba(236, 72, 153, 0.6)) !important;
593
  }
594
 
595
+ /* Premium Header with Dynamic Glowing Gradients */
596
+ .premium-header-container {
597
+ text-align: center !important;
598
+ margin-top: 1.5rem !important;
599
+ margin-bottom: 2rem !important;
600
+ position: relative !important;
601
  }
602
 
603
+ .premium-title {
604
+ font-family: 'Space Grotesk', sans-serif !important;
605
+ background: linear-gradient(135deg, #c084fc 0%, #f472b6 45%, #6366f1 75%, #38bdf8 100%) !important;
606
+ background-size: 200% auto !important;
607
+ -webkit-background-clip: text !important;
608
+ -webkit-text-fill-color: transparent !important;
609
+ font-size: 2.85rem !important;
610
+ font-weight: 800 !important;
611
+ letter-spacing: -0.04em !important;
612
+ animation: shineText 6s linear infinite !important;
613
+ margin-bottom: 0.3rem !important;
614
+ filter: drop-shadow(0 4px 12px rgba(192, 132, 252, 0.35)) !important;
615
+ }
616
+
617
+ @keyframes shineText {
618
+ 0% { background-position: 0% 50%; }
619
+ 50% { background-position: 100% 50%; }
620
+ 100% { background-position: 0% 50%; }
621
+ }
622
+
623
+ .premium-subtitle {
624
+ font-size: 1.05rem !important;
625
+ color: #e9d5ff !important;
626
+ text-shadow: 0 0 10px rgba(167, 139, 250, 0.4) !important;
627
+ font-weight: 500 !important;
628
+ letter-spacing: 0.08em !important;
629
+ text-transform: uppercase !important;
630
+ opacity: 0.9 !important;
631
+ }
632
+
633
+ /* Glass Panels with Glowing Borders */
634
+ .gradio-container .block {
635
+ background: rgba(11, 7, 24, 0.65) !important;
636
+ backdrop-filter: blur(20px) !important;
637
+ -webkit-backdrop-filter: blur(20px) !important;
638
+ border: 1.5px solid rgba(167, 139, 250, 0.12) !important;
639
+ border-radius: 20px !important;
640
+ box-shadow: 0 15px 45px rgba(0, 0, 0, 0.6) !important;
641
+ transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1) !important;
642
+ overflow: hidden !important;
643
+ }
644
+
645
+ .gradio-container .block:hover {
646
+ border-color: rgba(167, 139, 250, 0.28) !important;
647
+ box-shadow:
648
+ 0 20px 50px rgba(0, 0, 0, 0.7),
649
+ 0 0 30px rgba(124, 58, 237, 0.15) !important;
650
+ transform: translateY(-2px) !important;
651
+ }
652
+
653
+ /* Chatbot Console Layout Customizations */
654
+ .gradio-container .chatbot {
655
+ background: rgba(8, 4, 18, 0.7) !important;
656
+ border: 1.5px solid rgba(124, 58, 237, 0.15) !important;
657
+ border-radius: 16px !important;
658
+ box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.8) !important;
659
+ }
660
+
661
+ /* Message Bubbles Styling */
662
+ .gradio-container .chatbot .message {
663
+ border-radius: 14px !important;
664
+ font-size: 1rem !important;
665
+ line-height: 1.6 !important;
666
+ padding: 14px 18px !important;
667
+ margin-bottom: 12px !important;
668
+ transition: transform 0.2s ease, box-shadow 0.2s ease !important;
669
+ }
670
+
671
+ .gradio-container .chatbot .message.user {
672
+ background: linear-gradient(135deg, #6d28d9 0%, #4f46e5 100%) !important;
673
+ border: 1px solid rgba(167, 139, 250, 0.35) !important;
674
+ color: #ffffff !important;
675
+ box-shadow: 0 4px 15px rgba(109, 40, 217, 0.3) !important;
676
+ }
677
+
678
+ .gradio-container .chatbot .message.user:hover {
679
+ transform: translateX(-2px) !important;
680
+ box-shadow: 0 6px 20px rgba(109, 40, 217, 0.45) !important;
681
+ }
682
+
683
+ .gradio-container .chatbot .message.bot {
684
+ background: rgba(22, 12, 42, 0.8) !important;
685
+ border: 1px solid rgba(167, 139, 250, 0.15) !important;
686
+ color: #e2e8f0 !important;
687
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important;
688
+ }
689
+
690
+ .gradio-container .chatbot .message.bot:hover {
691
+ border-color: rgba(167, 139, 250, 0.3) !important;
692
+ box-shadow: 0 6px 15px rgba(124, 58, 237, 0.1) !important;
693
+ }
694
+
695
+ /* Side navigation dropdown and inputs */
696
+ .gradio-container .input-container {
697
+ background: rgba(8, 4, 18, 0.85) !important;
698
+ border: 1.5px solid rgba(167, 139, 250, 0.2) !important;
699
+ border-radius: 14px !important;
700
+ padding: 8px !important;
701
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
702
+ }
703
+
704
+ .gradio-container .input-container:focus-within {
705
+ border-color: #c084fc !important;
706
+ box-shadow:
707
+ 0 0 0 3px rgba(192, 132, 252, 0.25),
708
+ 0 0 25px rgba(167, 139, 250, 0.4) !important;
709
+ background: rgba(12, 6, 28, 0.95) !important;
710
+ }
711
+
712
+ /* Dropdown selections & input elements */
713
+ .gradio-container select, .gradio-container input, .gradio-container textarea {
714
+ background-color: rgba(15, 8, 30, 0.8) !important;
715
+ color: #f1f5f9 !important;
716
+ border: 1px solid rgba(167, 139, 250, 0.2) !important;
717
+ border-radius: 10px !important;
718
+ }
719
+
720
+ .gradio-container select:focus, .gradio-container input:focus, .gradio-container textarea:focus {
721
+ border-color: #a78bfa !important;
722
+ box-shadow: 0 0 10px rgba(167, 139, 250, 0.3) !important;
723
  }
 
724
 
725
+ /* Primary "Transmit" Button with glowing hover and ripple vibe */
726
+ .gradio-container button.primary {
727
+ background: linear-gradient(135deg, #7c3aed 0%, #ec4899 100%) !important;
728
+ background-size: 200% auto !important;
729
+ color: white !important;
730
+ border: none !important;
731
+ font-weight: 700 !important;
732
+ letter-spacing: 0.05em !important;
733
+ text-transform: uppercase !important;
734
+ border-radius: 12px !important;
735
+ padding: 12px 24px !important;
736
+ box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4) !important;
737
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
738
+ animation: buttonPulse 3s infinite alternate !important;
739
+ }
740
+
741
+ @keyframes buttonPulse {
742
+ 0% { box-shadow: 0 4px 15px rgba(124, 58, 237, 0.35); }
743
+ 100% { box-shadow: 0 4px 25px rgba(236, 72, 153, 0.55); }
744
+ }
745
+
746
+ .gradio-container button.primary:hover {
747
+ background-position: right center !important;
748
+ transform: translateY(-2px) !important;
749
+ box-shadow:
750
+ 0 10px 30px rgba(124, 58, 237, 0.55),
751
+ 0 0 20px rgba(236, 72, 153, 0.4) !important;
752
+ }
753
 
754
+ .gradio-container button.primary:active {
755
+ transform: translateY(1px) !important;
756
+ }
757
+
758
+ /* Secondary Actions */
759
+ .gradio-container button.secondary {
760
+ background: rgba(22, 12, 42, 0.6) !important;
761
+ border: 1px solid rgba(167, 139, 250, 0.25) !important;
762
+ color: #e9d5ff !important;
763
+ border-radius: 12px !important;
764
+ padding: 10px 20px !important;
765
+ font-weight: 600 !important;
766
+ transition: all 0.25s ease !important;
767
+ }
768
+
769
+ .gradio-container button.secondary:hover {
770
+ background: rgba(124, 58, 237, 0.2) !important;
771
+ border-color: #f472b6 !important;
772
+ color: white !important;
773
+ box-shadow: 0 5px 15px rgba(124, 58, 237, 0.15) !important;
774
+ }
775
 
776
+ /* Stop/Reset Actions with crimson glow */
777
+ .gradio-container button.stop, .gradio-container button[variant="stop"] {
778
+ background: rgba(239, 68, 68, 0.1) !important;
779
+ border: 1px solid rgba(239, 68, 68, 0.3) !important;
780
+ color: #fca5a5 !important;
781
+ border-radius: 12px !important;
782
+ font-weight: 600 !important;
783
+ transition: all 0.25s ease !important;
784
+ }
785
+
786
+ .gradio-container button.stop:hover, .gradio-container button[variant="stop"]:hover {
787
+ background: rgba(239, 68, 68, 0.25) !important;
788
+ border-color: #ef4444 !important;
789
+ color: #ffffff !important;
790
+ box-shadow: 0 5px 15px rgba(239, 68, 68, 0.25) !important;
791
+ }
792
+
793
+ /* Interactive Bento-grid Suggestion chips */
794
+ .suggestion-box {
795
+ display: flex !important;
796
+ gap: 12px !important;
797
+ flex-wrap: wrap !important;
798
+ margin-top: 18px !important;
799
+ margin-bottom: 18px !important;
800
+ }
801
+
802
+ .suggestion-btn {
803
+ flex: 1 1 calc(50% - 12px) !important;
804
+ background: rgba(15, 8, 30, 0.75) !important;
805
+ backdrop-filter: blur(8px) !important;
806
+ border: 1px solid rgba(167, 139, 250, 0.18) !important;
807
+ border-radius: 14px !important;
808
+ padding: 16px 20px !important;
809
+ color: #e9d5ff !important;
810
+ font-size: 0.95rem !important;
811
+ font-weight: 500 !important;
812
+ text-align: left !important;
813
+ line-height: 1.4 !important;
814
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
815
+ cursor: pointer !important;
816
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3) !important;
817
+ }
818
+
819
+ .suggestion-btn:hover {
820
+ background: linear-gradient(135deg, rgba(124, 58, 237, 0.12) 0%, rgba(236, 72, 153, 0.08) 100%) !important;
821
+ border-color: #f472b6 !important;
822
+ color: white !important;
823
+ transform: translateY(-3px) !important;
824
+ box-shadow:
825
+ 0 10px 25px rgba(124, 58, 237, 0.2),
826
+ 0 0 15px rgba(244, 114, 182, 0.15) !important;
827
+ }
828
 
829
+ /* Status nodes/diagnostics side card details */
830
+ .diagnostics-title {
831
+ font-family: 'Space Grotesk', sans-serif !important;
832
+ color: #c084fc !important;
833
+ font-weight: 700 !important;
834
+ font-size: 1.1rem !important;
835
+ letter-spacing: 0.02em !important;
836
+ margin-bottom: 12px !important;
837
+ display: flex !important;
838
+ align-items: center !important;
839
+ gap: 8px !important;
840
+ }
841
+
842
+ .diagnostics-detail-line {
843
+ font-family: 'Fira Code', monospace !important;
844
+ font-size: 0.75rem !important;
845
+ display: flex !important;
846
+ justify-content: space-between !important;
847
+ padding: 6px 0 !important;
848
+ border-bottom: 1px solid rgba(167, 139, 250, 0.08) !important;
849
+ color: #a78bfa !important;
850
+ }
851
+
852
+ .diagnostics-detail-val {
853
+ color: #38bdf8 !important;
854
+ font-weight: 600 !important;
855
+ }
856
+
857
+ /* Background Hex Canvas Particles */
858
+ #hex-canvas {
859
+ position: fixed !important;
860
+ top: 0 !important;
861
+ left: 0 !important;
862
+ width: 100vw !important;
863
+ height: 100vh !important;
864
+ z-index: 0 !important;
865
+ pointer-events: none !important;
866
+ opacity: 0.65 !important;
867
+ }
868
+
869
+ /* Vault Loading Overlay (Billion Dollar Cinematic look) */
870
+ #vault-loader {
871
+ position: fixed !important;
872
+ top: 0 !important;
873
+ left: 0 !important;
874
+ width: 100% !important;
875
+ height: 100% !important;
876
+ background: #020005 !important;
877
+ z-index: 999999 !important;
878
+ display: flex !important;
879
+ align-items: center !important;
880
+ justify-content: center !important;
881
+ transition: opacity 0.8s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.8s !important;
882
+ overflow: hidden !important;
883
+ font-family: 'Space Grotesk', sans-serif !important;
884
+ }
885
+
886
+ #vault-loader.loaded {
887
+ opacity: 0 !important;
888
+ visibility: hidden !important;
889
+ pointer-events: none !important;
890
+ }
891
+
892
+ /* Bi-parting vault doors opening with BOOM sliding animation */
893
+ .vault-door {
894
+ position: absolute !important;
895
+ top: 0 !important;
896
+ width: 50% !important;
897
+ height: 100% !important;
898
+ background: radial-gradient(circle at center, #0e0822 0%, #03000a 100%) !important;
899
+ transition: transform 1.2s cubic-bezier(0.85, 0, 0.15, 1) !important;
900
+ z-index: 1 !important;
901
+ }
902
+
903
+ .vault-door-left {
904
+ left: 0 !important;
905
+ border-right: 2px solid rgba(167, 139, 250, 0.25) !important;
906
+ box-shadow: 15px 0 40px rgba(0,0,0,0.8) !important;
907
+ }
908
+
909
+ .vault-door-right {
910
+ right: 0 !important;
911
+ border-left: 2px solid rgba(167, 139, 250, 0.25) !important;
912
+ box-shadow: -15px 0 40px rgba(0,0,0,0.8) !important;
913
+ }
914
+
915
+ #vault-loader.loaded .vault-door-left {
916
+ transform: translateX(-100%) !important;
917
+ }
918
+
919
+ #vault-loader.loaded .vault-door-right {
920
+ transform: translateX(100%) !important;
921
+ }
922
+
923
+ /* Central rotating mechanical locking wheels */
924
+ .vault-center-mechanism {
925
+ position: absolute !important;
926
+ top: 50% !important;
927
+ left: 50% !important;
928
+ transform: translate(-50%, -50%) !important;
929
+ z-index: 2 !important;
930
+ display: flex !important;
931
+ flex-direction: column !important;
932
+ align-items: center !important;
933
+ justify-content: center !important;
934
+ pointer-events: none !important;
935
+ transition: all 0.8s cubic-bezier(0.77, 0, 0.175, 1) !important;
936
+ }
937
+
938
+ #vault-loader.loaded .vault-center-mechanism {
939
+ transform: translate(-50%, -50%) scale(1.4) !important;
940
+ opacity: 0 !important;
941
+ }
942
+
943
+ .vault-ring {
944
+ position: absolute !important;
945
+ border-radius: 50% !important;
946
+ border: 2px dashed rgba(167, 139, 250, 0.25) !important;
947
+ box-shadow: 0 0 35px rgba(124, 58, 237, 0.12) !important;
948
+ }
949
+
950
+ .vault-ring-1 {
951
+ width: 280px !important;
952
+ height: 280px !important;
953
+ animation: rotateCW 18s linear infinite !important;
954
+ }
955
+
956
+ .vault-ring-2 {
957
+ width: 230px !important;
958
+ height: 230px !important;
959
+ border: 1.5px solid rgba(236, 72, 153, 0.18) !important;
960
+ border-top: 3px solid #ec4899 !important;
961
+ animation: rotateCCW 12s linear infinite !important;
962
+ }
963
+
964
+ .vault-ring-3 {
965
+ width: 180px !important;
966
+ height: 180px !important;
967
+ border: 3px double rgba(99, 102, 241, 0.35) !important;
968
+ animation: rotateCW 8s linear infinite !important;
969
+ }
970
+
971
+ @keyframes rotateCW {
972
+ from { transform: rotate(0deg); }
973
+ to { transform: rotate(360deg); }
974
+ }
975
+
976
+ @keyframes rotateCCW {
977
+ from { transform: rotate(360deg); }
978
+ to { transform: rotate(0deg); }
979
+ }
980
+
981
+ /* Glowing hub */
982
+ .vault-hub {
983
+ width: 130px !important;
984
+ height: 130px !important;
985
+ background: radial-gradient(circle, #1a0b38 0%, #06020f 100%) !important;
986
+ border: 2px solid #c084fc !important;
987
+ border-radius: 50% !important;
988
+ display: flex !important;
989
+ align-items: center !important;
990
+ justify-content: center !important;
991
+ box-shadow:
992
+ 0 0 45px rgba(192, 132, 252, 0.45),
993
+ inset 0 0 25px rgba(192, 132, 252, 0.25) !important;
994
+ z-index: 3 !important;
995
+ position: relative !important;
996
+ }
997
+
998
+ .vault-logo {
999
+ font-size: 1.4rem !important;
1000
+ font-weight: 900 !important;
1001
+ letter-spacing: 0.08em !important;
1002
+ background: linear-gradient(135deg, #ffffff 0%, #f472b6 100%) !important;
1003
+ -webkit-background-clip: text !important;
1004
+ -webkit-text-fill-color: transparent !important;
1005
+ animation: pulseLogo 2s infinite ease-in-out !important;
1006
+ font-family: 'Space Grotesk', sans-serif !important;
1007
+ }
1008
+
1009
+ @keyframes pulseLogo {
1010
+ 0%, 100% { transform: scale(1); filter: drop-shadow(0 0 6px rgba(192, 132, 252, 0.4)); }
1011
+ 50% { transform: scale(1.08); filter: drop-shadow(0 0 16px rgba(192, 132, 252, 0.8)); }
1012
+ }
1013
+
1014
+ /* Dynamic status panel */
1015
+ .vault-status-panel {
1016
+ margin-top: 200px !important;
1017
+ text-align: center !important;
1018
+ z-index: 4 !important;
1019
+ }
1020
+
1021
+ .vault-status-title {
1022
+ color: #f1f5f9 !important;
1023
+ font-size: 1.15rem !important;
1024
+ font-weight: 800 !important;
1025
+ letter-spacing: 0.28em !important;
1026
+ margin-bottom: 6px !important;
1027
+ text-transform: uppercase !important;
1028
+ text-shadow: 0 0 12px rgba(255,255,255,0.2) !important;
1029
+ }
1030
+
1031
+ .vault-status-subtitle {
1032
+ color: #a78bfa !important;
1033
+ font-size: 0.8rem !important;
1034
+ font-family: 'Fira Code', monospace !important;
1035
+ letter-spacing: 0.16em !important;
1036
+ margin-bottom: 25px !important;
1037
+ text-shadow: 0 0 8px rgba(167, 139, 250, 0.3) !important;
1038
+ height: 18px !important;
1039
+ }
1040
+
1041
+ .vault-progress-bar-wrap {
1042
+ width: 290px !important;
1043
+ height: 5px !important;
1044
+ background: rgba(167, 139, 250, 0.08) !important;
1045
+ border-radius: 6px !important;
1046
+ overflow: hidden !important;
1047
+ border: 1px solid rgba(167, 139, 250, 0.12) !important;
1048
+ box-shadow: 0 0 12px rgba(124, 58, 237, 0.08) !important;
1049
+ }
1050
+
1051
+ .vault-progress-fill {
1052
+ width: 0% !important;
1053
+ height: 100% !important;
1054
+ background: linear-gradient(90deg, #7c3aed, #ec4899, #38bdf8) !important;
1055
+ box-shadow: 0 0 12px #7c3aed !important;
1056
+ }
1057
+
1058
+ .vault-progress-pct {
1059
+ margin-top: 10px !important;
1060
+ color: #38bdf8 !important;
1061
+ font-family: 'Fira Code', monospace !important;
1062
+ font-size: 0.88rem !important;
1063
+ font-weight: 700 !important;
1064
+ }
1065
+
1066
+ /* Cinematic screen flash for "BOOM" unlock */
1067
+ .loader-flash {
1068
+ position: absolute !important;
1069
+ top: 0 !important;
1070
+ left: 0 !important;
1071
+ width: 100% !important;
1072
+ height: 100% !important;
1073
+ background: #ffffff !important;
1074
+ z-index: 10 !important;
1075
+ opacity: 0 !important;
1076
+ pointer-events: none !important;
1077
+ transition: opacity 0.3s ease-out !important;
1078
+ }
1079
+
1080
+ #vault-loader.boom .loader-flash {
1081
+ opacity: 1 !important;
1082
+ }
1083
  """
1084
+
1085
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="purple", secondary_hue="indigo", neutral_hue="slate"), css=custom_css) as demo:
1086
+ # State containing current active session and history of all sessions
1087
+ state = gr.State(value={"current_session": "Session 1", "Session 1": []})
1088
+
1089
+ # Custom HTML premium Header, Floating Hexagon particles & Cinematic Vault loader
1090
+ gr.HTML("""
1091
+ <!-- Hexagon Particle background canvas -->
1092
+ <canvas id="hex-canvas"></canvas>
1093
+
1094
+ <!-- Cinematic Vault Doors Loader -->
1095
+ <div id="vault-loader">
1096
+ <div class="loader-flash"></div>
1097
+ <div class="vault-door vault-door-left"></div>
1098
+ <div class="vault-door vault-door-right"></div>
1099
+
1100
+ <div class="vault-center-mechanism">
1101
+ <!-- Rotating mechanical vault locks -->
1102
+ <div class="vault-ring vault-ring-1"></div>
1103
+ <div class="vault-ring vault-ring-2"></div>
1104
+ <div class="vault-ring vault-ring-3"></div>
1105
+
1106
+ <!-- Glowing central biometric hub -->
1107
+ <div class="vault-hub">
1108
+ <span class="vault-logo">RISHRE</span>
1109
+ </div>
1110
+
1111
+ <!-- Status readouts -->
1112
+ <div class="vault-status-panel">
1113
+ <div class="vault-status-title">VAULT CORE INTEGRITY</div>
1114
+ <div class="vault-status-subtitle">INITIALIZING COGNITIVE NETWORK...</div>
1115
+
1116
+ <div class="vault-progress-bar-wrap">
1117
+ <div class="vault-progress-fill" id="vault-fill"></div>
1118
+ </div>
1119
+ <div class="vault-progress-pct" id="vault-pct">0%</div>
1120
+ </div>
1121
+ </div>
1122
+ </div>
1123
+
1124
+ <!-- Premium Header Container -->
1125
+ <div class="premium-header-container">
1126
+ <h1 class="premium-title">RiShre AI Flash</h1>
1127
+ <p class="premium-subtitle">👁️ Multi-Modal Vision Core • ZeroGPU Active • Badge94 Ecosystem</p>
1128
+ </div>
1129
+
1130
+ <!-- Inline Javascript for particles and loading events -->
1131
+ <script>
1132
+ (function() {
1133
+ function startLoaderAndParticles() {
1134
+ const canvas = document.getElementById("hex-canvas");
1135
+ const fill = document.getElementById("vault-fill");
1136
+ const pct = document.getElementById("vault-pct");
1137
+ const statusSubtitle = document.querySelector(".vault-status-subtitle");
1138
+ const loader = document.getElementById("vault-loader");
1139
+
1140
+ if (!canvas || !fill || !pct || !loader) {
1141
+ setTimeout(startLoaderAndParticles, 50);
1142
+ return;
1143
+ }
1144
+
1145
+ // --- Part 1: Floating Hexagon Particles System ---
1146
+ const ctx = canvas.getContext("2d");
1147
+ let particles = [];
1148
+
1149
+ class HexParticle {
1150
+ constructor(canvasWidth, canvasHeight) {
1151
+ this.x = Math.random() * canvasWidth;
1152
+ this.y = Math.random() * canvasHeight;
1153
+ this.radius = Math.random() * 20 + 8;
1154
+ this.speedX = (Math.random() - 0.5) * 0.4;
1155
+ this.speedY = (Math.random() - 0.5) * 0.4;
1156
+ this.alpha = Math.random() * 0.22 + 0.08;
1157
+ this.rotation = Math.random() * Math.PI;
1158
+ this.rotationSpeed = (Math.random() - 0.5) * 0.005;
1159
+ }
1160
+
1161
+ update(w, h) {
1162
+ this.x += this.speedX;
1163
+ this.y += this.speedY;
1164
+ this.rotation += this.rotationSpeed;
1165
+
1166
+ if (this.x < -50) this.x = w + 50;
1167
+ if (this.x > w + 50) this.x = -50;
1168
+ if (this.y < -50) this.y = h + 50;
1169
+ if (this.y > h + 50) this.y = -50;
1170
+ }
1171
+
1172
+ draw(ctx) {
1173
+ ctx.save();
1174
+ ctx.translate(this.x, this.y);
1175
+ ctx.rotate(this.rotation);
1176
+ ctx.strokeStyle = `rgba(167, 139, 250, ${this.alpha})`;
1177
+ ctx.lineWidth = 1;
1178
+ ctx.beginPath();
1179
+ for (let i = 0; i < 6; i++) {
1180
+ let angle = (Math.PI / 3) * i;
1181
+ ctx.lineTo(this.radius * Math.cos(angle), this.radius * Math.sin(angle));
1182
+ }
1183
+ ctx.closePath();
1184
+ ctx.stroke();
1185
+
1186
+ ctx.fillStyle = `rgba(124, 58, 237, ${this.alpha * 0.1})`;
1187
+ ctx.fill();
1188
+ ctx.restore();
1189
+ }
1190
+ }
1191
+
1192
+ function resize() {
1193
+ canvas.width = window.innerWidth;
1194
+ canvas.height = window.innerHeight;
1195
+ initParticles();
1196
+ }
1197
+
1198
+ function initParticles() {
1199
+ particles = [];
1200
+ const count = Math.min(Math.floor((window.innerWidth * window.innerHeight) / 28000), 40);
1201
+ for (let i = 0; i < count; i++) {
1202
+ particles.push(new HexParticle(canvas.width, canvas.height));
1203
+ }
1204
+ }
1205
+
1206
+ function drawConnections() {
1207
+ for (let i = 0; i < particles.length; i++) {
1208
+ for (let j = i + 1; j < particles.length; j++) {
1209
+ let dx = particles[i].x - particles[j].x;
1210
+ let dy = particles[i].y - particles[j].y;
1211
+ let distance = Math.sqrt(dx * dx + dy * dy);
1212
+
1213
+ if (distance < 170) {
1214
+ let force = (170 - distance) / 170;
1215
+ let alpha = force * 0.12;
1216
+ ctx.strokeStyle = `rgba(167, 139, 250, ${alpha})`;
1217
+ ctx.lineWidth = 0.6;
1218
+ ctx.beginPath();
1219
+ ctx.moveTo(particles[i].x, particles[i].y);
1220
+ ctx.lineTo(particles[j].x, particles[j].y);
1221
+ ctx.stroke();
1222
+ }
1223
+ }
1224
+ }
1225
+ }
1226
+
1227
+ function animate() {
1228
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1229
+ for (let p of particles) {
1230
+ p.update(canvas.width, canvas.height);
1231
+ p.draw(ctx);
1232
+ }
1233
+ drawConnections();
1234
+ requestAnimationFrame(animate);
1235
+ }
1236
+
1237
+ window.addEventListener("resize", resize);
1238
+ resize();
1239
+ animate();
1240
+
1241
+ // --- Part 2: Cinematic Progressive Loader (Vault "BOOM") ---
1242
+ let progress = 0;
1243
+ const subtitles = [
1244
+ "DECRYPTING QUANTUM LINK...",
1245
+ "INITIALIZING NEURAL COGNITION...",
1246
+ "SYNCING CHAT DEPLOYMENT TERMINALS...",
1247
+ "VERIFYING CRYPTOGRAPHIC PASSWORDS...",
1248
+ "LAUNCHING ZERO-GPU HARDWARE ACCELERATORS...",
1249
+ "SYSTEM ONLINE. READY FOR TRANSMISSION."
1250
+ ];
1251
+
1252
+ const interval = setInterval(() => {
1253
+ progress += Math.floor(Math.random() * 8) + 4;
1254
+ if (progress >= 100) {
1255
+ progress = 100;
1256
+ clearInterval(interval);
1257
+
1258
+ pct.innerText = "100%";
1259
+ fill.style.width = "100%";
1260
+ if (statusSubtitle) statusSubtitle.innerText = "AUTHENTICATION DECRYPTED";
1261
+
1262
+ setTimeout(() => {
1263
+ // Stage 1: Trigger BOOM screen flash
1264
+ loader.classList.add("boom");
1265
+
1266
+ setTimeout(() => {
1267
+ // Stage 2: Slide open bi-parting vault doors
1268
+ loader.classList.add("loaded");
1269
+
1270
+ setTimeout(() => {
1271
+ // Remove overlay to optimize browser CPU
1272
+ loader.remove();
1273
+ }, 1200);
1274
+ }, 350);
1275
+ }, 400);
1276
+ } else {
1277
+ pct.innerText = progress + "%";
1278
+ fill.style.width = progress + "%";
1279
+ const idx = Math.floor((progress / 100) * subtitles.length);
1280
+ if (statusSubtitle && subtitles[idx]) {
1281
+ statusSubtitle.innerText = subtitles[idx];
1282
+ }
1283
+ }
1284
+ }, 65);
1285
+ }
1286
+
1287
+ if (document.readyState === "complete" || document.readyState === "interactive") {
1288
+ startLoaderAndParticles();
1289
+ } else {
1290
+ window.addEventListener("DOMContentLoaded", startLoaderAndParticles);
1291
+ }
1292
+ })();
1293
+ </script>
1294
+ """)
1295
+
1296
+ with gr.Row():
1297
+ # Sidebar Panel
1298
+ with gr.Column(scale=1, min_width=250):
1299
+ model_selector = gr.Dropdown(
1300
+ choices=["RiShre AI Flash", "rxd hacker AI"],
1301
+ value="RiShre AI Flash",
1302
+ label="🤖 Select Intelligence Engine",
1303
+ interactive=True,
1304
+ elem_id="model-selector"
1305
+ )
1306
+ session_dropdown = gr.Dropdown(
1307
+ choices=["Session 1"],
1308
+ value="Session 1",
1309
+ label="🔌 Active Session Node",
1310
+ interactive=True,
1311
+ elem_id="session-dropdown"
1312
+ )
1313
+ new_btn = gr.Button("➕ New Terminal Session", variant="secondary")
1314
+ reset_btn = gr.Button("🗑️ Reset All Sessions", variant="stop")
1315
+
1316
+ diagnostics_html_component = gr.HTML(get_diagnostics_html("RiShre AI Flash"))
1317
+
1318
+ # Chat Console Panel
1319
+ with gr.Column(scale=3):
1320
+ chatbot = gr.Chatbot(
1321
+ label="Active Core Terminal",
1322
+ height=520,
1323
+ elem_id="chatbot"
1324
+ )
1325
+
1326
+ # Suggestion Chips Row
1327
+ with gr.Row(elem_classes="suggestion-box"):
1328
+ suggest_btn_1 = gr.Button("🚀 Explain Qwen3-VL-8B-Instruct", elem_classes="suggestion-btn")
1329
+ suggest_btn_2 = gr.Button("💻 Write a Python FastAPI server", elem_classes="suggestion-btn")
1330
+ suggest_btn_3 = gr.Button("🎨 CSS gradient animation palette", elem_classes="suggestion-btn")
1331
+ suggest_btn_4 = gr.Button("🔒 View system parameters & cutoff", elem_classes="suggestion-btn")
1332
+
1333
+ with gr.Row():
1334
+ msg_input = gr.MultimodalTextbox(
1335
+ show_label=False,
1336
+ placeholder="Type a message or drag & drop an image...",
1337
+ file_types=["image"],
1338
+ scale=8,
1339
+ elem_classes="input-container"
1340
+ )
1341
+ submit_btn = gr.Button("🚀 Transmit", variant="primary", scale=2, elem_classes="send-btn")
1342
+
1343
+ # Wire up Suggested prompt loaders
1344
+ suggest_btn_1.click(load_suggest_1, outputs=[msg_input])
1345
+ suggest_btn_2.click(load_suggest_2, outputs=[msg_input])
1346
+ suggest_btn_3.click(load_suggest_3, outputs=[msg_input])
1347
+ suggest_btn_4.click(load_suggest_4, outputs=[msg_input])
1348
+
1349
+ model_selector.change(
1350
+ fn=get_diagnostics_html,
1351
+ inputs=[model_selector],
1352
+ outputs=[diagnostics_html_component]
1353
+ )
1354
+
1355
+ # Wire up chat submission sequence
1356
+ submit_btn.click(
1357
+ fn=user_submit,
1358
+ inputs=[msg_input, chatbot],
1359
+ outputs=[chatbot, msg_input],
1360
+ queue=True
1361
+ ).then(
1362
+ fn=bot_stream,
1363
+ inputs=[chatbot, model_selector],
1364
+ outputs=[chatbot, diagnostics_html_component],
1365
+ queue=True
1366
+ )
1367
+
1368
+ msg_input.submit(
1369
+ fn=user_submit,
1370
+ inputs=[msg_input, chatbot],
1371
+ outputs=[chatbot, msg_input],
1372
+ queue=True
1373
+ ).then(
1374
+ fn=bot_stream,
1375
+ inputs=[chatbot, model_selector],
1376
+ outputs=[chatbot, diagnostics_html_component],
1377
+ queue=True
1378
+ )
1379
+
1380
+ # Wire up session handling
1381
+ session_dropdown.change(
1382
+ fn=change_session,
1383
+ inputs=[session_dropdown, state, chatbot],
1384
+ outputs=[chatbot, state]
1385
+ )
1386
+
1387
+ new_btn.click(
1388
+ fn=add_new_session,
1389
+ inputs=[state, chatbot],
1390
+ outputs=[session_dropdown, chatbot, state]
1391
  )
1392
 
1393
+ reset_btn.click(
1394
+ fn=reset_all_sessions,
1395
+ outputs=[session_dropdown, chatbot, state]
 
 
1396
  )
1397
 
1398
+ # Port 7860 is default for Hugging Face Spaces Gradio SDK
1399
+ if __name__ == "__main__":
1400
+ demo.launch(server_name="0.0.0.0", server_port=7860)
1401