vighnesh-shetty-vs commited on
Commit
2bf4a82
Β·
1 Parent(s): 4ae6245

Add updated files

Browse files
Files changed (1) hide show
  1. app.py +74 -35
app.py CHANGED
@@ -142,47 +142,90 @@ def format_alt_button(text, impact):
142
  return f"{icon} {text}\n\nπŸ† Score: +10 Pts\nπŸ’§ Save: {impact['water_ml']} mL\n⚑ Save: {impact['energy_wh']} Wh\n☁️ Save: {impact['co2_g']} g"
143
 
144
  def generate_victory_dashboard(state):
145
- """Generates a massive, celebratory end-game report."""
 
 
 
 
 
 
146
  rows = ""
147
  for item in state["history"]:
148
- alt_text = item['alt'] if item['alt'] else "Justified use (No alternative needed)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  rows += f"""
150
- <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);">
151
- <td style="padding: 12px; max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">"{item['query']}"</td>
152
- <td style="padding: 12px; color: #fca5a5;">{item['water_ml']}mL / {item['energy_wh']}Wh</td>
153
- <td style="padding: 12px; color: #86efac;">{alt_text}</td>
 
154
  </tr>
155
  """
156
 
157
  return f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  <div class="victory-dashboard">
159
- <h1 class="victory-title">πŸŽ‰ YOU SAVED DRIP! πŸŽ‰</h1>
160
- <p style="text-align: center; font-size: 1.2em; color: #a7f3d0;">You successfully navigated the AI ecosystem and reached {state['points']} points!</p>
161
 
162
  <div class="victory-stats-row">
163
  <div class="v-stat-box">
164
- <h4>Total Water Remaining</h4>
165
  <h2>{state['water']:.2f} L</h2>
166
  </div>
167
- <div class="v-stat-box">
168
- <h4>Queries Asked</h4>
169
- <h2>{state['queries']}</h2>
 
 
170
  </div>
171
- <div class="v-stat-box" style="border-color: #facc15;">
172
- <h4 style="color: #fde047;">Energy Wasted</h4>
173
- <h2 style="color: #fde047;">{state['energy']:.4f} kWh</h2>
 
 
174
  </div>
175
  </div>
176
 
177
- <h3 style="margin-top: 30px; color: #38bdf8;">πŸ“ Your AI Audit Log</h3>
178
- <p style="opacity: 0.8; margin-bottom: 15px;">Review what you queried, what it cost the planet, and the greener choices you could have made.</p>
179
 
180
- <div style="max-height: 300px; overflow-y: auto; background: rgba(15, 23, 42, 0.8); border-radius: 12px; border: 1px solid rgba(255,255,255,0.1);">
181
- <table style="width: 100%; text-align: left; border-collapse: collapse;">
182
- <tr style="background: rgba(255,255,255,0.05);">
183
- <th style="padding: 12px;">Your Query</th>
184
- <th style="padding: 12px;">LLM Cost Wasted</th>
185
- <th style="padding: 12px;">Greener Alternative</th>
 
186
  </tr>
187
  {rows}
188
  </table>
@@ -192,7 +235,6 @@ def generate_victory_dashboard(state):
192
 
193
  def process_query(user_input, selected_model, state):
194
  if state["game_over"] or not user_input.strip():
195
- # Update 14 fields (see outputs mapping below)
196
  return [state, gr.update()] + [gr.update()]*10 + [gr.update(visible=True), gr.update(visible=False), gr.update()]
197
 
198
  result = classifier(user_input, CATEGORIES)
@@ -208,7 +250,7 @@ def process_query(user_input, selected_model, state):
208
 
209
  show_alts = False
210
  alt_choices = ["", "", ""]
211
- best_alt_name = ""
212
 
213
  if category == "complex research query":
214
  state["points"] += 50
@@ -221,16 +263,16 @@ def process_query(user_input, selected_model, state):
221
 
222
  random.shuffle(raw_alts)
223
  state["current_shuffled_alts"] = raw_alts
224
- # Inject the impact metrics into the button formatting
225
  alt_choices = [format_alt_button(a["text"], impact) for a in raw_alts]
226
  dialogue = get_dialogue(state["water"], category)
227
 
228
- # Log the query in history for the victory dashboard
229
  state["history"].append({
230
  "query": user_input,
231
  "water_ml": impact["water_ml"],
232
  "energy_wh": impact["energy_wh"],
233
- "alt": best_alt_name if show_alts else ""
 
234
  })
235
 
236
  stats_ui = get_stats_html(state["water"], state["energy"], state["co2"], state["points"])
@@ -239,16 +281,14 @@ def process_query(user_input, selected_model, state):
239
  audio_path = generate_audio(dialogue)
240
  feedback_text = f"<div class='feedback-box'>🧠 <strong>{category.upper()}</strong> Detected on {selected_model}!<br><br><em>\"{dialogue}\"</em></div>"
241
 
242
- # Check for Win/Loss
243
  if state["points"] >= 500 or state["water"] <= 0:
244
  state["game_over"] = True
245
  victory_html = generate_victory_dashboard(state)
246
- # Hide main game, Show victory screen
247
  return (state, stats_ui, drip_ui, audio_path, impact_ui, gr.update(), gr.update(),
248
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(value=""),
249
  gr.update(visible=False), gr.update(visible=True), gr.update(value=victory_html))
250
 
251
- # Standard Return
252
  return (state, stats_ui, drip_ui, audio_path, impact_ui, gr.update(value=feedback_text), gr.update(visible=show_alts),
253
  gr.update(value=alt_choices[0]), gr.update(value=alt_choices[1]), gr.update(value=alt_choices[2]), gr.update(value=""), gr.update(value=""),
254
  gr.update(visible=True), gr.update(visible=False), gr.update())
@@ -257,7 +297,6 @@ def select_alternative(choice_text, state):
257
  if state["game_over"] or not state.get("current_best_alt"):
258
  return state, gr.update(), gr.update(), gr.update(), gr.update(visible=True), gr.update(visible=False), gr.update()
259
 
260
- # Extract just the name from the formatted button text (second line)
261
  clean_choice = choice_text.split("\n")[1].strip()
262
  selected_dict = next((item for item in state["current_shuffled_alts"] if item["text"] == clean_choice), None)
263
 
@@ -269,7 +308,7 @@ def select_alternative(choice_text, state):
269
 
270
  stats_ui = get_stats_html(state["water"], state["energy"], state["co2"], state["points"])
271
 
272
- # Check for win immediately after points award
273
  if state["points"] >= 500:
274
  state["game_over"] = True
275
  victory_html = generate_victory_dashboard(state)
@@ -277,7 +316,6 @@ def select_alternative(choice_text, state):
277
 
278
  return state, stats_ui, gr.update(value=msg), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update()
279
 
280
-
281
  custom_css = """
282
  @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;500;700&display=swap');
283
  body, .gradio-container { background-color: #0B1120 !important; font-family: 'Outfit', sans-serif !important; color: #e2e8f0 !important; }
@@ -371,13 +409,14 @@ with gr.Blocks(title="EcoQueryQuest") as demo:
371
  with gr.Column(visible=False) as victory_ui:
372
  victory_display = gr.HTML()
373
 
374
- # WIRING
375
  submit_btn.click(
376
  fn=process_query,
377
  inputs=[user_input, model_selector, game_state],
378
  outputs=[game_state, stats_html, drip_html, drip_audio, impact_display, drip_feedback, alternatives_group, alt_btn_1, alt_btn_2, alt_btn_3, alt_feedback, user_input, main_game_ui, victory_ui, victory_display]
379
  )
380
 
 
381
  for btn in [alt_btn_1, alt_btn_2, alt_btn_3]:
382
  btn.click(
383
  fn=select_alternative,
 
142
  return f"{icon} {text}\n\nπŸ† Score: +10 Pts\nπŸ’§ Save: {impact['water_ml']} mL\n⚑ Save: {impact['energy_wh']} Wh\n☁️ Save: {impact['co2_g']} g"
143
 
144
  def generate_victory_dashboard(state):
145
+ """Generates a massive, celebratory end-game report with detailed analytics."""
146
+
147
+ # Calculate Total Savings
148
+ total_water_saved = 0
149
+ total_energy_saved = 0
150
+ total_co2_saved = 0
151
+
152
  rows = ""
153
  for item in state["history"]:
154
+ # If it was a justified complex query, there are no savings
155
+ if item['alt_name'] == "None (Justified Use)":
156
+ saved_w, saved_e, saved_c = 0.0, 0.0, 0.0
157
+ alt_display = "<span style='color: #94a3b8;'>Justified Use (No Alternative)</span>"
158
+ else:
159
+ # Calculate savings (LLM cost - Eco-Alternative cost)
160
+ saved_w = max(0, item['water_ml'] - 0.0)
161
+ saved_e = max(0, item['energy_wh'] - 0.001)
162
+ saved_c = max(0, item['co2_g'] - 0.01)
163
+
164
+ total_water_saved += saved_w
165
+ total_energy_saved += saved_e
166
+ total_co2_saved += saved_c
167
+
168
+ alt_display = f"<span style='color: #34d399;'>{item['alt_name']}</span>"
169
+
170
  rows += f"""
171
+ <tr style="border-bottom: 1px solid rgba(255,255,255,0.1); background: rgba(0,0,0,0.2);">
172
+ <td style="padding: 15px; font-style: italic;">"{item['query']}"</td>
173
+ <td style="padding: 15px; color: #fca5a5;">{item['water_ml']:.1f}mL / {item['energy_wh']:.2f}Wh / {item['co2_g']:.2f}g</td>
174
+ <td style="padding: 15px;">{alt_display}</td>
175
+ <td style="padding: 15px; color: #60a5fa; font-weight: bold;">{saved_w:.1f}mL / {saved_e:.2f}Wh / {saved_c:.2f}g</td>
176
  </tr>
177
  """
178
 
179
  return f"""
180
+ <style>
181
+ @keyframes pulseGlow {{
182
+ 0% {{ box-shadow: 0 0 20px rgba(52, 211, 153, 0.4); }}
183
+ 50% {{ box-shadow: 0 0 60px rgba(52, 211, 153, 0.8); }}
184
+ 100% {{ box-shadow: 0 0 20px rgba(52, 211, 153, 0.4); }}
185
+ }}
186
+ .victory-dashboard {{ background: linear-gradient(135deg, #0f172a, #1e293b); padding: 40px; border-radius: 24px; border: 2px solid #34d399; animation: pulseGlow 2s infinite; color: white; }}
187
+ .victory-title {{ text-align: center; color: #34d399; font-size: 3.5em !important; text-shadow: 0 0 20px rgba(52, 211, 153, 0.6); margin-bottom: 5px; }}
188
+ .victory-subtitle {{ text-align: center; font-size: 1.3em; color: #a7f3d0; margin-bottom: 30px; }}
189
+ .victory-stats-row {{ display: flex; gap: 20px; margin-top: 30px; margin-bottom: 40px; }}
190
+ .v-stat-box {{ flex: 1; background: rgba(0,0,0,0.4); padding: 25px; border-radius: 16px; text-align: center; border: 1px solid rgba(52, 211, 153, 0.3); }}
191
+ .v-stat-box h4 {{ color: #94a3b8; font-size: 0.9em; text-transform: uppercase; letter-spacing: 1.5px; margin: 0 0 10px 0; }}
192
+ .v-stat-box h2 {{ color: #38bdf8; font-size: 2.8em; margin: 0; }}
193
+ .v-stat-highlight h2 {{ color: #34d399; }}
194
+ </style>
195
+
196
  <div class="victory-dashboard">
197
+ <h1 class="victory-title">πŸ† YOU BEAT THE SYSTEM! πŸ†</h1>
198
+ <p class="victory-subtitle">You successfully navigated the AI ecosystem, reached {state['points']} points, and saved Drip!</p>
199
 
200
  <div class="victory-stats-row">
201
  <div class="v-stat-box">
202
+ <h4>Water Remaining</h4>
203
  <h2>{state['water']:.2f} L</h2>
204
  </div>
205
+ <div class="v-stat-box v-stat-highlight">
206
+ <h4>Total Metrics Saved</h4>
207
+ <p style="font-size: 1.2em; color: #34d399; margin:0;">πŸ’§ {total_water_saved:.1f} mL</p>
208
+ <p style="font-size: 1.2em; color: #facc15; margin:0;">⚑ {total_energy_saved:.2f} Wh</p>
209
+ <p style="font-size: 1.2em; color: #a8a29e; margin:0;">☁️ {total_co2_saved:.2f} g</p>
210
  </div>
211
+ <div class="v-stat-box" style="border-color: #fca5a5;">
212
+ <h4 style="color: #fca5a5;">Metrics Wasted</h4>
213
+ <p style="font-size: 1.2em; color: #fca5a5; margin:0;">πŸ’§ {10.0 - state['water']:.2f} L</p>
214
+ <p style="font-size: 1.2em; color: #fca5a5; margin:0;">⚑ {state['energy']:.4f} kWh</p>
215
+ <p style="font-size: 1.2em; color: #fca5a5; margin:0;">☁️ {state['co2']:.2f} g</p>
216
  </div>
217
  </div>
218
 
219
+ <h3 style="margin-top: 30px; color: #38bdf8; font-size: 1.8em;">πŸ“Š Your AI Audit Log</h3>
220
+ <p style="opacity: 0.9; margin-bottom: 20px; font-size: 1.1em;">Review your query history below to see exactly what you could have saved by choosing eco-friendly alternatives.</p>
221
 
222
+ <div style="max-height: 400px; overflow-y: auto; background: rgba(15, 23, 42, 0.9); border-radius: 12px; border: 1px solid rgba(255,255,255,0.1);">
223
+ <table style="width: 100%; text-align: left; border-collapse: collapse; font-size: 1.05em;">
224
+ <tr style="background: rgba(56, 189, 248, 0.1); border-bottom: 2px solid #38bdf8;">
225
+ <th style="padding: 15px; color: #38bdf8;">Your Query</th>
226
+ <th style="padding: 15px; color: #fca5a5;">LLM Cost (Wasted)</th>
227
+ <th style="padding: 15px; color: #34d399;">Better Alternative</th>
228
+ <th style="padding: 15px; color: #60a5fa;">Potential Savings</th>
229
  </tr>
230
  {rows}
231
  </table>
 
235
 
236
  def process_query(user_input, selected_model, state):
237
  if state["game_over"] or not user_input.strip():
 
238
  return [state, gr.update()] + [gr.update()]*10 + [gr.update(visible=True), gr.update(visible=False), gr.update()]
239
 
240
  result = classifier(user_input, CATEGORIES)
 
250
 
251
  show_alts = False
252
  alt_choices = ["", "", ""]
253
+ best_alt_name = "None (Justified Use)"
254
 
255
  if category == "complex research query":
256
  state["points"] += 50
 
263
 
264
  random.shuffle(raw_alts)
265
  state["current_shuffled_alts"] = raw_alts
 
266
  alt_choices = [format_alt_button(a["text"], impact) for a in raw_alts]
267
  dialogue = get_dialogue(state["water"], category)
268
 
269
+ # Log the exact metrics for the victory dashboard
270
  state["history"].append({
271
  "query": user_input,
272
  "water_ml": impact["water_ml"],
273
  "energy_wh": impact["energy_wh"],
274
+ "co2_g": impact["co2_g"],
275
+ "alt_name": best_alt_name
276
  })
277
 
278
  stats_ui = get_stats_html(state["water"], state["energy"], state["co2"], state["points"])
 
281
  audio_path = generate_audio(dialogue)
282
  feedback_text = f"<div class='feedback-box'>🧠 <strong>{category.upper()}</strong> Detected on {selected_model}!<br><br><em>\"{dialogue}\"</em></div>"
283
 
284
+ # Check for Win/Loss immediately upon sending query
285
  if state["points"] >= 500 or state["water"] <= 0:
286
  state["game_over"] = True
287
  victory_html = generate_victory_dashboard(state)
 
288
  return (state, stats_ui, drip_ui, audio_path, impact_ui, gr.update(), gr.update(),
289
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(value=""),
290
  gr.update(visible=False), gr.update(visible=True), gr.update(value=victory_html))
291
 
 
292
  return (state, stats_ui, drip_ui, audio_path, impact_ui, gr.update(value=feedback_text), gr.update(visible=show_alts),
293
  gr.update(value=alt_choices[0]), gr.update(value=alt_choices[1]), gr.update(value=alt_choices[2]), gr.update(value=""), gr.update(value=""),
294
  gr.update(visible=True), gr.update(visible=False), gr.update())
 
297
  if state["game_over"] or not state.get("current_best_alt"):
298
  return state, gr.update(), gr.update(), gr.update(), gr.update(visible=True), gr.update(visible=False), gr.update()
299
 
 
300
  clean_choice = choice_text.split("\n")[1].strip()
301
  selected_dict = next((item for item in state["current_shuffled_alts"] if item["text"] == clean_choice), None)
302
 
 
308
 
309
  stats_ui = get_stats_html(state["water"], state["energy"], state["co2"], state["points"])
310
 
311
+ # Check for win after points are awarded from selecting an alternative
312
  if state["points"] >= 500:
313
  state["game_over"] = True
314
  victory_html = generate_victory_dashboard(state)
 
316
 
317
  return state, stats_ui, gr.update(value=msg), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update()
318
 
 
319
  custom_css = """
320
  @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;500;700&display=swap');
321
  body, .gradio-container { background-color: #0B1120 !important; font-family: 'Outfit', sans-serif !important; color: #e2e8f0 !important; }
 
409
  with gr.Column(visible=False) as victory_ui:
410
  victory_display = gr.HTML()
411
 
412
+ # Ensure these outputs match EXACTLY with the 15 return items in process_query
413
  submit_btn.click(
414
  fn=process_query,
415
  inputs=[user_input, model_selector, game_state],
416
  outputs=[game_state, stats_html, drip_html, drip_audio, impact_display, drip_feedback, alternatives_group, alt_btn_1, alt_btn_2, alt_btn_3, alt_feedback, user_input, main_game_ui, victory_ui, victory_display]
417
  )
418
 
419
+ # Ensure these outputs match EXACTLY with the 7 return items in select_alternative
420
  for btn in [alt_btn_1, alt_btn_2, alt_btn_3]:
421
  btn.click(
422
  fn=select_alternative,