← back to Model Arena
auto-save: 2026-07-22T23:47:26 (3 files) — data/challenges.json public/index.html server.js
956ad95e7d0b0b8e6c71a1fa89314571a4e0ea70 · 2026-07-22 23:47:32 -0700 · Steve Abrams
Files touched
M data/challenges.jsonM public/index.htmlM server.js
Diff
commit 956ad95e7d0b0b8e6c71a1fa89314571a4e0ea70
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 22 23:47:32 2026 -0700
auto-save: 2026-07-22T23:47:26 (3 files) — data/challenges.json public/index.html server.js
---
data/challenges.json | 29 +++++++++++++++++++++++++++++
public/index.html | 13 ++++++++++++-
server.js | 27 +++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/data/challenges.json b/data/challenges.json
index ea213c2..dc53815 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -884,5 +884,34 @@
"judging": false,
"aiPick": "gemma3-12b",
"judged_at": "2026-07-23T06:44:54.324Z"
+ },
+ {
+ "id": "661e816553cf",
+ "title": "Remix: Luxury Product Page",
+ "prompt": "Build a single-file HTML product page for a luxury grasscloth wallpaper \"Kyoto Silk\" in the colorway Celadon. Include: a hero area (CSS gradient placeholder), elegant serif display typography, price ($148/roll), an Add to Cart button, and a spec table (Material: Grasscloth, Width 36in, Repeat Random, Origin Japan). High-end interior-design aesthetic, no external resources.\n\nHere is a strong previous attempt at this exact challenge. IMPROVE on it — keep what works, fix its weaknesses, and elevate the visual quality and polish. Return a complete, improved single-file HTML document.\n\n=== PREVIOUS ATTEMPT (Gemma3 12B) ===\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Kyoto Silk - Celadon Wallpaper</title>\n <style>\n body {\n font-family: 'Playfair Display', serif; /* Placeholder - replace with actual font */\n margin: 0;\n padding: 0;\n background-color: #f9f7f6;\n color: #333;\n line-height: 1.6;\n }\n\n /* Hero Area (CSS Gradient Placeholder) */\n .hero {\n background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(245, 245, 245, 1)); /* Placeholder gradient - replace with desired effect */\n padding: 60px;\n text-align: center;\n }\n\n h1 {\n font-size: 3em;\n margin-bottom: 10px;\n color: #4a4a4a;\n }\n\n .subtitle {\n font-style: italic;\n font-size: 1.2em;\n color: #777;\n }\n\n /* Product Details */\n .product-details {\n padding: 40px;\n max-width: 960px;\n margin: 0 auto;\n }\n\n .price {\n font-size: 1.5em;\n font-weight: bold;\n color: #a87b3d; /* Gold/Bronze Accent */\n }\n\n button {\n background-color: #a87b3d;\n color: white;\n border: none;\n padding: 12px 24px;\n font-size: 1em;\n cursor: pointer;\n transition: background-color 0.3s ease;\n }\n\n button:hover {\n background-color: #8a692d;\n }\n\n\n table {\n width: 100%;\n border-collapse: collapse;\n margin-top: 30px;\n }\n\n th, td {\n padding: 12px;\n text-align: left;\n border-bottom: 1px solid #ddd;\n }\n\n th {\n background-color: #f5f5f5;\n font-weight: bold;\n }\n\n /* Responsive Adjustments */\n @media (max-width: 768px) {\n .product-details {\n padding: 20px;\n }\n h1 {\n font-size: 2.5em;\n }\n button {\n display: block;\n margin: 20px auto;\n }\n }\n </style>\n</head>\n<body>\n\n <div class=\"hero\">\n <h1>Kyoto Silk Wallpaper</h1>\n <p class=\"subtitle\">Celadon Colorway</p>\n </div>\n\n <div class=\"product-details\">\n <h2>Exquisite Grasscloth Texture</h2>\n <p>Immerse your space in the timeless elegance of Kyoto Silk, a luxurious grasscloth wallpaper handcrafted in Japan. The Celadon colorway evokes a sense of tranquility and natural beauty.</p>\n\n <div class=\"price\">$148/roll</div>\n\n <button onclick=\"addToCart()\">Add to Cart</button>\n\n <h3>Specifications</h3>\n <table>\n <tr>\n <th>Material</th>\n <td>Grasscloth</td>\n </tr>\n <tr>\n <th>Width</th>\n <td>36in</td>\n </tr>\n <tr>\n <th>Repeat</th>\n <td>Random</td>\n </tr>\n <tr>\n <th>Origin</th>\n <td>Japan</td>\n </tr>\n </table>\n\n <script>\n function addToCart() {\n alert(\"Added to cart! (Simulated)\"); // Simple simulation of adding to cart. Replace with actual logic.\n }\n </script>\n </div>\n\n</body>\n</html>",
+ "remixOf": "248ea25bf69b",
+ "remixSource": "gemma3-12b",
+ "created_at": "2026-07-23T06:46:37.185Z",
+ "winner": null,
+ "runs": [
+ {
+ "model": "gemma3-12b",
+ "status": "running",
+ "error": null,
+ "seconds": null,
+ "cost": null,
+ "started_at": "2026-07-23T06:46:37.192Z",
+ "finished_at": null
+ },
+ {
+ "model": "hermes3-8b",
+ "status": "queued",
+ "error": null,
+ "seconds": null,
+ "cost": null,
+ "started_at": null,
+ "finished_at": null
+ }
+ ]
}
]
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index 53d8103..fd4ad49 100644
--- a/public/index.html
+++ b/public/index.html
@@ -305,7 +305,8 @@ async function renderDetail(id, statusOnly){
if (!r.ok) return null;
const c = await r.json(); current = c;
$('#d-title').textContent = c.title + (c.winner ? ' — 👑 ' + mLabel(c.winner) : '');
- $('#d-meta').textContent = '🕓 ' + fmtWhen(c.created_at) + '\n' + c.prompt;
+ const remixNote = c.remixOf ? '🧬 remixed from ' + mLabel(c.remixSource) + "'s artifact\n" : '';
+ $('#d-meta').textContent = '🕓 ' + fmtWhen(c.created_at) + '\n' + remixNote + c.prompt;
// AI referee status bar
const anyArt = c.runs.some(r=>r.status==='done'&&r.thumb);
const ai = $('#d-ai');
@@ -317,6 +318,16 @@ async function renderDetail(id, statusOnly){
else ai.innerHTML = '';
const jb = $('#judge')||$('#rejudge');
if (jb) jb.onclick = async ()=>{ jb.disabled=true; jb.textContent='judging…'; await fetch(API+'/api/challenges/'+c.id+'/judge',{method:'POST'}); openDetail(c.id); };
+ // Remix control — feed the best artifact back to all local models to improve on ($0)
+ if (anyArt && !c.judging){
+ const src = c.winner || c.aiPick;
+ const rx = document.createElement('span');
+ rx.innerHTML = ` · 🧬 <button class="btn pink" id="remix">Remix${src?' '+mLabel(src)+"'s":' best'} artifact → improve it</button>`;
+ ai.appendChild(rx);
+ $('#remix').onclick = async e=>{ e.target.disabled=true; e.target.textContent='remixing…';
+ const nc = await (await fetch(API+'/api/challenges/'+c.id+'/remix',{method:'POST',headers:{'Content-Type':'application/json'},body:'{}'})).json();
+ if (nc.id) openDetail(nc.id); };
+ }
const arena = $('#d-arena');
const sig = c.runs.map(r=>r.model+':'+r.status+':'+(r.aiScore??'')+':'+(r.thumb?'t':'')).join('|') + '|' + c.winner + '|' + c.aiPick + '|' + c.judging;
if (statusOnly && arena.dataset.sig === sig) return c;
diff --git a/server.js b/server.js
index fef703f..68b8816 100644
--- a/server.js
+++ b/server.js
@@ -52,6 +52,8 @@ const MODELS = [
{ id: 'grok', label: 'Grok 4.5', kind: 'metered', provider: 'xai', model: process.env.GROK_MODEL || 'grok-4.5', envKey: 'XAI_API_KEY', estCost: 0.10 },
];
+const mLabelServer = (id) => { const m = MODELS.find(x => x.id === id); return m ? m.label : id; };
+
// ---------- storage ----------
function loadChallenges() { try { return JSON.parse(fs.readFileSync(CH_FILE, 'utf8')); } catch { return []; } }
function saveChallenges(list) {
@@ -394,6 +396,31 @@ const server = http.createServer(async (req, res) => {
return c ? send(res, 200, c) : send(res, 404, { error: 'not found' });
}
+ if ((m = p.match(/^\/api\/challenges\/([a-f0-9]+)\/remix$/)) && req.method === 'POST') {
+ const c = challenges.find(x => x.id === m[1]);
+ if (!c) return send(res, 404, { error: 'not found' });
+ const body = await readBody(req);
+ // source artifact: explicit, else the crown, else the AI pick, else first done
+ const srcId = body.source || c.winner || c.aiPick || (c.runs.find(r => r.status === 'done') || {}).model;
+ const srcRun = c.runs.find(r => r.model === srcId && r.status === 'done');
+ if (!srcRun) return send(res, 400, { error: 'no rendered source artifact to remix' });
+ let srcHtml;
+ try { srcHtml = fs.readFileSync(path.join(ART, c.id, srcId + '.html'), 'utf8'); } catch { return send(res, 400, { error: 'source artifact file missing' }); }
+ const ids = Array.isArray(body.models) && body.models.length ? body.models.filter(id => MODELS.some(x => x.id === id))
+ : MODELS.filter(x => x.kind === 'local').map(x => x.id); // default: all local ($0)
+ const remixPrompt = `${c.prompt}\n\nHere is a strong previous attempt at this exact challenge. IMPROVE on it — keep what works, fix its weaknesses, and elevate the visual quality and polish. Return a complete, improved single-file HTML document.\n\n=== PREVIOUS ATTEMPT (${mLabelServer(srcId)}) ===\n${srcHtml.slice(0, 14000)}`;
+ const nc = {
+ id: crypto.randomBytes(6).toString('hex'),
+ title: 'Remix: ' + c.title.replace(/^Remix: /, ''),
+ prompt: remixPrompt, remixOf: c.id, remixSource: srcId,
+ created_at: new Date().toISOString(), winner: null,
+ runs: ids.map(id => ({ model: id, status: 'queued', error: null, seconds: null, cost: null })),
+ };
+ challenges.push(nc); saveChallenges(challenges);
+ for (const id of ids) runModel(nc, id);
+ return send(res, 201, nc);
+ }
+
if ((m = p.match(/^\/api\/challenges\/([a-f0-9]+)\/vote$/)) && req.method === 'POST') {
const c = challenges.find(x => x.id === m[1]);
if (!c) return send(res, 404, { error: 'not found' });
← b15a98b yolo idea 6: daily auto-challenge generator (accrues real ju
·
back to Model Arena
·
yolo idea 7: remix mode — feed the winning/AI-pick artifact' 9944dae →