Spaces:
Running on Zero
Running on Zero
Update index.html
Browse files- index.html +35 -3
index.html
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
|
@@ -128,6 +129,8 @@
|
|
| 128 |
.py-bar { padding: 8px 14px; border-bottom: 1px solid var(--border); display: flex; gap: 8px; align-items: center; }
|
| 129 |
.py-bar button { font-size: 12px; padding: 6px 12px; }
|
| 130 |
.py-bar .py-status { color: var(--muted); font-size: 12px; margin-left: auto; }
|
|
|
|
|
|
|
| 131 |
</style>
|
| 132 |
</head>
|
| 133 |
<body>
|
|
@@ -165,6 +168,8 @@
|
|
| 165 |
<div class="py-bar">
|
| 166 |
<button class="primary" id="runBtn">▶ Run</button>
|
| 167 |
<button class="ghost" id="clearConsoleBtn">Clear</button>
|
|
|
|
|
|
|
| 168 |
<span class="py-status" id="pyStatus"></span>
|
| 169 |
</div>
|
| 170 |
<pre id="pyConsole"></pre>
|
|
@@ -213,6 +218,8 @@ let previewScrollY = 0;
|
|
| 213 |
let currentMode = "webpage";
|
| 214 |
let pyodideReady = null;
|
| 215 |
let currentPySource = "";
|
|
|
|
|
|
|
| 216 |
|
| 217 |
const SUBTITLES = {
|
| 218 |
webpage: "Describe a website and a block-diffusion LLM writes the HTML by denoising — every token updates at once. Watch the raw canvas take shape (left) while it renders into a live page (right), then send follow-up prompts to tweak it.",
|
|
@@ -401,9 +408,30 @@ async function runPython() {
|
|
| 401 |
py.setStderr({ batched: (s) => log("err", s) });
|
| 402 |
await py.runPythonAsync(currentPySource);
|
| 403 |
pyStatus.textContent = "done";
|
|
|
|
| 404 |
} catch (e) {
|
| 405 |
-
|
|
|
|
| 406 |
pyStatus.textContent = "error";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
}
|
| 408 |
}
|
| 409 |
|
|
@@ -431,9 +459,9 @@ async function ensureClient() {
|
|
| 431 |
}
|
| 432 |
|
| 433 |
async function run() {
|
| 434 |
-
if (busy) return;
|
| 435 |
const prompt = promptEl.value.trim();
|
| 436 |
-
if (!prompt) { promptEl.focus(); return; }
|
| 437 |
|
| 438 |
busy = true; buildBtn.disabled = true;
|
| 439 |
const isTweak = messages.length > 0;
|
|
@@ -442,6 +470,7 @@ async function run() {
|
|
| 442 |
if (!isTweak) { previewScrollY = 0; pyConsole.innerHTML = ""; }
|
| 443 |
const isPy = currentMode === "python";
|
| 444 |
|
|
|
|
| 445 |
try {
|
| 446 |
const c = await ensureClient();
|
| 447 |
const payload = {
|
|
@@ -489,6 +518,7 @@ async function run() {
|
|
| 489 |
lastFinalLines = finalSource.split("\n");
|
| 490 |
promptEl.value = "";
|
| 491 |
renderHistory();
|
|
|
|
| 492 |
}
|
| 493 |
} catch (e) {
|
| 494 |
setStatus("err", "error");
|
|
@@ -496,6 +526,7 @@ async function run() {
|
|
| 496 |
} finally {
|
| 497 |
busy = false; buildBtn.disabled = false;
|
| 498 |
}
|
|
|
|
| 499 |
}
|
| 500 |
|
| 501 |
function renderHistory() {
|
|
@@ -508,6 +539,7 @@ function renderHistory() {
|
|
| 508 |
function reset() {
|
| 509 |
messages = []; prevFrameLines = []; lastFinalLines = [];
|
| 510 |
previewScrollY = 0; pyConsole.innerHTML = ""; currentPySource = "";
|
|
|
|
| 511 |
codeEl.innerHTML = ""; renderPreview(""); renderPython("");
|
| 512 |
$("history").innerHTML = "";
|
| 513 |
capInfo.textContent = ""; pyCapInfo.textContent = "";
|
|
|
|
| 1 |
+
<!-- index.html -->
|
| 2 |
<!DOCTYPE html>
|
| 3 |
<html lang="en">
|
| 4 |
<head>
|
|
|
|
| 129 |
.py-bar { padding: 8px 14px; border-bottom: 1px solid var(--border); display: flex; gap: 8px; align-items: center; }
|
| 130 |
.py-bar button { font-size: 12px; padding: 6px 12px; }
|
| 131 |
.py-bar .py-status { color: var(--muted); font-size: 12px; margin-left: auto; }
|
| 132 |
+
.py-bar .py-opt { color: var(--muted); font-size: 12px; display: flex; align-items: center; gap: 5px; cursor: pointer; }
|
| 133 |
+
.py-bar .py-opt input { accent-color: var(--accent); width: 14px; height: 14px; }
|
| 134 |
</style>
|
| 135 |
</head>
|
| 136 |
<body>
|
|
|
|
| 168 |
<div class="py-bar">
|
| 169 |
<button class="primary" id="runBtn">▶ Run</button>
|
| 170 |
<button class="ghost" id="clearConsoleBtn">Clear</button>
|
| 171 |
+
<label class="py-opt"><input type="checkbox" id="autoFeedErr" checked> auto-fix on error</label>
|
| 172 |
+
<label class="py-opt"><input type="checkbox" id="autoRetryRun" checked> auto-retry run</label>
|
| 173 |
<span class="py-status" id="pyStatus"></span>
|
| 174 |
</div>
|
| 175 |
<pre id="pyConsole"></pre>
|
|
|
|
| 218 |
let currentMode = "webpage";
|
| 219 |
let pyodideReady = null;
|
| 220 |
let currentPySource = "";
|
| 221 |
+
let autoFixRetries = 0;
|
| 222 |
+
const MAX_AUTO_RETRIES = 3;
|
| 223 |
|
| 224 |
const SUBTITLES = {
|
| 225 |
webpage: "Describe a website and a block-diffusion LLM writes the HTML by denoising — every token updates at once. Watch the raw canvas take shape (left) while it renders into a live page (right), then send follow-up prompts to tweak it.",
|
|
|
|
| 408 |
py.setStderr({ batched: (s) => log("err", s) });
|
| 409 |
await py.runPythonAsync(currentPySource);
|
| 410 |
pyStatus.textContent = "done";
|
| 411 |
+
autoFixRetries = 0; // Reset retry count on successful run
|
| 412 |
} catch (e) {
|
| 413 |
+
const errMsg = String(e && e.message ? e.message : e);
|
| 414 |
+
log("err", errMsg);
|
| 415 |
pyStatus.textContent = "error";
|
| 416 |
+
|
| 417 |
+
// Auto-fix logic
|
| 418 |
+
if ($("autoFeedErr").checked && autoFixRetries < MAX_AUTO_RETRIES && currentMode === "python") {
|
| 419 |
+
autoFixRetries++;
|
| 420 |
+
pyStatus.textContent = `auto-fixing (${autoFixRetries}/${MAX_AUTO_RETRIES})...`;
|
| 421 |
+
|
| 422 |
+
const errorPrompt = `The previous Python code failed with the following error:\n\n\`\`\`\n${errMsg}\n\`\`\`\n\nPlease fix the error and return the full updated script.`;
|
| 423 |
+
promptEl.value = errorPrompt;
|
| 424 |
+
|
| 425 |
+
const success = await run(); // Trigger the build/tweak process
|
| 426 |
+
|
| 427 |
+
// If the model successfully generated new code, and auto-retry is checked, run it again.
|
| 428 |
+
if (success && $("autoRetryRun").checked && currentPySource.trim()) {
|
| 429 |
+
await runPython();
|
| 430 |
+
}
|
| 431 |
+
} else if (autoFixRetries >= MAX_AUTO_RETRIES) {
|
| 432 |
+
log("err", "Max auto-fix retries reached. Please debug manually.");
|
| 433 |
+
pyStatus.textContent = "max retries reached";
|
| 434 |
+
}
|
| 435 |
}
|
| 436 |
}
|
| 437 |
|
|
|
|
| 459 |
}
|
| 460 |
|
| 461 |
async function run() {
|
| 462 |
+
if (busy) return false;
|
| 463 |
const prompt = promptEl.value.trim();
|
| 464 |
+
if (!prompt) { promptEl.focus(); return false; }
|
| 465 |
|
| 466 |
busy = true; buildBtn.disabled = true;
|
| 467 |
const isTweak = messages.length > 0;
|
|
|
|
| 470 |
if (!isTweak) { previewScrollY = 0; pyConsole.innerHTML = ""; }
|
| 471 |
const isPy = currentMode === "python";
|
| 472 |
|
| 473 |
+
let success = false;
|
| 474 |
try {
|
| 475 |
const c = await ensureClient();
|
| 476 |
const payload = {
|
|
|
|
| 518 |
lastFinalLines = finalSource.split("\n");
|
| 519 |
promptEl.value = "";
|
| 520 |
renderHistory();
|
| 521 |
+
success = true;
|
| 522 |
}
|
| 523 |
} catch (e) {
|
| 524 |
setStatus("err", "error");
|
|
|
|
| 526 |
} finally {
|
| 527 |
busy = false; buildBtn.disabled = false;
|
| 528 |
}
|
| 529 |
+
return success;
|
| 530 |
}
|
| 531 |
|
| 532 |
function renderHistory() {
|
|
|
|
| 539 |
function reset() {
|
| 540 |
messages = []; prevFrameLines = []; lastFinalLines = [];
|
| 541 |
previewScrollY = 0; pyConsole.innerHTML = ""; currentPySource = "";
|
| 542 |
+
autoFixRetries = 0;
|
| 543 |
codeEl.innerHTML = ""; renderPreview(""); renderPython("");
|
| 544 |
$("history").innerHTML = "";
|
| 545 |
capInfo.textContent = ""; pyCapInfo.textContent = "";
|