File size: 6,015 Bytes
275cef9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40b1944
275cef9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40b1944
275cef9
 
 
 
 
 
 
 
 
 
40b1944
275cef9
 
 
 
 
 
5708a34
 
275cef9
5708a34
 
 
 
 
 
 
 
275cef9
 
 
5708a34
 
 
275cef9
5708a34
 
 
 
 
 
 
 
 
275cef9
 
5708a34
 
 
 
 
 
275cef9
5708a34
 
 
 
275cef9
5708a34
275cef9
5708a34
 
 
 
 
 
275cef9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations

# index 0-4 = teachers (aligns with MODEL_COLORS[1:] in _fig.py)
_TEACHER_COLORS = ["#7c3aed", "#06b6d4", "#f59e0b", "#34d399", "#f472b6"]


def gate_html(gate_weights: list[float], teacher_names: list[str]) -> str:
    """Horizontal bar chart sorted by weight descending."""
    ranked = sorted(
        enumerate(zip(gate_weights, teacher_names)),
        key=lambda x: x[1][0],
        reverse=True,
    )
    rows = []
    for orig_idx, (w, name) in ranked:
        color = _TEACHER_COLORS[orig_idx % len(_TEACHER_COLORS)]
        bar_pct = int(w * 100)
        rows.append(
            f'<div style="display:flex;align-items:center;gap:8px;margin:5px 0;">'
            f'<span style="width:80px;font-family:monospace;font-size:11px;color:{color};'
            f'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{name}</span>'
            f'<div style="flex:1;height:5px;background:#21262d;border-radius:3px;overflow:hidden;">'
            f'<div style="width:{bar_pct}%;height:100%;background:{color};border-radius:3px;"></div>'
            f'</div>'
            f'<span style="width:36px;font-family:monospace;font-size:11px;'
            f'color:#8b949e;text-align:right;">{w:.2f}</span>'
            f'</div>'
        )
    return (
        '<div style="background:#161b22;border:1px solid #30363d;border-radius:6px;padding:14px;margin-top:8px;">'
        '<div style="font-size:10px;color:#8b949e;font-family:monospace;margin-bottom:10px;letter-spacing:0.04em;">'
        'TEACHER INFLUENCE</div>'
        + "".join(rows)
        + "</div>"
    )


def task_html(gate_weights: list[float], teacher_names: list[str]) -> str:
    """Badge for argmax teacher + runner-up."""
    best_idx = max(range(len(gate_weights)), key=lambda i: gate_weights[i])
    second_idx = sorted(range(len(gate_weights)), key=lambda i: gate_weights[i])[-2]
    color = _TEACHER_COLORS[best_idx % len(_TEACHER_COLORS)]
    best = teacher_names[best_idx].upper()
    second = teacher_names[second_idx].upper()
    w2 = gate_weights[second_idx]
    n = len(teacher_names)
    return (
        '<div style="background:#161b22;border:1px solid #30363d;border-radius:6px;padding:14px;margin-top:8px;">'
        '<div style="font-size:10px;color:#8b949e;font-family:monospace;margin-bottom:10px;letter-spacing:0.04em;">'
        'DOMINANT TEACHER</div>'
        '<div style="display:flex;align-items:center;gap:12px;">'
        f'<span style="display:inline-flex;align-items:center;gap:6px;background:{color}22;'
        f'border:1px solid {color}55;border-radius:999px;padding:4px 14px;'
        f'font-family:monospace;font-weight:600;color:{color};font-size:13px;">'
        f'<span style="width:6px;height:6px;background:{color};border-radius:50%;'
        f'box-shadow:0 0 6px {color};"></span>{best}</span>'
        f'<span style="font-size:11px;color:#8b949e;font-family:monospace;">'
        f'runner-up <b style="color:#e6edf3;">{second}</b> · {w2:.2f}</span>'
        f'</div>'
        f'<div style="font-size:10px;color:#6e7681;margin-top:8px;font-family:monospace;">'
        f'gate picked this teacher for your prompt ({n} total)</div>'
        '</div>'
    )


def header_html() -> str:
    """App header with ∀ logo, wordmark, and status pills."""
    def pill(color: str, dot_color: str, text: str, pulse: bool = False) -> str:
        dot_class = ' class="live-dot"' if pulse else ''
        return (
            f'<span style="display:inline-flex;align-items:center;gap:8px;height:28px;'
            f'padding:0 12px;border-radius:999px;font-family:monospace;font-size:10px;'
            f'font-weight:600;letter-spacing:0.06em;color:{color};'
            f'background:rgba(13,17,23,0.8);border:1px solid {color}33;'
            f'backdrop-filter:blur(8px);white-space:nowrap;">'
            f'<span{dot_class} style="width:6px;height:6px;border-radius:50%;'
            f'background:{dot_color};box-shadow:0 0 7px {dot_color};flex-shrink:0;"></span>'
            f'{text}</span>'
        )
    return (
        '<div style="display:flex;align-items:center;justify-content:space-between;'
        'padding:20px 2px 14px;gap:16px;flex-wrap:wrap;">'

        # Left: logo + title
        '<div style="display:flex;align-items:center;gap:14px;">'
        '<div style="width:46px;height:46px;display:grid;place-items:center;flex-shrink:0;'
        'border-radius:10px;'
        'background:radial-gradient(circle at 40% 35%, rgba(124,58,237,0.45) 0%, rgba(8,11,16,0.9) 70%);'
        'border:1px solid rgba(124,58,237,0.35);'
        'box-shadow:0 0 20px rgba(124,58,237,0.2),inset 0 1px 0 rgba(255,255,255,0.07);">'
        '<span style="font-family:monospace;font-weight:800;font-size:26px;'
        'background:linear-gradient(135deg,#a78bfa,#7c3aed);'
        '-webkit-background-clip:text;-webkit-text-fill-color:transparent;'
        'background-clip:text;">∀</span>'
        '</div>'
        '<div>'
        '<div style="font-weight:700;font-size:18px;letter-spacing:-0.01em;'
        'background:linear-gradient(90deg,#e6edf3 0%,#a78bfa 100%);'
        '-webkit-background-clip:text;-webkit-text-fill-color:transparent;'
        'background-clip:text;">One for All</div>'
        '<div style="font-size:11px;color:#484f58;margin-top:2px;font-family:monospace;'
        'letter-spacing:0.05em;text-transform:uppercase;">multi-teacher soul distillation</div>'
        '</div></div>'

        # Right: pills
        '<div style="display:flex;gap:8px;flex-wrap:wrap;">'
        + pill("#06b6d4", "#06b6d4", "STUDENT · Qwen2.5-0.5B", pulse=True)
        + pill("#7c3aed", "#7c3aed", "5 TEACHERS")
        + pill("#f59e0b", "#f59e0b", "PATH B · GEOMETRY")
        + '</div></div>'

        # Divider with glow
        '<div style="height:1px;margin-bottom:22px;'
        'background:linear-gradient(90deg,transparent 0%,rgba(124,58,237,0.6) 40%,'
        'rgba(6,182,212,0.4) 70%,transparent 100%);'
        'box-shadow:0 0 12px rgba(124,58,237,0.15);"></div>'
    )