Spaces:
Running on Zero
Running on Zero
refactor: focus app ui on builders
Browse filesCo-authored-by: Codex <noreply@openai.com>
- README.md +28 -27
- static/app.js +28 -22
- static/index.html +1 -14
README.md
CHANGED
|
@@ -32,7 +32,7 @@ The current milestone is a deployable, deterministic vertical slice:
|
|
| 32 |
- Offline search over project titles, tags, models, and descriptions.
|
| 33 |
- Jargon correction for hackathon/model terms.
|
| 34 |
- One-turn advisor loop with overlap citations, whitespace suggestions, scoring, and plans.
|
| 35 |
-
- Custom `gradio.Server` frontend with
|
| 36 |
|
| 37 |
See [DESIGN.md](DESIGN.md) for the full product and model plan.
|
| 38 |
|
|
@@ -60,8 +60,9 @@ source, project order, and digest before the app starts.
|
|
| 60 |
|
| 61 |
## Trace Artifact
|
| 62 |
|
| 63 |
-
The app exposes a `trace_artifact` Gradio API endpoint
|
| 64 |
-
|
|
|
|
| 65 |
|
| 66 |
## Field Notes Artifact
|
| 67 |
|
|
@@ -77,45 +78,45 @@ the private Field Notes artifact.
|
|
| 77 |
|
| 78 |
## LoRA Dataset Artifact
|
| 79 |
|
| 80 |
-
The `lora_dataset` Gradio API endpoint
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
|
| 85 |
## LoRA Training Kit
|
| 86 |
|
| 87 |
-
`/api/lora-training-kit.zip`
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
`
|
| 91 |
-
|
| 92 |
|
| 93 |
## Submission Packet
|
| 94 |
|
| 95 |
-
The `submission_packet` Gradio API endpoint
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
|
| 100 |
## Demo Rehearsal
|
| 101 |
|
| 102 |
-
`/api/demo-session` and the `
|
| 103 |
-
target badges, score seal, build plan, trace,
|
| 104 |
-
|
| 105 |
-
|
| 106 |
|
| 107 |
## Demo Evidence Bundle
|
| 108 |
|
| 109 |
-
`/api/demo-bundle.zip`
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
|
| 114 |
## Prize Ledger
|
| 115 |
|
| 116 |
-
`/api/prize-ledger`
|
| 117 |
-
|
| 118 |
-
|
| 119 |
|
| 120 |
## Wood Map
|
| 121 |
|
|
|
|
| 32 |
- Offline search over project titles, tags, models, and descriptions.
|
| 33 |
- Jargon correction for hackathon/model terms.
|
| 34 |
- One-turn advisor loop with overlap citations, whitespace suggestions, scoring, and plans.
|
| 35 |
+
- Custom `gradio.Server` frontend focused on the builder's idea workflow, with submission evidence kept in API exports.
|
| 36 |
|
| 37 |
See [DESIGN.md](DESIGN.md) for the full product and model plan.
|
| 38 |
|
|
|
|
| 60 |
|
| 61 |
## Trace Artifact
|
| 62 |
|
| 63 |
+
The app exposes a `trace_artifact` Gradio API endpoint for submission evidence and debugging. It emits a manifest row
|
| 64 |
+
followed by one row per agent turn. `data/sample_trace.jsonl` is a checked-in, Hub-published sample trace. This endpoint
|
| 65 |
+
is intentionally kept out of the main user workflow.
|
| 66 |
|
| 67 |
## Field Notes Artifact
|
| 68 |
|
|
|
|
| 78 |
|
| 79 |
## LoRA Dataset Artifact
|
| 80 |
|
| 81 |
+
The `lora_dataset` Gradio API endpoint exports a compact chat JSONL dataset from successful session turns. Each included
|
| 82 |
+
turn yields a tool-call example and an advisor-response example for `openbmb/MiniCPM5-1B`, with the selected targets,
|
| 83 |
+
parsed XML tool call, tool observations, and score context preserved. This prepares the Well-Tuned path without claiming
|
| 84 |
+
that the adapter has already been trained or published.
|
| 85 |
|
| 86 |
## LoRA Training Kit
|
| 87 |
|
| 88 |
+
`/api/lora-training-kit.zip` exports a training kit for the deterministic demo session: SFT JSONL, training recipe,
|
| 89 |
+
adapter model-card draft, and the exact training command. The included `scripts/train_minicpm_lora.py` entrypoint
|
| 90 |
+
supports a dependency-light `--dry-run` validation path and a real `transformers + PEFT` training path after installing
|
| 91 |
+
`pip install -e '.[train]'`. The Prize Ledger still marks Well-Tuned as training-kit-ready until a real adapter is
|
| 92 |
+
trained and published.
|
| 93 |
|
| 94 |
## Submission Packet
|
| 95 |
|
| 96 |
+
The `submission_packet` Gradio API endpoint exports a Markdown submission bundle for the current session: live links,
|
| 97 |
+
snapshot provenance, a timed demo script, artifact checklist, Prize Ledger evidence, model budget, session trace
|
| 98 |
+
summary, social post draft, and open badge gaps. This keeps the final submission story tied to the same auditable state
|
| 99 |
+
as the app instead of a separate hand-curated checklist.
|
| 100 |
|
| 101 |
## Demo Rehearsal
|
| 102 |
|
| 103 |
+
`/api/demo-session` and the `Example` button load a deterministic two-turn sample: a complete project idea, profile,
|
| 104 |
+
target badges, score seal, build plan, trace, and wood map. It is built by running the same advisor engine as a normal
|
| 105 |
+
user session, so the visible app stays focused on the builder's idea while API exports remain available for submission
|
| 106 |
+
evidence.
|
| 107 |
|
| 108 |
## Demo Evidence Bundle
|
| 109 |
|
| 110 |
+
`/api/demo-bundle.zip` downloads a server-built ZIP for the deterministic demo session. The bundle includes a manifest,
|
| 111 |
+
demo session JSON, Prize Ledger JSON, trace JSONL, Field Notes, Almanac chapter, LoRA SFT JSONL, LoRA training kit,
|
| 112 |
+
Submission Packet, and a PNG export note. This gives judges or collaborators one auditable package without depending on
|
| 113 |
+
browser `localStorage`.
|
| 114 |
|
| 115 |
## Prize Ledger
|
| 116 |
|
| 117 |
+
`/api/prize-ledger` exposes submission evidence: the documented model stack, total parameter budget, Tiny Titan
|
| 118 |
+
eligibility, runtime backend, and badge readiness. It is kept as an API artifact rather than a primary in-app panel so
|
| 119 |
+
the user-facing app stays centered on idea evaluation.
|
| 120 |
|
| 121 |
## Wood Map
|
| 122 |
|
static/app.js
CHANGED
|
@@ -63,7 +63,7 @@ exportButton.addEventListener("click", () => {
|
|
| 63 |
exportArtifact(currentArtifact);
|
| 64 |
});
|
| 65 |
|
| 66 |
-
exportTraceButton.addEventListener("click", async () => {
|
| 67 |
await exportTrace();
|
| 68 |
});
|
| 69 |
|
|
@@ -75,19 +75,19 @@ exportChapterButton.addEventListener("click", async () => {
|
|
| 75 |
await exportChapter();
|
| 76 |
});
|
| 77 |
|
| 78 |
-
exportLoraButton.addEventListener("click", async () => {
|
| 79 |
await exportLoraDataset();
|
| 80 |
});
|
| 81 |
|
| 82 |
-
exportTrainKitButton.addEventListener("click", () => {
|
| 83 |
window.location.assign("/api/lora-training-kit.zip");
|
| 84 |
});
|
| 85 |
|
| 86 |
-
exportPacketButton.addEventListener("click", async () => {
|
| 87 |
await exportSubmissionPacket();
|
| 88 |
});
|
| 89 |
|
| 90 |
-
exportBundleButton.addEventListener("click", () => {
|
| 91 |
window.location.assign("/api/demo-bundle.zip");
|
| 92 |
});
|
| 93 |
|
|
@@ -181,7 +181,7 @@ async function loadDemoSession() {
|
|
| 181 |
setCommandDisabled(true);
|
| 182 |
ink.classList.remove("bleed", "gold");
|
| 183 |
ink.classList.add("thinking");
|
| 184 |
-
ink.textContent = "
|
| 185 |
corrections.textContent = "";
|
| 186 |
try {
|
| 187 |
const response = await fetch("/api/demo-session");
|
|
@@ -225,12 +225,12 @@ function applyDemoSession(data) {
|
|
| 225 |
renderProjects(data.projects || []);
|
| 226 |
}
|
| 227 |
exportButton.disabled = !currentArtifact;
|
| 228 |
-
exportTraceButton
|
| 229 |
-
exportNotesButton
|
| 230 |
-
exportChapterButton
|
| 231 |
-
exportLoraButton
|
| 232 |
-
exportPacketButton
|
| 233 |
-
corrections.textContent = `
|
| 234 |
saveSession();
|
| 235 |
}
|
| 236 |
|
|
@@ -263,11 +263,11 @@ function renderRestoredSession(data) {
|
|
| 263 |
renderIdeas(session.ideas || []);
|
| 264 |
renderPlan(session.last_plan || []);
|
| 265 |
renderTrace(session.trace || []);
|
| 266 |
-
exportTraceButton
|
| 267 |
-
exportNotesButton
|
| 268 |
-
exportChapterButton
|
| 269 |
-
exportLoraButton
|
| 270 |
-
exportPacketButton
|
| 271 |
}
|
| 272 |
|
| 273 |
function readSavedSession() {
|
|
@@ -354,6 +354,7 @@ function renderProfile(profile) {
|
|
| 354 |
}
|
| 355 |
|
| 356 |
function renderPrizeLedger(ledger) {
|
|
|
|
| 357 |
prizeLedgerEl.innerHTML = "";
|
| 358 |
if (!ledger) {
|
| 359 |
prizeLedgerEl.innerHTML = `<div class="empty">No prize ledger loaded.</div>`;
|
|
@@ -447,11 +448,11 @@ function handleEvent(event) {
|
|
| 447 |
renderWoodMap(event.artifact.wood_map || null);
|
| 448 |
exportButton.disabled = false;
|
| 449 |
}
|
| 450 |
-
exportTraceButton
|
| 451 |
-
exportNotesButton
|
| 452 |
-
exportChapterButton
|
| 453 |
-
exportLoraButton
|
| 454 |
-
exportPacketButton
|
| 455 |
saveSession();
|
| 456 |
}
|
| 457 |
}
|
|
@@ -604,6 +605,7 @@ function renderPlan(steps) {
|
|
| 604 |
}
|
| 605 |
|
| 606 |
function renderTrace(trace) {
|
|
|
|
| 607 |
traceEl.innerHTML = "";
|
| 608 |
if (!trace.length) {
|
| 609 |
traceEl.innerHTML = `<div class="empty">No tool marks yet.</div>`;
|
|
@@ -621,6 +623,10 @@ function renderTrace(trace) {
|
|
| 621 |
}
|
| 622 |
}
|
| 623 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 624 |
function setCommandDisabled(disabled) {
|
| 625 |
document.querySelectorAll(".command-row button").forEach((button) => {
|
| 626 |
if (button.id === "export-train-kit") return;
|
|
|
|
| 63 |
exportArtifact(currentArtifact);
|
| 64 |
});
|
| 65 |
|
| 66 |
+
exportTraceButton?.addEventListener("click", async () => {
|
| 67 |
await exportTrace();
|
| 68 |
});
|
| 69 |
|
|
|
|
| 75 |
await exportChapter();
|
| 76 |
});
|
| 77 |
|
| 78 |
+
exportLoraButton?.addEventListener("click", async () => {
|
| 79 |
await exportLoraDataset();
|
| 80 |
});
|
| 81 |
|
| 82 |
+
exportTrainKitButton?.addEventListener("click", () => {
|
| 83 |
window.location.assign("/api/lora-training-kit.zip");
|
| 84 |
});
|
| 85 |
|
| 86 |
+
exportPacketButton?.addEventListener("click", async () => {
|
| 87 |
await exportSubmissionPacket();
|
| 88 |
});
|
| 89 |
|
| 90 |
+
exportBundleButton?.addEventListener("click", () => {
|
| 91 |
window.location.assign("/api/demo-bundle.zip");
|
| 92 |
});
|
| 93 |
|
|
|
|
| 181 |
setCommandDisabled(true);
|
| 182 |
ink.classList.remove("bleed", "gold");
|
| 183 |
ink.classList.add("thinking");
|
| 184 |
+
ink.textContent = "A sample page is being inked.";
|
| 185 |
corrections.textContent = "";
|
| 186 |
try {
|
| 187 |
const response = await fetch("/api/demo-session");
|
|
|
|
| 225 |
renderProjects(data.projects || []);
|
| 226 |
}
|
| 227 |
exportButton.disabled = !currentArtifact;
|
| 228 |
+
setButtonDisabled(exportTraceButton, !(session.trace?.length));
|
| 229 |
+
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 230 |
+
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 231 |
+
setButtonDisabled(exportLoraButton, !(session.trace?.length));
|
| 232 |
+
setButtonDisabled(exportPacketButton, !(session.trace?.length));
|
| 233 |
+
corrections.textContent = `example loaded: ${data.turn_count || 0} advisor turns`;
|
| 234 |
saveSession();
|
| 235 |
}
|
| 236 |
|
|
|
|
| 263 |
renderIdeas(session.ideas || []);
|
| 264 |
renderPlan(session.last_plan || []);
|
| 265 |
renderTrace(session.trace || []);
|
| 266 |
+
setButtonDisabled(exportTraceButton, !(session.trace?.length));
|
| 267 |
+
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 268 |
+
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 269 |
+
setButtonDisabled(exportLoraButton, !(session.trace?.length));
|
| 270 |
+
setButtonDisabled(exportPacketButton, !(session.trace?.length));
|
| 271 |
}
|
| 272 |
|
| 273 |
function readSavedSession() {
|
|
|
|
| 354 |
}
|
| 355 |
|
| 356 |
function renderPrizeLedger(ledger) {
|
| 357 |
+
if (!prizeLedgerEl) return;
|
| 358 |
prizeLedgerEl.innerHTML = "";
|
| 359 |
if (!ledger) {
|
| 360 |
prizeLedgerEl.innerHTML = `<div class="empty">No prize ledger loaded.</div>`;
|
|
|
|
| 448 |
renderWoodMap(event.artifact.wood_map || null);
|
| 449 |
exportButton.disabled = false;
|
| 450 |
}
|
| 451 |
+
setButtonDisabled(exportTraceButton, !(session.trace?.length));
|
| 452 |
+
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 453 |
+
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 454 |
+
setButtonDisabled(exportLoraButton, !(session.trace?.length));
|
| 455 |
+
setButtonDisabled(exportPacketButton, !(session.trace?.length));
|
| 456 |
saveSession();
|
| 457 |
}
|
| 458 |
}
|
|
|
|
| 605 |
}
|
| 606 |
|
| 607 |
function renderTrace(trace) {
|
| 608 |
+
if (!traceEl) return;
|
| 609 |
traceEl.innerHTML = "";
|
| 610 |
if (!trace.length) {
|
| 611 |
traceEl.innerHTML = `<div class="empty">No tool marks yet.</div>`;
|
|
|
|
| 623 |
}
|
| 624 |
}
|
| 625 |
|
| 626 |
+
function setButtonDisabled(button, disabled) {
|
| 627 |
+
if (button) button.disabled = disabled;
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
function setCommandDisabled(disabled) {
|
| 631 |
document.querySelectorAll(".command-row button").forEach((button) => {
|
| 632 |
if (button.id === "export-train-kit") return;
|
static/index.html
CHANGED
|
@@ -27,19 +27,14 @@
|
|
| 27 |
<button id="submit" type="submit" title="Ink the page">Ink</button>
|
| 28 |
</form>
|
| 29 |
<div class="command-row" aria-label="Advisor commands">
|
| 30 |
-
<button type="button" id="load-demo" title="Load a
|
| 31 |
<button type="button" data-command="write bolder and find whitespace" title="Find a gold margin">
|
| 32 |
Gap
|
| 33 |
</button>
|
| 34 |
<button type="button" data-command="make a build plan" title="Draft a build plan">Plan</button>
|
| 35 |
<button type="button" data-command="compare ideas" title="Compare the idea board">Rank</button>
|
| 36 |
-
<button type="button" id="export-trace" title="Export the tool trace" disabled>JSONL</button>
|
| 37 |
<button type="button" id="export-notes" title="Export Field Notes" disabled>Notes</button>
|
| 38 |
<button type="button" id="export-chapter" title="Export the Almanac chapter" disabled>Chapter</button>
|
| 39 |
-
<button type="button" id="export-lora" title="Export the LoRA SFT dataset" disabled>LoRA</button>
|
| 40 |
-
<button type="button" id="export-train-kit" title="Download the LoRA training kit">Train</button>
|
| 41 |
-
<button type="button" id="export-packet" title="Export the submission packet" disabled>Packet</button>
|
| 42 |
-
<button type="button" id="export-bundle" title="Download the demo evidence bundle">Bundle</button>
|
| 43 |
<button type="button" id="export-artifact" title="Export the current fate page" disabled>PNG</button>
|
| 44 |
<button type="button" id="reset-session" title="Clear the saved session">Reset</button>
|
| 45 |
</div>
|
|
@@ -66,10 +61,6 @@
|
|
| 66 |
<h2>Profile</h2>
|
| 67 |
<div id="profile" class="profile-grid"></div>
|
| 68 |
</article>
|
| 69 |
-
<article class="wide-panel">
|
| 70 |
-
<h2>Prize Ledger</h2>
|
| 71 |
-
<div id="prize-ledger" class="prize-ledger"></div>
|
| 72 |
-
</article>
|
| 73 |
<article>
|
| 74 |
<h2>Idea Board</h2>
|
| 75 |
<div id="ideas" class="idea-list"></div>
|
|
@@ -86,10 +77,6 @@
|
|
| 86 |
<h2>Build Plan</h2>
|
| 87 |
<ol id="plan" class="plan-list"></ol>
|
| 88 |
</article>
|
| 89 |
-
<article>
|
| 90 |
-
<h2>Trace</h2>
|
| 91 |
-
<div id="trace" class="trace-list"></div>
|
| 92 |
-
</article>
|
| 93 |
</div>
|
| 94 |
</section>
|
| 95 |
</div>
|
|
|
|
| 27 |
<button id="submit" type="submit" title="Ink the page">Ink</button>
|
| 28 |
</form>
|
| 29 |
<div class="command-row" aria-label="Advisor commands">
|
| 30 |
+
<button type="button" id="load-demo" title="Load a sample idea">Example</button>
|
| 31 |
<button type="button" data-command="write bolder and find whitespace" title="Find a gold margin">
|
| 32 |
Gap
|
| 33 |
</button>
|
| 34 |
<button type="button" data-command="make a build plan" title="Draft a build plan">Plan</button>
|
| 35 |
<button type="button" data-command="compare ideas" title="Compare the idea board">Rank</button>
|
|
|
|
| 36 |
<button type="button" id="export-notes" title="Export Field Notes" disabled>Notes</button>
|
| 37 |
<button type="button" id="export-chapter" title="Export the Almanac chapter" disabled>Chapter</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
<button type="button" id="export-artifact" title="Export the current fate page" disabled>PNG</button>
|
| 39 |
<button type="button" id="reset-session" title="Clear the saved session">Reset</button>
|
| 40 |
</div>
|
|
|
|
| 61 |
<h2>Profile</h2>
|
| 62 |
<div id="profile" class="profile-grid"></div>
|
| 63 |
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
<article>
|
| 65 |
<h2>Idea Board</h2>
|
| 66 |
<div id="ideas" class="idea-list"></div>
|
|
|
|
| 77 |
<h2>Build Plan</h2>
|
| 78 |
<ol id="plan" class="plan-list"></ol>
|
| 79 |
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
</div>
|
| 81 |
</section>
|
| 82 |
</div>
|