VigneshVS2005 commited on
Commit
1b2c3a0
·
1 Parent(s): 7b75fa3

Major Project Finalization: Renamed Models, Implemented SQLite DB Auth, User Tracking, and adjusted model restraints per request.

Browse files
WhatsApp Image 2026-03-10 at 2.13.53 PM (1).jpeg ADDED
WhatsApp Image 2026-03-10 at 2.13.53 PM (2).jpeg ADDED
WhatsApp Image 2026-03-10 at 2.13.53 PM (3).jpeg ADDED
WhatsApp Image 2026-03-10 at 2.13.53 PM (4).jpeg ADDED
WhatsApp Image 2026-03-10 at 2.13.53 PM.jpeg ADDED
WhatsApp Image 2026-03-10 at 3.02.59 PM.jpeg ADDED
WhatsApp Image 2026-03-10 at 3.03.51 PM.jpeg ADDED
WhatsApp Image 2026-03-10 at 3.04.33 PM.jpeg ADDED
WhatsApp Image 2026-03-10 at 3.05.10 PM.jpeg ADDED
ai_router.py CHANGED
@@ -4,8 +4,6 @@ from models.gemini_vision import gemini_vision_answer
4
  from models.groq_vision import groq_vision_answer
5
  from models.blip_yolo_model import blip_yolo_answer
6
  from models.hf_boss_api import hf_boss_answer
7
- from models.florence_fusion_model import florence_answer
8
-
9
  try:
10
  from deep_translator import GoogleTranslator
11
  except:
@@ -31,8 +29,6 @@ def route_model(model_choice, image, question, lang="en"):
31
  cap, ans, exp = groq_vision_answer(image, question, lang)
32
  elif model_choice == "hf_boss":
33
  cap, ans, exp = hf_boss_answer(image, question, lang)
34
- elif model_choice == "florence":
35
- cap, ans, exp = florence_answer(image, question, lang)
36
  else:
37
  cap, ans, exp = "Unknown", "Invalid", "Invalid"
38
 
 
4
  from models.groq_vision import groq_vision_answer
5
  from models.blip_yolo_model import blip_yolo_answer
6
  from models.hf_boss_api import hf_boss_answer
 
 
7
  try:
8
  from deep_translator import GoogleTranslator
9
  except:
 
29
  cap, ans, exp = groq_vision_answer(image, question, lang)
30
  elif model_choice == "hf_boss":
31
  cap, ans, exp = hf_boss_answer(image, question, lang)
 
 
32
  else:
33
  cap, ans, exp = "Unknown", "Invalid", "Invalid"
34
 
database.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import os
3
+ import time
4
+
5
+ DB_PATH = "vqa.db"
6
+
7
+ def init_db():
8
+ conn = sqlite3.connect(DB_PATH)
9
+ cursor = conn.cursor()
10
+
11
+ # Users table
12
+ cursor.execute('''
13
+ CREATE TABLE IF NOT EXISTS users (
14
+ username TEXT PRIMARY KEY,
15
+ password TEXT
16
+ )
17
+ ''')
18
+
19
+ # Logs table
20
+ cursor.execute('''
21
+ CREATE TABLE IF NOT EXISTS logs (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ timestamp TEXT,
24
+ username TEXT,
25
+ model TEXT,
26
+ question TEXT
27
+ )
28
+ ''')
29
+
30
+ # Gemini Usage table
31
+ cursor.execute('''
32
+ CREATE TABLE IF NOT EXISTS gemini_usage (
33
+ username TEXT,
34
+ date TEXT,
35
+ call_count INTEGER,
36
+ PRIMARY KEY (username, date)
37
+ )
38
+ ''')
39
+
40
+ # Seed Admin
41
+ cursor.execute("INSERT OR IGNORE INTO users (username, password) VALUES (?, ?)", ("vignesh", "vignesh"))
42
+
43
+ conn.commit()
44
+ conn.close()
45
+
46
+ def login_user(username, password):
47
+ conn = sqlite3.connect(DB_PATH)
48
+ cursor = conn.cursor()
49
+ cursor.execute("SELECT password FROM users WHERE username=?", (username,))
50
+ row = cursor.fetchone()
51
+ conn.close()
52
+
53
+ if row and row[0] == password:
54
+ return True
55
+ return False
56
+
57
+ def signup_user(username, password):
58
+ conn = sqlite3.connect(DB_PATH)
59
+ cursor = conn.cursor()
60
+ try:
61
+ cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))
62
+ conn.commit()
63
+ success = True
64
+ except sqlite3.IntegrityError:
65
+ success = False
66
+ conn.close()
67
+ return success
68
+
69
+ def log_request_db(username, model, question):
70
+ conn = sqlite3.connect(DB_PATH)
71
+ cursor = conn.cursor()
72
+ from datetime import datetime
73
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
74
+ cursor.execute("INSERT INTO logs (timestamp, username, model, question) VALUES (?, ?, ?, ?)",
75
+ (timestamp, username, model, question))
76
+ conn.commit()
77
+ conn.close()
78
+
79
+ def check_gemini_limit(username):
80
+ if username == "vignesh":
81
+ return True # Admin bypass
82
+
83
+ from datetime import datetime
84
+ today_str = datetime.now().strftime("%Y-%m-%d")
85
+
86
+ conn = sqlite3.connect(DB_PATH)
87
+ cursor = conn.cursor()
88
+
89
+ cursor.execute("SELECT call_count FROM gemini_usage WHERE username=? AND date=?", (username, today_str))
90
+ row = cursor.fetchone()
91
+
92
+ if row is None:
93
+ count = 0
94
+ else:
95
+ count = row[0]
96
+
97
+ conn.close()
98
+
99
+ if count >= 10:
100
+ return False
101
+ return True
102
+
103
+ def increment_gemini_limit(username):
104
+ if username == "vignesh":
105
+ return
106
+
107
+ from datetime import datetime
108
+ today_str = datetime.now().strftime("%Y-%m-%d")
109
+
110
+ conn = sqlite3.connect(DB_PATH)
111
+ cursor = conn.cursor()
112
+
113
+ cursor.execute("SELECT call_count FROM gemini_usage WHERE username=? AND date=?", (username, today_str))
114
+ row = cursor.fetchone()
115
+
116
+ if row is None:
117
+ cursor.execute("INSERT INTO gemini_usage (username, date, call_count) VALUES (?, ?, ?)", (username, today_str, 1))
118
+ else:
119
+ cursor.execute("UPDATE gemini_usage SET call_count = call_count + 1 WHERE username=? AND date=?", (username, today_str))
120
+
121
+ conn.commit()
122
+ conn.close()
123
+
124
+ def get_user_logs(username):
125
+ conn = sqlite3.connect(DB_PATH)
126
+ conn.row_factory = sqlite3.Row
127
+ cursor = conn.cursor()
128
+
129
+ if username == "vignesh":
130
+ cursor.execute("SELECT * FROM logs ORDER BY id DESC")
131
+ else:
132
+ cursor.execute("SELECT * FROM logs WHERE username=? ORDER BY id DESC", (username,))
133
+
134
+ rows = cursor.fetchall()
135
+ conn.close()
136
+
137
+ return [dict(row) for row in rows]
main.py CHANGED
@@ -7,14 +7,18 @@ from fastapi.middleware.cors import CORSMiddleware
7
  from PIL import Image
8
 
9
  from ai_router import route_model
10
- from utils.logger import log_request
11
  from utils.security import check_rate_limit, validate_image_size
12
  from config import DEVICE, ENABLE_EXTERNAL_AI
 
 
13
 
14
 
15
  # ================= CREATE APP FIRST =================
16
  app = FastAPI(title="GenAI VQA System")
17
 
 
 
 
18
 
19
  # ================= CORS =================
20
  app.add_middleware(
@@ -38,34 +42,32 @@ async def home(request: Request):
38
 
39
 
40
  # ================= API =================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  @app.get("/api/logs")
42
  async def get_logs_endpoint(user: str):
43
- import os
44
- logs = []
45
- if os.path.exists("logs/requests.log"):
46
- with open("logs/requests.log", "r") as f:
47
- for line in f:
48
- if " - User: " in line:
49
- try:
50
- parts = line.split(" - INFO - User: ")
51
- timestamp = parts[0]
52
- rest = parts[1].split(" | Model: ")
53
- log_user = rest[0].strip()
54
- model_q = rest[1].split(" | Q: ")
55
- model = model_q[0].strip()
56
- question = model_q[1].strip()
57
-
58
- # Admin sees all, User sees only their own
59
- if user == "vignesh" or log_user == user:
60
- logs.append({
61
- "timestamp": timestamp,
62
- "user": log_user,
63
- "model": model,
64
- "question": question
65
- })
66
- except Exception as e:
67
- pass
68
- logs.reverse()
69
  return {"logs": logs}
70
 
71
 
@@ -77,9 +79,19 @@ async def ask_question(
77
  user: str = Form("guest"),
78
  lang: str = Form("en")
79
  ):
80
-
81
  check_rate_limit(user)
82
 
 
 
 
 
 
 
 
 
 
 
 
83
  image_bytes = await file.read()
84
  validate_image_size(len(image_bytes))
85
 
@@ -102,9 +114,10 @@ async def ask_question(
102
  lang
103
  )
104
 
105
-
106
-
107
- log_request(user, model_choice, question)
 
108
 
109
  return JSONResponse({
110
  "device": DEVICE,
 
7
  from PIL import Image
8
 
9
  from ai_router import route_model
 
10
  from utils.security import check_rate_limit, validate_image_size
11
  from config import DEVICE, ENABLE_EXTERNAL_AI
12
+ from database import init_db, login_user, signup_user, log_request_db, check_gemini_limit, increment_gemini_limit, get_user_logs
13
+ from fastapi import HTTPException
14
 
15
 
16
  # ================= CREATE APP FIRST =================
17
  app = FastAPI(title="GenAI VQA System")
18
 
19
+ @app.on_event("startup")
20
+ async def startup_event():
21
+ init_db()
22
 
23
  # ================= CORS =================
24
  app.add_middleware(
 
42
 
43
 
44
  # ================= API =================
45
+ @app.post("/api/login")
46
+ async def handle_login(request: Request):
47
+ data = await request.json()
48
+ username = data.get("username")
49
+ password = data.get("password")
50
+
51
+ if login_user(username, password):
52
+ return {"status": "success", "user": username}
53
+ return JSONResponse(status_code=401, content={"status": "error", "message": "Invalid password or user does not exist."})
54
+
55
+ @app.post("/api/signup")
56
+ async def handle_signup(request: Request):
57
+ data = await request.json()
58
+ username = data.get("username")
59
+ password = data.get("password")
60
+
61
+ if not username or not password:
62
+ return JSONResponse(status_code=400, content={"status": "error", "message": "Username and password required."})
63
+
64
+ if signup_user(username, password):
65
+ return {"status": "success", "user": username}
66
+ return JSONResponse(status_code=400, content={"status": "error", "message": "Username already taken."})
67
+
68
  @app.get("/api/logs")
69
  async def get_logs_endpoint(user: str):
70
+ logs = get_user_logs(user)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  return {"logs": logs}
72
 
73
 
 
79
  user: str = Form("guest"),
80
  lang: str = Form("en")
81
  ):
 
82
  check_rate_limit(user)
83
 
84
+ if model_choice == "gemini":
85
+ if not check_gemini_limit(user):
86
+ return JSONResponse({
87
+ "device": "Error",
88
+ "model_used": "gemini",
89
+ "caption": "Quota Exceeded",
90
+ "answer": "You have reached your limit of 10 Gemini requests per day.",
91
+ "explanation": "To prevent abusive cost spikes, users are limited to 10 Gemini requests per day. The Admin has unlimited access.",
92
+ "external_enabled": True
93
+ })
94
+
95
  image_bytes = await file.read()
96
  validate_image_size(len(image_bytes))
97
 
 
114
  lang
115
  )
116
 
117
+ log_request_db(user, model_choice, question)
118
+
119
+ if model_choice == "gemini":
120
+ increment_gemini_limit(user)
121
 
122
  return JSONResponse({
123
  "device": DEVICE,
models/groq_vision.py CHANGED
@@ -37,15 +37,15 @@ Question:
37
  CRITICAL RULES FOR YOUR RESPONSE:
38
  1. You MUST respond strictly in the language code: {lang}. All text in your output must be translated to '{lang}'.
39
  2. You MUST use EXACTLY the format below with these English labels.
40
- 3. The Caption MUST be exactly 1 line only.
41
- 4. The Final Answer MUST be exactly 1 line only.
42
- 5. The Explanation MUST be strictly 2 to 3 lines maximum. Be very concise and do not exceed this limit!
43
 
44
  Respond strictly following this exact structure without any deviations or markdown blocks.
45
 
46
- Caption: <one-line caption>
47
- Final Answer: <one-line answer>
48
- Explanation: <2-3 lines max explanation>"""
49
 
50
  payload = {
51
  "model": model_id,
 
37
  CRITICAL RULES FOR YOUR RESPONSE:
38
  1. You MUST respond strictly in the language code: {lang}. All text in your output must be translated to '{lang}'.
39
  2. You MUST use EXACTLY the format below with these English labels.
40
+ 3. You MUST provide a detailed descriptive Caption.
41
+ 4. You MUST provide a highly accurate Final Answer.
42
+ 5. You MUST provide an expansive, detailed Explanation justifying your answer.
43
 
44
  Respond strictly following this exact structure without any deviations or markdown blocks.
45
 
46
+ Caption: <detailed caption>
47
+ Final Answer: <detailed answer>
48
+ Explanation: <expansive explanation>"""
49
 
50
  payload = {
51
  "model": model_id,
models/hf_boss_api.py CHANGED
@@ -9,7 +9,8 @@ def hf_boss_answer(image, question, lang="en"):
9
  if not token:
10
  return "Setup Required", "HF Token is missing.", "Please set HF_TOKEN."
11
 
12
- model_id = "google/gemma-3-12b-it:featherless"
 
13
 
14
  try:
15
  api_url = "https://router.huggingface.co/v1/chat/completions"
@@ -68,12 +69,12 @@ Explanation: [2-3 sentences]"""
68
 
69
  # Fallback system
70
  if response.status_code != 200:
71
- model_id = "zai-org/GLM-4.5V:novita"
72
  payload["model"] = model_id
73
  response = requests.post(api_url, headers=headers, json=payload, timeout=90)
74
 
75
  if response.status_code != 200:
76
- model_id = "Qwen/Qwen2.5-VL-7B-Instruct:hyperbolic"
77
  payload["model"] = model_id
78
  response = requests.post(api_url, headers=headers, json=payload, timeout=90)
79
 
 
9
  if not token:
10
  return "Setup Required", "HF Token is missing.", "Please set HF_TOKEN."
11
 
12
+ # Using Qwen 2.5 VL as requested
13
+ model_id = "Qwen/Qwen2.5-VL-7B-Instruct:hyperbolic"
14
 
15
  try:
16
  api_url = "https://router.huggingface.co/v1/chat/completions"
 
69
 
70
  # Fallback system
71
  if response.status_code != 200:
72
+ model_id = "google/gemma-3-12b-it:featherless"
73
  payload["model"] = model_id
74
  response = requests.post(api_url, headers=headers, json=payload, timeout=90)
75
 
76
  if response.status_code != 200:
77
+ model_id = "zai-org/GLM-4.5V:novita"
78
  payload["model"] = model_id
79
  response = requests.post(api_url, headers=headers, json=payload, timeout=90)
80
 
static/app.js CHANGED
@@ -14,8 +14,14 @@ const els = {
14
 
15
  // Login
16
  loginOverlay: document.getElementById('login-overlay'),
17
- loginInput: document.getElementById('login-input'),
18
- loginBtn: document.getElementById('login-btn'),
 
 
 
 
 
 
19
  mainApp: document.getElementById('main-app'),
20
  displayUsername: document.getElementById('display-username'),
21
  logoutBtn: document.getElementById('logout-btn'),
@@ -67,8 +73,10 @@ function init() {
67
  // --- Event Listeners ---
68
  function setupEventListeners() {
69
  // Login System
70
- els.loginBtn.addEventListener('click', handleLogin);
71
- els.loginInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') handleLogin(); });
 
 
72
  els.logoutBtn.addEventListener('click', handleLogout);
73
 
74
  // Tabs
@@ -163,11 +171,77 @@ function setupEventListeners() {
163
  }
164
 
165
  // --- Login System ---
166
- function handleLogin() {
167
- const val = els.loginInput.value.trim().toLowerCase();
168
- if (!val) return alert("Please enter a username.");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- appState.username = val;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  els.loginOverlay.classList.add('hidden');
172
  els.mainApp.classList.remove('hidden');
173
  els.displayUsername.innerText = appState.username;
@@ -176,13 +250,9 @@ function handleLogin() {
176
  els.adminTabBtn.style.display = 'flex';
177
  } else {
178
  els.adminTabBtn.style.display = 'none';
179
- if (document.querySelector('.menu-btn.active').dataset.tab === 'admin') {
180
- switchTab('dashboard');
181
- }
182
  }
183
  fetchLogs();
184
-
185
- // Small welcome speech
186
  speak(`Welcome to GenAI Vision System, ${appState.username}`);
187
  }
188
 
@@ -190,7 +260,8 @@ function handleLogout() {
190
  appState.username = '';
191
  els.mainApp.classList.add('hidden');
192
  els.loginOverlay.classList.remove('hidden');
193
- els.loginInput.value = '';
 
194
  switchTab('dashboard');
195
  }
196
 
@@ -412,12 +483,12 @@ function initChart() {
412
 
413
  function getChartData() {
414
  return {
415
- labels: ['Local BLIP', 'Local YOLO', 'Gemini AI', 'Groq Vision', 'HF API', 'Florence Fusion'],
416
  datasets: [{
417
  label: 'Queries',
418
- data: [appState.stats.local, appState.stats.yolo, appState.stats.gemini, appState.stats.groq, appState.stats.hf_boss, appState.stats.florence],
419
- backgroundColor: ['rgba(16, 185, 129, 0.6)', 'rgba(52, 211, 153, 0.6)', 'rgba(99, 102, 241, 0.6)', 'rgba(245, 158, 11, 0.6)', 'rgba(139, 92, 246, 0.6)', 'rgba(236, 72, 153, 0.6)'],
420
- borderColor: ['rgba(16, 185, 129, 1)', 'rgba(52, 211, 153, 1)', 'rgba(99, 102, 241, 1)', 'rgba(245, 158, 11, 1)', 'rgba(139, 92, 246, 1)', 'rgba(236, 72, 153, 1)'],
421
  borderWidth: 1, borderRadius: 6
422
  }]
423
  };
 
14
 
15
  // Login
16
  loginOverlay: document.getElementById('login-overlay'),
17
+ loginUsername: document.getElementById('login-username'),
18
+ loginPassword: document.getElementById('login-password'),
19
+ authBtn: document.getElementById('auth-btn'),
20
+ googleAuthBtn: document.getElementById('google-auth-btn'),
21
+ authSwitchLink: document.getElementById('auth-switch-link'),
22
+ authTitle: document.getElementById('auth-title'),
23
+ authSubtitle: document.getElementById('auth-subtitle'),
24
+ authError: document.getElementById('auth-error'),
25
  mainApp: document.getElementById('main-app'),
26
  displayUsername: document.getElementById('display-username'),
27
  logoutBtn: document.getElementById('logout-btn'),
 
73
  // --- Event Listeners ---
74
  function setupEventListeners() {
75
  // Login System
76
+ els.authBtn.addEventListener('click', handleAuth);
77
+ els.loginPassword.addEventListener('keypress', (e) => { if (e.key === 'Enter') handleAuth(); });
78
+ els.authSwitchLink.addEventListener('click', toggleAuthMode);
79
+ els.googleAuthBtn.addEventListener('click', handleGoogleAuth);
80
  els.logoutBtn.addEventListener('click', handleLogout);
81
 
82
  // Tabs
 
171
  }
172
 
173
  // --- Login System ---
174
+ let isLoginMode = true;
175
+
176
+ function toggleAuthMode(e) {
177
+ e.preventDefault();
178
+ isLoginMode = !isLoginMode;
179
+ els.authError.style.display = 'none';
180
+ if (isLoginMode) {
181
+ els.authTitle.innerText = "GenAI VQA Portal";
182
+ els.authSubtitle.innerText = "Sign in to access the system";
183
+ els.authBtn.innerHTML = 'Login <i class="fa-solid fa-arrow-right"></i>';
184
+ document.getElementById('auth-switch-text').innerText = "Don't have an account?";
185
+ els.authSwitchLink.innerText = "Sign Up";
186
+ } else {
187
+ els.authTitle.innerText = "Create Account";
188
+ els.authSubtitle.innerText = "Register to save your logs";
189
+ els.authBtn.innerHTML = 'Sign Up <i class="fa-solid fa-user-plus"></i>';
190
+ document.getElementById('auth-switch-text').innerText = "Already have an account?";
191
+ els.authSwitchLink.innerText = "Login";
192
+ }
193
+ }
194
+
195
+ async function handleAuth() {
196
+ const username = els.loginUsername.value.trim().toLowerCase();
197
+ const password = els.loginPassword.value.trim();
198
+
199
+ if (!username || !password) {
200
+ els.authError.innerText = "Username and password required.";
201
+ els.authError.style.display = 'block';
202
+ return;
203
+ }
204
 
205
+ els.authBtn.disabled = true;
206
+ els.authBtn.innerText = "Processing...";
207
+
208
+ const endpoint = isLoginMode ? '/api/login' : '/api/signup';
209
+
210
+ try {
211
+ const res = await fetch(endpoint, {
212
+ method: 'POST',
213
+ headers: {'Content-Type': 'application/json'},
214
+ body: JSON.stringify({username, password})
215
+ });
216
+ const data = await res.json();
217
+
218
+ if (data.status === 'success') {
219
+ onLoginSuccess(data.user);
220
+ } else {
221
+ els.authError.innerText = data.message;
222
+ els.authError.style.display = 'block';
223
+ }
224
+ } catch(err) {
225
+ els.authError.innerText = "Server connection error.";
226
+ els.authError.style.display = 'block';
227
+ } finally {
228
+ els.authBtn.disabled = false;
229
+ els.authBtn.innerHTML = isLoginMode ? 'Login <i class="fa-solid fa-arrow-right"></i>' : 'Sign Up <i class="fa-solid fa-user-plus"></i>';
230
+ }
231
+ }
232
+
233
+ function handleGoogleAuth() {
234
+ // Mock Google Auth logic
235
+ const mockGoogleId = "google_user_" + Math.floor(Math.random() * 1000);
236
+ const mockEmail = prompt("Google Auth Simulation:\n\nEnter your Google email address:");
237
+ if (mockEmail) {
238
+ const username = mockEmail.split('@')[0];
239
+ onLoginSuccess(username);
240
+ }
241
+ }
242
+
243
+ function onLoginSuccess(user) {
244
+ appState.username = user;
245
  els.loginOverlay.classList.add('hidden');
246
  els.mainApp.classList.remove('hidden');
247
  els.displayUsername.innerText = appState.username;
 
250
  els.adminTabBtn.style.display = 'flex';
251
  } else {
252
  els.adminTabBtn.style.display = 'none';
253
+ if (document.querySelector('.menu-btn.active').dataset.tab === 'admin') switchTab('dashboard');
 
 
254
  }
255
  fetchLogs();
 
 
256
  speak(`Welcome to GenAI Vision System, ${appState.username}`);
257
  }
258
 
 
260
  appState.username = '';
261
  els.mainApp.classList.add('hidden');
262
  els.loginOverlay.classList.remove('hidden');
263
+ els.loginUsername.value = '';
264
+ els.loginPassword.value = '';
265
  switchTab('dashboard');
266
  }
267
 
 
483
 
484
  function getChartData() {
485
  return {
486
+ labels: ['Local BLIP', 'Local YOLO', 'Gemini AI', 'Groq Vision', 'HF API'],
487
  datasets: [{
488
  label: 'Queries',
489
+ data: [appState.stats.local, appState.stats.yolo, appState.stats.gemini, appState.stats.groq, appState.stats.hf_boss],
490
+ backgroundColor: ['rgba(16, 185, 129, 0.6)', 'rgba(52, 211, 153, 0.6)', 'rgba(99, 102, 241, 0.6)', 'rgba(245, 158, 11, 0.6)', 'rgba(139, 92, 246, 0.6)'],
491
+ borderColor: ['rgba(16, 185, 129, 1)', 'rgba(52, 211, 153, 1)', 'rgba(99, 102, 241, 1)', 'rgba(245, 158, 11, 1)', 'rgba(139, 92, 246, 1)'],
492
  borderWidth: 1, borderRadius: 6
493
  }]
494
  };
templates/index.html CHANGED
@@ -12,12 +12,22 @@
12
 
13
  <!-- Login Overlay -->
14
  <div id="login-overlay" class="login-overlay active">
15
- <div class="login-box glass-panel fade-in">
16
  <i class="fa-solid fa-brain" style="font-size: 50px; color: var(--accent); margin-bottom: 24px;"></i>
17
- <h2>GenAI VQA Portal</h2>
18
- <p style="margin-bottom: 24px; color: var(--text-secondary);">Enter your username to access the system</p>
19
- <input type="text" id="login-input" placeholder="Username (e.g. vignesh)" autocomplete="off">
20
- <button id="login-btn" class="primary-btn" style="width: 100%;">Enter System <i class="fa-solid fa-arrow-right"></i></button>
 
 
 
 
 
 
 
 
 
 
21
  </div>
22
  </div>
23
 
@@ -95,12 +105,11 @@
95
  <div class="control-group" style="flex: 1;">
96
  <label><i class="fa-solid fa-microchip"></i> Select Model</label>
97
  <select id="model-selector">
98
- <option value="local">BLIP + FLAN (Local)</option>
99
- <option value="local_yolo">BLIP + FLAN + YOLO (Local Advanced)</option>
100
- <option value="gemini" id="gemini-option">Gemini 3.1 Flash Vision (High Quota)</option>
101
- <option value="groq" id="groq-option">Groq Native Vision: Llama 4 Scout</option>
102
- <option value="hf_boss" id="hf-option">Hugging Face API: Llama 11B Vision (Unlimited Boss)</option>
103
- <option value="florence" id="florence-option">Florence-2 Fusion (Local Ultimate)</option>
104
  </select>
105
  </div>
106
  <div class="control-group" style="flex: 1;">
 
12
 
13
  <!-- Login Overlay -->
14
  <div id="login-overlay" class="login-overlay active">
15
+ <div class="login-box glass-panel fade-in" id="auth-box">
16
  <i class="fa-solid fa-brain" style="font-size: 50px; color: var(--accent); margin-bottom: 24px;"></i>
17
+ <h2 id="auth-title">GenAI VQA Portal</h2>
18
+ <p id="auth-subtitle" style="margin-bottom: 24px; color: var(--text-secondary);">Sign in to access the system</p>
19
+
20
+ <input type="text" id="login-username" placeholder="Username (e.g. vignesh)" autocomplete="off" style="margin-bottom: 12px; width:100%; padding: 12px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.1); background: rgba(0,0,0,0.5); color: white;">
21
+ <input type="password" id="login-password" placeholder="Password" autocomplete="off" style="margin-bottom: 16px; width:100%; padding: 12px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.1); background: rgba(0,0,0,0.5); color: white;">
22
+
23
+ <button id="auth-btn" class="primary-btn" style="width: 100%; margin-bottom: 12px;">Login <i class="fa-solid fa-arrow-right"></i></button>
24
+ <button id="google-auth-btn" class="secondary-btn" style="width: 100%; margin-bottom: 16px; background: white; color: #333;"><i class="fa-brands fa-google" style="color: #4285F4;"></i> Sign in with Google</button>
25
+
26
+ <div style="text-align: center; font-size: 14px;">
27
+ <span id="auth-switch-text" style="color: var(--text-secondary);">Don't have an account?</span>
28
+ <a href="#" id="auth-switch-link" style="color: var(--accent); font-weight: bold; text-decoration: none;">Sign Up</a>
29
+ </div>
30
+ <p id="auth-error" style="color: #ef4444; margin-top: 10px; font-size: 13px; display: none;"></p>
31
  </div>
32
  </div>
33
 
 
105
  <div class="control-group" style="flex: 1;">
106
  <label><i class="fa-solid fa-microchip"></i> Select Model</label>
107
  <select id="model-selector">
108
+ <option value="local">VQA with LSTM and CNN</option>
109
+ <option value="local_yolo">Hybrid YOLOv8 + Contextual VQA</option>
110
+ <option value="hf_boss" id="hf-option">Web-Scale Autonomous Vision Reasoner (Qwen-VL)</option>
111
+ <option value="groq" id="groq-option">Mixture-of-Experts (MoE) Accelerated Vision</option>
112
+ <option value="gemini" id="gemini-option">Google Gemini (Baseline Benchmark)</option>
 
113
  </select>
114
  </div>
115
  <div class="control-group" style="flex: 1;">