Spaces:
Running
Running
File size: 8,953 Bytes
85f36c8 7852159 85f36c8 7852159 85f36c8 | 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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | const $ = (selector) => document.querySelector(selector);
const $$ = (selector) => [...document.querySelectorAll(selector)];
const state = { runId: null, poller: null, lastRecord: null, startedAt: 0 };
const stageOrder = ["planning", "branching", "testing", "judging", "complete"];
function escapeHtml(value = "") {
return value.replace(/[&<>'"]/g, (char) => ({
"&": "&", "<": "<", ">": ">", "'": "'", '"': """
})[char]);
}
function toast(message) {
const node = $("#toast");
node.textContent = message;
node.classList.add("show");
window.setTimeout(() => node.classList.remove("show"), 2200);
}
async function api(path, options) {
const response = await fetch(path, options);
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
return response.json();
}
async function boot() {
try {
const [sample, health] = await Promise.all([api("/api/sample"), api("/api/health")]);
$("#issue").value = sample.issue;
$("#repository").value = sample.repository;
$("#provider-badge").textContent = health.provider;
const planner = health.model.split("/").pop().replaceAll("_", ".").replace("Nemotron-", "N");
const judge = health.judge_model.split("/").pop().replaceAll("_", ".").replace("Nemotron-", "N");
$("#model-badge").textContent = planner === judge ? `${planner} · 2 STAGES` : `${planner} → ${judge}`;
} catch (error) {
$("#issue").value = "Refunds at half-cent boundaries round against the customer. Preserve validation and prove a safe fix.";
}
}
function resetRunUi() {
$("#evidence").hidden = true;
$("#run-status").classList.add("running");
$("#run-status").innerHTML = "<span></span> Preparing experiment";
$("#branch-grid").innerHTML = ["amber", "violet", "green"].map((color, i) => `
<article class="branch-card skeleton running ${color}">
<div class="branch-top"><span>${String.fromCharCode(65 + i)}</span><i></i><small>PLANNING</small></div>
<h3>Generating hypothesis</h3>
<p>Nemotron is searching for a distinct, executable repair strategy.</p>
</article>`).join("");
updateStages("planning");
}
function updateStages(activeStage) {
const activeIndex = stageOrder.indexOf(activeStage);
$$(".stage").forEach((node) => {
const index = stageOrder.indexOf(node.dataset.stage);
node.classList.toggle("active", index === activeIndex || activeStage === "complete" && index === 3);
node.classList.toggle("done", index < activeIndex || activeStage === "complete");
});
$$("#stage-track > i").forEach((node, index) => node.classList.toggle("done", index < activeIndex));
}
function runningCards(stage) {
const labels = {
planning: ["FORMING THESIS", "Generating hypothesis", "Nemotron is creating independent repair strategies."],
branching: ["FORKING STATE", "Creating checkpoint", "ConTree is forking the same filesystem state."],
testing: ["EXECUTING", "Running regression suite", "Each branch is producing comparable test evidence."],
judging: ["SCORING", "Weighing the evidence", "Nemotron is reviewing safety, clarity, and observed results."]
};
const [tag, title, body] = labels[stage] || labels.planning;
$$(".branch-card").forEach((card, i) => {
const top = card.querySelector("small");
const h3 = card.querySelector("h3");
const p = card.querySelector("p");
if (top) top.textContent = tag;
if (h3) h3.textContent = `${title} ${String.fromCharCode(65 + i)}`;
if (p) p.textContent = body;
});
}
function renderBranch(branch, index) {
const { candidate, tests, score, verdict } = branch;
const statusClass = tests.exit_code === 0 ? "pass" : "fail";
const statusText = tests.exit_code === 0 ? "PASS" : "FAIL";
const winner = verdict === "winner";
return `
<article class="branch-card ${candidate.accent} ${winner ? "winner" : ""}">
${winner ? '<span class="winner-chip">SELECTED</span>' : ""}
<div class="branch-top"><span>${String.fromCharCode(65 + index)}</span><i></i><small>${escapeHtml(tests.checkpoint.slice(0, 13).toUpperCase())}</small></div>
<h3>${escapeHtml(candidate.name)}</h3>
<p>${escapeHtml(candidate.thesis)}</p>
<div class="score-row"><span>EVIDENCE SCORE</span><strong>${score}</strong><div class="score-bar"><i style="--score:${score}%"></i></div></div>
<div class="test-strip"><span>TESTS <strong>${tests.passed}/${tests.total}</strong></span><span>${tests.duration_ms}ms</span><strong class="${statusClass}">${statusText}</strong></div>
<div class="branch-risk"><b>RISK</b><span>${escapeHtml(candidate.risk)}</span></div>
</article>`;
}
function paintDiff(diff) {
return escapeHtml(diff || "No diff returned.").split("\n").map((line) => {
const cls = line.startsWith("+") && !line.startsWith("+++") ? "diff-add" :
line.startsWith("-") && !line.startsWith("---") ? "diff-remove" :
line.startsWith("@@") || line.startsWith("+++") || line.startsWith("---") ? "diff-head" : "";
return `<span class="${cls}">${line}</span>`;
}).join("\n");
}
function renderComplete(record) {
$("#branch-grid").innerHTML = record.branches.map(renderBranch).join("");
record.branches.forEach((branch, index) => {
const tree = document.querySelector(`[data-tree="${index}"]`);
if (tree) tree.lastChild.textContent = branch.candidate.name.toLowerCase();
});
updateStages("complete");
$("#run-status").classList.remove("running");
$("#run-status").innerHTML = `<span style="background:var(--green-2);border-color:var(--green-2)"></span> ${escapeHtml(record.events.at(-1)?.message || "Evidence sealed")}`;
const winner = record.branches.find((branch) => branch.candidate.id === record.winner_id) || record.branches[0];
$("#winner-name").textContent = winner.candidate.name;
$("#winner-synthesis").textContent = record.synthesis;
$("#winner-score").textContent = winner.score;
$("#receipt-tests").textContent = `${winner.tests.passed} / ${winner.tests.total} passed`;
$("#receipt-checkpoint").textContent = winner.tests.checkpoint;
$("#model-path-value").textContent = `${record.planner_mode} / ${record.judge_mode}`.toUpperCase();
$("#runtime-pill").textContent = record.sandbox_mode.replaceAll("-", " ").toUpperCase();
$("#isolation-value").textContent = record.sandbox_mode === "nebius-sandbox" ? "VM boundary" : "Local process";
$("#patch-diff").innerHTML = `<code>${paintDiff(winner.diff)}</code>`;
$("#evidence").hidden = false;
$("#run-button").disabled = false;
$("#run-button .button-copy b").textContent = "Forge again";
window.setTimeout(() => $("#evidence").scrollIntoView({ behavior: "smooth", block: "start" }), 220);
}
async function pollRun() {
try {
const record = await api(`/api/runs/${state.runId}`);
state.lastRecord = record;
if (record.status === "failed") {
throw new Error(record.error || "The experiment stopped safely.");
}
updateStages(record.status);
runningCards(record.status);
const message = record.events.at(-1)?.message || "Working";
$("#run-status").innerHTML = `<span></span> ${escapeHtml(message)}`;
if (record.branches.length) $("#branch-grid").innerHTML = record.branches.map(renderBranch).join("");
if (record.status === "complete") {
const elapsed = Date.now() - state.startedAt;
const minimumShowcaseMs = 2400;
window.clearInterval(state.poller);
window.setTimeout(() => renderComplete(record), Math.max(0, minimumShowcaseMs - elapsed));
}
} catch (error) {
window.clearInterval(state.poller);
$("#run-button").disabled = false;
$("#run-status").classList.remove("running");
$("#run-status").innerHTML = `<span style="border-color:var(--danger)"></span> Run stopped safely`;
toast(error.message);
}
}
async function startRun() {
const issue = $("#issue").value.trim();
if (issue.length < 12) return toast("Add a more specific issue brief.");
$("#run-button").disabled = true;
$("#run-button .button-copy b").textContent = "Forging evidence…";
resetRunUi();
$("#run-section").scrollIntoView({ behavior: "smooth", block: "start" });
state.startedAt = Date.now();
try {
const record = await api("/api/runs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ repository: $("#repository").value.trim(), issue, mode: "sample" })
});
state.runId = record.id;
state.poller = window.setInterval(pollRun, 420);
await pollRun();
} catch (error) {
$("#run-button").disabled = false;
toast(error.message);
}
}
$("#run-button").addEventListener("click", startRun);
$("#copy-patch").addEventListener("click", async () => {
const winner = state.lastRecord?.branches.find((branch) => branch.candidate.id === state.lastRecord.winner_id);
if (!winner) return;
await navigator.clipboard.writeText(winner.diff);
toast("Verified diff copied.");
});
boot();
|