OptimismBench / app /src /content /embeds /dataset-explorer.html
seonglae's picture
explorer: language selector (10 langs, native-prompt runs) + per-model show/hide toggle chips
e4557f1
Raw
History Blame Contribute Delete
15 kB
<div id="ob-dx" role="region" aria-label="Interactive explorer of OptimismBench model responses: mean P(positive) and P(negative) per Track B scenario per model, with directional Skew. Browse by scenario or by model, switch prompt language, and toggle which models are shown.">
<div class="dx-head">
<span class="dx-title">Explore the responses</span>
<a class="dx-badge" id="dx-badge" href="https://huggingface.co/datasets/seonglae/OptimismBench" target="_blank" rel="noopener noreferrer">🤗 seonglae/OptimismBench</a>
</div>
<div class="dx-controls">
<span class="dx-tog">
<button class="dx-btn" data-m="scenario" aria-pressed="true">By scenario</button>
<button class="dx-btn" data-m="model" aria-pressed="false">By model</button>
</span>
<label class="dx-lang"><span>Language</span><select class="dx-sel dx-langsel" id="dx-lang" aria-label="prompt language"></select></label>
<select class="dx-sel" id="dx-sel" aria-label="pick"></select>
<span class="dx-nav"><button class="dx-navbtn" id="dx-prev" aria-label="previous"></button><span class="dx-count" id="dx-count">1 / 60</span><button class="dx-navbtn" id="dx-next" aria-label="next"></button></span>
</div>
<div class="dx-filter" id="dx-filter"></div>
<div class="dx-body"></div>
<div class="dx-cap" id="dx-cap">Mean of 10 runs per item. P(positive) and P(negative) are the two framings; a coherent judge sums to 100, the leftover is Skew. Per-model means are precomputed from the released 🤗 response corpus.</div>
</div>
<style>
#ob-dx { font:13px/1.45 system-ui,sans-serif; color:var(--text-color,#222); width:100%; position:relative; }
#ob-dx .dx-head { display:flex; align-items:baseline; gap:10px; margin-bottom:10px; flex-wrap:wrap; }
#ob-dx .dx-title { font-weight:650; font-size:15px; }
#ob-dx .dx-badge { margin-left:auto; font-size:11.5px; color:var(--muted-color,#777); text-decoration:none; border:1px solid var(--border-color,#e7e2dc); border-radius:999px; padding:3px 10px; }
#ob-dx .dx-badge:hover { color:var(--text-color,#222); }
#ob-dx .dx-controls { display:flex; gap:10px; align-items:center; margin-bottom:10px; flex-wrap:wrap; }
#ob-dx .dx-tog { display:inline-flex; gap:6px; }
#ob-dx .dx-btn { font:inherit; font-size:12px; cursor:pointer; padding:4px 11px; border-radius:7px; border:1px solid var(--border-color,#ccc); background:transparent; color:var(--muted-color,#666); }
#ob-dx .dx-btn[aria-pressed="true"] { background:var(--primary-color,#2d2926); color:#fff; border-color:var(--primary-color,#2d2926); }
#ob-dx .dx-lang { display:inline-flex; align-items:center; gap:6px; font-size:11px; color:var(--muted-color,#888); text-transform:uppercase; letter-spacing:.03em; }
#ob-dx .dx-langsel { max-width:none; width:auto; }
#ob-dx .dx-sel { font:inherit; font-size:12.5px; height:34px; box-sizing:border-box; padding:0 10px; border-radius:8px; border:1px solid var(--border-color,#ccc); background:var(--surface-bg,#fff); color:var(--text-color,#222); max-width:min(440px,52%); }
#ob-dx .dx-filter { display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-bottom:12px; }
#ob-dx .dx-flab { font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted-color,#999); margin-right:2px; }
#ob-dx .dx-chip { font:inherit; font-size:11.5px; cursor:pointer; padding:3px 9px 3px 7px; border-radius:999px; border:1px solid var(--border-color,#ddd); background:transparent; color:var(--muted-color,#777); display:inline-flex; align-items:center; gap:5px; }
#ob-dx .dx-chip[aria-pressed="true"] { color:var(--text-color,#222); border-color:color-mix(in oklab, var(--border-color,#ccc), var(--text-color,#222) 28%); background:var(--surface-bg,#faf8f6); }
#ob-dx .dx-chip[aria-pressed="false"] { opacity:.55; text-decoration:line-through; }
#ob-dx .dx-chip img { width:13px; height:13px; object-fit:contain; }
#ob-dx .dx-chip .dx-sw { width:9px; height:9px; border-radius:50%; }
#ob-dx .dx-scen { background:var(--surface-bg,#faf8f6); border:1px solid var(--border-color,#e7e2dc); border-radius:10px; padding:11px 13px; margin-bottom:12px; }
#ob-dx .dx-scen .dx-dom { font-size:11px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--muted-color,#888); }
#ob-dx .dx-scen .dx-txt { margin-top:4px; font-size:13.5px; line-height:1.5; }
#ob-dx .dx-scen .dx-qs { margin-top:7px; font-size:12px; color:var(--muted-color,#666); }
#ob-dx table { width:100%; border-collapse:collapse; }
#ob-dx th, #ob-dx td { text-align:left; padding:6px 8px; font-size:12.5px; border-bottom:1px solid var(--border-color,#eee); vertical-align:middle; }
#ob-dx th { font-size:11px; text-transform:uppercase; letter-spacing:.03em; color:var(--muted-color,#888); font-weight:600; }
#ob-dx td.num { text-align:right; font-variant-numeric:tabular-nums; }
#ob-dx .dx-m { display:flex; align-items:center; gap:7px; }
#ob-dx .dx-ic { width:15px; height:15px; flex:none; border-radius:3px; object-fit:contain; }
#ob-dx .dx-sw { width:11px; height:11px; border-radius:50%; flex:none; display:inline-block; }
#ob-dx .dx-bar { height:7px; border-radius:4px; background:var(--border-color,#ece7e1); overflow:hidden; min-width:54px; }
#ob-dx .dx-fill { height:100%; border-radius:4px; }
#ob-dx .dx-badge2 { font-weight:700; font-variant-numeric:tabular-nums; padding:1px 8px; border-radius:999px; color:#fff; font-size:11.5px; }
#ob-dx .dx-nav { display:inline-flex; align-items:stretch; height:34px; border:1px solid var(--border-color,#ccc); border-radius:8px; overflow:hidden; }
#ob-dx .dx-navbtn { font:inherit; font-size:17px; line-height:1; cursor:pointer; width:34px; border:none; background:transparent; color:var(--text-color,#333); display:flex; align-items:center; justify-content:center; }
#ob-dx .dx-navbtn:hover { background:var(--surface-bg,#f1ece8); }
#ob-dx .dx-count { display:flex; align-items:center; padding:0 12px; font-size:12px; color:var(--muted-color,#888); border-left:1px solid var(--border-color,#ccc); border-right:1px solid var(--border-color,#ccc); white-space:nowrap; font-variant-numeric:tabular-nums; }
#ob-dx .dx-cap { margin-top:12px; font-size:12px; color:var(--muted-color,#666); }
</style>
<script>
(function () {
var root = document.getElementById("ob-dx");
if (!root) { return; }
var sel = root.querySelector("#dx-sel"), langSel = root.querySelector("#dx-lang"),
body = root.querySelector(".dx-body"), filter = root.querySelector("#dx-filter"),
cap = root.querySelector("#dx-cap");
function cssVar(n, fb) { var v = getComputedStyle(document.documentElement).getPropertyValue(n); return (v && v.trim()) || fb; }
var PROV = { OpenAI: "#2a8f82", Anthropic: "#a66e4e", Google: "#3d5a80", Mistral: "#c4553a", Alibaba: "#c49a3a", DeepSeek: "#5c6b73", Zhipu: "#8a8478" };
var ICON = { OpenAI: "openai", Anthropic: "anthropic", Google: "google", Mistral: "mistral", Alibaba: "alibaba", DeepSeek: "deepseek", Meta: "meta", NVIDIA: "nvidia", Zhipu: "zhipu" };
var LANGNAME = { EN: "English", KO: "Korean", ZH: "Chinese", ES: "Spanish", AR: "Arabic", RU: "Russian", DE: "German", FR: "French", HI: "Hindi", JA: "Japanese" };
var DATA = null, MODE = "scenario", LANG = "EN", PROVOF = {}, ACTIVE = {};
function esc(s) { return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); }
function provMark(p) {
var slug = ICON[p];
if (slug) { return '<img class="dx-ic" src="icons/' + slug + '.svg" alt="' + esc(p) + '" loading="lazy">'; }
return '<span class="dx-sw" style="background:' + (PROV[p] || "#888") + '"></span>';
}
function bar(v, color, max) {
var w = Math.max(0, Math.min(100, (v / (max || 100)) * 100));
return '<div class="dx-bar"><div class="dx-fill" style="width:' + w + '%;background:' + color + '"></div></div>';
}
function skewBadge(s) {
var OPT = cssVar("--opt", "#e07a5f"), PES = cssVar("--pes", "#3d5a80");
return '<span class="dx-badge2" style="background:' + (s >= 0 ? OPT : PES) + '">' + (s >= 0 ? "+" : "−") + Math.abs(s).toFixed(0) + '</span>';
}
// models available for the current language, in registry order
function langModels() {
var entry = (DATA.languages || []).filter(function (l) { return l.code === LANG; })[0];
var avail = entry ? entry.models : DATA.models.map(function (m) { return m.name; });
return DATA.models.map(function (m) { return m.name; }).filter(function (n) { return avail.indexOf(n) >= 0; });
}
function activeModels() { return langModels().filter(function (n) { return ACTIVE[n] !== false; }); }
function cell(s, name) { return (s.byLang && s.byLang[LANG]) ? s.byLang[LANG][name] : null; }
function fillLang() {
langSel.innerHTML = (DATA.languages || [{ code: "EN" }]).map(function (l) {
return '<option value="' + l.code + '">' + (LANGNAME[l.code] || l.code) + " (" + l.models.length + ")</option>";
}).join("");
langSel.value = LANG;
}
function fillFilter() {
if (MODE !== "scenario") { filter.innerHTML = ""; return; }
var html = '<span class="dx-flab">Show models</span>';
langModels().forEach(function (n) {
var on = ACTIVE[n] !== false;
html += '<button class="dx-chip" data-n="' + esc(n) + '" aria-pressed="' + on + '">' + provMark(PROVOF[n]) + esc(n) + '</button>';
});
filter.innerHTML = html;
filter.querySelectorAll(".dx-chip").forEach(function (c) {
c.addEventListener("click", function () {
var n = c.getAttribute("data-n");
ACTIVE[n] = (ACTIVE[n] === false);
c.setAttribute("aria-pressed", ACTIVE[n] !== false);
render();
});
});
}
function fillSelect() {
if (MODE === "scenario") {
sel.innerHTML = DATA.scenarios.map(function (s, i) {
return '<option value="' + i + '">' + esc(s.domain) + " · " + esc(s.scenario.slice(0, 64)) + "…</option>";
}).join("");
} else {
sel.innerHTML = activeModels().map(function (n, i) { return '<option value="' + i + '">' + esc(n) + " (" + esc(PROVOF[n]) + ")</option>"; }).join("");
}
}
function renderScenario(idx) {
var MUT = cssVar("--muted-color", "#888");
var s = DATA.scenarios[idx];
var act = activeModels();
var rows = act.map(function (n) {
var d = cell(s, n); if (!d) { return null; }
return { name: n, prov: PROVOF[n], pg: d.pg, pb: d.pb, skew: d.skew };
}).filter(Boolean).sort(function (a, b) { return b.skew - a.skew; });
var html = '<div class="dx-scen"><div class="dx-dom">' + esc(s.domain) + '</div><div class="dx-txt">' + esc(s.scenario) + '</div>' +
'<div class="dx-qs"><b>+</b> ' + esc(s.pos) + ' &nbsp;·&nbsp; <b>−</b> ' + esc(s.neg) + '</div></div>';
if (!rows.length) { body.innerHTML = html + '<div class="dx-cap">No models selected for ' + (LANGNAME[LANG] || LANG) + '.</div>'; return; }
html += '<table><thead><tr><th>Model</th><th>P(positive)</th><th>P(negative)</th><th class="num">Skew</th></tr></thead><tbody>';
rows.forEach(function (r) {
html += '<tr><td><span class="dx-m">' + provMark(r.prov) + esc(r.name) + '</span></td>' +
'<td><span class="dx-m">' + bar(r.pg, MUT) + '<span style="font-variant-numeric:tabular-nums">' + r.pg.toFixed(0) + '</span></span></td>' +
'<td><span class="dx-m">' + bar(r.pb, MUT) + '<span style="font-variant-numeric:tabular-nums">' + r.pb.toFixed(0) + '</span></span></td>' +
'<td>' + skewBadge(r.skew) + '</td></tr>';
});
body.innerHTML = html + '</tbody></table>';
}
function renderModel(idx) {
var MUT = cssVar("--muted-color", "#888");
var names = activeModels(), name = names[idx] || names[0];
if (!name) { body.innerHTML = '<div class="dx-cap">No models for this language.</div>'; return; }
var rows = DATA.scenarios.map(function (s) {
var d = cell(s, name); if (!d) { return null; }
return { s: s, skew: d.skew, pg: d.pg, pb: d.pb };
}).filter(Boolean).sort(function (a, b) { return b.skew - a.skew; });
var mean = rows.reduce(function (a, r) { return a + r.skew; }, 0) / (rows.length || 1);
var html = '<div class="dx-scen"><div class="dx-dom"><span class="dx-m">' + provMark(PROVOF[name]) + esc(name) + " · " + esc(PROVOF[name]) + '</span></div>' +
'<div class="dx-txt" style="font-size:13px">Mean Skew across ' + rows.length + ' scenarios (' + (LANGNAME[LANG] || LANG) + ' prompts): ' + skewBadge(Math.round(mean)) + ' &nbsp;(' + (mean >= 0 ? "+" : "") + mean.toFixed(1) + ')</div></div>';
html += '<table><thead><tr><th>Scenario</th><th>Domain</th><th class="num">P+</th><th class="num">P−</th><th class="num">Skew</th></tr></thead><tbody>';
rows.forEach(function (r) {
html += '<tr><td>' + esc(r.s.scenario.slice(0, 58)) + '…</td><td style="color:' + MUT + '">' + esc(r.s.domain) + '</td>' +
'<td class="num">' + r.pg.toFixed(0) + '</td><td class="num">' + r.pb.toFixed(0) + '</td><td class="num">' + skewBadge(r.skew) + '</td></tr>';
});
body.innerHTML = html + '</tbody></table>';
}
function render() {
var n = sel.options.length, i = sel.selectedIndex < 0 ? 0 : Math.min(sel.selectedIndex, n - 1);
if (MODE === "scenario") { renderScenario(i); } else { renderModel(i); }
var cnt = root.querySelector("#dx-count"); if (cnt) { cnt.textContent = (n ? i + 1 : 0) + " / " + n; }
}
function step(d) { var n = sel.options.length; if (!n) { return; } sel.selectedIndex = (sel.selectedIndex + d + n) % n; render(); }
function rebuild(keepIdx) {
var prev = keepIdx ? sel.selectedIndex : 0;
fillFilter(); fillSelect();
sel.selectedIndex = Math.max(0, Math.min(prev, sel.options.length - 1));
render();
}
sel.addEventListener("change", render);
langSel.addEventListener("change", function () {
LANG = langSel.value;
// reset model visibility to all-available for the new language
ACTIVE = {};
rebuild(true);
});
root.querySelector("#dx-prev").addEventListener("click", function () { step(-1); });
root.querySelector("#dx-next").addEventListener("click", function () { step(1); });
root.querySelectorAll(".dx-btn").forEach(function (b) {
b.addEventListener("click", function () {
MODE = b.getAttribute("data-m");
root.querySelectorAll(".dx-btn").forEach(function (o) { o.setAttribute("aria-pressed", o === b ? "true" : "false"); });
rebuild(false);
});
});
fetch("data/responses_agg.json").then(function (r) { if (!r.ok) { throw new Error("x"); } return r.json(); })
.then(function (j) {
DATA = j;
DATA.models.forEach(function (m) { PROVOF[m.name] = m.provider; });
fillLang(); rebuild(false);
})
.catch(function () { body.innerHTML = '<div class="dx-cap">Could not load data/responses_agg.json.</div>'; });
new MutationObserver(render).observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
})();
</script>