riazmo commited on
Commit
3bc2adc
Β·
verified Β·
1 Parent(s): 9068c4c

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -22
app.py CHANGED
@@ -1067,10 +1067,16 @@ async def run_stage2_analysis_v2(
1067
  semantic_analysis=semantic_analysis,
1068
  log_callback=state.log,
1069
  )
 
 
 
 
 
 
1070
  except Exception as e:
1071
- state.log(f" ⚠️ Brand Identifier failed: {str(e)[:50]}")
1072
  brand_result = BrandIdentification()
1073
-
1074
  # Benchmark Advisor
1075
  if benchmark_comparisons:
1076
  try:
@@ -1081,20 +1087,38 @@ async def run_stage2_analysis_v2(
1081
  benchmark_comparisons=benchmark_comparisons,
1082
  log_callback=state.log,
1083
  )
 
 
 
 
 
 
 
1084
  except Exception as e:
1085
- state.log(f" ⚠️ Benchmark Advisor failed: {str(e)[:50]}")
1086
  benchmark_advice = BenchmarkAdvice()
1087
  else:
1088
  benchmark_advice = BenchmarkAdvice()
1089
-
1090
  # Best Practices Validator
1091
  try:
1092
  best_practices = await best_practices_agent.analyze(
1093
  rule_engine_results=rule_results,
1094
  log_callback=state.log,
1095
  )
 
 
 
 
 
 
 
 
 
 
 
1096
  except Exception as e:
1097
- state.log(f" ⚠️ Best Practices Validator failed: {str(e)[:50]}")
1098
  best_practices = BestPracticesResult(overall_score=rule_results.consistency_score)
1099
  else:
1100
  # No HF client - use defaults
@@ -1129,8 +1153,21 @@ async def run_stage2_analysis_v2(
1129
  best_practices=best_practices,
1130
  log_callback=state.log,
1131
  )
 
 
 
 
 
 
 
 
 
 
 
1132
  except Exception as e:
1133
- state.log(f" ⚠️ HEAD Synthesizer failed: {str(e)[:50]}")
 
 
1134
  final_synthesis = None
1135
 
1136
  # Create fallback synthesis if needed
@@ -1203,9 +1240,16 @@ async def run_stage2_analysis_v2(
1203
 
1204
  # Generate visual previews
1205
  typography_preview_html = ""
 
 
 
1206
  try:
1207
- from core.preview_generator import generate_typography_preview_html
1208
-
 
 
 
 
1209
  primary_font = fonts.get("primary", "Open Sans")
1210
  desktop_typo_dict = {
1211
  name: {
@@ -1216,23 +1260,89 @@ async def run_stage2_analysis_v2(
1216
  for name, t in state.desktop_normalized.typography.items()
1217
  }
1218
  typography_preview_html = generate_typography_preview_html(desktop_typo_dict, primary_font)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1219
  except Exception as preview_err:
1220
- state.log(f" ⚠️ Preview generation failed: {str(preview_err)[:50]}")
1221
- typography_preview_html = "<div class='placeholder-msg'>Preview unavailable</div>"
1222
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1223
  except Exception as format_err:
1224
  state.log(f" ⚠️ Formatting failed: {str(format_err)[:100]}")
1225
- # Return minimal results
 
 
1226
  return (
1227
  f"⚠️ Analysis completed with formatting errors: {str(format_err)[:50]}",
1228
  state.get_logs(),
1229
  "*Benchmark comparison unavailable*",
1230
- "<div>Scores unavailable</div>",
1231
- "<div>Actions unavailable</div>",
1232
  [],
1233
  None,
1234
  None,
1235
- "",
 
 
1236
  )
1237
 
1238
  progress(0.95, desc="βœ… Complete!")
@@ -1277,8 +1387,10 @@ async def run_stage2_analysis_v2(
1277
  typography_desktop_data,
1278
  typography_mobile_data,
1279
  typography_preview_html,
 
 
1280
  )
1281
-
1282
  except Exception as e:
1283
  import traceback
1284
  state.log(f"❌ Critical Error: {str(e)}")
@@ -1345,17 +1457,19 @@ def create_fallback_synthesis(rule_results, benchmark_comparisons, brand_result,
1345
 
1346
 
1347
  def create_stage2_error_response(error_msg: str):
1348
- """Create error response tuple for Stage 2."""
1349
  return (
1350
  error_msg,
1351
  state.get_logs(),
1352
  "", # benchmark_md
1353
- "", # scores_html
1354
  "", # actions_html
1355
  [], # color_recs_table
1356
  None, # typography_desktop
1357
  None, # typography_mobile
1358
  "", # typography_preview
 
 
1359
  )
1360
 
1361
 
@@ -3870,15 +3984,17 @@ def create_ui():
3870
  fn=run_stage2_analysis_v2,
3871
  inputs=[benchmark_checkboxes],
3872
  outputs=[
3873
- stage2_status,
3874
- stage2_log,
3875
  benchmark_comparison_md,
3876
  scores_dashboard,
3877
  priority_actions_html,
3878
  color_recommendations_table,
3879
- typography_desktop,
3880
- typography_mobile,
3881
  stage2_typography_preview,
 
 
3882
  ],
3883
  )
3884
 
 
1067
  semantic_analysis=semantic_analysis,
1068
  log_callback=state.log,
1069
  )
1070
+ # Log what the LLM contributed
1071
+ if brand_result:
1072
+ state.log(f" β”œβ”€ Brand Primary: {brand_result.primary_color or 'N/A'} ({brand_result.confidence or 'N/A'} confidence)")
1073
+ state.log(f" β”œβ”€ Brand Secondary: {brand_result.secondary_color or 'N/A'}")
1074
+ state.log(f" β”œβ”€ Palette Strategy: {brand_result.palette_strategy or 'N/A'}")
1075
+ state.log(f" └─ Cohesion Score: {brand_result.cohesion_score or 'N/A'}/10")
1076
  except Exception as e:
1077
+ state.log(f" ⚠️ Brand Identifier failed: {str(e)[:120]}")
1078
  brand_result = BrandIdentification()
1079
+
1080
  # Benchmark Advisor
1081
  if benchmark_comparisons:
1082
  try:
 
1087
  benchmark_comparisons=benchmark_comparisons,
1088
  log_callback=state.log,
1089
  )
1090
+ # Log what the LLM contributed
1091
+ if benchmark_advice:
1092
+ state.log(f" β”œβ”€ Recommended: {benchmark_advice.recommended_system or 'N/A'}")
1093
+ changes = getattr(benchmark_advice, 'changes_needed', []) or []
1094
+ state.log(f" β”œβ”€ Changes Needed: {len(changes)}")
1095
+ if changes:
1096
+ state.log(f" └─ Key Change: {changes[0].get('what', 'N/A') if isinstance(changes[0], dict) else changes[0]}")
1097
  except Exception as e:
1098
+ state.log(f" ⚠️ Benchmark Advisor failed: {str(e)[:120]}")
1099
  benchmark_advice = BenchmarkAdvice()
1100
  else:
1101
  benchmark_advice = BenchmarkAdvice()
1102
+
1103
  # Best Practices Validator
1104
  try:
1105
  best_practices = await best_practices_agent.analyze(
1106
  rule_engine_results=rule_results,
1107
  log_callback=state.log,
1108
  )
1109
+ # Log what the LLM contributed
1110
+ if best_practices:
1111
+ checks = getattr(best_practices, 'checks', []) or []
1112
+ passing = sum(1 for c in checks if c.get('pass', False)) if checks else 0
1113
+ failing = len(checks) - passing if checks else 0
1114
+ state.log(f" β”œβ”€ Overall Score: {best_practices.overall_score or 'N/A'}/100")
1115
+ state.log(f" β”œβ”€ Passing: {passing} | Failing: {failing}")
1116
+ if checks:
1117
+ top_fail = next((c for c in checks if not c.get('pass', True)), None)
1118
+ if top_fail:
1119
+ state.log(f" └─ Top Fix: {top_fail.get('fix', top_fail.get('name', 'N/A'))[:60]}")
1120
  except Exception as e:
1121
+ state.log(f" ⚠️ Best Practices Validator failed: {str(e)[:120]}")
1122
  best_practices = BestPracticesResult(overall_score=rule_results.consistency_score)
1123
  else:
1124
  # No HF client - use defaults
 
1153
  best_practices=best_practices,
1154
  log_callback=state.log,
1155
  )
1156
+ if final_synthesis:
1157
+ state.log("")
1158
+ state.log(f" βœ… HEAD Synthesizer: COMPLETE")
1159
+ state.log(f" β”œβ”€ Scores: {final_synthesis.scores}")
1160
+ if final_synthesis.executive_summary:
1161
+ state.log(f" β”œβ”€ Summary: {final_synthesis.executive_summary[:100]}...")
1162
+ color_recs = getattr(final_synthesis, 'color_recommendations', {})
1163
+ if color_recs:
1164
+ state.log(f" β”œβ”€ Color Recommendations: {len(color_recs)} suggested changes")
1165
+ if final_synthesis.top_3_actions:
1166
+ state.log(f" └─ Top Actions: {len(final_synthesis.top_3_actions)} priorities")
1167
  except Exception as e:
1168
+ state.log(f" ⚠️ HEAD Synthesizer failed: {str(e)[:120]}")
1169
+ import traceback
1170
+ state.log(f" └─ {traceback.format_exc()[:200]}")
1171
  final_synthesis = None
1172
 
1173
  # Create fallback synthesis if needed
 
1240
 
1241
  # Generate visual previews
1242
  typography_preview_html = ""
1243
+ color_ramps_preview_html = ""
1244
+ llm_recs_html = ""
1245
+
1246
  try:
1247
+ from core.preview_generator import (
1248
+ generate_typography_preview_html,
1249
+ generate_semantic_color_ramps_html,
1250
+ generate_color_ramps_preview_html,
1251
+ )
1252
+
1253
  primary_font = fonts.get("primary", "Open Sans")
1254
  desktop_typo_dict = {
1255
  name: {
 
1260
  for name, t in state.desktop_normalized.typography.items()
1261
  }
1262
  typography_preview_html = generate_typography_preview_html(desktop_typo_dict, primary_font)
1263
+
1264
+ # Generate color ramps preview (semantic groups)
1265
+ semantic_analysis = getattr(state, 'semantic_analysis', {})
1266
+ desktop_dict_for_colors = normalized_to_dict(state.desktop_normalized)
1267
+
1268
+ if semantic_analysis:
1269
+ color_ramps_preview_html = generate_semantic_color_ramps_html(
1270
+ semantic_analysis=semantic_analysis,
1271
+ color_tokens=desktop_dict_for_colors.get("colors", {}),
1272
+ )
1273
+ else:
1274
+ color_ramps_preview_html = generate_color_ramps_preview_html(
1275
+ color_tokens=desktop_dict_for_colors.get("colors", {}),
1276
+ )
1277
+
1278
+ state.log(" βœ… Color ramps preview generated")
1279
+
1280
  except Exception as preview_err:
1281
+ state.log(f" ⚠️ Preview generation failed: {str(preview_err)[:80]}")
1282
+ typography_preview_html = typography_preview_html or "<div class='placeholder-msg'>Preview unavailable</div>"
1283
+ color_ramps_preview_html = "<div class='placeholder-msg'>Color ramps preview unavailable</div>"
1284
+
1285
+ # Generate LLM recommendations HTML
1286
+ try:
1287
+ # Build recs dict in the format expected by the HTML formatter
1288
+ synth_recs = {}
1289
+ if final_synthesis:
1290
+ # Convert list of color recs to dict keyed by role
1291
+ color_recs_dict = {}
1292
+ for rec in (final_synthesis.color_recommendations or []):
1293
+ if isinstance(rec, dict) and rec.get("role"):
1294
+ color_recs_dict[rec["role"]] = rec
1295
+ synth_recs["color_recommendations"] = color_recs_dict
1296
+
1297
+ # Add AA fixes from rule engine
1298
+ aa_fixes = []
1299
+ if rule_results and rule_results.accessibility:
1300
+ for a in rule_results.accessibility:
1301
+ if not a.passes_aa_normal:
1302
+ aa_fixes.append(a.to_dict() if hasattr(a, 'to_dict') else {"color": str(a)})
1303
+ synth_recs["accessibility_fixes"] = aa_fixes
1304
+
1305
+ llm_recs_html = format_llm_color_recommendations_html(
1306
+ final_recs=synth_recs,
1307
+ semantic_analysis=getattr(state, 'semantic_analysis', {}),
1308
+ )
1309
+ except Exception as recs_err:
1310
+ state.log(f" ⚠️ LLM recs HTML failed: {str(recs_err)[:120]}")
1311
+ import traceback
1312
+ state.log(f" └─ {traceback.format_exc()[:200]}")
1313
+ llm_recs_html = "<div class='placeholder-msg'>LLM recommendations unavailable</div>"
1314
+
1315
+ # Store upgrade_recommendations for Apply Upgrades button
1316
+ aa_failures_list = []
1317
+ if rule_results and rule_results.accessibility:
1318
+ aa_failures_list = [
1319
+ a.to_dict() for a in rule_results.accessibility
1320
+ if not a.passes_aa_normal
1321
+ ]
1322
+ state.upgrade_recommendations = {
1323
+ "color_recommendations": (final_synthesis.color_recommendations if final_synthesis else []),
1324
+ "accessibility_fixes": aa_failures_list,
1325
+ "scores": (final_synthesis.scores if final_synthesis else {}),
1326
+ "top_3_actions": (final_synthesis.top_3_actions if final_synthesis else []),
1327
+ }
1328
+
1329
  except Exception as format_err:
1330
  state.log(f" ⚠️ Formatting failed: {str(format_err)[:100]}")
1331
+ import traceback
1332
+ state.log(traceback.format_exc()[:500])
1333
+ # Return minimal results (must match 11 outputs)
1334
  return (
1335
  f"⚠️ Analysis completed with formatting errors: {str(format_err)[:50]}",
1336
  state.get_logs(),
1337
  "*Benchmark comparison unavailable*",
1338
+ "<div class='placeholder-msg'>Scores unavailable</div>",
1339
+ "<div class='placeholder-msg'>Actions unavailable</div>",
1340
  [],
1341
  None,
1342
  None,
1343
+ "<div class='placeholder-msg'>Typography preview unavailable</div>",
1344
+ "<div class='placeholder-msg'>Color ramps preview unavailable</div>",
1345
+ "<div class='placeholder-msg'>LLM recommendations unavailable</div>",
1346
  )
1347
 
1348
  progress(0.95, desc="βœ… Complete!")
 
1387
  typography_desktop_data,
1388
  typography_mobile_data,
1389
  typography_preview_html,
1390
+ color_ramps_preview_html,
1391
+ llm_recs_html,
1392
  )
1393
+
1394
  except Exception as e:
1395
  import traceback
1396
  state.log(f"❌ Critical Error: {str(e)}")
 
1457
 
1458
 
1459
  def create_stage2_error_response(error_msg: str):
1460
+ """Create error response tuple for Stage 2 (must match 11 outputs)."""
1461
  return (
1462
  error_msg,
1463
  state.get_logs(),
1464
  "", # benchmark_md
1465
+ f"<div class='placeholder-msg'>{error_msg}</div>", # scores_html
1466
  "", # actions_html
1467
  [], # color_recs_table
1468
  None, # typography_desktop
1469
  None, # typography_mobile
1470
  "", # typography_preview
1471
+ "", # color_ramps_preview
1472
+ "", # llm_recs_html
1473
  )
1474
 
1475
 
 
3984
  fn=run_stage2_analysis_v2,
3985
  inputs=[benchmark_checkboxes],
3986
  outputs=[
3987
+ stage2_status,
3988
+ stage2_log,
3989
  benchmark_comparison_md,
3990
  scores_dashboard,
3991
  priority_actions_html,
3992
  color_recommendations_table,
3993
+ typography_desktop,
3994
+ typography_mobile,
3995
  stage2_typography_preview,
3996
+ stage2_color_ramps_preview,
3997
+ llm_color_recommendations,
3998
  ],
3999
  )
4000