SchemeArena / js /explorer.js
JieRuan's picture
Open the Scenario Explorer on scenario 38 (paper Appendix D example)
c131f06 verified
Raw History Blame Contribute Delete
8.74 kB
/* Scenario Explorer. Dataset text is always inserted with textContent, never innerHTML. */
(function () {
"use strict";
var data = null, filtered = [], current = null, loading = false;
var DEFAULT_ID = 38;
function el(tag, cls, text) {
var e = document.createElement(tag);
if (cls) e.className = cls;
if (text !== undefined && text !== null) e.textContent = text;
return e;
}
function prettyCat(c) { return String(c || "").replace(/_/g, " "); }
function section(title, child) {
var s = el("div", "ex-sec");
s.appendChild(el("h4", null, title));
s.appendChild(child);
return s;
}
function segmented(options, render) {
var wrap = el("div");
var seg = el("div", "seg");
var body = el("div");
options.forEach(function (o, i) {
var b = el("button", i === 0 ? "active" : "", o.label);
b.type = "button";
b.addEventListener("click", function () {
seg.querySelectorAll("button").forEach(function (x) { x.classList.remove("active"); });
b.classList.add("active");
body.replaceChildren(render(o));
});
seg.appendChild(b);
});
wrap.appendChild(seg);
wrap.appendChild(body);
body.appendChild(render(options[0]));
return wrap;
}
function promptBlock(label, text) {
var p = el("div", "prompt-pre");
p.appendChild(el("span", "lbl", label));
p.appendChild(document.createTextNode(text || ""));
return p;
}
function renderDetail(sc) {
var d = document.getElementById("exDetail");
d.replaceChildren();
if (!sc) { d.appendChild(el("p", "empty", "No scenario selected.")); return; }
var head = el("div", "head");
head.appendChild(el("h2", null, "Scenario " + sc.id));
head.appendChild(el("span", "cat-chip", prettyCat(sc.category)));
d.appendChild(head);
d.appendChild(section("Environment", el("p", null, sc.environment)));
d.appendChild(section("Character", el("p", null, sc.character)));
var task = el("div", "task-box"); task.appendChild(el("p", null, sc.goal_short_term));
d.appendChild(section("Short-term task (benign)", task));
d.appendChild(section("Instrumental long-term goal", segmented([
{ label: "Goal", text: sc.goal_long_term },
{ label: "No-hint variant", text: sc.goal_long_term_no_hint },
{ label: "Detailed (strategic hints)", text: sc.goal_long_term_detailed }
], function (o) { var b = el("div", "goal-box"); b.appendChild(el("p", null, o.text)); return b; })));
var prop = sc.propensity || {};
d.appendChild(section("Prompts", segmented([
{ label: "Capability setups", sys: sc.system_prompt, usr: sc.user_prompt },
{ label: "Propensity setups (no explicit goal)", sys: prop.system_prompt, usr: prop.user_prompt }
], function (o) {
var w = el("div");
w.appendChild(promptBlock("System prompt", o.sys));
w.appendChild(promptBlock("User prompt", o.usr));
return w;
})));
var tools = el("div", "tools");
var tkeys = Object.keys(sc.tools || {});
if (!tkeys.length) tools.appendChild(el("p", "empty", "Only file-system tools."));
tkeys.forEach(function (k) {
var t = sc.tools[k] || {};
var c = el("div", "tool");
c.appendChild(el("div", "nm", t.tool_name || k));
var meta = el("div", "meta");
var method = String(t.method || "").trim();
var shortVerb = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)$/i.test(method);
if (shortVerb) meta.appendChild(el("span", "m", method.toUpperCase()));
meta.appendChild(document.createTextNode([t.api_name, t.category_name].filter(Boolean).join(" · ")));
c.appendChild(meta);
c.appendChild(el("div", "ds", t.tool_description || ""));
if (method && !shortVerb) c.appendChild(el("div", "mnote", method));
tools.appendChild(c);
});
var ttl = el("div");
var note = el("p", "empty", "Plus file-system tools: create_file, read_file, list_files, write_file.");
note.style.marginTop = "8px";
ttl.appendChild(tools); ttl.appendChild(note);
d.appendChild(section("Scenario-specific tools (" + tkeys.length + ")", ttl));
var files = sc.files || [];
var fw = el("div", "files");
var list = el("div", "file-list");
var view = el("pre", "file-view");
function show(i, btn) {
list.querySelectorAll(".file-btn").forEach(function (x) { x.classList.remove("active"); });
if (btn) btn.classList.add("active");
view.textContent = files[i] ? (files[i].content || "") : "";
}
files.forEach(function (f, i) {
var b = el("button", "file-btn", String(f.path || "").replace(/^\.\/files\//, ""));
b.type = "button";
b.addEventListener("click", function () { show(i, b); });
list.appendChild(b);
});
fw.appendChild(list); fw.appendChild(view);
if (files.length) show(0, list.firstChild); else view.textContent = "(no files)";
d.appendChild(section("Initial workspace (" + files.length + " files)", fw));
}
function renderList() {
var list = document.getElementById("exList");
list.replaceChildren();
document.getElementById("exCount").textContent = filtered.length + " of " + data.length + " scenarios";
if (!filtered.length) { var e = el("p", "empty", "No scenarios match."); e.style.padding = "14px"; list.appendChild(e); return; }
var frag = document.createDocumentFragment();
filtered.forEach(function (sc) {
var b = el("button", "ex-item" + (current && current.id === sc.id ? " active" : ""));
b.type = "button";
b.dataset.id = sc.id;
var top = el("div", "top");
top.appendChild(el("b", null, "#" + sc.id));
top.appendChild(el("span", null, prettyCat(sc.category)));
b.appendChild(top);
b.appendChild(el("div", "task", sc.goal_short_term));
b.addEventListener("click", function () { select(sc.id, true); });
frag.appendChild(b);
});
list.appendChild(frag);
}
function applyFilter() {
var q = document.getElementById("exSearch").value.trim().toLowerCase();
var cat = document.getElementById("exCategory").value;
filtered = data.filter(function (sc) {
if (cat && sc.category !== cat) return false;
if (!q) return true;
if (String(sc.id) === q.replace("#", "")) return true;
return (sc._hay || (sc._hay = [sc.environment, sc.character, sc.goal_short_term, sc.goal_long_term, sc.category].join(" ").toLowerCase())).indexOf(q) !== -1;
});
renderList();
}
function select(id, updateHash) {
var sc = data.find(function (s) { return s.id === Number(id); });
if (!sc) return;
current = sc;
document.querySelectorAll(".ex-item").forEach(function (b) { b.classList.toggle("active", Number(b.dataset.id) === sc.id); });
renderDetail(sc);
if (updateHash) history.replaceState(null, "", "#explorer/" + sc.id);
if (window.innerWidth <= 980 && updateHash) document.getElementById("exDetail").scrollIntoView({ behavior: "smooth", block: "start" });
}
window.openExplorer = function (id) {
if (data) { if (id) select(id, false); return; }
if (loading) return;
loading = true;
fetch("data/scenarios.json").then(function (r) {
if (!r.ok) throw new Error("HTTP " + r.status);
return r.json();
}).then(function (json) {
data = json.sort(function (a, b) { return a.id - b.id; });
var cats = {};
data.forEach(function (s) { cats[s.category] = (cats[s.category] || 0) + 1; });
var sel = document.getElementById("exCategory");
Object.keys(cats).sort().forEach(function (c) {
var o = el("option", null, prettyCat(c) + " (" + cats[c] + ")");
o.value = c;
sel.appendChild(o);
});
sel.addEventListener("change", applyFilter);
var t;
document.getElementById("exSearch").addEventListener("input", function () { clearTimeout(t); t = setTimeout(applyFilter, 120); });
filtered = data.slice();
renderList();
// Default to scenario 38, the worked example in Appendix D of the paper.
var start = id || (data.some(function (s) { return s.id === DEFAULT_ID; }) ? DEFAULT_ID : data[0].id);
select(start, false);
var list = document.getElementById("exList");
var item = list.querySelector('.ex-item[data-id="' + Number(start) + '"]');
if (item) list.scrollTop = item.offsetTop - list.offsetTop - 8;
}).catch(function (err) {
var d = document.getElementById("exDetail");
d.replaceChildren(el("p", "empty", "Could not load scenarios (" + err.message + "). The full dataset is on Hugging Face: launch/SchemeArena."));
document.getElementById("exList").replaceChildren();
loading = false;
});
};
})();