#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Data-Viewer Side-by-Side tab for ICBCBench. """ import gradio as gr import random import re from tabs.shared_data import get_entries_for_task, get_index def make_user_task_markdown(item_id, prompt): return f"""### User Task 🎯 **Task ID:** {item_id} **Description:** {prompt}""" def make_article_markdown(article: str) -> str: if article and isinstance(article, str): processed_article = re.sub(r'\n{2,}', '\n\n', article) table_pattern = r'(\|[^\n]*\n(?:[\|\s\-:]+\n)?(?:\|[^\n]*\n)*)' tables = [] def replace_table(match): tables.append(match.group(1)) return f'__TABLE_PLACEHOLDER_{len(tables)-1}__' processed_article = re.sub(table_pattern, replace_table, processed_article) processed_article = re.sub(r'(? str: """Build score cards for ICBCBench side-by-side viewer.""" track = entry.get("track", "subjective") overall = entry.get("overall_score") objective = entry.get("objective_score") subjective = entry.get("subjective_score") expert = entry.get("expert_score") citation = entry.get("citation_score") source = entry.get("source_quality_score") confidence = entry.get("confidence") correct = entry.get("correct") comp = entry.get("comprehensiveness_score") insight = entry.get("insight_score") inst = entry.get("instruction_following_score") read = entry.get("readability_score") def fmt(val): if val is None: return "N/A" try: return f"{float(val):.2f}" except (TypeError, ValueError): return str(val) if track == "objective": scores_data = [ ("Overall
Score", fmt(overall)), ("Objective
Score", fmt(objective)), ("Confidence", fmt(confidence)), ("Correct", "Yes" if correct is True else ("No" if correct is False else "N/A")), ] else: scores_data = [ ("Overall
Score", fmt(overall)), ("Subjective
Score", fmt(subjective)), ("Expert
Score", fmt(expert)), ("Citation", fmt(citation)), ("Source
Quality", fmt(source)), ] if subjective is None and any(v is not None for v in [comp, insight, inst, read]): scores_data = [ ("Overall
Score", fmt(overall)), ("Comprehen-
siveness", fmt(comp)), ("Insight
Score", fmt(insight)), ("Instruction
Following", fmt(inst)), ("Readability
Score", fmt(read)), ] html_items_str = "" for title, score in scores_data: html_items_str += f"""

{title}

{score}

""" return f"""
{html_items_str}
""" # ---------- 生成 Tab ---------- def create_data_viewer_side_by_side_tab(): with gr.Tab("⚔️Side-by-Side Viewer"): gr.HTML( """""" ) with gr.Row(): task_dd = gr.Dropdown(label="Select Task", choices=[], interactive=True) user_task_display_md = gr.Markdown(value="Loading data…", elem_classes=["card", "scrollable-sm"]) with gr.Row(): with gr.Column(scale=1): model_a_dd = gr.Dropdown(label="Select Model A", choices=[], interactive=True) article_a_md = gr.Markdown(elem_classes=["card", "scrollable-lg"]) scores_a_html = gr.HTML() with gr.Column(scale=1): model_b_dd = gr.Dropdown(label="Select Model B", choices=[], interactive=True) article_b_md = gr.Markdown(elem_classes=["card", "scrollable-lg"]) scores_b_html = gr.HTML() def fetch_side_by_side_data(selected_task_display, model_a_name, model_b_name): empty_article = make_article_markdown("") empty_scores = make_scores_html({}) if not selected_task_display: no_task_msg = "请选择一个任务。" return make_user_task_markdown("--", no_task_msg), \ empty_article, empty_scores, empty_article, empty_scores item_id_str = selected_task_display.split(".", 1)[0].strip() index = get_index() task_prompt = next( (task.get("prompt", "") for task in index.get("tasks", []) if str(task.get("id")) == item_id_str), "任务描述未找到。" ) user_task_md_content = make_user_task_markdown(item_id_str, task_prompt) outputs_a = [make_article_markdown("模型A未选择或数据未找到"), empty_scores] outputs_b = [make_article_markdown("模型B未选择或数据未找到"), empty_scores] selected_models = {name for name in (model_a_name, model_b_name) if name} entries = get_entries_for_task(item_id_str, selected_models) if model_a_name: entry_a = entries.get(model_a_name) if entry_a: outputs_a[0] = make_article_markdown(entry_a.get("article", "")) outputs_a[1] = make_scores_html(entry_a) if model_b_name: entry_b = entries.get(model_b_name) if entry_b: outputs_b[0] = make_article_markdown(entry_b.get("article", "")) outputs_b[1] = make_scores_html(entry_b) return user_task_md_content, outputs_a[0], outputs_a[1], outputs_b[0], outputs_b[1] def _build_task_choices(tasks): return [ f"{task['id']}. {task.get('prompt', '')[:60] + ('…' if len(task.get('prompt', '')) > 60 else '')}" for task in tasks ] def on_load(): index = get_index() empty_article = make_article_markdown("") empty_scores = make_scores_html({}) all_models = index.get("models", []) tasks = index.get("tasks", []) if not all_models or not tasks: return (gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), make_user_task_markdown("--", "No data"), empty_article, empty_scores, empty_article, empty_scores) task_choices = _build_task_choices(tasks) init_task = random.choice(task_choices) if task_choices else None init_a = random.choice(all_models) if all_models else None init_b = random.choice([m for m in all_models if m != init_a]) if len(all_models) > 1 else init_a data = ( make_user_task_markdown("--", "请选择任务"), empty_article, empty_scores, empty_article, empty_scores ) return (gr.update(choices=task_choices, value=init_task), gr.update(choices=all_models, value=init_a), gr.update(choices=all_models, value=init_b), *data) task_dd.change(fetch_side_by_side_data, inputs=[task_dd, model_a_dd, model_b_dd], outputs=[user_task_display_md, article_a_md, scores_a_html, article_b_md, scores_b_html]) model_a_dd.change(fetch_side_by_side_data, inputs=[task_dd, model_a_dd, model_b_dd], outputs=[user_task_display_md, article_a_md, scores_a_html, article_b_md, scores_b_html]) model_b_dd.change(fetch_side_by_side_data, inputs=[task_dd, model_a_dd, model_b_dd], outputs=[user_task_display_md, article_a_md, scores_a_html, article_b_md, scores_b_html]) return on_load, [task_dd, model_a_dd, model_b_dd, user_task_display_md, article_a_md, scores_a_html, article_b_md, scores_b_html]