Supastrikas-004 commited on
Commit
ebdd779
Β·
verified Β·
1 Parent(s): f07e656

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -378
app.py CHANGED
@@ -3,27 +3,21 @@ import pandas as pd
3
  import numpy as np
4
  import json
5
  import plotly.graph_objects as go
6
- import plotly.express as px
7
- from datetime import datetime
8
- import hashlib
9
  from typing import Dict, List, Tuple, Optional
10
- import re
11
- from collections import defaultdict
12
- import seaborn as sns
13
- import matplotlib.pyplot as plt
14
- from io import BytesIO
15
- import base64
16
 
17
  # Import evaluation modules
18
  from evaluator_module import AetherScoreEvaluator
19
  from visualizer_module import EvaluationVisualizer
20
  from report_generator import ReportGenerator
21
 
22
- # Initialize components
23
  evaluator = AetherScoreEvaluator()
24
  visualizer = EvaluationVisualizer()
25
  report_gen = ReportGenerator()
26
 
 
 
 
27
  # CSS for better styling
28
  custom_css = """
29
  .gradio-container {
@@ -36,65 +30,58 @@ custom_css = """
36
  color: white;
37
  margin: 10px 0;
38
  }
39
- .leaderboard-row {
40
- transition: all 0.3s ease;
41
- }
42
- .leaderboard-row:hover {
43
- transform: translateX(5px);
44
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
- }
46
  """
47
 
 
 
48
  def process_single_evaluation(
49
  prompt: str,
50
  response: str,
51
  expected_answer: Optional[str] = None,
52
  agent_name: str = "Agent-1",
53
  task_type: str = "general"
54
- ) -> Tuple[Dict, str, str, str]:
55
  """Process a single agent response evaluation"""
56
-
57
  if not prompt or not response:
58
- return {}, "", "", "Please provide both prompt and response"
59
-
60
  # Evaluate the response
61
- scores = evaluator.evaluate_single(
62
  prompt=prompt,
63
  response=response,
64
  expected_answer=expected_answer,
65
  task_type=task_type
66
  )
 
67
 
 
 
 
 
 
 
68
  # Generate visualizations
69
  spider_chart = visualizer.create_spider_chart(scores, agent_name)
70
  score_bars = visualizer.create_score_bars(scores, agent_name)
71
-
72
  # Generate explanation
73
- explanation = evaluator.generate_explanation(scores, prompt, response)
74
-
75
  # Format scores for display
76
- scores_display = {
77
- "Overall Score": f"{scores.get('overall_score', 0):.2f}",
78
- "Instruction Following": f"{scores.get('instruction_following', 0):.2f}",
79
- "Hallucination Score": f"{scores.get('hallucination_score', 0):.2f}",
80
- "Assumption Control": f"{scores.get('assumption_control', 0):.2f}",
81
- "Coherence": f"{scores.get('coherence', 0):.2f}",
82
- "Accuracy": f"{scores.get('accuracy', 0):.2f}"
83
- }
84
 
85
  return scores_display, spider_chart, score_bars, explanation
86
 
87
  def process_batch_evaluation(
88
  file_input,
89
  evaluation_mode: str = "comprehensive"
90
- ) -> Tuple[str, str, str, str, pd.DataFrame]:
91
  """Process batch evaluation from uploaded file"""
92
-
93
  if file_input is None:
94
- return "", "", "", "", pd.DataFrame()
95
-
96
  try:
97
- # Parse the uploaded file
98
  if file_input.name.endswith('.json'):
99
  with open(file_input.name, 'r') as f:
100
  data = json.load(f)
@@ -104,55 +91,45 @@ def process_batch_evaluation(
104
  for line in f:
105
  data.append(json.loads(line))
106
  else:
107
- return "", "", "", "Unsupported file format. Please upload JSON or JSONL", pd.DataFrame()
108
-
109
  # Process batch evaluation
110
  results = evaluator.evaluate_batch(data, mode=evaluation_mode)
111
 
 
 
 
 
 
 
112
  # Generate visualizations
113
  heatmap = visualizer.create_evaluation_heatmap(results)
114
  distribution = visualizer.create_score_distribution(results)
115
  trends = visualizer.create_performance_trends(results)
116
-
117
- # Generate comprehensive report
118
  report = report_gen.generate_batch_report(results)
119
-
120
- # Create leaderboard
121
  leaderboard = create_leaderboard(results)
122
 
123
  return heatmap, distribution, trends, report, leaderboard
124
 
125
  except Exception as e:
126
  error_msg = f"Error processing batch file: {str(e)}"
127
- return "", "", "", error_msg, pd.DataFrame()
128
 
129
  def create_leaderboard(results: List[Dict]) -> pd.DataFrame:
130
  """Create a leaderboard from evaluation results"""
131
-
132
- agent_scores = defaultdict(list)
133
-
134
- for result in results:
135
- agent_name = result.get('agent_name', 'Unknown')
136
- overall_score = result.get('scores', {}).get('overall_score', 0)
137
- agent_scores[agent_name].append(overall_score)
138
 
139
  leaderboard_data = []
140
  for agent, scores in agent_scores.items():
141
  leaderboard_data.append({
142
- 'Rank': 0, # Will be assigned after sorting
143
- 'Agent': agent,
144
- 'Avg Score': np.mean(scores),
145
- 'Max Score': np.max(scores),
146
- 'Min Score': np.min(scores),
147
- 'Std Dev': np.std(scores),
148
- 'Evaluations': len(scores)
149
  })
150
 
151
- df = pd.DataFrame(leaderboard_data)
152
- df = df.sort_values('Avg Score', ascending=False)
153
  df['Rank'] = range(1, len(df) + 1)
154
 
155
- # Format scores
156
  for col in ['Avg Score', 'Max Score', 'Min Score', 'Std Dev']:
157
  df[col] = df[col].apply(lambda x: f"{x:.3f}")
158
 
@@ -161,366 +138,136 @@ def create_leaderboard(results: List[Dict]) -> pd.DataFrame:
161
  def compare_agents(
162
  agent1_file,
163
  agent2_file,
164
- comparison_metric: str = "all"
165
- ) -> Tuple[str, str, str, str]:
166
  """Compare two agents' performance"""
167
-
168
  if not agent1_file or not agent2_file:
169
- return "", "", "", "Please upload files for both agents"
170
-
171
  try:
172
- # Load agent data
173
- agent1_data = load_agent_data(agent1_file)
174
- agent2_data = load_agent_data(agent2_file)
175
-
176
- # Evaluate both agents
177
- agent1_results = evaluator.evaluate_batch(agent1_data)
178
- agent2_results = evaluator.evaluate_batch(agent2_data)
179
-
180
- # Generate comparison visualizations
181
- comparison_chart = visualizer.create_agent_comparison(
182
- agent1_results,
183
- agent2_results,
184
- agent1_name="Agent 1",
185
- agent2_name="Agent 2"
186
- )
187
-
188
- radar_comparison = visualizer.create_radar_comparison(
189
- agent1_results,
190
- agent2_results
191
- )
192
-
193
- performance_delta = visualizer.create_performance_delta(
194
- agent1_results,
195
- agent2_results
196
- )
197
 
198
- # Generate comparison report
199
- comparison_report = report_gen.generate_comparison_report(
200
- agent1_results,
201
- agent2_results
202
- )
203
 
204
  return comparison_chart, radar_comparison, performance_delta, comparison_report
205
 
206
  except Exception as e:
207
  error_msg = f"Error comparing agents: {str(e)}"
208
- return "", "", "", error_msg
209
 
210
- def load_agent_data(file_input):
211
- """Load agent data from file"""
212
- if file_input.name.endswith('.json'):
213
- with open(file_input.name, 'r') as f:
214
- return json.load(f)
215
- elif file_input.name.endswith('.jsonl'):
216
- data = []
217
- with open(file_input.name, 'r') as f:
218
- for line in f:
219
- data.append(json.loads(line))
220
- return data
221
- else:
222
- raise ValueError("Unsupported file format")
223
 
224
- def export_results(results_data: Dict, export_format: str = "json") -> str:
225
- """Export evaluation results in various formats"""
226
-
227
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
228
-
229
- if export_format == "json":
230
- filename = f"aetherscore_results_{timestamp}.json"
231
- with open(filename, 'w') as f:
232
- json.dump(results_data, f, indent=2)
233
- elif export_format == "csv":
234
- filename = f"aetherscore_results_{timestamp}.csv"
235
- df = pd.DataFrame(results_data)
236
- df.to_csv(filename, index=False)
237
- else:
238
- filename = f"aetherscore_results_{timestamp}.html"
239
- # Generate HTML report
240
- html_content = report_gen.generate_html_report(results_data)
241
- with open(filename, 'w') as f:
242
- f.write(html_content)
243
-
244
- return filename
245
 
246
- # Create Gradio Interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  with gr.Blocks(title="AetherScore - AI Agent Evaluation Framework", css=custom_css) as demo:
248
-
249
- gr.Markdown("""
250
- # 🌟 AetherScore - Advanced AI Agent Evaluation Framework
251
-
252
- **Comprehensive evaluation system for AI agents with multi-dimensional scoring, explainability, and advanced visualizations**
253
-
254
- ---
255
- """)
256
 
257
  with gr.Tabs():
258
  # Tab 1: Single Evaluation
259
  with gr.TabItem("🎯 Single Evaluation"):
260
- gr.Markdown("### Evaluate a single agent response")
261
-
262
  with gr.Row():
263
  with gr.Column(scale=1):
264
- prompt_input = gr.Textbox(
265
- label="Prompt",
266
- placeholder="Enter the prompt given to the agent...",
267
- lines=3
268
- )
269
- response_input = gr.Textbox(
270
- label="Agent Response",
271
- placeholder="Enter the agent's response...",
272
- lines=3
273
- )
274
- expected_answer = gr.Textbox(
275
- label="Expected Answer (Optional)",
276
- placeholder="Enter the expected/correct answer for accuracy scoring...",
277
- lines=2
278
- )
279
-
280
- with gr.Row():
281
- agent_name_input = gr.Textbox(
282
- label="Agent Name",
283
- value="Agent-1",
284
- scale=1
285
- )
286
- task_type = gr.Dropdown(
287
- label="Task Type",
288
- choices=["general", "QA", "summarization", "reasoning", "code"],
289
- value="general",
290
- scale=1
291
- )
292
-
293
  evaluate_btn = gr.Button("πŸ” Evaluate", variant="primary")
294
-
295
  with gr.Column(scale=1):
296
  scores_output = gr.JSON(label="πŸ“Š Evaluation Scores")
297
- explanation_output = gr.Textbox(
298
- label="πŸ“ Explanation",
299
- lines=6,
300
- interactive=False
301
- )
302
-
303
  with gr.Row():
304
- spider_chart_output = gr.HTML(label="πŸ•ΈοΈ Spider Chart")
305
- score_bars_output = gr.HTML(label="πŸ“Š Score Breakdown")
306
 
307
- evaluate_btn.click(
308
- fn=process_single_evaluation,
309
- inputs=[prompt_input, response_input, expected_answer, agent_name_input, task_type],
310
- outputs=[scores_output, spider_chart_output, score_bars_output, explanation_output]
311
- )
312
-
313
  # Tab 2: Batch Evaluation
314
  with gr.TabItem("πŸ“¦ Batch Evaluation"):
315
- gr.Markdown("### Evaluate multiple agents and responses at scale")
316
-
317
  with gr.Row():
318
  with gr.Column(scale=1):
319
- batch_file = gr.File(
320
- label="Upload Evaluation File (JSON/JSONL)",
321
- file_types=[".json", ".jsonl"]
322
- )
323
- evaluation_mode = gr.Radio(
324
- label="Evaluation Mode",
325
- choices=["comprehensive", "fast", "detailed"],
326
- value="comprehensive"
327
- )
328
  batch_evaluate_btn = gr.Button("πŸš€ Run Batch Evaluation", variant="primary")
329
-
330
- gr.Markdown("""
331
- **Expected Format:**
332
- ```json
333
- {
334
- "task_id": "task_001",
335
- "agent_name": "GPT-4",
336
- "prompt": "...",
337
- "response": "...",
338
- "expected_answer": "..." (optional)
339
- }
340
- ```
341
- """)
342
-
343
  with gr.Column(scale=2):
344
- batch_report = gr.Textbox(
345
- label="πŸ“„ Evaluation Report",
346
- lines=10,
347
- interactive=False
348
- )
349
-
350
  with gr.Row():
351
- heatmap_output = gr.HTML(label="πŸ—ΊοΈ Evaluation Heatmap")
352
- distribution_output = gr.HTML(label="πŸ“ˆ Score Distribution")
 
 
353
 
354
- trends_output = gr.HTML(label="πŸ“Š Performance Trends")
355
- leaderboard_output = gr.Dataframe(
356
- label="πŸ† Agent Leaderboard",
357
- interactive=False
358
- )
359
-
360
- batch_evaluate_btn.click(
361
- fn=process_batch_evaluation,
362
- inputs=[batch_file, evaluation_mode],
363
- outputs=[heatmap_output, distribution_output, trends_output, batch_report, leaderboard_output]
364
- )
365
-
366
  # Tab 3: Agent Comparison
367
  with gr.TabItem("βš”οΈ Agent Comparison"):
368
- gr.Markdown("### Compare performance between two agents")
369
-
370
  with gr.Row():
371
  with gr.Column():
372
- agent1_file = gr.File(
373
- label="Agent 1 Results (JSON/JSONL)",
374
- file_types=[".json", ".jsonl"]
375
- )
376
- agent2_file = gr.File(
377
- label="Agent 2 Results (JSON/JSONL)",
378
- file_types=[".json", ".jsonl"]
379
- )
380
- comparison_metric = gr.Dropdown(
381
- label="Comparison Focus",
382
- choices=["all", "accuracy", "hallucination", "instruction_following"],
383
- value="all"
384
- )
385
  compare_btn = gr.Button("βš–οΈ Compare Agents", variant="primary")
386
-
387
  with gr.Column():
388
- comparison_report = gr.Textbox(
389
- label="πŸ“Š Comparison Analysis",
390
- lines=8,
391
- interactive=False
392
- )
393
-
394
  with gr.Row():
395
- comparison_chart = gr.HTML(label="πŸ“Š Performance Comparison")
396
- radar_comparison = gr.HTML(label="🎯 Radar Comparison")
 
397
 
398
- performance_delta = gr.HTML(label="πŸ“ˆ Performance Delta Analysis")
399
-
400
- compare_btn.click(
401
- fn=compare_agents,
402
- inputs=[agent1_file, agent2_file, comparison_metric],
403
- outputs=[comparison_chart, radar_comparison, performance_delta, comparison_report]
404
- )
405
-
406
  # Tab 4: Explainability Dashboard
407
  with gr.TabItem("πŸ” Explainability"):
408
- gr.Markdown("### Deep dive into evaluation decisions")
409
-
410
  with gr.Row():
411
- with gr.Column():
412
- eval_id_input = gr.Textbox(
413
- label="Evaluation ID or Task ID",
414
- placeholder="Enter evaluation ID to analyze..."
415
- )
416
- load_eval_btn = gr.Button("Load Evaluation", variant="secondary")
417
-
418
- with gr.Column():
419
- eval_details = gr.JSON(label="Evaluation Details")
420
-
421
  with gr.Row():
422
- decision_tree = gr.HTML(label="Decision Tree")
423
- feature_importance = gr.HTML(label="Feature Importance")
424
-
425
- detailed_breakdown = gr.Textbox(
426
- label="Detailed Score Breakdown",
427
- lines=10,
428
- interactive=False
429
- )
430
-
431
- # Tab 5: Settings & Export
432
- with gr.TabItem("βš™οΈ Settings & Export"):
433
- gr.Markdown("### Configuration and Export Options")
434
-
435
- with gr.Row():
436
- with gr.Column():
437
- gr.Markdown("#### Evaluation Settings")
438
-
439
- hallucination_threshold = gr.Slider(
440
- label="Hallucination Detection Threshold",
441
- minimum=0.0,
442
- maximum=1.0,
443
- value=0.7,
444
- step=0.1
445
- )
446
-
447
- coherence_weight = gr.Slider(
448
- label="Coherence Weight",
449
- minimum=0.0,
450
- maximum=1.0,
451
- value=0.25,
452
- step=0.05
453
- )
454
-
455
- accuracy_weight = gr.Slider(
456
- label="Accuracy Weight",
457
- minimum=0.0,
458
- maximum=1.0,
459
- value=0.25,
460
- step=0.05
461
- )
462
-
463
- save_settings_btn = gr.Button("πŸ’Ύ Save Settings", variant="secondary")
464
-
465
- with gr.Column():
466
- gr.Markdown("#### Export Options")
467
-
468
- export_format = gr.Radio(
469
- label="Export Format",
470
- choices=["JSON", "CSV", "HTML Report"],
471
- value="JSON"
472
- )
473
-
474
- include_visualizations = gr.Checkbox(
475
- label="Include Visualizations in Export",
476
- value=True
477
- )
478
-
479
- export_btn = gr.Button("πŸ“₯ Export Results", variant="primary")
480
- export_status = gr.Textbox(
481
- label="Export Status",
482
- interactive=False
483
- )
484
-
485
- gr.Markdown("""
486
- ---
487
-
488
- ### πŸ“š About AetherScore
489
-
490
- AetherScore is a comprehensive evaluation framework designed to assess AI agents across multiple dimensions:
491
-
492
- - **Instruction Following**: How well the agent adheres to given instructions
493
- - **Hallucination Detection**: Identifies fabricated or unsupported information
494
- - **Assumption Control**: Measures unwarranted assumptions made by the agent
495
- - **Coherence**: Evaluates logical consistency and flow
496
- - **Accuracy**: Compares responses against ground truth when available
497
-
498
- ### 🎯 Key Features
499
-
500
- - **Multi-dimensional Scoring**: Comprehensive evaluation across 5+ metrics
501
- - **Batch Processing**: Evaluate thousands of responses efficiently
502
- - **Advanced Visualizations**: Spider charts, heatmaps, trend analysis
503
- - **Explainable AI**: Understand why scores were assigned
504
- - **Agent Comparison**: Head-to-head performance analysis
505
- - **Customizable Weights**: Adjust importance of different metrics
506
-
507
- ### πŸ”§ API Integration
508
-
509
- ```python
510
- # Example API usage
511
- from aetherscore import evaluate
512
-
513
- result = evaluate(
514
- prompt="Your prompt here",
515
- response="Agent response",
516
- metrics=["all"]
517
- )
518
- ```
519
-
520
- ---
521
-
522
- **Version**: 1.0.0 | **License**: MIT | **GitHub**: [AetherScore](https://github.com/aetherscore)
523
- """)
524
 
525
  if __name__ == "__main__":
526
  demo.launch(share=True)
 
3
  import numpy as np
4
  import json
5
  import plotly.graph_objects as go
 
 
 
6
  from typing import Dict, List, Tuple, Optional
 
 
 
 
 
 
7
 
8
  # Import evaluation modules
9
  from evaluator_module import AetherScoreEvaluator
10
  from visualizer_module import EvaluationVisualizer
11
  from report_generator import ReportGenerator
12
 
13
+ # --- Global Components & Storage ---
14
  evaluator = AetherScoreEvaluator()
15
  visualizer = EvaluationVisualizer()
16
  report_gen = ReportGenerator()
17
 
18
+ # In-memory storage for explainability feature
19
+ evaluation_storage: Dict[str, Dict] = {}
20
+
21
  # CSS for better styling
22
  custom_css = """
23
  .gradio-container {
 
30
  color: white;
31
  margin: 10px 0;
32
  }
 
 
 
 
 
 
 
33
  """
34
 
35
+ # --- Core Functions ---
36
+
37
  def process_single_evaluation(
38
  prompt: str,
39
  response: str,
40
  expected_answer: Optional[str] = None,
41
  agent_name: str = "Agent-1",
42
  task_type: str = "general"
43
+ ) -> Tuple[Dict, go.Figure, go.Figure, str]:
44
  """Process a single agent response evaluation"""
 
45
  if not prompt or not response:
46
+ return {}, go.Figure(), go.Figure(), "Please provide both prompt and response."
47
+
48
  # Evaluate the response
49
+ eval_result = evaluator.evaluate_single(
50
  prompt=prompt,
51
  response=response,
52
  expected_answer=expected_answer,
53
  task_type=task_type
54
  )
55
+ scores = eval_result.get("scores", {})
56
 
57
+ # Store result for explainability
58
+ eval_id = scores.get("eval_id", "")
59
+ if eval_id:
60
+ evaluation_storage[eval_id] = eval_result
61
+ print(f"Stored evaluation {eval_id}")
62
+
63
  # Generate visualizations
64
  spider_chart = visualizer.create_spider_chart(scores, agent_name)
65
  score_bars = visualizer.create_score_bars(scores, agent_name)
66
+
67
  # Generate explanation
68
+ explanation = evaluator.generate_explanation(scores)
69
+
70
  # Format scores for display
71
+ scores_display = {k: f"{v:.2f}" for k, v in scores.items() if isinstance(v, float)}
72
+ scores_display["eval_id"] = eval_id
 
 
 
 
 
 
73
 
74
  return scores_display, spider_chart, score_bars, explanation
75
 
76
  def process_batch_evaluation(
77
  file_input,
78
  evaluation_mode: str = "comprehensive"
79
+ ) -> Tuple[go.Figure, go.Figure, go.Figure, str, pd.DataFrame]:
80
  """Process batch evaluation from uploaded file"""
 
81
  if file_input is None:
82
+ return go.Figure(), go.Figure(), go.Figure(), "Please upload a file.", pd.DataFrame()
83
+
84
  try:
 
85
  if file_input.name.endswith('.json'):
86
  with open(file_input.name, 'r') as f:
87
  data = json.load(f)
 
91
  for line in f:
92
  data.append(json.loads(line))
93
  else:
94
+ raise ValueError("Unsupported file format. Please upload JSON or JSONL.")
95
+
96
  # Process batch evaluation
97
  results = evaluator.evaluate_batch(data, mode=evaluation_mode)
98
 
99
+ # Store all results for explainability
100
+ for res in results:
101
+ eval_id = res.get('scores', {}).get('eval_id')
102
+ if eval_id:
103
+ evaluation_storage[eval_id] = res
104
+
105
  # Generate visualizations
106
  heatmap = visualizer.create_evaluation_heatmap(results)
107
  distribution = visualizer.create_score_distribution(results)
108
  trends = visualizer.create_performance_trends(results)
 
 
109
  report = report_gen.generate_batch_report(results)
 
 
110
  leaderboard = create_leaderboard(results)
111
 
112
  return heatmap, distribution, trends, report, leaderboard
113
 
114
  except Exception as e:
115
  error_msg = f"Error processing batch file: {str(e)}"
116
+ return go.Figure(), go.Figure(), go.Figure(), error_msg, pd.DataFrame()
117
 
118
  def create_leaderboard(results: List[Dict]) -> pd.DataFrame:
119
  """Create a leaderboard from evaluation results"""
120
+ agent_scores = evaluator.get_agent_scores_from_results(results)
 
 
 
 
 
 
121
 
122
  leaderboard_data = []
123
  for agent, scores in agent_scores.items():
124
  leaderboard_data.append({
125
+ 'Rank': 0, 'Agent': agent, 'Avg Score': np.mean(scores),
126
+ 'Max Score': np.max(scores), 'Min Score': np.min(scores),
127
+ 'Std Dev': np.std(scores), 'Evaluations': len(scores)
 
 
 
 
128
  })
129
 
130
+ df = pd.DataFrame(leaderboard_data).sort_values('Avg Score', ascending=False)
 
131
  df['Rank'] = range(1, len(df) + 1)
132
 
 
133
  for col in ['Avg Score', 'Max Score', 'Min Score', 'Std Dev']:
134
  df[col] = df[col].apply(lambda x: f"{x:.3f}")
135
 
 
138
  def compare_agents(
139
  agent1_file,
140
  agent2_file,
141
+ ) -> Tuple[go.Figure, go.Figure, go.Figure, str]:
 
142
  """Compare two agents' performance"""
 
143
  if not agent1_file or not agent2_file:
144
+ return go.Figure(), go.Figure(), go.Figure(), "Please upload files for both agents."
145
+
146
  try:
147
+ def load_agent_data(file):
148
+ if file.name.endswith('.json'):
149
+ with open(file.name, 'r') as f: return json.load(f)
150
+ elif file.name.endswith('.jsonl'):
151
+ data = [];
152
+ with open(file.name, 'r') as f:
153
+ for line in f: data.append(json.loads(line))
154
+ return data
155
+ raise ValueError("Unsupported file format")
156
+
157
+ agent1_results = evaluator.evaluate_batch(load_agent_data(agent1_file))
158
+ agent2_results = evaluator.evaluate_batch(load_agent_data(agent2_file))
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
+ comparison_chart = visualizer.create_agent_comparison(agent1_results, agent2_results)
161
+ radar_comparison = visualizer.create_radar_comparison(agent1_results, agent2_results)
162
+ performance_delta = visualizer.create_performance_delta(agent1_results, agent2_results)
163
+ comparison_report = report_gen.generate_comparison_report(agent1_results, agent2_results)
 
164
 
165
  return comparison_chart, radar_comparison, performance_delta, comparison_report
166
 
167
  except Exception as e:
168
  error_msg = f"Error comparing agents: {str(e)}"
169
+ return go.Figure(), go.Figure(), go.Figure(), error_msg
170
 
171
+ def get_detailed_explanation(eval_id: str) -> Tuple[Dict, str]:
172
+ """Retrieve and format the detailed explanation for an evaluation ID."""
173
+ if not eval_id:
174
+ return {}, "Please enter an Evaluation ID."
175
+
176
+ eval_result = evaluation_storage.get(eval_id)
 
 
 
 
 
 
 
177
 
178
+ if not eval_result:
179
+ return {}, f"Error: Evaluation ID '{eval_id}' not found in memory."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
+ scores = eval_result.get("scores", {})
182
+ reasons = eval_result.get("reasons", {})
183
+
184
+ # Format details for JSON display
185
+ details_to_display = {
186
+ "evaluation_id": scores.get("eval_id"),
187
+ "timestamp": scores.get("timestamp"),
188
+ "task_type": scores.get("task_type"),
189
+ "scores": {k: v for k, v in scores.items() if k not in ["eval_id", "timestamp", "task_type"]}
190
+ }
191
+
192
+ # Format breakdown for text display
193
+ breakdown = []
194
+ breakdown.append(f"### Detailed Breakdown for Evaluation: {eval_id}\n")
195
+ for metric, reason in reasons.items():
196
+ metric_name = metric.replace('_', ' ').title()
197
+ score = scores.get(metric, 0)
198
+ breakdown.append(f"**{metric_name}**: {score:.2f}\n"
199
+ f"> *Reasoning*: {reason}\n")
200
+
201
+ return details_to_display, "\n".join(breakdown)
202
+
203
+ # --- Gradio Interface ---
204
  with gr.Blocks(title="AetherScore - AI Agent Evaluation Framework", css=custom_css) as demo:
205
+ gr.Markdown("# 🌟 AetherScore - Advanced AI Agent Evaluation Framework")
 
 
 
 
 
 
 
206
 
207
  with gr.Tabs():
208
  # Tab 1: Single Evaluation
209
  with gr.TabItem("🎯 Single Evaluation"):
 
 
210
  with gr.Row():
211
  with gr.Column(scale=1):
212
+ prompt_input = gr.Textbox(label="Prompt", lines=3)
213
+ response_input = gr.Textbox(label="Agent Response", lines=3)
214
+ expected_answer = gr.Textbox(label="Expected Answer (Optional)", lines=2)
215
+ agent_name_input = gr.Textbox(label="Agent Name", value="Agent-1")
216
+ task_type = gr.Dropdown(label="Task Type", choices=["general", "QA", "summarization", "reasoning", "code"], value="general")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  evaluate_btn = gr.Button("πŸ” Evaluate", variant="primary")
 
218
  with gr.Column(scale=1):
219
  scores_output = gr.JSON(label="πŸ“Š Evaluation Scores")
220
+ explanation_output = gr.Textbox(label="πŸ“ Explanation", lines=6, interactive=False)
 
 
 
 
 
221
  with gr.Row():
222
+ spider_chart_output = gr.Plot(label="πŸ•ΈοΈ Spider Chart")
223
+ score_bars_output = gr.Plot(label="πŸ“Š Score Breakdown")
224
 
225
+ evaluate_btn.click(fn=process_single_evaluation, inputs=[prompt_input, response_input, expected_answer, agent_name_input, task_type], outputs=[scores_output, spider_chart_output, score_bars_output, explanation_output])
226
+
 
 
 
 
227
  # Tab 2: Batch Evaluation
228
  with gr.TabItem("πŸ“¦ Batch Evaluation"):
 
 
229
  with gr.Row():
230
  with gr.Column(scale=1):
231
+ batch_file = gr.File(label="Upload Evaluation File (JSON/JSONL)", file_types=[".json", ".jsonl"])
232
+ evaluation_mode = gr.Radio(label="Evaluation Mode", choices=["comprehensive", "fast", "detailed"], value="comprehensive")
 
 
 
 
 
 
 
233
  batch_evaluate_btn = gr.Button("πŸš€ Run Batch Evaluation", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  with gr.Column(scale=2):
235
+ batch_report = gr.Textbox(label="πŸ“„ Evaluation Report", lines=10, interactive=False)
 
 
 
 
 
236
  with gr.Row():
237
+ heatmap_output = gr.Plot(label="πŸ—ΊοΈ Evaluation Heatmap")
238
+ distribution_output = gr.Plot(label="πŸ“ˆ Score Distribution")
239
+ trends_output = gr.Plot(label="πŸ“Š Performance Trends")
240
+ leaderboard_output = gr.Dataframe(label="πŸ† Agent Leaderboard", interactive=False)
241
 
242
+ batch_evaluate_btn.click(fn=process_batch_evaluation, inputs=[batch_file, evaluation_mode], outputs=[heatmap_output, distribution_output, trends_output, batch_report, leaderboard_output])
243
+
 
 
 
 
 
 
 
 
 
 
244
  # Tab 3: Agent Comparison
245
  with gr.TabItem("βš”οΈ Agent Comparison"):
 
 
246
  with gr.Row():
247
  with gr.Column():
248
+ agent1_file = gr.File(label="Agent 1 Results (JSON/JSONL)", file_types=[".json", ".jsonl"])
249
+ agent2_file = gr.File(label="Agent 2 Results (JSON/JSONL)", file_types=[".json", ".jsonl"])
 
 
 
 
 
 
 
 
 
 
 
250
  compare_btn = gr.Button("βš–οΈ Compare Agents", variant="primary")
 
251
  with gr.Column():
252
+ comparison_report = gr.Textbox(label="πŸ“Š Comparison Analysis", lines=8, interactive=False)
 
 
 
 
 
253
  with gr.Row():
254
+ comparison_chart = gr.Plot(label="πŸ“Š Performance Comparison")
255
+ radar_comparison = gr.Plot(label="🎯 Radar Comparison")
256
+ performance_delta = gr.Plot(label="πŸ“ˆ Performance Delta Analysis")
257
 
258
+ compare_btn.click(fn=compare_agents, inputs=[agent1_file, agent2_file], outputs=[comparison_chart, radar_comparison, performance_delta, comparison_report])
259
+
 
 
 
 
 
 
260
  # Tab 4: Explainability Dashboard
261
  with gr.TabItem("πŸ” Explainability"):
262
+ gr.Markdown("### Deep dive into evaluation decisions. Enter an `eval_id` from a previous run.")
 
263
  with gr.Row():
264
+ eval_id_input = gr.Textbox(label="Evaluation ID", placeholder="Enter evaluation ID to analyze...")
265
+ load_eval_btn = gr.Button("Load Evaluation", variant="secondary")
 
 
 
 
 
 
 
 
266
  with gr.Row():
267
+ eval_details = gr.JSON(label="Evaluation Details")
268
+ detailed_breakdown = gr.Markdown(label="Detailed Score Breakdown")
269
+
270
+ load_eval_btn.click(fn=get_detailed_explanation, inputs=[eval_id_input], outputs=[eval_details, detailed_breakdown])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  if __name__ == "__main__":
273
  demo.launch(share=True)