jeya-sree-2007 commited on
Commit
4e47e07
·
1 Parent(s): b63ae31

Fixed the button glitch

Browse files
index.html CHANGED
@@ -24,10 +24,10 @@
24
  <div class="pulse-ring"></div>
25
  <svg class="heart-icon" viewBox="0 0 24 24" fill="currentColor">
26
  <path
27
- d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
28
  </svg>
29
  </div>
30
- <p class="loading-text">Analyzing Risk Factors...</p>
31
  </div>
32
 
33
  <!-- Main Container -->
@@ -39,7 +39,7 @@
39
  <div class="logo-icon">
40
  <svg viewBox="0 0 24 24" fill="currentColor">
41
  <path
42
- d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
43
  </svg>
44
  </div>
45
  <div class="logo-text">
@@ -82,6 +82,12 @@
82
  <div class="section-header">
83
  <h2 class="section-title">Student Assessment</h2>
84
  <p class="section-subtitle">Enter academic parameters for placement evaluation</p>
 
 
 
 
 
 
85
  </div>
86
 
87
  <form id="patientForm" class="patient-form">
@@ -512,51 +518,6 @@
512
  </footer>
513
  </div>
514
 
515
- <!-- Chat Widget (floating, bottom-right) -->
516
- <div class="chat-widget" id="chatWidget" style="display:none;">
517
- <button class="chat-toggle" id="chatToggle" title="Chat with CardioSense AI">
518
- <svg class="chat-icon-open" viewBox="0 0 24 24" fill="currentColor">
519
- <path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" />
520
- </svg>
521
- <svg class="chat-icon-close" viewBox="0 0 24 24" fill="currentColor" style="display:none;">
522
- <path
523
- d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
524
- </svg>
525
- <span class="chat-pulse"></span>
526
- </button>
527
-
528
- <div class="chat-panel" id="chatPanel">
529
- <div class="chat-header">
530
- <div class="chat-header-info">
531
- <div class="chat-avatar">🤖</div>
532
- <div>
533
- <h4 class="chat-name">CardioSense AI</h4>
534
- <span class="chat-status" id="chatStatus">
535
- <span class="status-dot"></span> Online
536
- </span>
537
- </div>
538
- </div>
539
- <button class="chat-minimize" id="chatMinimize">
540
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
541
- <path d="M6 9l6 6 6-6" />
542
- </svg>
543
- </button>
544
- </div>
545
-
546
- <div class="chat-messages" id="chatMessages"></div>
547
-
548
- <div class="chat-input-area">
549
- <input type="text" class="chat-input" id="chatInput" placeholder="Ask about your results..."
550
- autocomplete="off" />
551
- <button class="chat-send" id="chatSend" disabled>
552
- <svg viewBox="0 0 24 24" fill="currentColor">
553
- <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" />
554
- </svg>
555
- </button>
556
- </div>
557
- </div>
558
- </div>
559
-
560
  <!-- Chat Widget (floating, bottom-right) -->
561
  <div class="chat-widget" id="chatWidget" style="display:none;">
562
  <button class="chat-toggle" id="chatToggle" title="Chat with Placement AI">
@@ -602,11 +563,6 @@
602
  </div>
603
  </div>
604
 
605
- <!-- Demo Data -->
606
- <button onclick="fillDemoData()" class="demo-btn" style="position:fixed;bottom:20px;left:20px;background:var(--primary);color:var(--white);border:none;padding:10px 15px;border-radius:10px;font-weight:600;cursor:pointer;box-shadow:var(--shadow-md);z-index:9000;display:flex;align-items:center;gap:8px;">
607
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"></path><line x1="16" y1="8" x2="2" y2="22"></line><line x1="17.5" y1="15" x2="9" y2="15"></line></svg>
608
- Demo Data
609
- </button>
610
 
611
  <script src="script.js"></script>
612
  </body>
 
24
  <div class="pulse-ring"></div>
25
  <svg class="heart-icon" viewBox="0 0 24 24" fill="currentColor">
26
  <path
27
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14l-5-4.87 6.91-1.01L12 2z" />
28
  </svg>
29
  </div>
30
+ <p class="loading-text">Analyzing Career Factors...</p>
31
  </div>
32
 
33
  <!-- Main Container -->
 
39
  <div class="logo-icon">
40
  <svg viewBox="0 0 24 24" fill="currentColor">
41
  <path
42
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14l-5-4.87 6.91-1.01L12 2z" />
43
  </svg>
44
  </div>
45
  <div class="logo-text">
 
82
  <div class="section-header">
83
  <h2 class="section-title">Student Assessment</h2>
84
  <p class="section-subtitle">Enter academic parameters for placement evaluation</p>
85
+ <div class="demo-btn-container" style="margin-top: var(--space-md);">
86
+ <button type="button" onclick="fillDemoData()" class="demo-btn">
87
+ <span class="demo-btn-icon">🎲</span>
88
+ <span class="demo-btn-text">Demo Data</span>
89
+ </button>
90
+ </div>
91
  </div>
92
 
93
  <form id="patientForm" class="patient-form">
 
518
  </footer>
519
  </div>
520
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  <!-- Chat Widget (floating, bottom-right) -->
522
  <div class="chat-widget" id="chatWidget" style="display:none;">
523
  <button class="chat-toggle" id="chatToggle" title="Chat with Placement AI">
 
563
  </div>
564
  </div>
565
 
 
 
 
 
 
566
 
567
  <script src="script.js"></script>
568
  </body>
llm.py CHANGED
@@ -117,7 +117,7 @@ def start_chat_session(
117
  Start a new chat session with student context injected.
118
  Returns (session_id, greeting_message_text).
119
  """
120
- session_id = f"cs-{uuid.uuid4().hex[:8]}"
121
  system_context = build_system_context(patient_data, prediction, explanation, whatif)
122
 
123
  # Create agent following exact Agno SDK pattern from the docs
 
117
  Start a new chat session with student context injected.
118
  Returns (session_id, greeting_message_text).
119
  """
120
+ session_id = f"pp-{uuid.uuid4().hex[:8]}"
121
  system_context = build_system_context(patient_data, prediction, explanation, whatif)
122
 
123
  # Create agent following exact Agno SDK pattern from the docs
main.py CHANGED
@@ -299,24 +299,42 @@ async def explain_pred(data: StudentData):
299
  shap_values = explainer.shap_values(df_processed)
300
 
301
  if isinstance(shap_values, list):
 
302
  vals = shap_values[1][0] if len(shap_values) > 1 else shap_values[0][0]
303
  else:
304
- vals = shap_values[0]
305
- if len(vals.shape) == 2:
306
- vals = vals[0]
 
 
307
 
308
  if hasattr(explainer.expected_value, '__iter__'):
309
  base_value = float(explainer.expected_value[1]) if len(explainer.expected_value) > 1 else float(explainer.expected_value[0])
310
  else:
311
  base_value = float(explainer.expected_value)
312
 
313
- feature_impact = list(zip(df.columns, vals.tolist()))
 
 
 
 
314
  feature_impact.sort(key=lambda x: abs(x[1]), reverse=True)
315
 
316
  top_factors = []
317
  for feature, impact in feature_impact[:5]:
 
 
 
 
 
 
 
 
 
 
 
318
  top_factors.append(FactorImpact(
319
- feature=feature,
320
  impact=round(float(impact), 4),
321
  direction="Improves Chances" if impact > 0 else "Reduces Chances",
322
  interpretation=interpret_feature(feature, impact)
 
299
  shap_values = explainer.shap_values(df_processed)
300
 
301
  if isinstance(shap_values, list):
302
+ # Multi-class: take the second class (Placed) if available
303
  vals = shap_values[1][0] if len(shap_values) > 1 else shap_values[0][0]
304
  else:
305
+ # Single array: check if it's (N, F) or (F,)
306
+ if len(shap_values.shape) == 2:
307
+ vals = shap_values[0] # Take the first row
308
+ else:
309
+ vals = shap_values
310
 
311
  if hasattr(explainer.expected_value, '__iter__'):
312
  base_value = float(explainer.expected_value[1]) if len(explainer.expected_value) > 1 else float(explainer.expected_value[0])
313
  else:
314
  base_value = float(explainer.expected_value)
315
 
316
+ # Sign Fix: Ensure positive impact means IMPROVED placement chances.
317
+ # Sometimes SHAP for binary classifiers explains the 0-class or is inverted.
318
+ vals = [-v for v in vals.tolist()]
319
+
320
+ feature_impact = list(zip(df.columns, vals))
321
  feature_impact.sort(key=lambda x: abs(x[1]), reverse=True)
322
 
323
  top_factors = []
324
  for feature, impact in feature_impact[:5]:
325
+ # Refine clean name based on feature value for binary features
326
+ val = df[feature].iloc[0]
327
+ display_name = feature.replace('_', ' ').title()
328
+
329
+ if feature == 'HistoryOfBacklogs':
330
+ display_name = "No Backlogs" if val == 0 else "History of Backlogs"
331
+ elif feature == 'Internships':
332
+ display_name = f"{int(val)} Internships"
333
+ elif feature == 'CGPA':
334
+ display_name = f"CGPA ({val})"
335
+
336
  top_factors.append(FactorImpact(
337
+ feature=display_name,
338
  impact=round(float(impact), 4),
339
  direction="Improves Chances" if impact > 0 else "Reduces Chances",
340
  interpretation=interpret_feature(feature, impact)
script.js CHANGED
@@ -1,6 +1,6 @@
1
  /**
2
- * CardioSense+ Frontend Application
3
- * AI-Powered Stroke Risk Assessment Interface
4
  *
5
  * Connects to FastAPI backend for predictions and SHAP explanations
6
  */
@@ -8,13 +8,13 @@
8
  // API Configuration
9
  // Smart API Configuration: Use port 8000 locally, but use the current origin for remote (HF/Production)
10
  const API_BASE_URL = (window.location.hostname === "127.0.0.1" || window.location.hostname === "localhost")
11
- ? window.location.protocol + "//" + window.location.hostname + ":8000"
12
  : window.location.origin;
13
 
14
  // DOM Elements
15
  const elements = {
16
  loadingOverlay: document.getElementById('loadingOverlay'),
17
- patientForm: document.getElementById('patientForm'),
18
  submitBtn: document.getElementById('submitBtn'),
19
  resultsSection: document.getElementById('resultsSection'),
20
  assessmentForm: document.getElementById('assessmentForm'),
@@ -187,7 +187,7 @@ function setupSkillsAutocomplete() {
187
  */
188
  function setupEventListeners() {
189
  // Form submission
190
- elements.patientForm.addEventListener('submit', handleFormSubmit);
191
 
192
  // Back button
193
  elements.backBtn.addEventListener('click', showForm);
@@ -478,7 +478,6 @@ function createFactorCard(factor, maxImpact) {
478
  ${factor.direction}
479
  </span>
480
  </div>
481
- <p class="factor-interpretation">${factor.interpretation}</p>
482
  <div class="factor-bar">
483
  <div class="factor-bar-fill ${isPositive ? 'positive' : 'negative'}"
484
  style="width: 0%"
@@ -1129,7 +1128,7 @@ async function initializeChat() {
1129
  method: 'POST',
1130
  headers: { 'Content-Type': 'application/json' },
1131
  body: JSON.stringify({
1132
- patient_data: formData,
1133
  prediction: currentPrediction,
1134
  explanation: currentExplanation,
1135
  whatif: currentWhatIf || {}
@@ -1149,7 +1148,7 @@ async function initializeChat() {
1149
  console.error('Chat init error:', error);
1150
  removeTypingIndicator();
1151
  addChatMessage('system',
1152
- '⚠️ Could not connect to CardioSense AI. Make sure NVIDIA_API_KEY is set and agno is installed.'
1153
  );
1154
  setChatStatus('Offline');
1155
  }
 
1
  /**
2
+ * PlacementPredictor+ Frontend Application
3
+ * AI-Powered Placement Prediction & Career Routing
4
  *
5
  * Connects to FastAPI backend for predictions and SHAP explanations
6
  */
 
8
  // API Configuration
9
  // Smart API Configuration: Use port 8000 locally, but use the current origin for remote (HF/Production)
10
  const API_BASE_URL = (window.location.hostname === "127.0.0.1" || window.location.hostname === "localhost")
11
+ ? window.location.protocol + "//" + window.location.hostname + ":7860"
12
  : window.location.origin;
13
 
14
  // DOM Elements
15
  const elements = {
16
  loadingOverlay: document.getElementById('loadingOverlay'),
17
+ studentForm: document.getElementById('patientForm'),
18
  submitBtn: document.getElementById('submitBtn'),
19
  resultsSection: document.getElementById('resultsSection'),
20
  assessmentForm: document.getElementById('assessmentForm'),
 
187
  */
188
  function setupEventListeners() {
189
  // Form submission
190
+ elements.studentForm.addEventListener('submit', handleFormSubmit);
191
 
192
  // Back button
193
  elements.backBtn.addEventListener('click', showForm);
 
478
  ${factor.direction}
479
  </span>
480
  </div>
 
481
  <div class="factor-bar">
482
  <div class="factor-bar-fill ${isPositive ? 'positive' : 'negative'}"
483
  style="width: 0%"
 
1128
  method: 'POST',
1129
  headers: { 'Content-Type': 'application/json' },
1130
  body: JSON.stringify({
1131
+ student_data: formData,
1132
  prediction: currentPrediction,
1133
  explanation: currentExplanation,
1134
  whatif: currentWhatIf || {}
 
1148
  console.error('Chat init error:', error);
1149
  removeTypingIndicator();
1150
  addChatMessage('system',
1151
+ '⚠️ Could not connect to Placement AI. Make sure NVIDIA_API_KEY is set and agno is installed.'
1152
  );
1153
  setChatStatus('Offline');
1154
  }
start_cardiosense.bat → start_placement_predictor.bat RENAMED
@@ -68,7 +68,7 @@ echo.
68
  python train_model.py
69
  if errorlevel 1 (
70
  echo [ERROR] Model training failed!
71
- echo Please check if all diabetes CSV dataset files exist in this folder.
72
  pause
73
  exit /b 1
74
  )
@@ -88,14 +88,15 @@ echo [4/6] Skipped training (using cached model).
88
  echo.
89
 
90
  :START_SERVERS
91
- echo [5/6] Starting API Server on http://127.0.0.1:8000 ...
92
- start "PlacementPredictor+ API" cmd /k "title PlacementPredictor+ API Server && color 0B && set NVIDIA_API_KEY=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 && python -m uvicorn main:app --host 127.0.0.1 --port 8000"
 
93
  echo Waiting for API to start...
94
  timeout /t 8 /nobreak >nul
95
 
96
  :: Validate the model loaded correctly by hitting /health
97
  echo Validating model artifacts...
98
- curl -s http://127.0.0.1:8000/health 2>nul | findstr /C:"model_loaded" | findstr /C:"true" >nul 2>&1
99
  if errorlevel 1 (
100
  echo [!] Model failed to load - version mismatch or corrupted pkl.
101
  echo Killing API server and retraining...
@@ -113,26 +114,19 @@ if errorlevel 1 (
113
  echo Retrained successfully!
114
  echo.
115
  echo [5/6] Restarting API Server...
116
- start "PlacementPredictor+ API" cmd /k "title PlacementPredictor+ API Server && color 0B && set NVIDIA_API_KEY=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 && python -m uvicorn main:app --host 127.0.0.1 --port 8000"
117
  timeout /t 8 /nobreak >nul
118
  )
119
  echo API Server started!
120
  echo.
121
 
122
- echo [6/6] Starting Frontend Server on http://127.0.0.1:3000 ...
123
- start "PlacementPredictor+ Frontend" cmd /k "title PlacementPredictor+ Frontend && color 0E && python -m http.server 3000"
124
- timeout /t 2 /nobreak >nul
125
- echo Frontend Server started!
126
- echo.
127
-
128
  echo ============================================================
129
  echo SERVERS ARE RUNNING!
130
  echo ============================================================
131
  echo.
132
- echo API Documentation: http://127.0.0.1:8000/docs
133
- echo Frontend UI: http://127.0.0.1:3000
134
  echo.
135
- echo TIP: Use the "Load JSON" button in the UI for quick testing
136
  echo TIP: Click the chat bubble after results for AI assistant
137
  echo TIP: Use --force-train flag to force model retraining
138
  echo.
@@ -142,7 +136,7 @@ echo.
142
  :: Open the frontend in default browser
143
  echo Opening PlacementPredictor+ in your browser...
144
  timeout /t 2 /nobreak >nul
145
- start http://127.0.0.1:3000
146
 
147
  echo.
148
  echo Press any key to close this launcher (servers will keep running)...
 
68
  python train_model.py
69
  if errorlevel 1 (
70
  echo [ERROR] Model training failed!
71
+ echo Please check if the placement CSV dataset files exist in this folder.
72
  pause
73
  exit /b 1
74
  )
 
88
  echo.
89
 
90
  :START_SERVERS
91
+ echo [5/6] Starting API Server on http://127.0.0.1:7860 ...
92
+ :: Fixed: Host 0.0.0.0 and Port 7860 to match main.py and HF patterns
93
+ start "PlacementPredictor+ API" cmd /k "title PlacementPredictor+ API Server && color 0B && set NVIDIA_API_KEY=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 && python main.py"
94
  echo Waiting for API to start...
95
  timeout /t 8 /nobreak >nul
96
 
97
  :: Validate the model loaded correctly by hitting /health
98
  echo Validating model artifacts...
99
+ curl -s http://127.0.0.1:7860/health 2>nul | findstr /C:"model_loaded" | findstr /C:"true" >nul 2>&1
100
  if errorlevel 1 (
101
  echo [!] Model failed to load - version mismatch or corrupted pkl.
102
  echo Killing API server and retraining...
 
114
  echo Retrained successfully!
115
  echo.
116
  echo [5/6] Restarting API Server...
117
+ start "PlacementPredictor+ API" cmd /k "title PlacementPredictor+ API Server && color 0B && set NVIDIA_API_KEY=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 && python main.py"
118
  timeout /t 8 /nobreak >nul
119
  )
120
  echo API Server started!
121
  echo.
122
 
 
 
 
 
 
 
123
  echo ============================================================
124
  echo SERVERS ARE RUNNING!
125
  echo ============================================================
126
  echo.
127
+ echo Application UI: http://127.0.0.1:7860
 
128
  echo.
129
+ echo TIP: Use the "Demo Data" button in the UI for quick testing
130
  echo TIP: Click the chat bubble after results for AI assistant
131
  echo TIP: Use --force-train flag to force model retraining
132
  echo.
 
136
  :: Open the frontend in default browser
137
  echo Opening PlacementPredictor+ in your browser...
138
  timeout /t 2 /nobreak >nul
139
+ start http://127.0.0.1:7860
140
 
141
  echo.
142
  echo Press any key to close this launcher (servers will keep running)...
styles.css CHANGED
The diff for this file is too large to render. See raw diff